diff --git a/.flake8 b/.flake8
deleted file mode 100644
index ba265fe89..000000000
--- a/.flake8
+++ /dev/null
@@ -1,3 +0,0 @@
-[flake8]
-max-line-length = 120
-extend-ignore = E501, E203, B028
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4312eb7b9..a755133cc 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,30 +1,11 @@
repos:
- - repo: https://github.com/psf/black
- rev: 24.2.0
- hooks:
- - id: black
-
- - repo: https://github.com/PyCQA/flake8
- rev: 7.0.0
- hooks:
- - id: flake8
- additional_dependencies:
- - flake8-bugbear
- - flake8-comprehensions
- - flake8-simplify
- - pep8-naming
-
- - repo: https://github.com/pycqa/isort
- rev: 5.13.2
- hooks:
- - id: isort
- - repo: https://github.com/asottile/pyupgrade
- rev: v3.15.0
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.1.6
hooks:
- - id: pyupgrade
- args:
- - --py38-plus
+ - id: ruff
+ args: [--fix]
+ - id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
diff --git a/docs/conf.py b/docs/conf.py
index c9826cfd5..f9355ad77 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -55,7 +55,9 @@
needs_debug_measurement = True
add_module_names = False # Used to shorten function name output
-autodoc_docstring_signature = True # Used to read spec. func-defs from docstring (e.g. get rid of self)
+autodoc_docstring_signature = (
+ True # Used to read spec. func-defs from docstring (e.g. get rid of self)
+)
NOTE_TEMPLATE = """
.. _{{id}}:
@@ -80,9 +82,7 @@
{% endif %}
"""
-DEFAULT_DIAGRAM_TEMPLATE = (
- "{{type_name}}\\n**{{title|wordwrap(15, wrapstring='**\\\\n**')}}**\\n{{id}}"
-)
+DEFAULT_DIAGRAM_TEMPLATE = "{{type_name}}\\n**{{title|wordwrap(15, wrapstring='**\\\\n**')}}**\\n{{id}}"
# You can uncomment some of the following lines to override the default configuration for Sphinx-Needs.
# needs_diagram_template = DEFAULT_DIAGRAM_TEMPLATE
@@ -110,16 +110,71 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "title": "System", "content": "plantuml", "prefix": "S_", "color": "#BFD8D2", "style": "card"},
+ {
+ "directive": "sys",
+ "title": "System",
+ "content": "plantuml",
+ "prefix": "S_",
+ "color": "#BFD8D2",
+ "style": "card",
+ },
# Normal types
- {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "S_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "I_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "T_", "color": "#DCB239", "style": "node"},
- {"directive": "feature", "title": "Feature", "prefix": "F_", "color": "#FFCC00", "style": "node"},
- {"directive": "user", "title": "User", "prefix": "U_", "color": "#777777", "style": "node"},
- {"directive": "action", "title": "Action", "prefix": "A_", "color": "#FFCC00", "style": "node"},
- {"directive": "milestone", "title": "Milestone", "prefix": "M_", "color": "#FF3333", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "R_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "S_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "I_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "T_",
+ "color": "#DCB239",
+ "style": "node",
+ },
+ {
+ "directive": "feature",
+ "title": "Feature",
+ "prefix": "F_",
+ "color": "#FFCC00",
+ "style": "node",
+ },
+ {
+ "directive": "user",
+ "title": "User",
+ "prefix": "U_",
+ "color": "#777777",
+ "style": "node",
+ },
+ {
+ "directive": "action",
+ "title": "Action",
+ "prefix": "A_",
+ "color": "#FFCC00",
+ "style": "node",
+ },
+ {
+ "directive": "milestone",
+ "title": "Milestone",
+ "prefix": "M_",
+ "color": "#FF3333",
+ "style": "node",
+ },
]
needs_extra_links = [
@@ -208,7 +263,9 @@
needs_id_required = False
# needs_css = "dark.css"
-local_plantuml_path = os.path.join(os.path.dirname(__file__), "utils", "plantuml-1.2022.14.jar")
+local_plantuml_path = os.path.join(
+ os.path.dirname(__file__), "utils", "plantuml-1.2022.14.jar"
+)
plantuml = f"java -Djava.awt.headless=true -jar {local_plantuml_path}"
# plantuml_output_format = 'png'
@@ -246,7 +303,10 @@
"grid": "simple_side_right_partial",
"layout": {
"head": ['**<>** for *<>*'],
- "meta": ['**status**: <>', '**author**: <>'],
+ "meta": [
+ '**status**: <>',
+ '**author**: <>',
+ ],
"side": ['<>'],
},
},
@@ -450,14 +510,22 @@ def custom_defined_func():
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, "needstestdocs.tex", "needs test docs Documentation", "team useblocks", "manual"),
+ (
+ master_doc,
+ "needstestdocs.tex",
+ "needs test docs Documentation",
+ "team useblocks",
+ "manual",
+ ),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
-man_pages = [(master_doc, "needstestdocs", "needs test docs Documentation", [author], 1)]
+man_pages = [
+ (master_doc, "needstestdocs", "needs test docs Documentation", [author], 1)
+]
# -- Options for Texinfo output -------------------------------------------
@@ -478,7 +546,11 @@ def custom_defined_func():
# contains different constraints
needs_constraints = {
- "critical": {"check_0": "'critical' in tags", "check_1": "'SECURITY_REQ' in links", "severity": "CRITICAL"},
+ "critical": {
+ "check_0": "'critical' in tags",
+ "check_1": "'SECURITY_REQ' in links",
+ "severity": "CRITICAL",
+ },
"security": {"check_0": "'security' in tags", "severity": "HIGH"},
"team": {"check_0": 'author == "Bob"', "severity": "LOW"},
}
diff --git a/noxfile.py b/noxfile.py
index 467cb545e..a67fef8da 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -72,7 +72,15 @@ def pre_commit(session):
def linkcheck(session):
session.install(".[docs]")
with session.chdir("docs"):
- session.run("sphinx-build", "-b", "linkcheck", ".", "_build/linkcheck", *session.posargs, external=True)
+ session.run(
+ "sphinx-build",
+ "-b",
+ "linkcheck",
+ ".",
+ "_build/linkcheck",
+ *session.posargs,
+ external=True,
+ )
@session(python="3.11")
diff --git a/performance/performance_test.py b/performance/performance_test.py
index 1733f6328..c7ca7e368 100644
--- a/performance/performance_test.py
+++ b/performance/performance_test.py
@@ -23,7 +23,15 @@ def cli():
def start(
- needs=1000, needtables=0, dummies=0, pages=1, parallel=1, keep=False, browser=False, debug=False, basic=False
+ needs=1000,
+ needtables=0,
+ dummies=0,
+ pages=1,
+ parallel=1,
+ keep=False,
+ browser=False,
+ debug=False,
+ basic=False,
):
"""
Test run implementation
@@ -163,11 +171,31 @@ def start(
@cli.command()
-@click.option("--profile", default=[], type=str, multiple=True, help="Activates profiling for given area")
-@click.option("--needs", default=[50, 10], type=int, multiple=True, help="Number of maximum needs.")
-@click.option("--needtables", default=-1, type=int, help="Number of maximum needtables.")
+@click.option(
+ "--profile",
+ default=[],
+ type=str,
+ multiple=True,
+ help="Activates profiling for given area",
+)
+@click.option(
+ "--needs",
+ default=[50, 10],
+ type=int,
+ multiple=True,
+ help="Number of maximum needs.",
+)
+@click.option(
+ "--needtables", default=-1, type=int, help="Number of maximum needtables."
+)
@click.option("--dummies", default=-1, type=int, help="Number of standard rst dummies.")
-@click.option("--pages", default=[5, 1], type=int, multiple=True, help="Number of additional pages with needs.")
+@click.option(
+ "--pages",
+ default=[5, 1],
+ type=int,
+ multiple=True,
+ help="Number of additional pages with needs.",
+)
@click.option(
"--parallel",
default=[1, 4],
@@ -177,9 +205,19 @@ def start(
)
@click.option("--keep", is_flag=True, help="Keeps the temporary src and build folders")
@click.option("--browser", is_flag=True, help="Opens the project in your browser")
-@click.option("--snakeviz", is_flag=True, help="Opens snakeviz view for measured profiles in browser")
-@click.option("--debug", is_flag=True, help="Prints more information, incl. sphinx build output")
-@click.option("--basic", is_flag=True, help="Use only default config of Sphinx-Needs (e.g. no extra options)")
+@click.option(
+ "--snakeviz",
+ is_flag=True,
+ help="Opens snakeviz view for measured profiles in browser",
+)
+@click.option(
+ "--debug", is_flag=True, help="Prints more information, incl. sphinx build output"
+)
+@click.option(
+ "--basic",
+ is_flag=True,
+ help="Use only default config of Sphinx-Needs (e.g. no extra options)",
+)
def series(
profile,
needs,
diff --git a/pyproject.toml b/pyproject.toml
index 054de6c18..23fe436da 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -101,11 +101,19 @@ markers = [
"jstest: marks tests as JavaScript test (deselect with '-m \"not jstest\"')",
]
-[tool.black]
-line-length = 120
-
-[tool.isort]
-profile = "black"
+[tool.ruff]
+extend-select = [
+ "B", # flake8-bugbear
+ "C4", # flake8-comprehensions
+ "I", # isort
+ "ICN", # flake8-import-conventions
+ "ISC", # flake8-implicit-str-concat
+ "N", # pep8-naming
+ "RUF", # Ruff-specific rules
+ "SIM", # flake8-simplify
+ "UP", # pyupgrade
+]
+extend-ignore = ["B904", "ISC001", "ICN001", "N818", "RUF005", "RUF013", "RUF012", "SIM108", "SIM118"]
[tool.mypy]
files = "sphinx_needs"
diff --git a/sphinx_needs/api/configuration.py b/sphinx_needs/api/configuration.py
index 8b06ab045..1197cd8c4 100644
--- a/sphinx_needs/api/configuration.py
+++ b/sphinx_needs/api/configuration.py
@@ -37,7 +37,12 @@ def get_need_types(app: Sphinx) -> list[str]:
def add_need_type(
- app: Sphinx, directive: str, title: str, prefix: str, color: str = "#ffffff", style: str = "node"
+ app: Sphinx,
+ directive: str,
+ title: str,
+ prefix: str,
+ color: str = "#ffffff",
+ style: str = "node",
) -> None:
"""
Adds a new need_type to the configuration.
@@ -68,7 +73,15 @@ def add_need_type(
if directive in type_names:
raise NeedsApiConfigException(f"{directive} already exists as need type")
- needs_types.append({"directive": directive, "title": title, "prefix": prefix, "color": color, "style": style})
+ needs_types.append(
+ {
+ "directive": directive,
+ "title": title,
+ "prefix": prefix,
+ "color": color,
+ "style": style,
+ }
+ )
app.add_directive(directive, sphinx_needs.directives.need.NeedDirective)
@@ -93,7 +106,9 @@ def add_extra_option(app: Sphinx, name: str) -> None:
NEEDS_CONFIG.extra_options[name] = directives.unchanged
-def add_dynamic_function(app: Sphinx, function: DynamicFunction, name: str | None = None) -> None:
+def add_dynamic_function(
+ app: Sphinx, function: DynamicFunction, name: str | None = None
+) -> None:
"""
Registers a new dynamic function for sphinx-needs.
@@ -124,7 +139,12 @@ def my_function(app, need, needs, *args, **kwargs):
WarningCheck = Callable[[NeedsInfoType, SphinxLoggerAdapter], bool]
-def add_warning(app: Sphinx, name: str, function: WarningCheck | None = None, filter_string: str | None = None) -> None:
+def add_warning(
+ app: Sphinx,
+ name: str,
+ function: WarningCheck | None = None,
+ filter_string: str | None = None,
+) -> None:
"""
Registers a warning.
@@ -137,11 +157,14 @@ def add_warning(app: Sphinx, name: str, function: WarningCheck | None = None, fi
:return: None
"""
if function is None and filter_string is None:
- raise NeedsApiConfigException("Function or filter_string must be given for add_warning_func")
+ raise NeedsApiConfigException(
+ "Function or filter_string must be given for add_warning_func"
+ )
if function is not None and filter_string is not None:
raise NeedsApiConfigException(
- "For add_warning_func only function or filter_string is allowed to be set, " "not both."
+ "For add_warning_func only function or filter_string is allowed to be set, "
+ "not both."
)
warning_check = function or filter_string
diff --git a/sphinx_needs/api/need.py b/sphinx_needs/api/need.py
index 1a1b87f8b..32dec8513 100644
--- a/sphinx_needs/api/need.py
+++ b/sphinx_needs/api/need.py
@@ -152,8 +152,8 @@ def run():
configured_need_types = [ntype["directive"] for ntype in types]
if need_type not in configured_need_types:
logger.warning(
- "Couldn't create need {}. Reason: The need-type (i.e. `{}`) is not set "
- "in the project's 'need_types' configuration in conf.py. [needs]".format(id, need_type),
+ f"Couldn't create need {id}. Reason: The need-type (i.e. `{need_type}`) is not set "
+ "in the project's 'need_types' configuration in conf.py. [needs]",
type="needs",
)
@@ -161,7 +161,9 @@ def run():
if ntype["directive"] == need_type:
type_name = ntype["title"]
type_prefix = ntype["prefix"]
- type_color = ntype["color"] or "#000000" # if no color set up user in config
+ type_color = (
+ ntype["color"] or "#000000"
+ ) # if no color set up user in config
type_style = ntype["style"] or "node" # if no style set up user in config
found = True
break
@@ -184,7 +186,7 @@ def run():
if id is None and needs_config.id_required:
raise NeedsNoIdException(
"An id is missing for this need and must be set, because 'needs_id_required' "
- "is set to True in conf.py. Need '{}' in {} ({})".format(title, docname, lineno)
+ f"is set to True in conf.py. Need '{title}' in {docname} ({lineno})"
)
if id is None:
@@ -193,13 +195,18 @@ def run():
need_id = id
if needs_config.id_regex and not re.match(needs_config.id_regex, need_id):
- raise NeedsInvalidException(f"Given ID '{need_id}' does not match configured regex '{needs_config.id_regex}'")
+ raise NeedsInvalidException(
+ f"Given ID '{need_id}' does not match configured regex '{needs_config.id_regex}'"
+ )
# Handle status
# Check if status is in needs_statuses. If not raise an error.
- if needs_config.statuses and status not in [stat["name"] for stat in needs_config.statuses]:
+ if needs_config.statuses and status not in [
+ stat["name"] for stat in needs_config.statuses
+ ]:
raise NeedsStatusNotAllowed(
- f"Status {status} of need id {need_id} is not allowed " "by config value 'needs_statuses'."
+ f"Status {status} of need id {need_id} is not allowed "
+ "by config value 'needs_statuses'."
)
if tags is None:
@@ -212,7 +219,8 @@ def run():
for i in range(len(tags)):
if len(tags[i]) == 0 or tags[i].isspace():
logger.warning(
- f"Scruffy tag definition found in need {need_id}. " "Defined tag contains spaces only. [needs]",
+ f"Scruffy tag definition found in need {need_id}. "
+ "Defined tag contains spaces only. [needs]",
type="needs",
)
else:
@@ -225,7 +233,8 @@ def run():
needs_tags = [tag["name"] for tag in needs_config.tags]
if tag not in needs_tags:
raise NeedsTagNotAllowed(
- f"Tag {tag} of need id {need_id} is not allowed " "by config value 'needs_tags'."
+ f"Tag {tag} of need id {need_id} is not allowed "
+ "by config value 'needs_tags'."
)
# This may have cut also dynamic function strings, as they can contain , as well.
# So let put them together again
@@ -237,7 +246,9 @@ def run():
if len(constraints) > 0:
# tags should be a string, but it can also be already a list,which can be used.
if isinstance(constraints, str):
- constraints = [constraint.strip() for constraint in re.split("[;,]", constraints)]
+ constraints = [
+ constraint.strip() for constraint in re.split("[;,]", constraints)
+ ]
new_constraints = [] # Shall contain only valid constraints
for i in range(len(constraints)):
@@ -356,9 +367,9 @@ def run():
for keyword in kwargs:
if keyword not in needs_extra_option_names and keyword not in link_names:
raise NeedsInvalidOption(
- "Unknown Option {}. "
+ f"Unknown Option {keyword}. "
"Use needs_extra_options or needs_extra_links in conf.py"
- "to define this option.".format(keyword)
+ "to define this option."
)
# Merge links
@@ -366,11 +377,15 @@ def run():
for link_type in needs_config.extra_links:
# Check, if specific link-type got some arguments during method call
- if link_type["option"] not in kwargs and link_type["option"] not in needs_global_options:
+ if (
+ link_type["option"] not in kwargs
+ and link_type["option"] not in needs_global_options
+ ):
# if not we set no links, but entry in needS_info must be there
links = []
elif link_type["option"] in needs_global_options and (
- link_type["option"] not in kwargs or len(str(kwargs[link_type["option"]])) == 0
+ link_type["option"] not in kwargs
+ or len(str(kwargs[link_type["option"]])) == 0
):
# If it is in global option, value got already set during prior handling of them
links_string = needs_info[link_type["option"]]
@@ -585,7 +600,9 @@ def _prepare_template(app: Sphinx, needs_info, template_key: str) -> str:
template_folder = os.path.join(app.srcdir, template_folder)
if not os.path.isdir(template_folder):
- raise NeedsTemplateException(f"Template folder does not exist: {template_folder}")
+ raise NeedsTemplateException(
+ f"Template folder does not exist: {template_folder}"
+ )
template_file_name = needs_info[template_key] + ".need"
template_path = os.path.join(template_folder, template_file_name)
@@ -600,7 +617,9 @@ def _prepare_template(app: Sphinx, needs_info, template_key: str) -> str:
return new_content
-def _render_template(content: str, docname: str, lineno: int, state: RSTState) -> nodes.Element:
+def _render_template(
+ content: str, docname: str, lineno: int, state: RSTState
+) -> nodes.Element:
rst = StringList()
for line in content.split("\n"):
rst.append(line, docname, lineno)
@@ -610,7 +629,9 @@ def _render_template(content: str, docname: str, lineno: int, state: RSTState) -
return node_need_content
-def _render_plantuml_template(content: str, docname: str, lineno: int, state: RSTState) -> nodes.Element:
+def _render_plantuml_template(
+ content: str, docname: str, lineno: int, state: RSTState
+) -> nodes.Element:
rst = StringList()
rst.append(".. needuml::", docname, lineno)
rst.append("", docname, lineno) # Empty option line for needuml
@@ -636,7 +657,8 @@ def _read_in_links(links_string: str | list[str]) -> list[str]:
for link in link_list:
if link.isspace():
logger.warning(
- f"Grubby link definition found in need {id}. " "Defined link contains spaces only. [needs]",
+ f"Grubby link definition found in need {id}. "
+ "Defined link contains spaces only. [needs]",
type="needs",
)
else:
@@ -648,7 +670,13 @@ def _read_in_links(links_string: str | list[str]) -> list[str]:
return _fix_list_dyn_func(links)
-def make_hashed_id(app: Sphinx, need_type: str, full_title: str, content: str, id_length: int | None = None) -> str:
+def make_hashed_id(
+ app: Sphinx,
+ need_type: str,
+ full_title: str,
+ content: str,
+ id_length: int | None = None,
+) -> str:
"""
Creates an ID based on title or need.
@@ -671,7 +699,9 @@ def make_hashed_id(app: Sphinx, need_type: str, full_title: str, content: str, i
type_prefix = ntype["prefix"]
break
if type_prefix is None:
- raise NeedsInvalidException(f"Given need_type {need_type} is unknown. File {app.env.docname}")
+ raise NeedsInvalidException(
+ f"Given need_type {need_type} is unknown. File {app.env.docname}"
+ )
hashable_content = full_title or "\n".join(content)
hashed_id = hashlib.sha1(hashable_content.encode("UTF-8")).hexdigest().upper()
@@ -764,11 +794,15 @@ def _merge_global_options(app: Sphinx, needs_info, global_options) -> None:
for single_value in values:
if len(single_value) < 2 or len(single_value) > 3:
- raise NeedsInvalidException(f"global option tuple has wrong amount of parameters: {key}")
+ raise NeedsInvalidException(
+ f"global option tuple has wrong amount of parameters: {key}"
+ )
if filter_single_need(needs_info, config, single_value[1]):
# Set value, if filter has matched
needs_info[key] = single_value[0]
- elif len(single_value) == 3 and (key not in needs_info.keys() or len(str(needs_info[key])) > 0):
+ elif len(single_value) == 3 and (
+ key not in needs_info.keys() or len(str(needs_info[key])) > 0
+ ):
# Otherwise set default, but only if no value was set before or value is "" and a default is defined
needs_info[key] = single_value[2]
else:
diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py
index e1eaf7994..b4ebea207 100644
--- a/sphinx_needs/builder.py
+++ b/sphinx_needs/builder.py
@@ -50,7 +50,9 @@ def write(
if not SphinxNeedsData(self.env).has_export_filters:
return
LOGGER.warning(
- "At least one use of `export_id` directive option, requires a slower build", type="needs", subtype="build"
+ "At least one use of `export_id` directive option, requires a slower build",
+ type="needs",
+ subtype="build",
)
return super().write(build_docnames, updated_docnames, method)
@@ -70,7 +72,9 @@ def finish(self) -> None:
# check if needs.json file exists in conf.py directory
needs_json = os.path.join(self.srcdir, "needs.json")
if os.path.exists(needs_json):
- LOGGER.info("needs.json found, but will not be used because needs_file not configured.")
+ LOGGER.info(
+ "needs.json found, but will not be used because needs_file not configured."
+ )
# Clean needs_list from already stored needs of the current version.
# This is needed as needs could have been removed from documentation and if this is the case,
@@ -170,7 +174,9 @@ def finish(self) -> None:
post_process_needs_data(self.app)
data = SphinxNeedsData(self.env)
- needs = data.get_or_create_needs().values() # We need a list of needs for later filter checks
+ needs = (
+ data.get_or_create_needs().values()
+ ) # We need a list of needs for later filter checks
version = getattr(self.env.config, "version", "unset")
needs_config = NeedsSphinxConfig(self.env.config)
filter_string = needs_config.builder_filter
diff --git a/sphinx_needs/config.py b/sphinx_needs/config.py
index a988074fe..785436f7e 100644
--- a/sphinx_needs/config.py
+++ b/sphinx_needs/config.py
@@ -26,7 +26,9 @@ class Config:
def __init__(self) -> None:
self._extra_options: dict[str, Callable[[str], Any]] = {}
- self._warnings: dict[str, str | Callable[[NeedsInfoType, SphinxLoggerAdapter], bool]] = {}
+ self._warnings: dict[
+ str, str | Callable[[NeedsInfoType, SphinxLoggerAdapter], bool]
+ ] = {}
def clear(self) -> None:
self._extra_options = {}
@@ -44,7 +46,9 @@ def extra_options(self) -> dict[str, Callable[[str], Any]]:
return self._extra_options
@property
- def warnings(self) -> dict[str, str | Callable[[NeedsInfoType, SphinxLoggerAdapter], bool]]:
+ def warnings(
+ self
+ ) -> dict[str, str | Callable[[NeedsInfoType, SphinxLoggerAdapter], bool]]:
"""Warning handlers that are added by the user,
then called at the end of the build.
"""
@@ -130,58 +134,117 @@ def __setattr__(self, name: str, value: Any) -> None:
metadata={"rebuild": "html", "types": ()},
)
"""Custom user need types"""
- include_needs: bool = field(default=True, metadata={"rebuild": "html", "types": (bool,)})
- need_name: str = field(default="Need", metadata={"rebuild": "html", "types": (str,)})
- spec_name: str = field(default="Specification", metadata={"rebuild": "html", "types": (str,)})
- id_prefix_needs: str = field(default="", metadata={"rebuild": "html", "types": (str,)})
- id_prefix_specs: str = field(default="", metadata={"rebuild": "html", "types": (str,)})
+ include_needs: bool = field(
+ default=True, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ need_name: str = field(
+ default="Need", metadata={"rebuild": "html", "types": (str,)}
+ )
+ spec_name: str = field(
+ default="Specification", metadata={"rebuild": "html", "types": (str,)}
+ )
+ id_prefix_needs: str = field(
+ default="", metadata={"rebuild": "html", "types": (str,)}
+ )
+ id_prefix_specs: str = field(
+ default="", metadata={"rebuild": "html", "types": (str,)}
+ )
id_length: int = field(default=5, metadata={"rebuild": "html", "types": (int,)})
- id_from_title: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- specs_show_needlist: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- id_required: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- id_regex: str = field(default="^[A-Z0-9_]{5,}", metadata={"rebuild": "html", "types": ()})
- show_link_type: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- show_link_title: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- show_link_id: bool = field(default=True, metadata={"rebuild": "html", "types": (bool,)})
+ id_from_title: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ specs_show_needlist: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ id_required: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ id_regex: str = field(
+ default="^[A-Z0-9_]{5,}", metadata={"rebuild": "html", "types": ()}
+ )
+ show_link_type: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ show_link_title: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ show_link_id: bool = field(
+ default=True, metadata={"rebuild": "html", "types": (bool,)}
+ )
file: None | str = field(default=None, metadata={"rebuild": "html", "types": ()})
table_columns: str = field(
- default="ID;TITLE;STATUS;TYPE;OUTGOING;TAGS", metadata={"rebuild": "html", "types": (str,)}
- )
- table_style: str = field(default="DATATABLES", metadata={"rebuild": "html", "types": (str,)})
- role_need_template: str = field(default="{title} ({id})", metadata={"rebuild": "html", "types": (str,)})
- role_need_max_title_length: int = field(default=30, metadata={"rebuild": "html", "types": (int,)})
- extra_options: list[str] = field(default_factory=list, metadata={"rebuild": "html", "types": (list,)})
- title_optional: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- max_title_length: int = field(default=-1, metadata={"rebuild": "html", "types": (int,)})
- title_from_content: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
+ default="ID;TITLE;STATUS;TYPE;OUTGOING;TAGS",
+ metadata={"rebuild": "html", "types": (str,)},
+ )
+ table_style: str = field(
+ default="DATATABLES", metadata={"rebuild": "html", "types": (str,)}
+ )
+ role_need_template: str = field(
+ default="{title} ({id})", metadata={"rebuild": "html", "types": (str,)}
+ )
+ role_need_max_title_length: int = field(
+ default=30, metadata={"rebuild": "html", "types": (int,)}
+ )
+ extra_options: list[str] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": (list,)}
+ )
+ title_optional: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ max_title_length: int = field(
+ default=-1, metadata={"rebuild": "html", "types": (int,)}
+ )
+ title_from_content: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
diagram_template: str = field(
default=DEFAULT_DIAGRAM_TEMPLATE,
metadata={"rebuild": "html", "types": (str,)},
)
- functions: list[Callable[..., Any]] = field(default_factory=list, metadata={"rebuild": "html", "types": (list,)})
- global_options: dict[str, Any] = field(default_factory=dict, metadata={"rebuild": "html", "types": (dict,)})
- duration_option: str = field(default="duration", metadata={"rebuild": "html", "types": (str,)})
- completion_option: str = field(default="completion", metadata={"rebuild": "html", "types": (str,)})
- needextend_strict: bool = field(default=True, metadata={"rebuild": "html", "types": (bool,)})
- statuses: list[dict[str, str]] = field(default_factory=list, metadata={"rebuild": "html", "types": ()})
+ functions: list[Callable[..., Any]] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": (list,)}
+ )
+ global_options: dict[str, Any] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": (dict,)}
+ )
+ duration_option: str = field(
+ default="duration", metadata={"rebuild": "html", "types": (str,)}
+ )
+ completion_option: str = field(
+ default="completion", metadata={"rebuild": "html", "types": (str,)}
+ )
+ needextend_strict: bool = field(
+ default=True, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ statuses: list[dict[str, str]] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": ()}
+ )
"""If given, only the defined status are allowed.
Values needed for each status:
* name
* description
Example: [{"name": "open", "description": "open status"}, {...}, {...}]
"""
- tags: list[dict[str, str]] = field(default_factory=list, metadata={"rebuild": "html", "types": (list,)})
+ tags: list[dict[str, str]] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": (list,)}
+ )
"""If given, only the defined tags are allowed.
Values needed for each tag:
* name
* description
Example: [{"name": "new", "description": "new needs"}, {...}, {...}]
"""
- css: str = field(default="modern.css", metadata={"rebuild": "html", "types": (str,)})
+ css: str = field(
+ default="modern.css", metadata={"rebuild": "html", "types": (str,)}
+ )
"""Path of css file, which shall be used for need style"""
- part_prefix: str = field(default="→\xa0", metadata={"rebuild": "html", "types": (str,)})
+ part_prefix: str = field(
+ default="→\xa0", metadata={"rebuild": "html", "types": (str,)}
+ )
"""Prefix for need_part output in tables"""
- extra_links: list[dict[str, Any]] = field(default_factory=list, metadata={"rebuild": "html", "types": ()})
+ extra_links: list[dict[str, Any]] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": ()}
+ )
"""List of additional links, which can be used by setting related option
Values needed for each new link:
* option (will also be the option name)
@@ -190,48 +253,97 @@ def __setattr__(self, name: str, value: Any) -> None:
* color (used for needflow. Default: #000000)
Example: [{"name": "blocks, "incoming": "is blocked by", "copy_link": True, "color": "#ffcc00"}]
"""
- report_dead_links: bool = field(default=True, metadata={"rebuild": "html", "types": (bool,)})
+ report_dead_links: bool = field(
+ default=True, metadata={"rebuild": "html", "types": (bool,)}
+ )
"""DEPRECATED: Use ``suppress_warnings = ["needs.link_outgoing"]`` instead."""
- filter_data: dict[str, Any] = field(default_factory=dict, metadata={"rebuild": "html", "types": ()})
- allow_unsafe_filters: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- flow_show_links: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- flow_link_types: list[str] = field(default_factory=lambda: ["links"], metadata={"rebuild": "html", "types": ()})
+ filter_data: dict[str, Any] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": ()}
+ )
+ allow_unsafe_filters: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ flow_show_links: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ flow_link_types: list[str] = field(
+ default_factory=lambda: ["links"], metadata={"rebuild": "html", "types": ()}
+ )
"""Defines the link_types to show in a needflow diagram."""
- warnings: dict[str, Any] = field(default_factory=dict, metadata={"rebuild": "html", "types": ()})
- warnings_always_warn: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- layouts: dict[str, dict[str, Any]] = field(default_factory=dict, metadata={"rebuild": "html", "types": ()})
- default_layout: str = field(default="clean", metadata={"rebuild": "html", "types": (str,)})
- default_style: None | str = field(default=None, metadata={"rebuild": "html", "types": ()})
- flow_configs: dict[str, str] = field(default_factory=dict, metadata={"rebuild": "html", "types": ()})
- template_folder: str = field(default="needs_templates/", metadata={"rebuild": "html", "types": (str,)})
- services: dict[str, dict[str, Any]] = field(default_factory=dict, metadata={"rebuild": "html", "types": ()})
- service_all_data: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- debug_no_external_calls: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- external_needs: list[dict[str, Any]] = field(default_factory=list, metadata={"rebuild": "html", "types": ()})
+ warnings: dict[str, Any] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": ()}
+ )
+ warnings_always_warn: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ layouts: dict[str, dict[str, Any]] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": ()}
+ )
+ default_layout: str = field(
+ default="clean", metadata={"rebuild": "html", "types": (str,)}
+ )
+ default_style: None | str = field(
+ default=None, metadata={"rebuild": "html", "types": ()}
+ )
+ flow_configs: dict[str, str] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": ()}
+ )
+ template_folder: str = field(
+ default="needs_templates/", metadata={"rebuild": "html", "types": (str,)}
+ )
+ services: dict[str, dict[str, Any]] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": ()}
+ )
+ service_all_data: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ debug_no_external_calls: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ external_needs: list[dict[str, Any]] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": ()}
+ )
"""Reference external needs, outside of the documentation."""
- builder_filter: str = field(default="is_external==False", metadata={"rebuild": "html", "types": (str,)})
+ builder_filter: str = field(
+ default="is_external==False", metadata={"rebuild": "html", "types": (str,)}
+ )
table_classes: list[str] = field(
- default_factory=lambda: NEEDS_TABLES_CLASSES, metadata={"rebuild": "html", "types": (list,)}
+ default_factory=lambda: NEEDS_TABLES_CLASSES,
+ metadata={"rebuild": "html", "types": (list,)},
)
"""Additional classes to set for needs and needtable."""
string_links: dict[str, dict[str, Any]] = field(
default_factory=dict, metadata={"rebuild": "html", "types": (dict,)}
)
- build_json: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
+ build_json: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
"""If True, the JSON needs file should be built."""
- reproducible_json: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
+ reproducible_json: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
"""If True, the JSON needs file should be idempotent for multiple builds fo the same documentation."""
- build_needumls: str = field(default="", metadata={"rebuild": "html", "types": (str,)})
- permalink_file: str = field(default="permalink.html", metadata={"rebuild": "html", "types": (str,)})
+ build_needumls: str = field(
+ default="", metadata={"rebuild": "html", "types": (str,)}
+ )
+ permalink_file: str = field(
+ default="permalink.html", metadata={"rebuild": "html", "types": (str,)}
+ )
"""Permalink related config values.
path to permalink.html; absolute path from web-root
"""
- permalink_data: str = field(default="needs.json", metadata={"rebuild": "html", "types": (str,)})
+ permalink_data: str = field(
+ default="needs.json", metadata={"rebuild": "html", "types": (str,)}
+ )
"""path to needs.json relative to permalink.html"""
- report_template: str = field(default="", metadata={"rebuild": "html", "types": (str,)})
+ report_template: str = field(
+ default="", metadata={"rebuild": "html", "types": (str,)}
+ )
"""path to needs_report_template file which is based on the conf.py directory."""
- constraints: dict[str, dict[str, str]] = field(default_factory=dict, metadata={"rebuild": "html", "types": (dict,)})
+ constraints: dict[str, dict[str, str]] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": (dict,)}
+ )
"""Mapping of constraint name, to check name, to filter string.
There are also some special keys for a constraint:
@@ -242,21 +354,35 @@ def __setattr__(self, name: str, value: Any) -> None:
default_factory=dict, metadata={"rebuild": "html", "types": (dict,)}
)
"""Mapping of constraint severity to what to do if a constraint is not fulfilled."""
- constraints_failed_color: str = field(default="", metadata={"rebuild": "html", "types": (str,)})
+ constraints_failed_color: str = field(
+ default="", metadata={"rebuild": "html", "types": (str,)}
+ )
"""DEPRECATED: Use constraint_failed_options instead."""
# add variants option
- variants: dict[str, str] = field(default_factory=dict, metadata={"rebuild": "html", "types": (dict,)})
- variant_options: list[str] = field(default_factory=list, metadata={"rebuild": "html", "types": (list,)})
+ variants: dict[str, str] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": (dict,)}
+ )
+ variant_options: list[str] = field(
+ default_factory=list, metadata={"rebuild": "html", "types": (list,)}
+ )
# add render context option
- render_context: dict[str, Any] = field(default_factory=dict, metadata={"rebuild": "html", "types": (dict,)})
+ render_context: dict[str, Any] = field(
+ default_factory=dict, metadata={"rebuild": "html", "types": (dict,)}
+ )
"""Jinja context for rendering templates"""
- debug_measurement: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
+ debug_measurement: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
# add config for needs_id_builder
- build_json_per_id: bool = field(default=False, metadata={"rebuild": "html", "types": (bool,)})
- build_json_per_id_path: str = field(default="needs_id", metadata={"rebuild": "html", "types": (str,)})
+ build_json_per_id: bool = field(
+ default=False, metadata={"rebuild": "html", "types": (bool,)}
+ )
+ build_json_per_id_path: str = field(
+ default="needs_id", metadata={"rebuild": "html", "types": (str,)}
+ )
@classmethod
def add_config_values(cls, app: Sphinx) -> None:
@@ -267,7 +393,9 @@ def add_config_values(cls, app: Sphinx) -> None:
elif item.default is not MISSING:
default = item.default
else:
- raise Exception(f"Config item {item.name} has no default value or factory.")
+ raise Exception(
+ f"Config item {item.name} has no default value or factory."
+ )
app.add_config_value(
f"needs_{item.name}",
default,
diff --git a/sphinx_needs/data.py b/sphinx_needs/data.py
index abea4ce70..a36e362e3 100644
--- a/sphinx_needs/data.py
+++ b/sphinx_needs/data.py
@@ -592,7 +592,9 @@ def get_or_create_umls(self) -> dict[str, NeedsUmlType]:
return self.env.needs_all_needumls
-def merge_data(_app: Sphinx, env: BuildEnvironment, _docnames: list[str], other: BuildEnvironment) -> None:
+def merge_data(
+ _app: Sphinx, env: BuildEnvironment, _docnames: list[str], other: BuildEnvironment
+) -> None:
"""
Performs data merge of parallel executed workers.
Used only for parallel builds.
@@ -621,14 +623,17 @@ def _merge(name: str, is_complex_dict: bool = False) -> None:
for other_key, other_value in other_objects.items():
# other_value is a list from here on!
if other_key in objects:
- objects[other_key] = list(set(objects[other_key]) | set(other_value))
+ objects[other_key] = list(
+ set(objects[other_key]) | set(other_value)
+ )
else:
objects[other_key] = other_value
elif isinstance(other_objects, list) and isinstance(objects, list):
objects = list(set(objects) | set(other_objects))
else:
raise TypeError(
- f'Objects to "merge" must be dict or list, ' f"not {type(other_objects)} and {type(objects)}"
+ f'Objects to "merge" must be dict or list, '
+ f"not {type(other_objects)} and {type(objects)}"
)
_merge("needs_all_docs", is_complex_dict=True)
diff --git a/sphinx_needs/debug.py b/sphinx_needs/debug.py
index 1fca7239b..ee426a076 100644
--- a/sphinx_needs/debug.py
+++ b/sphinx_needs/debug.py
@@ -18,14 +18,18 @@
from sphinx.application import Sphinx
TIME_MEASUREMENTS: dict[str, Any] = {} # Stores the timing results
-EXECUTE_TIME_MEASUREMENTS = False # Will be used to de/activate measurements. Set during a Sphinx Event
+EXECUTE_TIME_MEASUREMENTS = (
+ False # Will be used to de/activate measurements. Set during a Sphinx Event
+)
START_TIME = 0.0
T = TypeVar("T", bound=Callable[..., Any])
-def measure_time(category: str | None = None, source: str = "internal", name: str | None = None) -> Callable[[T], T]:
+def measure_time(
+ category: str | None = None, source: str = "internal", name: str | None = None
+) -> Callable[[T], T]:
"""
Decorator for measuring the needed execution time of a specific function.
@@ -108,9 +112,13 @@ def wrapper(*args: list[object], **kwargs: dict[object, object]) -> Any:
runtime_dict["max"] = runtime
runtime_dict["max_params"] = { # Store parameters as a shorten string
"args": str([str(arg)[:80] for arg in args]),
- "kwargs": str({key: str(value)[:80] for key, value in kwargs.items()}),
+ "kwargs": str(
+ {key: str(value)[:80] for key, value in kwargs.items()}
+ ),
}
- runtime_dict["min_max_spread"] = runtime_dict["max"] / runtime_dict["min"] * 100
+ runtime_dict["min_max_spread"] = (
+ runtime_dict["max"] / runtime_dict["min"] * 100
+ )
runtime_dict["avg"] = runtime_dict["overall"] / runtime_dict["amount"]
return result
@@ -119,7 +127,12 @@ def wrapper(*args: list[object], **kwargs: dict[object, object]) -> Any:
return inner
-def measure_time_func(func: T, category: str | None = None, source: str = "internal", name: str | None = None) -> T:
+def measure_time_func(
+ func: T,
+ category: str | None = None,
+ source: str = "internal",
+ name: str | None = None,
+) -> T:
"""Wrapper for measuring the needed execution time of a specific function.
Usage as function::
@@ -154,7 +167,9 @@ def store_timing_results_json(outdir: str, build_data: dict[str, Any]) -> None:
def store_timing_results_html(outdir: str, build_data: dict[str, Any]) -> None:
- jinja_env = Environment(loader=PackageLoader("sphinx_needs"), autoescape=select_autoescape())
+ jinja_env = Environment(
+ loader=PackageLoader("sphinx_needs"), autoescape=select_autoescape()
+ )
template = jinja_env.get_template("time_measurements.html")
out_file = Path(outdir) / "debug_measurement.html"
with open(out_file, "w", encoding="utf-8") as f:
diff --git a/sphinx_needs/diagrams_common.py b/sphinx_needs/diagrams_common.py
index 15de4321c..0eced3edb 100644
--- a/sphinx_needs/diagrams_common.py
+++ b/sphinx_needs/diagrams_common.py
@@ -114,7 +114,9 @@ def add_config(config: str) -> str:
uml = ""
if config and len(config) >= 3:
# Remove all empty lines
- config = "\n".join([line.strip() for line in config.split("\n") if line.strip()])
+ config = "\n".join(
+ [line.strip() for line in config.split("\n") if line.strip()]
+ )
uml += "\n' Config\n\n"
uml += config
uml += "\n\n"
@@ -125,13 +127,27 @@ def get_filter_para(node_element: NeedsFilteredBaseType) -> nodes.paragraph:
"""Return paragraph containing the used filter description"""
para = nodes.paragraph()
filter_text = "Used filter:"
- filter_text += " status(%s)" % " OR ".join(node_element["status"]) if len(node_element["status"]) > 0 else ""
+ filter_text += (
+ " status(%s)" % " OR ".join(node_element["status"])
+ if len(node_element["status"]) > 0
+ else ""
+ )
if len(node_element["status"]) > 0 and len(node_element["tags"]) > 0:
filter_text += " AND "
- filter_text += " tags(%s)" % " OR ".join(node_element["tags"]) if len(node_element["tags"]) > 0 else ""
- if (len(node_element["status"]) > 0 or len(node_element["tags"]) > 0) and len(node_element["types"]) > 0:
+ filter_text += (
+ " tags(%s)" % " OR ".join(node_element["tags"])
+ if len(node_element["tags"]) > 0
+ else ""
+ )
+ if (len(node_element["status"]) > 0 or len(node_element["tags"]) > 0) and len(
+ node_element["types"]
+ ) > 0:
filter_text += " AND "
- filter_text += " types(%s)" % " OR ".join(node_element["types"]) if len(node_element["types"]) > 0 else ""
+ filter_text += (
+ " types(%s)" % " OR ".join(node_element["types"])
+ if len(node_element["types"]) > 0
+ else ""
+ )
filter_node = nodes.emphasis(filter_text, filter_text)
para += filter_node
@@ -152,7 +168,9 @@ def get_debug_container(puml_node: nodes.Element) -> nodes.container:
return debug_container
-def calculate_link(app: Sphinx, need_info: NeedsPartsInfoType, _fromdocname: str) -> str:
+def calculate_link(
+ app: Sphinx, need_info: NeedsPartsInfoType, _fromdocname: str
+) -> str:
"""
Link calculation
All links we can get from docutils functions will be relative.
@@ -168,7 +186,9 @@ def calculate_link(app: Sphinx, need_info: NeedsPartsInfoType, _fromdocname: str
builder = app.builder
try:
if need_info["is_external"]:
- assert need_info["external_url"] is not None, "external_url must be set for external needs"
+ assert (
+ need_info["external_url"] is not None
+ ), "external_url must be set for external needs"
link = need_info["external_url"]
# check if need_info["external_url"] is relative path
parsed_url = urlparse(need_info["external_url"])
@@ -176,7 +196,12 @@ def calculate_link(app: Sphinx, need_info: NeedsPartsInfoType, _fromdocname: str
# only need to add ../ or ..\ to get out of the image folder
link = ".." + os.path.sep + need_info["external_url"]
else:
- link = "../" + builder.get_target_uri(need_info["docname"]) + "#" + need_info["target_id"]
+ link = (
+ "../"
+ + builder.get_target_uri(need_info["docname"])
+ + "#"
+ + need_info["target_id"]
+ )
if need_info["is_part"]:
link = f"{link}.{need_info['id']}"
@@ -188,7 +213,9 @@ def calculate_link(app: Sphinx, need_info: NeedsPartsInfoType, _fromdocname: str
def create_legend(need_types: list[dict[str, Any]]) -> str:
def create_row(need_type: dict[str, Any]) -> str:
- return "\n| {color} | {name} |".format(color=need_type["color"], name=need_type["title"])
+ return "\n| {color} | {name} |".format(
+ color=need_type["color"], name=need_type["title"]
+ )
rows = map(create_row, need_types)
table = "|= Color |= Type |" + "".join(rows)
diff --git a/sphinx_needs/directives/list2need.py b/sphinx_needs/directives/list2need.py
index bbdd27643..928a73d1a 100644
--- a/sphinx_needs/directives/list2need.py
+++ b/sphinx_needs/directives/list2need.py
@@ -23,8 +23,12 @@
"""
-LINE_REGEX = re.compile(r"(?P[^\S\n]*)\*\s*(?P.*)|[\S\*]*(?P.*)")
-ID_REGEX = re.compile(r"(\((?P[^\"'=\n]+)?\))") # Exclude some chars, which are used by option list
+LINE_REGEX = re.compile(
+ r"(?P[^\S\n]*)\*\s*(?P.*)|[\S\*]*(?P.*)"
+)
+ID_REGEX = re.compile(
+ r"(\((?P[^\"'=\n]+)?\))"
+) # Exclude some chars, which are used by option list
OPTION_AREA_REGEX = re.compile(r"\(\((.*)\)\)")
OPTIONS_REGEX = re.compile(r"([^=,\s]*)=[\"']([^\"]*)[\"']")
@@ -83,7 +87,9 @@ def run(self) -> Sequence[nodes.Node]:
for x in range(0, len(types_raw_list)):
types[x] = types_raw_list[x]
if types[x] not in conf_types:
- raise SphinxError(f"Unknown type configured: {types[x]}. Allowed are {', '.join(conf_types)}")
+ raise SphinxError(
+ f"Unknown type configured: {types[x]}. Allowed are {', '.join(conf_types)}"
+ )
down_links_raw = self.options.get("links-down")
if down_links_raw is None or down_links_raw == "":
@@ -99,7 +105,10 @@ def run(self) -> Sequence[nodes.Node]:
for i, down_link_raw in enumerate(down_links_raw_list):
down_links_types[i] = down_link_raw
if down_link_raw not in link_types:
- raise SphinxError(f"Unknown link configured: {down_link_raw}. " f"Allowed are {', '.join(link_types)}")
+ raise SphinxError(
+ f"Unknown link configured: {down_link_raw}. "
+ f"Allowed are {', '.join(link_types)}"
+ )
list_needs = []
# Storing the data in a sorted list
for content_line in content_raw.split("\n"):
@@ -112,23 +121,30 @@ def run(self) -> Sequence[nodes.Node]:
if text:
indent = len(indent)
if not indent % 2 == 0:
- raise IndentationError("Indentation for list must be always a multiply of 2.")
+ raise IndentationError(
+ "Indentation for list must be always a multiply of 2."
+ )
level = int(indent / 2)
if level not in types:
raise SphinxWarning(
- f"No need type defined for indentation level {level}." f" Defined types {types}"
+ f"No need type defined for indentation level {level}."
+ f" Defined types {types}"
)
if down_links_types and level > len(down_links_types):
- raise SphinxWarning(f"Not enough links-down defined for indentation level {level}.")
+ raise SphinxWarning(
+ f"Not enough links-down defined for indentation level {level}."
+ )
splitted_text = text.split(delimiter)
title = splitted_text[0]
content = ""
with suppress(IndexError):
- content = delimiter.join(splitted_text[1:]) # Put the content together again
+ content = delimiter.join(
+ splitted_text[1:]
+ ) # Put the content together again
need_id_result = ID_REGEX.search(title)
if need_id_result:
@@ -158,7 +174,9 @@ def run(self) -> Sequence[nodes.Node]:
more_text = more_text.lstrip()
if more_text.startswith(":"):
more_text = f" {more_text}"
- list_needs[-1]["content"] = f"{list_needs[-1]['content']}\n {more_text}"
+ list_needs[-1][
+ "content"
+ ] = f"{list_needs[-1]['content']}\n {more_text}"
# Finally creating the rst code
overall_text = []
@@ -179,7 +197,11 @@ def run(self) -> Sequence[nodes.Node]:
data = list_need
need_links_down = self.get_down_needs(list_needs, index)
- if down_links_types and list_need["level"] in down_links_types and need_links_down:
+ if (
+ down_links_types
+ and list_need["level"] in down_links_types
+ and need_links_down
+ ):
data["links_down"] = need_links_down
data["links_down_type"] = down_links_types[list_need["level"]]
data["set_links_down"] = True
@@ -193,14 +215,19 @@ def run(self) -> Sequence[nodes.Node]:
text_list = indented_text_list
overall_text += text_list
- self.state_machine.insert_input(overall_text, self.state_machine.document.attributes["source"])
+ self.state_machine.insert_input(
+ overall_text, self.state_machine.document.attributes["source"]
+ )
return []
def make_hashed_id(self, type_prefix: str, title: str, id_length: int) -> str:
hashable_content = title
return "{}{}".format(
- type_prefix, hashlib.sha1(hashable_content.encode("UTF-8")).hexdigest().upper()[:id_length]
+ type_prefix,
+ hashlib.sha1(hashable_content.encode("UTF-8"))
+ .hexdigest()
+ .upper()[:id_length],
)
def get_down_needs(self, list_needs: list[Any], index: int) -> list[str]:
diff --git a/sphinx_needs/directives/need.py b/sphinx_needs/directives/need.py
index f4c527791..7863b161f 100644
--- a/sphinx_needs/directives/need.py
+++ b/sphinx_needs/directives/need.py
@@ -64,7 +64,17 @@ def __init__(
state: RSTState,
state_machine: RSTStateMachine,
):
- super().__init__(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
+ super().__init__(
+ name,
+ arguments,
+ options,
+ content,
+ lineno,
+ content_offset,
+ block_text,
+ state,
+ state_machine,
+ )
self.needs_config = NeedsSphinxConfig(self.env.config)
self.log = get_logger(__name__)
self.full_title = self._get_full_title()
@@ -109,7 +119,9 @@ def run(self) -> Sequence[nodes.Node]:
content = "\n".join(self.content)
status = self.options.get("status")
if status:
- status = status.replace("__", "") # Support for multiline options, which must use __ for empty lines
+ status = status.replace(
+ "__", ""
+ ) # Support for multiline options, which must use __ for empty lines
tags = self.options.get("tags", "")
style = self.options.get("style")
layout = self.options.get("layout", "")
@@ -121,7 +133,9 @@ def run(self) -> Sequence[nodes.Node]:
need_extra_options = {"duration": duration, "completion": completion}
for extra_link in self.needs_config.extra_links:
- need_extra_options[extra_link["option"]] = self.options.get(extra_link["option"], "")
+ need_extra_options[extra_link["option"]] = self.options.get(
+ extra_link["option"], ""
+ )
for extra_option in NEEDS_CONFIG.extra_options:
need_extra_options[extra_option] = self.options.get(extra_option, "")
@@ -175,12 +189,17 @@ def read_in_links(self, name: str) -> list[str]:
def make_hashed_id(self, type_prefix: str, id_length: int) -> str:
hashable_content = self.full_title or "\n".join(self.content)
return "{}{}".format(
- type_prefix, hashlib.sha1(hashable_content.encode("UTF-8")).hexdigest().upper()[:id_length]
+ type_prefix,
+ hashlib.sha1(hashable_content.encode("UTF-8"))
+ .hexdigest()
+ .upper()[:id_length],
)
@property
def title_from_content(self) -> bool:
- return "title_from_content" in self.options or self.needs_config.title_from_content
+ return (
+ "title_from_content" in self.options or self.needs_config.title_from_content
+ )
@property
def docname(self) -> str:
@@ -211,8 +230,8 @@ def _get_full_title(self) -> str:
if len(self.arguments) > 0: # a title was passed
if "title_from_content" in self.options:
self.log.warning(
- 'need "{}" has :title_from_content: set, '
- "but a title was provided. (see file {}) [needs]".format(self.arguments[0], self.docname),
+ f'need "{self.arguments[0]}" has :title_from_content: set, '
+ f"but a title was provided. (see file {self.docname}) [needs]",
type="needs",
location=(self.env.docname, self.lineno),
)
@@ -223,7 +242,7 @@ def _get_full_title(self) -> str:
raise NeedsInvalidException(
":title_from_content: set, but "
"no content provided. "
- "(Line {} of file {}".format(self.lineno, self.docname)
+ f"(Line {self.lineno} of file {self.docname}"
)
return first_sentence
else:
@@ -260,7 +279,9 @@ def get_sections_and_signature_and_needs(
if isinstance(sibling, desc_signature):
# Check the child of the found signature for the text content/node.
for desc_child in sibling.children:
- if isinstance(desc_child, desc_name) and isinstance(desc_child.children[0], nodes.Text):
+ if isinstance(desc_child, desc_name) and isinstance(
+ desc_child.children[0], nodes.Text
+ ):
signature = desc_child.children[0]
if signature:
break
@@ -324,7 +345,9 @@ def analyse_need_locations(app: Sphinx, doctree: nodes.document) -> None:
# Fetch values from need
# Start from the target node, which is a sibling of the current need node
- sections, signature, parent_needs = get_sections_and_signature_and_needs(previous_sibling(need_node))
+ sections, signature, parent_needs = get_sections_and_signature_and_needs(
+ previous_sibling(need_node)
+ )
# append / set values from need
if sections:
@@ -410,7 +433,12 @@ def process_need_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) -
@profile("NEED_FORMAT")
-def format_need_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str, found_needs_nodes: list[Need]) -> None:
+def format_need_nodes(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_needs_nodes: list[Need],
+) -> None:
"""Replace need nodes in the document with node trees suitable for output"""
env = app.env
needs = SphinxNeedsData(env).get_or_create_needs()
@@ -423,7 +451,9 @@ def format_need_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
find_and_replace_node_content(node_need, env, need_data)
for index, attribute in enumerate(node_need.attributes["classes"]):
- node_need.attributes["classes"][index] = check_and_get_content(attribute, need_data, env)
+ node_need.attributes["classes"][index] = check_and_get_content(
+ attribute, need_data, env
+ )
layout = need_data["layout"] or NeedsSphinxConfig(app.config).default_layout
@@ -441,14 +471,15 @@ def check_links(needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig) -> N
report_dead_links = config.report_dead_links
for need in needs.values():
for link_type in extra_links:
- need_link_value = (
- [need[link_type["option"]]] if isinstance(need[link_type["option"]], str) else need[link_type["option"]] # type: ignore
- )
+ _value = need[link_type["option"]] # type: ignore[literal-required]
+ need_link_value = [_value] if isinstance(_value, str) else _value
for need_id_full in need_link_value:
need_id_main, need_id_part = split_need_id(need_id_full)
if need_id_main not in needs or (
- need_id_main in needs and need_id_part and need_id_part not in needs[need_id_main]["parts"]
+ need_id_main in needs
+ and need_id_part
+ and need_id_part not in needs[need_id_main]["parts"]
):
need["has_dead_links"] = True
if not link_type.get("allow_dead_links", False):
@@ -473,7 +504,9 @@ def check_links(needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig) -> N
)
-def create_back_links(needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig) -> None:
+def create_back_links(
+ needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig
+) -> None:
"""Create back-links in all found needs.
These are fields for each link type, ``_back``,
@@ -484,7 +517,9 @@ def create_back_links(needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig
option_back = f"{option}_back"
for key, need in needs.items():
- need_link_value: list[str] = [need[option]] if isinstance(need[option], str) else need[option] # type: ignore[literal-required]
+ need_link_value: list[str] = (
+ [need[option]] if isinstance(need[option], str) else need[option] # type: ignore[literal-required]
+ )
for need_id_full in need_link_value:
need_id_main, need_id_part = split_need_id(need_id_full)
@@ -494,9 +529,14 @@ def create_back_links(needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig
# Handling of links to need_parts inside a need
if need_id_part and need_id_part in needs[need_id_main]["parts"]:
- if option_back not in needs[need_id_main]["parts"][need_id_part].keys():
+ if (
+ option_back
+ not in needs[need_id_main]["parts"][need_id_part].keys()
+ ):
needs[need_id_main]["parts"][need_id_part][option_back] = [] # type: ignore[literal-required]
- needs[need_id_main]["parts"][need_id_part][option_back].append(key) # type: ignore[literal-required]
+ needs[need_id_main]["parts"][need_id_part][option_back].append( # type: ignore[literal-required]
+ key
+ )
def _fix_list_dyn_func(list: list[str]) -> list[str]:
diff --git a/sphinx_needs/directives/needbar.py b/sphinx_needs/directives/needbar.py
index 623bef414..598b425a8 100644
--- a/sphinx_needs/directives/needbar.py
+++ b/sphinx_needs/directives/needbar.py
@@ -82,7 +82,11 @@ def run(self) -> Sequence[nodes.Node]:
style = self.options.get("style")
matplotlib = import_matplotlib()
- style = style.strip() if style else (matplotlib.style.use("default") if matplotlib else "default")
+ style = (
+ style.strip()
+ if style
+ else (matplotlib.style.use("default") if matplotlib else "default")
+ )
legend = "legend" in self.options
@@ -167,7 +171,12 @@ def run(self) -> Sequence[nodes.Node]:
# 8. create figure
# 9. final storage
# 10. cleanup matplotlib
-def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_needbar(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
env = app.env
needs_data = SphinxNeedsData(env)
needs_config = NeedsSphinxConfig(env.config)
@@ -221,13 +230,19 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
else:
# We can only process content with the same lenght for each line
if test_columns_length != len(row_data):
- raise Exception(f"{error_id}: each content line must have the same length")
+ raise Exception(
+ f"{error_id}: each content line must have the same length"
+ )
# 3. process the labels (maybe from content)
xlabels = current_needbar["xlabels"]
- xlabels_in_content = bool(xlabels and len(xlabels) >= 1 and xlabels[0] == "FROM_DATA")
+ xlabels_in_content = bool(
+ xlabels and len(xlabels) >= 1 and xlabels[0] == "FROM_DATA"
+ )
ylabels = current_needbar["ylabels"]
- ylabels_in_content = bool(ylabels and len(ylabels) >= 1 and ylabels[0] == "FROM_DATA")
+ ylabels_in_content = bool(
+ ylabels and len(ylabels) >= 1 and ylabels[0] == "FROM_DATA"
+ )
if xlabels_in_content:
# get xlabels from content => first row in content
@@ -265,14 +280,19 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
# 4. transpose the data if needed
if current_needbar["transpose"]:
- local_data = [[local_data[j][i] for j in range(len(local_data))] for i in range(len(local_data[0]))]
+ local_data = [
+ [local_data[j][i] for j in range(len(local_data))]
+ for i in range(len(local_data[0]))
+ ]
tmp = ylabels
ylabels = xlabels
xlabels = tmp
# 5. process content
local_data_number = []
- need_list = list(prepare_need_list(needs_data.get_or_create_needs().values())) # adds parts to need_list
+ need_list = list(
+ prepare_need_list(needs_data.get_or_create_needs().values())
+ ) # adds parts to need_list
for line in local_data:
line_number = []
@@ -335,7 +355,9 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
colors = colors + matplotlib.rcParams["axes.prop_cycle"].by_key()["color"]
multi = math.ceil(len(local_data) / len(colors))
if multi > 1:
- print(f"{error_id} warning: color schema is smaller than data, double coloring is occurring")
+ print(
+ f"{error_id} warning: color schema is smaller than data, double coloring is occurring"
+ )
colors = colors * multi
colors = colors[: len(local_data)]
@@ -368,9 +390,13 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
if current_needbar["show_sum"]:
try:
- bar_label = axes.bar_label(bar, label_type="center") # show label in the middel of each bar
+ bar_label = axes.bar_label(
+ bar, label_type="center"
+ ) # show label in the middel of each bar
bar_labels.append(bar_label)
- except AttributeError: # bar_label is not support in older matplotlib versions
+ except (
+ AttributeError
+ ): # bar_label is not support in older matplotlib versions
current_needbar["show_sum"] = None
current_needbar["show_top_sum"] = None
@@ -381,18 +407,24 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
try:
bar_label = axes.bar_label(bar)
bar_labels.append(bar_label)
- except AttributeError: # bar_label is not support in older matplotlib versions
+ except (
+ AttributeError
+ ): # bar_label is not support in older matplotlib versions
current_needbar["show_sum"] = None
current_needbar["show_top_sum"] = None
sum_rotation = current_needbar["sum_rotation"]
- if sum_rotation and (current_needbar["show_top_sum"] or current_needbar["show_sum"]):
+ if sum_rotation and (
+ current_needbar["show_top_sum"] or current_needbar["show_sum"]
+ ):
sum_rotation = sum_rotation.strip()
# Rotate the bar labels
if sum_rotation.isdigit():
matplotlib.pyplot.setp(bar_labels, rotation=int(sum_rotation))
- centers = [(i + j) / 2.0 for i, j in zip(index[0], index[len(local_data_number) - 1])]
+ centers = [
+ (i + j) / 2.0 for i, j in zip(index[0], index[len(local_data_number) - 1])
+ ]
if not current_needbar["horizontal"]:
# We want to support even older version of matplotlib, which do not support axes.set_xticks(labels)
axes.set_xticks(centers)
@@ -408,14 +440,18 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
xlabels_rotation = xlabels_rotation.strip()
# Rotate the tick labels
if xlabels_rotation.isdigit():
- matplotlib.pyplot.setp(axes.get_xticklabels(), rotation=int(xlabels_rotation))
+ matplotlib.pyplot.setp(
+ axes.get_xticklabels(), rotation=int(xlabels_rotation)
+ )
ylabels_rotation = current_needbar["ylabels_rotation"]
if ylabels_rotation:
ylabels_rotation = ylabels_rotation.strip()
# Rotate the tick labels
if ylabels_rotation.isdigit():
- matplotlib.pyplot.setp(axes.get_yticklabels(), rotation=int(ylabels_rotation))
+ matplotlib.pyplot.setp(
+ axes.get_yticklabels(), rotation=int(ylabels_rotation)
+ )
if current_needbar["title"]:
axes.set_title(current_needbar["title"].strip())
@@ -433,7 +469,9 @@ def process_needbar(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
# We need to calculate an unique bar-image file name
hash_value = hashlib.sha256(id.encode()).hexdigest()[:5]
- image_node = save_matplotlib_figure(app, figure, f"need_bar_{hash_value}", fromdocname)
+ image_node = save_matplotlib_figure(
+ app, figure, f"need_bar_{hash_value}", fromdocname
+ )
# Add lineno to node
image_node.line = current_needbar["lineno"]
diff --git a/sphinx_needs/directives/needextend.py b/sphinx_needs/directives/needextend.py
index 886aaa123..054d97f53 100644
--- a/sphinx_needs/directives/needextend.py
+++ b/sphinx_needs/directives/needextend.py
@@ -44,9 +44,13 @@ def run(self) -> Sequence[nodes.Node]:
extend_filter = self.arguments[0] if self.arguments else None
if not extend_filter:
- raise NeedsInvalidFilter(f"Filter of needextend must be set. See {env.docname}:{self.lineno}")
+ raise NeedsInvalidFilter(
+ f"Filter of needextend must be set. See {env.docname}:{self.lineno}"
+ )
- strict_option = self.options.get("strict", str(NeedsSphinxConfig(self.env.app.config).needextend_strict))
+ strict_option = self.options.get(
+ "strict", str(NeedsSphinxConfig(self.env.app.config).needextend_strict)
+ )
strict = True
if strict_option.upper() == "TRUE":
strict = True
@@ -69,7 +73,9 @@ def run(self) -> Sequence[nodes.Node]:
def extend_needs_data(
- all_needs: dict[str, NeedsInfoType], extends: dict[str, NeedsExtendType], needs_config: NeedsSphinxConfig
+ all_needs: dict[str, NeedsInfoType],
+ extends: dict[str, NeedsExtendType],
+ needs_config: NeedsSphinxConfig,
) -> None:
"""Use data gathered from needextend directives to modify fields of existing needs."""
@@ -81,7 +87,9 @@ def extend_needs_data(
if need_filter in all_needs:
# a single known ID
found_needs = [all_needs[need_filter]]
- elif need_filter is not None and re.fullmatch(needs_config.id_regex, need_filter):
+ elif need_filter is not None and re.fullmatch(
+ needs_config.id_regex, need_filter
+ ):
# an unknown ID
error = f"Provided id {need_filter} for needextend does not exist."
if current_needextend["strict"]:
@@ -92,7 +100,9 @@ def extend_needs_data(
else:
# a filter string
try:
- found_needs = filter_needs(all_needs.values(), needs_config, need_filter)
+ found_needs = filter_needs(
+ all_needs.values(), needs_config, need_filter
+ )
except NeedsInvalidFilter as e:
raise NeedsInvalidFilter(
f"Filter not valid for needextend on page {current_needextend['docname']}:\n{e}"
@@ -108,7 +118,9 @@ def extend_needs_data(
if option.startswith("+"):
option_name = option[1:]
if option_name in link_names:
- if value.strip().startswith("[[") and value.strip().endswith("]]"): # dynamic function
+ if value.strip().startswith("[[") and value.strip().endswith(
+ "]]"
+ ): # dynamic function
need[option_name].append(value)
else:
for ref_need in [i.strip() for i in re.split(";|,", value)]:
@@ -116,13 +128,18 @@ def extend_needs_data(
logger.warning(
f"Provided link id {ref_need} for needextend does not exist. [needs]",
type="needs",
- location=(current_needextend["docname"], current_needextend["lineno"]),
+ location=(
+ current_needextend["docname"],
+ current_needextend["lineno"],
+ ),
)
continue
if ref_need not in need[option_name]:
need[option_name].append(ref_need)
elif option_name in list_values:
- if value.strip().startswith("[[") and value.strip().endswith("]]"): # dynamic function
+ if value.strip().startswith("[[") and value.strip().endswith(
+ "]]"
+ ): # dynamic function
need[option_name].append(value)
else:
for item in [i.strip() for i in re.split(";|,", value)]:
@@ -145,7 +162,9 @@ def extend_needs_data(
else:
if option in link_names:
need[option] = []
- if value.strip().startswith("[[") and value.strip().endswith("]]"): # dynamic function
+ if value.strip().startswith("[[") and value.strip().endswith(
+ "]]"
+ ): # dynamic function
need[option].append(value)
else:
for ref_need in [i.strip() for i in re.split(";|,", value)]:
@@ -153,12 +172,17 @@ def extend_needs_data(
logger.warning(
f"Provided link id {ref_need} for needextend does not exist. [needs]",
type="needs",
- location=(current_needextend["docname"], current_needextend["lineno"]),
+ location=(
+ current_needextend["docname"],
+ current_needextend["lineno"],
+ ),
)
continue
need[option].append(ref_need)
elif option in list_values:
- if value.strip().startswith("[[") and value.strip().endswith("]]"): # dynamic function
+ if value.strip().startswith("[[") and value.strip().endswith(
+ "]]"
+ ): # dynamic function
need[option].append(value)
else:
need[option] = [i.strip() for i in re.split(";|,", value)]
diff --git a/sphinx_needs/directives/needextract.py b/sphinx_needs/directives/needextract.py
index 18f5cb060..9ceba1a09 100644
--- a/sphinx_needs/directives/needextract.py
+++ b/sphinx_needs/directives/needextract.py
@@ -43,7 +43,9 @@ class NeedextractDirective(FilterBase):
def run(self) -> Sequence[nodes.Node]:
env = self.env
- targetid = "needextract-{docname}-{id}".format(docname=env.docname, id=env.new_serialno("needextract"))
+ targetid = "needextract-{docname}-{id}".format(
+ docname=env.docname, id=env.new_serialno("needextract")
+ )
targetnode = nodes.target("", "", ids=[targetid])
filter_arg = self.arguments[0] if self.arguments else None
@@ -67,7 +69,10 @@ def run(self) -> Sequence[nodes.Node]:
def process_needextract(
- app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
"""
Replace all needextract nodes with a list of the collected needs.
@@ -88,14 +93,18 @@ def process_needextract(
# check if filter argument and option filter both exist
need_filter_arg = current_needextract["filter_arg"]
if need_filter_arg and current_needextract["filter"]:
- raise NeedsInvalidFilter("Needextract can't have filter arguments and option filter at the same time.")
+ raise NeedsInvalidFilter(
+ "Needextract can't have filter arguments and option filter at the same time."
+ )
elif need_filter_arg:
# check if given filter argument is need-id
if need_filter_arg in all_needs:
need_filter_arg = f'id == "{need_filter_arg}"'
elif re.fullmatch(needs_config.id_regex, need_filter_arg):
# check if given filter argument is need-id, but not exists
- raise NeedsInvalidFilter(f"Provided id {need_filter_arg} for needextract does not exist.")
+ raise NeedsInvalidFilter(
+ f"Provided id {need_filter_arg} for needextract does not exist."
+ )
current_needextract["filter"] = need_filter_arg
found_needs = process_filters(app, all_needs.values(), current_needextract)
@@ -118,7 +127,9 @@ def process_needextract(
content.append(need_extract)
if len(content) == 0:
- content.append(no_needs_found_paragraph(current_needextract.get("filter_warning")))
+ content.append(
+ no_needs_found_paragraph(current_needextract.get("filter_warning"))
+ )
if current_needextract["show_filters"]:
content.append(used_filter_paragraph(current_needextract))
diff --git a/sphinx_needs/directives/needfilter.py b/sphinx_needs/directives/needfilter.py
index ef0cb3d71..0d7cd00c8 100644
--- a/sphinx_needs/directives/needfilter.py
+++ b/sphinx_needs/directives/needfilter.py
@@ -49,7 +49,9 @@ def layout(argument: str) -> str:
def run(self) -> Sequence[nodes.Node]:
env = self.env
- targetid = "needfilter-{docname}-{id}".format(docname=env.docname, id=env.new_serialno("needfilter"))
+ targetid = "needfilter-{docname}-{id}".format(
+ docname=env.docname, id=env.new_serialno("needfilter")
+ )
targetnode = nodes.target("", "", ids=[targetid])
# Add the need and all needed information
@@ -72,7 +74,10 @@ def run(self) -> Sequence[nodes.Node]:
def process_needfilters(
- app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
# Replace all needlist nodes with a list of the collected needs.
# Augment each need with a backlink to the original location.
@@ -129,7 +134,14 @@ def process_needfilters(
status_colspec = nodes.colspec(colwidth=5)
links_colspec = nodes.colspec(colwidth=5)
tags_colspec = nodes.colspec(colwidth=5)
- tgroup += [id_colspec, title_colspec, type_colspec, status_colspec, links_colspec, tags_colspec]
+ tgroup += [
+ id_colspec,
+ title_colspec,
+ type_colspec,
+ status_colspec,
+ links_colspec,
+ tags_colspec,
+ ]
tgroup += nodes.thead(
"",
nodes.row(
@@ -170,7 +182,9 @@ def process_needfilters(
else:
ref = nodes.reference("", "")
ref["refdocname"] = need_info["docname"]
- ref["refuri"] = builder.get_relative_uri(fromdocname, need_info["docname"])
+ ref["refuri"] = builder.get_relative_uri(
+ fromdocname, need_info["docname"]
+ )
ref["refuri"] += "#" + target_id
ref.append(title)
line_node += ref
@@ -178,11 +192,17 @@ def process_needfilters(
line_block.append(line_node)
elif current_needfilter["layout"] == "table":
row = nodes.row()
- row += row_col_maker(app, fromdocname, all_needs, need_info, "id", make_ref=True)
+ row += row_col_maker(
+ app, fromdocname, all_needs, need_info, "id", make_ref=True
+ )
row += row_col_maker(app, fromdocname, all_needs, need_info, "title")
- row += row_col_maker(app, fromdocname, all_needs, need_info, "type_name")
+ row += row_col_maker(
+ app, fromdocname, all_needs, need_info, "type_name"
+ )
row += row_col_maker(app, fromdocname, all_needs, need_info, "status")
- row += row_col_maker(app, fromdocname, all_needs, need_info, "links", ref_lookup=True)
+ row += row_col_maker(
+ app, fromdocname, all_needs, need_info, "links", ref_lookup=True
+ )
row += row_col_maker(app, fromdocname, all_needs, need_info, "tags")
tbody += row
elif current_needfilter["layout"] == "diagram":
@@ -203,9 +223,13 @@ def process_needfilters(
link = ""
diagram_template = Template(needs_config.diagram_template)
- node_text = diagram_template.render(**need_info, **needs_config.render_context)
+ node_text = diagram_template.render(
+ **need_info, **needs_config.render_context
+ )
- puml_node["uml"] += '{style} "{node_text}" as {id} [[{link}]] {color}\n'.format(
+ puml_node[
+ "uml"
+ ] += '{style} "{node_text}" as {id} [[{link}]] {color}\n'.format(
id=need_info["id"],
node_text=node_text,
link=link,
@@ -213,7 +237,9 @@ def process_needfilters(
style=need_info["type_style"],
)
for link in need_info["links"]:
- puml_connections += "{id} --> {link}\n".format(id=need_info["id"], link=link)
+ puml_connections += "{id} --> {link}\n".format(
+ id=need_info["id"], link=link
+ )
if current_needfilter["layout"] == "list":
content.append(line_block)
@@ -227,11 +253,15 @@ def process_needfilters(
puml_node["uml"] += create_legend(needs_config.types)
puml_node["uml"] += "@enduml"
puml_node["incdir"] = os.path.dirname(current_needfilter["docname"])
- puml_node["filename"] = os.path.split(current_needfilter["docname"])[1] # Needed for plantuml >= 0.9
+ puml_node["filename"] = os.path.split(current_needfilter["docname"])[
+ 1
+ ] # Needed for plantuml >= 0.9
content.append(puml_node)
if len(content) == 0:
- content.append(no_needs_found_paragraph(current_needfilter.get("filter_warning")))
+ content.append(
+ no_needs_found_paragraph(current_needfilter.get("filter_warning"))
+ )
if current_needfilter["show_filters"]:
para_node = nodes.paragraph()
filter_text = "Used filter:"
@@ -240,17 +270,25 @@ def process_needfilters(
if len(current_needfilter["status"]) > 0
else ""
)
- if len(current_needfilter["status"]) > 0 and len(current_needfilter["tags"]) > 0:
+ if (
+ len(current_needfilter["status"]) > 0
+ and len(current_needfilter["tags"]) > 0
+ ):
filter_text += " AND "
filter_text += (
- " tags(%s)" % " OR ".join(current_needfilter["tags"]) if len(current_needfilter["tags"]) > 0 else ""
+ " tags(%s)" % " OR ".join(current_needfilter["tags"])
+ if len(current_needfilter["tags"]) > 0
+ else ""
)
- if (len(current_needfilter["status"]) > 0 or len(current_needfilter["tags"]) > 0) and len(
- current_needfilter["types"]
- ) > 0:
+ if (
+ len(current_needfilter["status"]) > 0
+ or len(current_needfilter["tags"]) > 0
+ ) and len(current_needfilter["types"]) > 0:
filter_text += " AND "
filter_text += (
- " types(%s)" % " OR ".join(current_needfilter["types"]) if len(current_needfilter["types"]) > 0 else ""
+ " types(%s)" % " OR ".join(current_needfilter["types"])
+ if len(current_needfilter["types"]) > 0
+ else ""
)
filter_node = nodes.emphasis(filter_text, filter_text)
diff --git a/sphinx_needs/directives/needflow.py b/sphinx_needs/directives/needflow.py
index 31572afb4..5f4df8d92 100644
--- a/sphinx_needs/directives/needflow.py
+++ b/sphinx_needs/directives/needflow.py
@@ -74,7 +74,9 @@ def run(self) -> Sequence[nodes.Node]:
targetnode = nodes.target("", "", ids=[targetid])
all_link_types = ",".join(x["option"] for x in needs_config.extra_links)
- link_types = split_link_types(self.options.get("link_types", all_link_types), location)
+ link_types = split_link_types(
+ self.options.get("link_types", all_link_types), location
+ )
config_names = self.options.get("config")
configs = []
@@ -220,7 +222,12 @@ def walk_curr_need_tree(
# check curr need child has children or has parts
if curr_child_need["parent_needs_back"] or curr_child_need["parts"]:
curr_need_tree += walk_curr_need_tree(
- app, fromdocname, current_needflow, all_needs, found_needs, curr_child_need
+ app,
+ fromdocname,
+ current_needflow,
+ all_needs,
+ found_needs,
+ curr_child_need,
)
# add newline for next element
curr_need_tree += "\n"
@@ -261,7 +268,9 @@ def cal_needs_node(
top_needs = get_root_needs(found_needs)
curr_need_tree = ""
for top_need in top_needs:
- top_need_node = get_need_node_rep_for_plantuml(app, fromdocname, current_needflow, all_needs, top_need)
+ top_need_node = get_need_node_rep_for_plantuml(
+ app, fromdocname, current_needflow, all_needs, top_need
+ )
curr_need_tree += (
top_need_node
+ walk_curr_need_tree(
@@ -278,7 +287,12 @@ def cal_needs_node(
@measure_time("needflow")
-def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_needflow(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
# Replace all needflow nodes with a list of the collected needs.
# Augment each need with a backlink to the original location.
env = app.env
@@ -305,7 +319,9 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
if lt not in link_type_names:
logger.warning(
"Unknown link type {link_type} in needflow {flow}. Allowed values: {link_types} [needs]".format(
- link_type=lt, flow=current_needflow["target_id"], link_types=",".join(link_type_names)
+ link_type=lt,
+ flow=current_needflow["target_id"],
+ link_types=",".join(link_type_names),
),
type="needs",
)
@@ -342,7 +358,9 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
config = current_needflow["config"]
if config and len(config) >= 3:
# Remove all empty lines
- config = "\n".join([line.strip() for line in config.split("\n") if line.strip()])
+ config = "\n".join(
+ [line.strip() for line in config.split("\n") if line.strip()]
+ )
puml_node["uml"] += "\n' Config\n\n"
puml_node["uml"] += config
puml_node["uml"] += "\n\n"
@@ -353,9 +371,13 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
for link_type in link_types:
# Skip link-type handling, if it is not part of a specified list of allowed link_types or
# if not part of the overall configuration of needs_flow_link_types
- if (current_needflow["link_types"] and link_type["option"].upper() not in option_link_types) or (
+ if (
+ current_needflow["link_types"]
+ and link_type["option"].upper() not in option_link_types
+ ) or (
not current_needflow["link_types"]
- and link_type["option"].upper() not in allowed_link_types_options
+ and link_type["option"].upper()
+ not in allowed_link_types_options
):
continue
@@ -367,30 +389,42 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
# If source or target of link is a need_part, a specific style is needed
if "." in link or "." in need_info["id_complete"]:
final_link = link
- if current_needflow["show_link_names"] or needs_config.flow_show_links:
+ if (
+ current_needflow["show_link_names"]
+ or needs_config.flow_show_links
+ ):
desc = link_type["outgoing"] + "\\n"
comment = f": {desc}"
else:
comment = ""
if "style_part" in link_type and link_type["style_part"]:
- link_style = "[{style}]".format(style=link_type["style_part"])
+ link_style = "[{style}]".format(
+ style=link_type["style_part"]
+ )
else:
link_style = "[dotted]"
else:
final_link = link
- if current_needflow["show_link_names"] or needs_config.flow_show_links:
+ if (
+ current_needflow["show_link_names"]
+ or needs_config.flow_show_links
+ ):
comment = ": {desc}".format(desc=link_type["outgoing"])
else:
comment = ""
if "style" in link_type and link_type["style"]:
- link_style = "[{style}]".format(style=link_type["style"])
+ link_style = "[{style}]".format(
+ style=link_type["style"]
+ )
else:
link_style = ""
# Do not create an links, if the link target is not part of the search result.
- if final_link not in [x["id"] for x in found_needs if x["is_need"]] and final_link not in [
+ if final_link not in [
+ x["id"] for x in found_needs if x["is_need"]
+ ] and final_link not in [
x["id_complete"] for x in found_needs if x["is_part"]
]:
continue
@@ -415,7 +449,9 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
)
# calculate needs node representation for plantuml
- puml_node["uml"] += cal_needs_node(app, fromdocname, current_needflow, all_needs.values(), found_needs)
+ puml_node["uml"] += cal_needs_node(
+ app, fromdocname, current_needflow, all_needs.values(), found_needs
+ )
puml_node["uml"] += "\n' Connection definition \n\n"
puml_node["uml"] += puml_connections
@@ -426,7 +462,9 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
puml_node["uml"] += "\n@enduml"
puml_node["incdir"] = os.path.dirname(current_needflow["docname"])
- puml_node["filename"] = os.path.split(current_needflow["docname"])[1] # Needed for plantuml >= 0.9
+ puml_node["filename"] = os.path.split(current_needflow["docname"])[
+ 1
+ ] # Needed for plantuml >= 0.9
scale = int(current_needflow["scale"])
# if scale != 100:
@@ -452,8 +490,14 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
gen_flow_link = generate_name(app, puml_node.children[0], file_ext)
current_file_parts = fromdocname.split("/")
subfolder_amount = len(current_file_parts) - 1
- img_locaton = "../" * subfolder_amount + "_images/" + gen_flow_link[0].split("/")[-1]
- flow_ref = nodes.reference("t", current_needflow["caption"], refuri=img_locaton)
+ img_locaton = (
+ "../" * subfolder_amount
+ + "_images/"
+ + gen_flow_link[0].split("/")[-1]
+ )
+ flow_ref = nodes.reference(
+ "t", current_needflow["caption"], refuri=img_locaton
+ )
puml_node += nodes.caption("", "", flow_ref)
# Add lineno to node
@@ -461,25 +505,36 @@ def process_needflow(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
content.append(puml_node)
else: # no needs found
- content.append(no_needs_found_paragraph(current_needflow.get("filter_warning")))
+ content.append(
+ no_needs_found_paragraph(current_needflow.get("filter_warning"))
+ )
if current_needflow["show_filters"]:
para = nodes.paragraph()
filter_text = "Used filter:"
filter_text += (
- " status(%s)" % " OR ".join(current_needflow["status"]) if len(current_needflow["status"]) > 0 else ""
+ " status(%s)" % " OR ".join(current_needflow["status"])
+ if len(current_needflow["status"]) > 0
+ else ""
)
- if len(current_needflow["status"]) > 0 and len(current_needflow["tags"]) > 0:
+ if (
+ len(current_needflow["status"]) > 0
+ and len(current_needflow["tags"]) > 0
+ ):
filter_text += " AND "
filter_text += (
- " tags(%s)" % " OR ".join(current_needflow["tags"]) if len(current_needflow["tags"]) > 0 else ""
+ " tags(%s)" % " OR ".join(current_needflow["tags"])
+ if len(current_needflow["tags"]) > 0
+ else ""
)
- if (len(current_needflow["status"]) > 0 or len(current_needflow["tags"]) > 0) and len(
- current_needflow["types"]
- ) > 0:
+ if (
+ len(current_needflow["status"]) > 0 or len(current_needflow["tags"]) > 0
+ ) and len(current_needflow["types"]) > 0:
filter_text += " AND "
filter_text += (
- " types(%s)" % " OR ".join(current_needflow["types"]) if len(current_needflow["types"]) > 0 else ""
+ " types(%s)" % " OR ".join(current_needflow["types"])
+ if len(current_needflow["types"]) > 0
+ else ""
)
filter_node = nodes.emphasis(filter_text, filter_text)
diff --git a/sphinx_needs/directives/needgantt.py b/sphinx_needs/directives/needgantt.py
index d0f4b9c11..5f8e8f3f1 100644
--- a/sphinx_needs/directives/needgantt.py
+++ b/sphinx_needs/directives/needgantt.py
@@ -88,15 +88,21 @@ def run(self) -> Sequence[nodes.Node]:
timeline_options = ["daily", "weekly", "monthly"]
if timeline and timeline not in timeline_options:
raise NeedGanttException(
- "Given scale value {} is invalid. Please use: " "{}".format(timeline, ",".join(timeline_options))
+ "Given scale value {} is invalid. Please use: " "{}".format(
+ timeline, ",".join(timeline_options)
+ )
)
else:
timeline = None # Timeline/scale not set later
no_color = "no_color" in self.options
- duration_option = self.options.get("duration_option", needs_config.duration_option)
- completion_option = self.options.get("completion_option", needs_config.completion_option)
+ duration_option = self.options.get(
+ "duration_option", needs_config.duration_option
+ )
+ completion_option = self.options.get(
+ "completion_option", needs_config.completion_option
+ )
# Add the needgantt and all needed information
SphinxNeedsData(env).get_or_create_gantts()[targetid] = {
@@ -121,7 +127,9 @@ def run(self) -> Sequence[nodes.Node]:
return [targetnode] + [Needgantt("")]
def get_link_type_option(self, name: str, default: str = "") -> list[str]:
- link_types = [x.strip() for x in re.split(";|,", self.options.get(name, default))]
+ link_types = [
+ x.strip() for x in re.split(";|,", self.options.get(name, default))
+ ]
conf_link_types = NeedsSphinxConfig(self.env.config).extra_links
conf_link_types_name = [x["option"] for x in conf_link_types]
@@ -131,14 +139,20 @@ def get_link_type_option(self, name: str, default: str = "") -> list[str]:
continue
if link_type not in conf_link_types_name:
raise SphinxNeedsLinkTypeException(
- link_type + "does not exist in configuration option needs_extra_links"
+ link_type
+ + "does not exist in configuration option needs_extra_links"
)
final_link_types.append(link_type)
return final_link_types
-def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_needgantt(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
# Replace all needgantt nodes with a list of the collected needs.
env = app.env
needs_config = NeedsSphinxConfig(app.config)
@@ -196,7 +210,9 @@ def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
except Exception:
raise NeedGanttException(
'start_date "{}"for needgantt is invalid. '
- 'File: {}:current_needgantt["lineno"]'.format(start_date_string, current_needgantt["docname"])
+ 'File: {}:current_needgantt["lineno"]'.format(
+ start_date_string, current_needgantt["docname"]
+ )
)
month = MONTH_NAMES[int(start_date.strftime("%m"))]
@@ -212,12 +228,16 @@ def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
complete = None
if current_needgantt["milestone_filter"]:
- is_milestone = filter_single_need(need, needs_config, current_needgantt["milestone_filter"])
+ is_milestone = filter_single_need(
+ need, needs_config, current_needgantt["milestone_filter"]
+ )
else:
is_milestone = False
if current_needgantt["milestone_filter"] and is_milestone:
- gantt_element = "[{}] as [{}] lasts 0 days\n".format(need["title"], need["id"])
+ gantt_element = "[{}] as [{}] lasts 0 days\n".format(
+ need["title"], need["id"]
+ )
else: # Normal gantt element handling
duration_option = current_needgantt["duration_option"]
duration = need[duration_option] # type: ignore[literal-required]
@@ -230,18 +250,26 @@ def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
type="needs",
)
duration = 1
- gantt_element = "[{}] as [{}] lasts {} days\n".format(need["title"], need["id"], duration)
+ gantt_element = "[{}] as [{}] lasts {} days\n".format(
+ need["title"], need["id"], duration
+ )
if complete:
complete = complete.replace("%", "")
- el_completion_string += "[{}] is {}% completed\n".format(need["title"], complete)
+ el_completion_string += "[{}] is {}% completed\n".format(
+ need["title"], complete
+ )
- el_color_string += "[{}] is colored in {}\n".format(need["title"], need["type_color"])
+ el_color_string += "[{}] is colored in {}\n".format(
+ need["title"], need["type_color"]
+ )
puml_node["uml"] += gantt_element
puml_node["uml"] += "\n' Element links definition \n\n"
- puml_node["uml"] += "\n' Deactivated, as currently supported by plantuml beta only"
+ puml_node[
+ "uml"
+ ] += "\n' Deactivated, as currently supported by plantuml beta only"
puml_node["uml"] += "\n' Element completion definition \n\n"
puml_node["uml"] += el_completion_string + "\n"
@@ -257,10 +285,16 @@ def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
puml_node["uml"] += "\n' Constraints definition \n\n"
for need in found_needs:
if current_needgantt["milestone_filter"]:
- is_milestone = filter_single_need(need, needs_config, current_needgantt["milestone_filter"])
+ is_milestone = filter_single_need(
+ need, needs_config, current_needgantt["milestone_filter"]
+ )
else:
is_milestone = False
- for con_type in ("starts_with_links", "starts_after_links", "ends_with_links"):
+ for con_type in (
+ "starts_with_links",
+ "starts_after_links",
+ "ends_with_links",
+ ):
if is_milestone:
keyword = "happens"
elif con_type in ["starts_with_links", "starts_after_links"]:
@@ -288,7 +322,9 @@ def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
puml_node["uml"] += "\n@endgantt"
puml_node["incdir"] = os.path.dirname(current_needgantt["docname"])
- puml_node["filename"] = os.path.split(current_needgantt["docname"])[1] # Needed for plantuml >= 0.9
+ puml_node["filename"] = os.path.split(current_needgantt["docname"])[
+ 1
+ ] # Needed for plantuml >= 0.9
scale = int(current_needgantt["scale"])
# if scale != 100:
@@ -311,14 +347,20 @@ def process_needgantt(app: Sphinx, doctree: nodes.document, fromdocname: str, fo
gen_flow_link = generate_name(app, puml_node.children[0], file_ext)
current_file_parts = fromdocname.split("/")
subfolder_amount = len(current_file_parts) - 1
- img_location = "../" * subfolder_amount + "_images/" + gen_flow_link[0].split("/")[-1]
- flow_ref = nodes.reference("t", current_needgantt["caption"], refuri=img_location)
+ img_location = (
+ "../" * subfolder_amount + "_images/" + gen_flow_link[0].split("/")[-1]
+ )
+ flow_ref = nodes.reference(
+ "t", current_needgantt["caption"], refuri=img_location
+ )
puml_node += nodes.caption("", "", flow_ref)
content.append(puml_node)
if len(found_needs) == 0:
- content = [no_needs_found_paragraph(current_needgantt.get("filter_warning"))]
+ content = [
+ no_needs_found_paragraph(current_needgantt.get("filter_warning"))
+ ]
if current_needgantt["show_filters"]:
content.append(get_filter_para(current_needgantt))
diff --git a/sphinx_needs/directives/needimport.py b/sphinx_needs/directives/needimport.py
index b66148079..cf9d26cc3 100644
--- a/sphinx_needs/directives/needimport.py
+++ b/sphinx_needs/directives/needimport.py
@@ -73,19 +73,25 @@ def run(self) -> Sequence[nodes.Node]:
response.json()
) # The downloaded file MUST be json. Everything else we do not handle!
except Exception as e:
- raise NeedimportException(f"Getting {need_import_path} didn't work. Reason: {e}.")
+ raise NeedimportException(
+ f"Getting {need_import_path} didn't work. Reason: {e}."
+ )
else:
logger.info(f"Importing needs from {need_import_path}")
if not os.path.isabs(need_import_path):
# Relative path should start from current rst file directory
curr_dir = os.path.dirname(self.docname)
- new_need_import_path = os.path.join(self.env.app.srcdir, curr_dir, need_import_path)
+ new_need_import_path = os.path.join(
+ self.env.app.srcdir, curr_dir, need_import_path
+ )
correct_need_import_path = new_need_import_path
if not os.path.exists(new_need_import_path):
# Check the old way that calculates relative path starting from conf.py directory
- old_need_import_path = os.path.join(self.env.app.srcdir, need_import_path)
+ old_need_import_path = os.path.join(
+ self.env.app.srcdir, need_import_path
+ )
if os.path.exists(old_need_import_path):
correct_need_import_path = old_need_import_path
logger.warning(
@@ -97,14 +103,20 @@ def run(self) -> Sequence[nodes.Node]:
)
else:
# Absolute path starts with /, based on the source directory. The / need to be striped
- correct_need_import_path = os.path.join(self.env.app.srcdir, need_import_path[1:])
+ correct_need_import_path = os.path.join(
+ self.env.app.srcdir, need_import_path[1:]
+ )
if not os.path.exists(correct_need_import_path):
- raise ReferenceError(f"Could not load needs import file {correct_need_import_path}")
+ raise ReferenceError(
+ f"Could not load needs import file {correct_need_import_path}"
+ )
errors = check_needs_file(correct_need_import_path)
if errors.schema:
- logger.info(f"Schema validation errors detected in file {correct_need_import_path}:")
+ logger.info(
+ f"Schema validation errors detected in file {correct_need_import_path}:"
+ )
for error in errors.schema:
logger.info(f' {error.message} -> {".".join(error.path)}')
@@ -121,13 +133,19 @@ def run(self) -> Sequence[nodes.Node]:
if not isinstance(version, str):
raise KeyError
except KeyError:
- raise CorruptedNeedsFile(f"Key 'current_version' missing or corrupted in {correct_need_import_path}")
+ raise CorruptedNeedsFile(
+ f"Key 'current_version' missing or corrupted in {correct_need_import_path}"
+ )
if version not in needs_import_list["versions"].keys():
- raise VersionNotFound(f"Version {version} not found in needs import file {correct_need_import_path}")
+ raise VersionNotFound(
+ f"Version {version} not found in needs import file {correct_need_import_path}"
+ )
needs_config = NeedsSphinxConfig(self.config)
# TODO this is not exactly NeedsInfoType, because the export removes/adds some keys
- needs_list: dict[str, NeedsInfoType] = needs_import_list["versions"][version]["needs"]
+ needs_list: dict[str, NeedsInfoType] = needs_import_list["versions"][version][
+ "needs"
+ ]
# Filter imported needs
needs_list_filtered = {}
@@ -161,13 +179,20 @@ def run(self) -> Sequence[nodes.Node]:
for id in needs_list:
# Manipulate links in all link types
for extra_link in extra_links:
- if extra_link["option"] in need and id in need[extra_link["option"]]: # type: ignore[literal-required]
+ if (
+ extra_link["option"] in need
+ and id in need[extra_link["option"]] # type: ignore[literal-required]
+ ):
for n, link in enumerate(need[extra_link["option"]]): # type: ignore[literal-required]
if id == link:
- need[extra_link["option"]][n] = "".join([id_prefix, id]) # type: ignore[literal-required]
+ need[extra_link["option"]][n] = "".join( # type: ignore[literal-required]
+ [id_prefix, id]
+ )
# Manipulate descriptions
# ToDo: Use regex for better matches.
- need["description"] = need["description"].replace(id, "".join([id_prefix, id])) # type: ignore[typeddict-item]
+ need["description"] = need["description"].replace( # type: ignore[typeddict-item]
+ id, "".join([id_prefix, id])
+ )
# tags update
for need in needs_list.values():
@@ -194,8 +219,12 @@ def run(self) -> Sequence[nodes.Node]:
for need in needs_list.values():
# Set some values based on given option or value from imported need.
need["template"] = self.options.get("template", need.get("template"))
- need["pre_template"] = self.options.get("pre_template", need.get("pre_template"))
- need["post_template"] = self.options.get("post_template", need.get("post_template"))
+ need["pre_template"] = self.options.get(
+ "pre_template", need.get("pre_template")
+ )
+ need["post_template"] = self.options.get(
+ "post_template", need.get("post_template")
+ )
need["layout"] = self.options.get("layout", need.get("layout"))
need["style"] = self.options.get("style", need.get("style"))
diff --git a/sphinx_needs/directives/needlist.py b/sphinx_needs/directives/needlist.py
index 91a2950f2..d6b1a528d 100644
--- a/sphinx_needs/directives/needlist.py
+++ b/sphinx_needs/directives/needlist.py
@@ -41,7 +41,9 @@ class NeedlistDirective(FilterBase):
def run(self) -> Sequence[nodes.Node]:
env = self.env
- targetid = "needlist-{docname}-{id}".format(docname=env.docname, id=env.new_serialno("needlist"))
+ targetid = "needlist-{docname}-{id}".format(
+ docname=env.docname, id=env.new_serialno("needlist")
+ )
targetnode = nodes.target("", "", ids=[targetid])
# Add the need and all needed information
@@ -60,7 +62,12 @@ def run(self) -> Sequence[nodes.Node]:
return [targetnode, Needlist("")]
-def process_needlist(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_needlist(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
"""
Replace all needlist nodes with a list of the collected needs.
Augment each need with a backlink to the original location.
@@ -81,7 +88,7 @@ def process_needlist(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
all_needs = list(SphinxNeedsData(env).get_or_create_needs().values())
found_needs = process_filters(app, all_needs, current_needfilter)
- if 0 < len(found_needs):
+ if len(found_needs) > 0:
line_block = nodes.line_block()
# Add lineno to node
@@ -102,10 +109,14 @@ def process_needlist(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
if need_info["hide"]:
para += title
elif need_info["is_external"]:
- assert need_info["external_url"] is not None, "External need without URL"
+ assert (
+ need_info["external_url"] is not None
+ ), "External need without URL"
ref = nodes.reference("", "")
- ref["refuri"] = check_and_calc_base_url_rel_path(need_info["external_url"], fromdocname)
+ ref["refuri"] = check_and_calc_base_url_rel_path(
+ need_info["external_url"], fromdocname
+ )
ref["classes"].append(need_info["external_css"])
ref.append(title)
@@ -114,7 +125,9 @@ def process_needlist(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
target_id = need_info["target_id"]
ref = nodes.reference("", "")
ref["refdocname"] = need_info["docname"]
- ref["refuri"] = builder.get_relative_uri(fromdocname, need_info["docname"])
+ ref["refuri"] = builder.get_relative_uri(
+ fromdocname, need_info["docname"]
+ )
ref["refuri"] += "#" + target_id
ref.append(title)
para += ref
@@ -122,7 +135,9 @@ def process_needlist(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
content.append(line_block)
if len(content) == 0:
- content.append(no_needs_found_paragraph(current_needfilter.get("filter_warning")))
+ content.append(
+ no_needs_found_paragraph(current_needfilter.get("filter_warning"))
+ )
if current_needfilter["show_filters"]:
content.append(used_filter_paragraph(current_needfilter))
diff --git a/sphinx_needs/directives/needpie.py b/sphinx_needs/directives/needpie.py
index f055dffe3..700c25247 100644
--- a/sphinx_needs/directives/needpie.py
+++ b/sphinx_needs/directives/needpie.py
@@ -106,7 +106,12 @@ def run(self) -> Sequence[nodes.Node]:
@measure_time("needpie")
-def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_needpie(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
env = app.env
needs_data = SphinxNeedsData(env)
needs_config = NeedsSphinxConfig(env.config)
@@ -149,7 +154,9 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
content = current_needpie["content"]
sizes = []
- need_list = list(prepare_need_list(needs_data.get_or_create_needs().values())) # adds parts to need_list
+ need_list = list(
+ prepare_need_list(needs_data.get_or_create_needs().values())
+ ) # adds parts to need_list
if content and not current_needpie["filter_func"]:
for line in content:
if line.isdigit():
@@ -160,7 +167,9 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
elif current_needpie["filter_func"] and not content:
try:
# check and get filter_func
- filter_func, filter_args = check_and_get_external_filter_func(current_needpie.get("filter_func"))
+ filter_func, filter_args = check_and_get_external_filter_func(
+ current_needpie.get("filter_func")
+ )
# execute filter_func code
# Provides only a copy of needs to avoid data manipulations.
context = {
@@ -192,7 +201,9 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
except Exception as e:
raise e
elif current_needpie["filter_func"] and content:
- logger.error("filter_func and content can't be used at the same time for needpie.")
+ logger.error(
+ "filter_func and content can't be used at the same time for needpie."
+ )
else:
logger.error("Both filter_func and content are not used for needpie.")
@@ -215,7 +226,9 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
shadow = current_needpie["shadow"]
text_color = current_needpie["text_color"]
- fig, axes = matplotlib.pyplot.subplots(figsize=(8, 4), subplot_kw={"aspect": "equal"})
+ fig, axes = matplotlib.pyplot.subplots(
+ figsize=(8, 4), subplot_kw={"aspect": "equal"}
+ )
pie_kwargs = {
"labels": labels,
@@ -229,7 +242,9 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
if text_color:
pie_kwargs["textprops"] = {"color": text_color}
- wedges, _texts, autotexts = axes.pie(sizes, normalize=sum(float(s) for s in sizes) >= 1, **pie_kwargs)
+ wedges, _texts, autotexts = axes.pie(
+ sizes, normalize=sum(float(s) for s in sizes) >= 1, **pie_kwargs
+ )
ratio = 20 # we will remove all labels with size smaller 5%
legend_enforced = False
@@ -248,12 +263,12 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
for i in range(len(sizes)):
if sum(sizes) > 0:
labels[i] = "{label} {percent:.1f}% ({size:.0f})".format(
- label=labels[i], percent=100 * sizes[i] / sum(sizes), size=sizes[i]
+ label=labels[i],
+ percent=100 * sizes[i] / sum(sizes),
+ size=sizes[i],
)
else:
- labels[i] = "{label} {percent:.1f}% ({size:.0f})".format(
- label=labels[i], percent=0.0, size=sizes[i]
- )
+ labels[i] = f"{labels[i]} {0.0:.1f}% ({sizes[i]:.0f})"
if text_color:
for autotext in autotexts:
@@ -262,7 +277,13 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
# Legend preparation
if current_needpie["legend"]:
- axes.legend(wedges, labels, title="legend", loc="center left", bbox_to_anchor=(0.8, 0, 0.5, 1))
+ axes.legend(
+ wedges,
+ labels,
+ title="legend",
+ loc="center left",
+ bbox_to_anchor=(0.8, 0, 0.5, 1),
+ )
matplotlib.pyplot.setp(autotexts, size=8, weight="bold")
@@ -273,13 +294,17 @@ def process_needpie(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
# We need to calculate an unique pie-image file name
hash_value = hashlib.sha256(id.encode()).hexdigest()[:5]
- image_node = save_matplotlib_figure(app, fig, f"need_pie_{hash_value}", fromdocname)
+ image_node = save_matplotlib_figure(
+ app, fig, f"need_pie_{hash_value}", fromdocname
+ )
# Add lineno to node
image_node.line = current_needpie["lineno"]
if len(sizes) == 0 or all(s == 0 for s in sizes):
- node.replace_self(no_needs_found_paragraph(current_needpie.get("filter_warning")))
+ node.replace_self(
+ no_needs_found_paragraph(current_needpie.get("filter_warning"))
+ )
else:
node.replace_self(image_node)
diff --git a/sphinx_needs/directives/needreport.py b/sphinx_needs/directives/needreport.py
index 97f4b5c08..516a70abe 100644
--- a/sphinx_needs/directives/needreport.py
+++ b/sphinx_needs/directives/needreport.py
@@ -49,12 +49,18 @@ def run(self) -> Sequence[nodes.raw]:
report_info.update(**needs_config.render_context)
if "template" in self.options:
- need_report_template_path = Path(self.env.relfn2path(self.options["template"], self.env.docname)[1])
+ need_report_template_path = Path(
+ self.env.relfn2path(self.options["template"], self.env.docname)[1]
+ )
elif needs_config.report_template:
# Absolute path starts with /, based on the conf.py directory. The / need to be striped
- need_report_template_path = Path(str(env.app.srcdir)) / needs_config.report_template.lstrip("/")
+ need_report_template_path = Path(
+ str(env.app.srcdir)
+ ) / needs_config.report_template.lstrip("/")
else:
- need_report_template_path = Path(__file__).parent / "needreport_template.rst"
+ need_report_template_path = (
+ Path(__file__).parent / "needreport_template.rst"
+ )
if not need_report_template_path.is_file():
LOGGER.warning(
@@ -65,11 +71,15 @@ def run(self) -> Sequence[nodes.raw]:
)
return []
- needs_report_template_file_content = need_report_template_path.read_text(encoding="utf8")
+ needs_report_template_file_content = need_report_template_path.read_text(
+ encoding="utf8"
+ )
template = Template(needs_report_template_file_content, autoescape=True)
text = template.render(**report_info)
- self.state_machine.insert_input(text.split("\n"), self.state_machine.document.attributes["source"])
+ self.state_machine.insert_input(
+ text.split("\n"), self.state_machine.document.attributes["source"]
+ )
report_node = nodes.raw()
diff --git a/sphinx_needs/directives/needsequence.py b/sphinx_needs/directives/needsequence.py
index 42b1e1e25..bba1269dc 100644
--- a/sphinx_needs/directives/needsequence.py
+++ b/sphinx_needs/directives/needsequence.py
@@ -57,7 +57,8 @@ def run(self) -> Sequence[nodes.Node]:
start = self.options.get("start")
if start is None or len(start.strip()) == 0:
raise NeedSequenceException(
- "No valid start option given for needsequence. " "See file {}:{}".format(env.docname, self.lineno)
+ "No valid start option given for needsequence. "
+ f"See file {env.docname}:{self.lineno}"
)
# Add the needsequence and all needed information
@@ -76,7 +77,10 @@ def run(self) -> Sequence[nodes.Node]:
def process_needsequence(
- app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
# Replace all needsequence nodes with a list of the collected needs.
env = app.env
@@ -98,13 +102,17 @@ def process_needsequence(
id = node.attributes["ids"][0]
current_needsequence = needs_data.get_or_create_sequences()[id]
- option_link_types = [link.upper() for link in current_needsequence["link_types"]]
+ option_link_types = [
+ link.upper() for link in current_needsequence["link_types"]
+ ]
for lt in option_link_types:
if lt not in link_type_names:
logger.warning(
"Unknown link type {link_type} in needsequence {flow}. Allowed values:"
" {link_types} [needs]".format(
- link_type=lt, flow=current_needsequence["target_id"], link_types=",".join(link_type_names)
+ link_type=lt,
+ flow=current_needsequence["target_id"],
+ link_types=",".join(link_type_names),
),
type="needs",
)
@@ -131,7 +139,9 @@ def process_needsequence(
config = current_needsequence["config"]
puml_node["uml"] += add_config(config)
- start_needs_id = [x.strip() for x in re.split(";|,", current_needsequence["start"])]
+ start_needs_id = [
+ x.strip() for x in re.split(";|,", current_needsequence["start"])
+ ]
if len(start_needs_id) == 0:
# TODO this should be a warning (and not tested)
raise NeedSequenceException(
@@ -150,9 +160,11 @@ def process_needsequence(
need = all_needs_dict[need_id.strip()]
except KeyError:
raise NeedSequenceException(
- "Given {} in needsequence unknown."
- " File {}"
- ":{}".format(need_id, current_needsequence["docname"], current_needsequence["lineno"])
+ "Given {} in needsequence unknown." " File {}" ":{}".format(
+ need_id,
+ current_needsequence["docname"],
+ current_needsequence["lineno"],
+ )
)
# Add children of participants
@@ -177,7 +189,9 @@ def process_needsequence(
puml_node["uml"] += "\n@enduml"
puml_node["incdir"] = os.path.dirname(current_needsequence["docname"])
- puml_node["filename"] = os.path.split(current_needsequence["docname"])[1] # Needed for plantuml >= 0.9
+ puml_node["filename"] = os.path.split(current_needsequence["docname"])[
+ 1
+ ] # Needed for plantuml >= 0.9
scale = int(current_needsequence["scale"])
# if scale != 100:
@@ -203,8 +217,12 @@ def process_needsequence(
gen_flow_link = generate_name(app, puml_node.children[0], file_ext)
current_file_parts = fromdocname.split("/")
subfolder_amount = len(current_file_parts) - 1
- img_locaton = "../" * subfolder_amount + "_images/" + gen_flow_link[0].split("/")[-1]
- flow_ref = nodes.reference("t", current_needsequence["caption"], refuri=img_locaton)
+ img_locaton = (
+ "../" * subfolder_amount + "_images/" + gen_flow_link[0].split("/")[-1]
+ )
+ flow_ref = nodes.reference(
+ "t", current_needsequence["caption"], refuri=img_locaton
+ )
puml_node += nodes.caption("", "", flow_ref)
# Add lineno to node
@@ -212,8 +230,12 @@ def process_needsequence(
content.append(puml_node)
- if len(c_string) == 0 and p_string.count("participant") == 1: # no connections and just one (start) participant
- content = [(no_needs_found_paragraph(current_needsequence.get("filter_warning")))]
+ if (
+ len(c_string) == 0 and p_string.count("participant") == 1
+ ): # no connections and just one (start) participant
+ content = [
+ (no_needs_found_paragraph(current_needsequence.get("filter_warning")))
+ ]
if current_needsequence["show_filters"]:
content.append(get_filter_para(current_needsequence))
@@ -241,7 +263,11 @@ def get_message_needs(
p_string = ""
c_string = ""
for msg_need in msg_needs:
- messages[msg_need["id"]] = {"id": msg_need["id"], "title": msg_need["title"], "receivers": {}}
+ messages[msg_need["id"]] = {
+ "id": msg_need["id"],
+ "title": msg_need["title"],
+ "receivers": {},
+ }
if sender["id"] not in tracked_receivers:
p_string += 'participant "{}" as {}\n'.format(sender["title"], sender["id"])
tracked_receivers.append(sender["id"])
@@ -252,17 +278,31 @@ def get_message_needs(
from sphinx_needs.filter_common import filter_single_need
if not filter_single_need(
- all_needs_dict[rec_id], NeedsSphinxConfig(app.config), filter, needs=all_needs_dict.values()
+ all_needs_dict[rec_id],
+ NeedsSphinxConfig(app.config),
+ filter,
+ needs=all_needs_dict.values(),
):
continue
- rec_data = {"id": rec_id, "title": all_needs_dict[rec_id]["title"], "messages": []}
+ rec_data = {
+ "id": rec_id,
+ "title": all_needs_dict[rec_id]["title"],
+ "messages": [],
+ }
- c_string += "{} -> {}: {}\n".format(sender["id"], rec_data["id"], msg_need["title"])
+ c_string += "{} -> {}: {}\n".format(
+ sender["id"], rec_data["id"], msg_need["title"]
+ )
if rec_id not in tracked_receivers:
rec_messages, p_string_new, c_string_new = get_message_needs(
- app, all_needs_dict[rec_id], link_types, all_needs_dict, tracked_receivers, filter=filter
+ app,
+ all_needs_dict[rec_id],
+ link_types,
+ all_needs_dict,
+ tracked_receivers,
+ filter=filter,
)
p_string += p_string_new
c_string += c_string_new
diff --git a/sphinx_needs/directives/needservice.py b/sphinx_needs/directives/needservice.py
index bf234f7fe..73f920b7d 100644
--- a/sphinx_needs/directives/needservice.py
+++ b/sphinx_needs/directives/needservice.py
@@ -48,7 +48,17 @@ def __init__(
state: RSTState,
state_machine: RSTStateMachine,
):
- super().__init__(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
+ super().__init__(
+ name,
+ arguments,
+ options,
+ content,
+ lineno,
+ content_offset,
+ block_text,
+ state,
+ state_machine,
+ )
self.log = get_logger(__name__)
def run(self) -> Sequence[nodes.Node]:
@@ -94,8 +104,12 @@ def run(self) -> Sequence[nodes.Node]:
missing_options = {}
for element in datum.keys():
defined_options = list(self.__class__.option_spec.keys())
- defined_options.append("content") # Add content, so that it gets not detected as missing
- if element not in defined_options and element not in getattr(app.config, "needs_extra_links", []):
+ defined_options.append(
+ "content"
+ ) # Add content, so that it gets not detected as missing
+ if element not in defined_options and element not in getattr(
+ app.config, "needs_extra_links", []
+ ):
missing_options[element] = datum[element]
# Finally delete not found options
@@ -112,13 +126,25 @@ def run(self) -> Sequence[nodes.Node]:
datum.update(options)
# ToDo: Tags and Status are not set (but exist in data)
- section += add_need(self.env.app, self.state, docname, self.lineno, need_type, need_title, **datum)
+ section += add_need(
+ self.env.app,
+ self.state,
+ docname,
+ self.lineno,
+ need_type,
+ need_title,
+ **datum,
+ )
else:
try:
service_debug_data = service.debug(self.options)
except NotImplementedError:
- service_debug_data = {"error": f'Service {service_name} does not support "debug" output.'}
- viewer_node = get_data_viewer_node(title="Debug data", data=service_debug_data)
+ service_debug_data = {
+ "error": f'Service {service_name} does not support "debug" output.'
+ }
+ viewer_node = get_data_viewer_node(
+ title="Debug data", data=service_debug_data
+ )
section.append(viewer_node)
add_doc(self.env, self.env.docname)
diff --git a/sphinx_needs/directives/needtable.py b/sphinx_needs/directives/needtable.py
index c05dfb61b..e6c492d79 100644
--- a/sphinx_needs/directives/needtable.py
+++ b/sphinx_needs/directives/needtable.py
@@ -52,7 +52,9 @@ class NeedtableDirective(FilterBase):
def run(self) -> Sequence[nodes.Node]:
env = self.env
- targetid = "needtable-{docname}-{id}".format(docname=env.docname, id=env.new_serialno("needtable"))
+ targetid = "needtable-{docname}-{id}".format(
+ docname=env.docname, id=env.new_serialno("needtable")
+ )
targetnode = nodes.target("", "", ids=[targetid])
columns_str = str(self.options.get("columns", ""))
@@ -68,7 +70,9 @@ def run(self) -> Sequence[nodes.Node]:
colwidths = str(self.options.get("colwidths", ""))
colwidths_list = []
if colwidths:
- colwidths_list = [int(width.strip()) for width in re.split(";|,", colwidths)]
+ colwidths_list = [
+ int(width.strip()) for width in re.split(";|,", colwidths)
+ ]
if len(columns) != len(colwidths_list):
raise NeedsInvalidException(
f"Amount of elements in colwidths and columns do not match: "
@@ -115,7 +119,10 @@ def run(self) -> Sequence[nodes.Node]:
@measure_time("needtable")
@profile("NEEDTABLE")
def process_needtables(
- app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
"""
Replace all needtables nodes with a table of filtered nodes.
@@ -149,7 +156,9 @@ def process_needtables(
id = node.attributes["ids"][0]
current_needtable = needs_data.get_or_create_tables()[id]
- if current_needtable["style"] == "" or current_needtable["style"].upper() not in ["TABLE", "DATATABLES"]:
+ if current_needtable["style"] == "" or current_needtable[
+ "style"
+ ].upper() not in ["TABLE", "DATATABLES"]:
if needs_config.table_style == "":
style = "DATATABLES"
else:
@@ -199,7 +208,9 @@ def process_needtables(
# Perform filtering of needs
try:
- filtered_needs = process_filters(app, list(all_needs.values()), current_needtable)
+ filtered_needs = process_filters(
+ app, list(all_needs.values()), current_needtable
+ )
except Exception as e:
raise e
@@ -228,8 +239,12 @@ def sort(need: NeedsInfoType) -> Any:
filtered_needs.sort(key=get_sorter(current_needtable["sort"]))
for need_info in filtered_needs:
- style_row = check_and_get_content(current_needtable["style_row"], need_info, env)
- style_row = style_row.replace(" ", "_") # Replace whitespaces with _ to get valid css name
+ style_row = check_and_get_content(
+ current_needtable["style_row"], need_info, env
+ )
+ style_row = style_row.replace(
+ " ", "_"
+ ) # Replace whitespaces with _ to get valid css name
temp_need = need_info.copy()
if temp_need["is_need"]:
@@ -243,12 +258,26 @@ def sort(need: NeedsInfoType) -> Any:
for option, _title in current_needtable["columns"]:
if option == "ID":
- row += row_col_maker(app, fromdocname, all_needs, temp_need, "id", make_ref=True, prefix=prefix)
+ row += row_col_maker(
+ app,
+ fromdocname,
+ all_needs,
+ temp_need,
+ "id",
+ make_ref=True,
+ prefix=prefix,
+ )
elif option == "TITLE":
- row += row_col_maker(app, fromdocname, all_needs, temp_need, "title", prefix=prefix)
+ row += row_col_maker(
+ app, fromdocname, all_needs, temp_need, "title", prefix=prefix
+ )
elif option in link_type_list:
link_type = link_type_list[option]
- if option in ["INCOMING", link_type["option"].upper() + "_BACK", link_type["incoming"].upper()]:
+ if option in [
+ "INCOMING",
+ link_type["option"].upper() + "_BACK",
+ link_type["incoming"].upper(),
+ ]:
row += row_col_maker(
app,
fromdocname,
@@ -259,10 +288,17 @@ def sort(need: NeedsInfoType) -> Any:
)
else:
row += row_col_maker(
- app, fromdocname, all_needs, temp_need, link_type["option"], ref_lookup=True
+ app,
+ fromdocname,
+ all_needs,
+ temp_need,
+ link_type["option"],
+ ref_lookup=True,
)
else:
- row += row_col_maker(app, fromdocname, all_needs, temp_need, option.lower())
+ row += row_col_maker(
+ app, fromdocname, all_needs, temp_need, option.lower()
+ )
tbody += row
# Need part rows
@@ -315,7 +351,9 @@ def sort(need: NeedsInfoType) -> Any:
ref_lookup=True,
)
else:
- row += row_col_maker(app, fromdocname, all_needs, temp_part, option.lower())
+ row += row_col_maker(
+ app, fromdocname, all_needs, temp_part, option.lower()
+ )
tbody += row
diff --git a/sphinx_needs/directives/needuml.py b/sphinx_needs/directives/needuml.py
index 0b2efb482..3fd8f3b41 100644
--- a/sphinx_needs/directives/needuml.py
+++ b/sphinx_needs/directives/needuml.py
@@ -45,10 +45,14 @@ def run(self) -> Sequence[nodes.Node]:
env = self.env
if self.name == "needarch":
- targetid = "needarch-{docname}-{id}".format(docname=env.docname, id=env.new_serialno("needarch"))
+ targetid = "needarch-{docname}-{id}".format(
+ docname=env.docname, id=env.new_serialno("needarch")
+ )
is_arch = True
else:
- targetid = "needuml-{docname}-{id}".format(docname=env.docname, id=env.new_serialno("needuml"))
+ targetid = "needuml-{docname}-{id}".format(
+ docname=env.docname, id=env.new_serialno("needuml")
+ )
is_arch = False
targetnode = nodes.target("", "", ids=[targetid])
@@ -87,7 +91,9 @@ def run(self) -> Sequence[nodes.Node]:
plantuml_code_out_path = None
if save_path:
if os.path.isabs(save_path):
- raise NeedumlException(f"Given save path: {save_path}, is not a relative path.")
+ raise NeedumlException(
+ f"Given save path: {save_path}, is not a relative path."
+ )
else:
plantuml_code_out_path = save_path
@@ -123,7 +129,9 @@ def run(self) -> Sequence[nodes.Node]:
return NeedumlDirective.run(self)
-def transform_uml_to_plantuml_node(app, uml_content: str, parent_need_id: str, key: str, kwargs: dict, config: str):
+def transform_uml_to_plantuml_node(
+ app, uml_content: str, parent_need_id: str, key: str, kwargs: dict, config: str
+):
try:
if "sphinxcontrib.plantuml" not in app.config.extensions:
raise ImportError
@@ -178,7 +186,13 @@ def get_debug_node_from_puml_node(puml_node):
def jinja2uml(
- app, fromdocname, uml_content: str, parent_need_id: str, key: str, processed_need_ids: {}, kwargs: dict
+ app,
+ fromdocname,
+ uml_content: str,
+ parent_need_id: str,
+ key: str,
+ processed_need_ids: {},
+ kwargs: dict,
) -> (str, {}):
# Let's render jinja templates with uml content template to 'plantuml syntax' uml
# 1. Remove @startuml and @enduml
@@ -192,7 +206,9 @@ def jinja2uml(
# 4. Append need_id to processed_need_ids, so it will not been processed again
if parent_need_id:
- jinja_utils.append_need_to_processed_needs(need_id=parent_need_id, art="uml", key=key, kwargs=kwargs)
+ jinja_utils.append_need_to_processed_needs(
+ need_id=parent_need_id, art="uml", key=key, kwargs=kwargs
+ )
# 5. Get data for the jinja processing
data = {}
@@ -229,13 +245,17 @@ class JinjaFunctions:
Provides access to sphinx-app and all Needs objects.
"""
- def __init__(self, app: Sphinx, fromdocname, parent_need_id: str, processed_need_ids: dict):
+ def __init__(
+ self, app: Sphinx, fromdocname, parent_need_id: str, processed_need_ids: dict
+ ):
self.needs = SphinxNeedsData(app.env).get_or_create_needs()
self.app = app
self.fromdocname = fromdocname
self.parent_need_id = parent_need_id
if parent_need_id and parent_need_id not in self.needs:
- raise NeedumlException(f"JinjaFunctions initialized with undefined parent_need_id: '{parent_need_id}'")
+ raise NeedumlException(
+ f"JinjaFunctions initialized with undefined parent_need_id: '{parent_need_id}'"
+ )
self.processed_need_ids = processed_need_ids
def need_to_processed_data(self, art: str, key: str, kwargs: dict) -> {}:
@@ -246,7 +266,9 @@ def need_to_processed_data(self, art: str, key: str, kwargs: dict) -> {}:
}
return d
- def append_need_to_processed_needs(self, need_id: str, art: str, key: str, kwargs: dict) -> None:
+ def append_need_to_processed_needs(
+ self, need_id: str, art: str, key: str, kwargs: dict
+ ) -> None:
data = self.need_to_processed_data(art=art, key=key, kwargs=kwargs)
if need_id not in self.processed_need_ids:
self.processed_need_ids[need_id] = []
@@ -261,18 +283,26 @@ def append_needs_to_processed_needs(self, processed_needs_data: dict) -> None:
if d not in self.processed_need_ids[k]:
self.processed_need_ids[k].append(d)
- def data_in_processed_data(self, need_id: str, art: str, key: str, kwargs: dict) -> bool:
+ def data_in_processed_data(
+ self, need_id: str, art: str, key: str, kwargs: dict
+ ) -> bool:
data = self.need_to_processed_data(art=art, key=key, kwargs=kwargs)
- return (need_id in self.processed_need_ids) and (data in self.processed_need_ids[need_id])
+ return (need_id in self.processed_need_ids) and (
+ data in self.processed_need_ids[need_id]
+ )
def get_processed_need_ids(self) -> {}:
return self.processed_need_ids
def uml_from_need(self, need_id: str, key: str = "diagram", **kwargs) -> str:
if need_id not in self.needs:
- raise NeedumlException(f"Jinja function uml() is called with undefined need_id: '{need_id}'.")
+ raise NeedumlException(
+ f"Jinja function uml() is called with undefined need_id: '{need_id}'."
+ )
- if self.data_in_processed_data(need_id=need_id, art="uml", key=key, kwargs=kwargs):
+ if self.data_in_processed_data(
+ need_id=need_id, art="uml", key=key, kwargs=kwargs
+ ):
return ""
need_info = self.needs[need_id]
@@ -281,7 +311,9 @@ def uml_from_need(self, need_id: str, key: str = "diagram", **kwargs) -> str:
if need_info["arch"][key]:
uml_content = need_info["arch"][key]
else:
- raise NeedumlException(f"Option key name: {key} does not exist in need {need_id}.")
+ raise NeedumlException(
+ f"Option key name: {key} does not exist in need {need_id}."
+ )
else:
if "diagram" in need_info["arch"] and need_info["arch"]["diagram"]:
uml_content = need_info["arch"]["diagram"]
@@ -307,13 +339,17 @@ def uml_from_need(self, need_id: str, key: str = "diagram", **kwargs) -> str:
def flow(self, need_id) -> str:
if need_id not in self.needs:
- raise NeedumlException(f"Jinja function flow is called with undefined need_id: '{need_id}'.")
+ raise NeedumlException(
+ f"Jinja function flow is called with undefined need_id: '{need_id}'."
+ )
if self.data_in_processed_data(need_id=need_id, art="flow", key="", kwargs={}):
return ""
# append need_id to processed_need_ids, so it will not been processed again
- self.append_need_to_processed_needs(need_id=need_id, art="flow", key="", kwargs={})
+ self.append_need_to_processed_needs(
+ need_id=need_id, art="flow", key="", kwargs={}
+ )
need_info = self.needs[need_id]
link = calculate_link(self.app, need_info, self.fromdocname)
@@ -334,9 +370,13 @@ def flow(self, need_id) -> str:
def ref(self, need_id: str, option: str = None, text: str = None) -> str:
if need_id not in self.needs:
- raise NeedumlException(f"Jinja function ref is called with undefined need_id: '{need_id}'.")
+ raise NeedumlException(
+ f"Jinja function ref is called with undefined need_id: '{need_id}'."
+ )
if (option and text) and (not option and not text):
- raise NeedumlException("Jinja function ref requires exactly one entry 'option' or 'text'")
+ raise NeedumlException(
+ "Jinja function ref requires exactly one entry 'option' or 'text'"
+ )
need_info = self.needs[need_id]
link = calculate_link(self.app, need_info, self.fromdocname)
@@ -354,11 +394,15 @@ def filter(self, filter_string):
"""
needs_config = NeedsSphinxConfig(self.app.config)
- return filter_needs(list(self.needs.values()), needs_config, filter_string=filter_string)
+ return filter_needs(
+ list(self.needs.values()), needs_config, filter_string=filter_string
+ )
def imports(self, *args):
if not self.parent_need_id:
- raise NeedumlException("Jinja function 'import()' is not supported in needuml directive.")
+ raise NeedumlException(
+ "Jinja function 'import()' is not supported in needuml directive."
+ )
# gets all need ids from need links/extra_links options and wrap into jinja function uml()
need_info = self.needs[self.parent_need_id]
uml_ids = []
@@ -378,7 +422,9 @@ def imports(self, *args):
def need(self):
if not self.parent_need_id:
- raise NeedumlException("Jinja function 'need()' is not supported in needuml directive.")
+ raise NeedumlException(
+ "Jinja function 'need()' is not supported in needuml directive."
+ )
return self.needs[self.parent_need_id]
@@ -407,7 +453,12 @@ def is_element_of_need(node: nodes.Element) -> str:
@measure_time("needuml")
-def process_needuml(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_needuml(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
env = app.env
# for node in doctree.findall(Needuml):
@@ -421,14 +472,18 @@ def process_needuml(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
# Check if needarch is only used inside a need
parent_need_id = is_element_of_need(node)
if not parent_need_id:
- raise NeedArchException("Directive needarch can only be used inside a need.")
+ raise NeedArchException(
+ "Directive needarch can only be used inside a need."
+ )
content = []
# Adding config
config = current_needuml["config"]
if config and len(config) >= 3:
# Remove all empty lines
- config = "\n".join([line.strip() for line in config.split("\n") if line.strip()])
+ config = "\n".join(
+ [line.strip() for line in config.split("\n") if line.strip()]
+ )
puml_node = transform_uml_to_plantuml_node(
app=app,
@@ -459,7 +514,9 @@ def process_needuml(app: Sphinx, doctree: nodes.document, fromdocname: str, foun
puml_node["align"] = "center"
puml_node["incdir"] = os.path.dirname(current_needuml["docname"])
- puml_node["filename"] = os.path.split(current_needuml["docname"])[1] # Needed for plantuml >= 0.9
+ puml_node["filename"] = os.path.split(current_needuml["docname"])[
+ 1
+ ] # Needed for plantuml >= 0.9
content.append(puml_node)
diff --git a/sphinx_needs/directives/utils.py b/sphinx_needs/directives/utils.py
index 378342909..abb3b891b 100644
--- a/sphinx_needs/directives/utils.py
+++ b/sphinx_needs/directives/utils.py
@@ -24,17 +24,25 @@ def used_filter_paragraph(current_needfilter: NeedsFilteredBaseType) -> nodes.pa
para = nodes.paragraph()
filter_text = "Used filter:"
filter_text += (
- " status(%s)" % " OR ".join(current_needfilter["status"]) if len(current_needfilter["status"]) > 0 else ""
+ " status(%s)" % " OR ".join(current_needfilter["status"])
+ if len(current_needfilter["status"]) > 0
+ else ""
)
if len(current_needfilter["status"]) > 0 and len(current_needfilter["tags"]) > 0:
filter_text += " AND "
- filter_text += " tags(%s)" % " OR ".join(current_needfilter["tags"]) if len(current_needfilter["tags"]) > 0 else ""
- if (len(current_needfilter["status"]) > 0 or len(current_needfilter["tags"]) > 0) and len(
- current_needfilter["types"]
- ) > 0:
+ filter_text += (
+ " tags(%s)" % " OR ".join(current_needfilter["tags"])
+ if len(current_needfilter["tags"]) > 0
+ else ""
+ )
+ if (
+ len(current_needfilter["status"]) > 0 or len(current_needfilter["tags"]) > 0
+ ) and len(current_needfilter["types"]) > 0:
filter_text += " AND "
filter_text += (
- " types(%s)" % " OR ".join(current_needfilter["types"]) if len(current_needfilter["types"]) > 0 else ""
+ " types(%s)" % " OR ".join(current_needfilter["types"])
+ if len(current_needfilter["types"]) > 0
+ else ""
)
filter_node = nodes.emphasis(filter_text, filter_text)
@@ -91,7 +99,9 @@ def analyse_needs_metrics(env: BuildEnvironment) -> dict[str, Any]:
if i["type"] in needs_types:
needs_types[i["type"]] += 1
- metric_data["needs_types"] = {i[0]: i[1] for i in sorted(needs_types.items(), key=lambda x: x[0])}
+ metric_data["needs_types"] = {
+ i[0]: i[1] for i in sorted(needs_types.items(), key=lambda x: x[0])
+ }
return metric_data
diff --git a/sphinx_needs/environment.py b/sphinx_needs/environment.py
index 61dbf95dc..786ea2666 100644
--- a/sphinx_needs/environment.py
+++ b/sphinx_needs/environment.py
@@ -40,13 +40,21 @@ def safe_add_file(filename: Path, app: Sphinx) -> None:
if pure_path.suffix == ".js":
# Make sure the calculated (posix)-path is not already registered as "web"-path
- if hasattr(builder, "script_files") and str(static_data_file) not in builder.script_files:
+ if (
+ hasattr(builder, "script_files")
+ and str(static_data_file) not in builder.script_files
+ ):
app.add_js_file(str(pure_path))
elif pure_path.suffix == ".css":
- if hasattr(builder, "css_files") and str(static_data_file) not in builder.css_files:
+ if (
+ hasattr(builder, "css_files")
+ and str(static_data_file) not in builder.css_files
+ ):
app.add_css_file(str(pure_path))
else:
- raise NotImplementedError(f"File type {pure_path.suffix} not support by save_add_file")
+ raise NotImplementedError(
+ f"File type {pure_path.suffix} not support by save_add_file"
+ )
def safe_remove_file(filename: Path, app: Sphinx) -> None:
@@ -120,7 +128,10 @@ def _find_css_files() -> Iterable[Path]:
if not source_file_path.exists():
source_file_path = css_root / "blank" / "blank.css"
- logger.warning(f"{source_file_path} not found. Copying sphinx-internal blank.css [needs]", type="needs")
+ logger.warning(
+ f"{source_file_path} not found. Copying sphinx-internal blank.css [needs]",
+ type="needs",
+ )
dest_file = dest_dir / source_file_path.name
dest_dir.mkdir(exist_ok=True)
@@ -215,7 +226,9 @@ def install_permalink_file(app: Sphinx, env: BuildEnvironment) -> None:
return
# load jinja template
- jinja_env = Environment(loader=PackageLoader("sphinx_needs"), autoescape=select_autoescape())
+ jinja_env = Environment(
+ loader=PackageLoader("sphinx_needs"), autoescape=select_autoescape()
+ )
template = jinja_env.get_template("permalink.html")
# save file to build dir
diff --git a/sphinx_needs/external_needs.py b/sphinx_needs/external_needs.py
index fc8003648..331038996 100644
--- a/sphinx_needs/external_needs.py
+++ b/sphinx_needs/external_needs.py
@@ -47,18 +47,28 @@ def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> No
)
)
elif not (source.get("json_url", False) or source.get("json_path", False)):
- raise NeedsExternalException("json_path or json_url must be configured to use external_needs.")
+ raise NeedsExternalException(
+ "json_path or json_url must be configured to use external_needs."
+ )
if source.get("json_url", False):
- log.info(clean_log(f"Loading external needs from url {source['json_url']}."))
+ log.info(
+ clean_log(f"Loading external needs from url {source['json_url']}.")
+ )
s = requests.Session()
s.mount("file://", FileAdapter())
try:
response = s.get(source["json_url"])
- needs_json = response.json() # The downloaded file MUST be json. Everything else we do not handle!
+ needs_json = (
+ response.json()
+ ) # The downloaded file MUST be json. Everything else we do not handle!
except Exception as e:
raise NeedsExternalException(
- clean_log("Getting {} didn't work. Reason: {}".format(source["json_url"], e))
+ clean_log(
+ "Getting {} didn't work. Reason: {}".format(
+ source["json_url"], e
+ )
+ )
)
if source.get("json_path", False):
@@ -68,7 +78,9 @@ def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> No
json_path = os.path.join(app.srcdir, source["json_path"])
if not os.path.exists(json_path):
- raise NeedsExternalException(f"Given json_path {json_path} does not exist.")
+ raise NeedsExternalException(
+ f"Given json_path {json_path} does not exist."
+ )
with open(json_path) as json_file:
needs_json = json.load(json_file)
@@ -83,7 +95,9 @@ def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> No
needs = needs_json["versions"][version]["needs"]
except KeyError:
raise NeedsExternalException(
- clean_log(f"Version {version} not found in json file from {source['json_url']}")
+ clean_log(
+ f"Version {version} not found in json file from {source['json_url']}"
+ )
)
log.debug(f"Loading {len(needs)} needs.")
@@ -98,7 +112,16 @@ def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> No
if (
key not in needs_config.extra_options
and key not in extra_links
- and key not in ["title", "type", "id", "description", "tags", "docname", "status"]
+ and key
+ not in [
+ "title",
+ "type",
+ "id",
+ "description",
+ "tags",
+ "docname",
+ "status",
+ ]
):
del need_params[key]
@@ -112,9 +135,9 @@ def load_external_needs(app: Sphinx, env: BuildEnvironment, _docname: str) -> No
cal_target_url = mem_template.render(**{"need": need})
need_params["external_url"] = f'{source["base_url"]}/{cal_target_url}'
else:
- need_params["external_url"] = (
- f'{source["base_url"]}/{need.get("docname", "__error__")}.html#{need["id"]}'
- )
+ need_params[
+ "external_url"
+ ] = f'{source["base_url"]}/{need.get("docname", "__error__")}.html#{need["id"]}'
need_params["content"] = need["description"]
need_params["links"] = need.get("links", [])
diff --git a/sphinx_needs/filter_common.py b/sphinx_needs/filter_common.py
index 896256860..0ba740372 100644
--- a/sphinx_needs/filter_common.py
+++ b/sphinx_needs/filter_common.py
@@ -55,7 +55,11 @@ class FilterBase(SphinxDirective):
def collect_filter_attributes(self) -> FilterAttributesType:
_tags = str(self.options.get("tags", ""))
- tags = [tag.strip() for tag in re.split(";|,", _tags) if len(tag) > 0] if _tags else []
+ tags = (
+ [tag.strip() for tag in re.split(";|,", _tags) if len(tag) > 0]
+ if _tags
+ else []
+ )
status = self.options.get("status")
if status:
@@ -92,7 +96,10 @@ def collect_filter_attributes(self) -> FilterAttributesType:
def process_filters(
- app: Sphinx, all_needs: Iterable[NeedsInfoType], filter_data: NeedsFilteredBaseType, include_external: bool = True
+ app: Sphinx,
+ all_needs: Iterable[NeedsInfoType],
+ filter_data: NeedsFilteredBaseType,
+ include_external: bool = True,
) -> list[NeedsPartsInfoType]:
"""
Filters all needs with given configuration.
@@ -112,7 +119,10 @@ def process_filters(
try:
all_needs = sorted(all_needs, key=lambda node: node[sort_key] or "") # type: ignore[literal-required]
except KeyError as e:
- log.warning(f"Sorting parameter {sort_key} not valid: Error: {e} [needs]", type="needs")
+ log.warning(
+ f"Sorting parameter {sort_key} not valid: Error: {e} [needs]",
+ type="needs",
+ )
# check if include external needs
checked_all_needs: Iterable[NeedsInfoType]
@@ -130,7 +140,9 @@ def process_filters(
all_needs_incl_parts = prepare_need_list(checked_all_needs)
# Check if external filter code is defined
- filter_func, filter_args = check_and_get_external_filter_func(filter_data.get("filter_func"))
+ filter_func, filter_args = check_and_get_external_filter_func(
+ filter_data.get("filter_func")
+ )
filter_code = None
# Get filter_code from
@@ -141,12 +153,19 @@ def process_filters(
if bool(filter_data["status"] or filter_data["tags"] or filter_data["types"]):
for need_info in all_needs_incl_parts:
status_filter_passed = False
- if not filter_data["status"] or need_info["status"] and need_info["status"] in filter_data["status"]:
+ if (
+ not filter_data["status"]
+ or need_info["status"]
+ and need_info["status"] in filter_data["status"]
+ ):
# Filtering for status was not requested or match was found
status_filter_passed = True
tags_filter_passed = False
- if len(set(need_info["tags"]) & set(filter_data["tags"])) > 0 or len(filter_data["tags"]) == 0:
+ if (
+ len(set(need_info["tags"]) & set(filter_data["tags"])) > 0
+ or len(filter_data["tags"]) == 0
+ ):
tags_filter_passed = True
type_filter_passed = False
@@ -160,13 +179,19 @@ def process_filters(
if status_filter_passed and tags_filter_passed and type_filter_passed:
found_needs_by_options.append(need_info)
# Get need by filter string
- found_needs_by_string = filter_needs(all_needs_incl_parts, needs_config, filter_data["filter"])
+ found_needs_by_string = filter_needs(
+ all_needs_incl_parts, needs_config, filter_data["filter"]
+ )
# Make an intersection of both lists
- found_needs = intersection_of_need_results(found_needs_by_options, found_needs_by_string)
+ found_needs = intersection_of_need_results(
+ found_needs_by_options, found_needs_by_string
+ )
else:
# There is no other config as the one for filter string.
# So we only need this result.
- found_needs = filter_needs(all_needs_incl_parts, needs_config, filter_data["filter"])
+ found_needs = filter_needs(
+ all_needs_incl_parts, needs_config, filter_data["filter"]
+ )
else:
# Provides only a copy of needs to avoid data manipulations.
context = {
@@ -185,7 +210,9 @@ def process_filters(
context[f"arg{index+1}"] = arg
# Decorate function to allow time measurments
- filter_func = measure_time_func(filter_func, category="filter_func", source="user")
+ filter_func = measure_time_func(
+ filter_func, category="filter_func", source="user"
+ )
filter_func(**context)
else:
log.warning("Something went wrong running filter [needs]", type="needs")
@@ -237,7 +264,11 @@ def prepare_need_list(need_list: Iterable[NeedsInfoType]) -> list[NeedsPartsInfo
for need in need_list:
for part in need["parts"].values():
id_complete = ".".join([need["id"], part["id"]])
- filter_part: NeedsPartsInfoType = {**need, **part, **{"id_parent": need["id"], "id_complete": id_complete}} # type: ignore[typeddict-item]
+ filter_part: NeedsPartsInfoType = {
+ **need,
+ **part,
+ **{"id_parent": need["id"], "id_complete": id_complete}, # type: ignore[typeddict-item]
+ }
all_needs_incl_parts.append(filter_part)
# Be sure extra attributes, which makes only sense for need_parts, are also available on
@@ -288,12 +319,21 @@ def filter_needs(
for filter_need in needs:
try:
if filter_single_need(
- filter_need, config, filter_string, needs, current_need, filter_compiled=filter_compiled
+ filter_need,
+ config,
+ filter_string,
+ needs,
+ current_need,
+ filter_compiled=filter_compiled,
):
found_needs.append(filter_need)
except Exception as e:
if not error_reported: # Let's report a filter-problem only onces
- location = (current_need["docname"], current_need["lineno"]) if current_need else None
+ location = (
+ (current_need["docname"], current_need["lineno"])
+ if current_need
+ else None
+ )
log.warning(str(e) + " [needs]", type="needs", location=location)
error_reported = True
diff --git a/sphinx_needs/functions/common.py b/sphinx_needs/functions/common.py
index f5d96bf06..467743294 100644
--- a/sphinx_needs/functions/common.py
+++ b/sphinx_needs/functions/common.py
@@ -19,7 +19,13 @@
from sphinx_needs.utils import logger
-def test(app: Sphinx, need: NeedsInfoType, needs: dict[str, NeedsInfoType], *args: Any, **kwargs: Any) -> str:
+def test(
+ app: Sphinx,
+ need: NeedsInfoType,
+ needs: dict[str, NeedsInfoType],
+ *args: Any,
+ **kwargs: Any,
+) -> str:
"""
Test function for dynamic functions in sphinx needs.
@@ -41,7 +47,12 @@ def test(app: Sphinx, need: NeedsInfoType, needs: dict[str, NeedsInfoType], *arg
def echo(
- app: Sphinx, need: NeedsInfoType, needs: dict[str, NeedsInfoType], text: str, *args: Any, **kwargs: Any
+ app: Sphinx,
+ need: NeedsInfoType,
+ needs: dict[str, NeedsInfoType],
+ text: str,
+ *args: Any,
+ **kwargs: Any,
) -> str:
"""
.. versionadded:: 0.6.3
@@ -154,7 +165,9 @@ def copy(
need = needs[need_id]
if filter:
- result = filter_needs(needs.values(), NeedsSphinxConfig(app.config), filter, need)
+ result = filter_needs(
+ needs.values(), NeedsSphinxConfig(app.config), filter, need
+ )
if result:
need = result[0]
@@ -323,7 +336,10 @@ def check_linked_values(
if not filter_single_need(need, needs_config, filter_string):
continue
except Exception as e:
- logger.warning(f"CheckLinkedValues: Filter {filter_string} not valid: Error: {e} [needs]", type="needs")
+ logger.warning(
+ f"CheckLinkedValues: Filter {filter_string} not valid: Error: {e} [needs]",
+ type="needs",
+ )
need_value = need[search_option] # type: ignore[literal-required]
if not one_hit and need_value not in search_value:
@@ -422,7 +438,9 @@ def calc_sum(
:return: A float number
"""
needs_config = NeedsSphinxConfig(app.config)
- check_needs = [needs[link] for link in need["links"]] if links_only else needs.values()
+ check_needs = (
+ [needs[link] for link in need["links"]] if links_only else needs.values()
+ )
calculated_sum = 0.0
@@ -434,7 +452,9 @@ def calc_sum(
except ValueError:
pass
except NeedsInvalidFilter as ex:
- logger.warning(f"Given filter is not valid. Error: {ex} [needs]", type="needs")
+ logger.warning(
+ f"Given filter is not valid. Error: {ex} [needs]", type="needs"
+ )
with contextlib.suppress(ValueError):
calculated_sum += float(check_need[option]) # type: ignore[literal-required]
@@ -514,7 +534,9 @@ def links_from_content(
needs_config = NeedsSphinxConfig(app.config)
filtered_links = []
for link in raw_links:
- if link not in filtered_links and filter_single_need(needs[link], needs_config, filter):
+ if link not in filtered_links and filter_single_need(
+ needs[link], needs_config, filter
+ ):
filtered_links.append(link)
return filtered_links
diff --git a/sphinx_needs/functions/functions.py b/sphinx_needs/functions/functions.py
index 694435d17..32ead7438 100644
--- a/sphinx_needs/functions/functions.py
+++ b/sphinx_needs/functions/functions.py
@@ -29,7 +29,8 @@
# TODO these functions also take optional *args and **kwargs
DynamicFunction = Callable[
- [Sphinx, NeedsInfoType, Dict[str, NeedsInfoType]], Union[str, int, float, List[Union[str, int, float]]]
+ [Sphinx, NeedsInfoType, Dict[str, NeedsInfoType]],
+ Union[str, int, float, List[Union[str, int, float]]],
]
@@ -55,7 +56,9 @@ def register_func(need_function: DynamicFunction, name: str | None = None) -> No
# We can not throw an exception here, as using sphinx-needs in different sphinx-projects with the
# same python interpreter session does not clean NEEDS_FUNCTIONS.
# This is mostly the case during tet runs.
- logger.info(f"sphinx-needs: Function name {func_name} already registered. Ignoring the new one!")
+ logger.info(
+ f"sphinx-needs: Function name {func_name} already registered. Ignoring the new one!"
+ )
NEEDS_FUNCTIONS[func_name] = {"name": func_name, "function": need_function}
@@ -72,10 +75,22 @@ def execute_func(app: Sphinx, need: NeedsInfoType, func_string: str) -> Any:
func_name, func_args, func_kwargs = _analyze_func_string(func_string, need)
if func_name not in NEEDS_FUNCTIONS:
- raise SphinxError("Unknown dynamic sphinx-needs function: {}. Found in need: {}".format(func_name, need["id"]))
+ raise SphinxError(
+ "Unknown dynamic sphinx-needs function: {}. Found in need: {}".format(
+ func_name, need["id"]
+ )
+ )
- func = measure_time_func(NEEDS_FUNCTIONS[func_name]["function"], category="dyn_func", source="user")
- func_return = func(app, need, SphinxNeedsData(app.env).get_or_create_needs(), *func_args, **func_kwargs)
+ func = measure_time_func(
+ NEEDS_FUNCTIONS[func_name]["function"], category="dyn_func", source="user"
+ )
+ func_return = func(
+ app,
+ need,
+ SphinxNeedsData(app.env).get_or_create_needs(),
+ *func_args,
+ **func_kwargs,
+ )
if not isinstance(func_return, (str, int, float, list, unicode)) and func_return:
raise SphinxError(
@@ -97,7 +112,9 @@ def execute_func(app: Sphinx, need: NeedsInfoType, func_string: str) -> Any:
func_pattern = re.compile(r"\[\[(.*?)\]\]") # RegEx to detect function strings
-def find_and_replace_node_content(node: nodes.Node, env: BuildEnvironment, need: NeedsInfoType) -> nodes.Node:
+def find_and_replace_node_content(
+ node: nodes.Node, env: BuildEnvironment, need: NeedsInfoType
+) -> nodes.Node:
"""
Search inside a given node and its children for nodes of type Text,
if found, check if it contains a function string and run/replace it.
@@ -106,7 +123,11 @@ def find_and_replace_node_content(node: nodes.Node, env: BuildEnvironment, need:
:return: None
"""
new_children = []
- if not node.children and isinstance(node, nodes.Text) or isinstance(node, nodes.reference):
+ if (
+ not node.children
+ and isinstance(node, nodes.Text)
+ or isinstance(node, nodes.reference)
+ ):
if isinstance(node, nodes.reference):
try:
new_text = node.attributes["refuri"]
@@ -127,8 +148,8 @@ def find_and_replace_node_content(node: nodes.Node, env: BuildEnvironment, need:
func_string = func_string.replace("”", '"')
func_string = func_string.replace("”", '"')
- func_string = func_string.replace("‘", "'")
- func_string = func_string.replace("’", "'")
+ func_string = func_string.replace("‘", "'") # noqa: RUF001
+ func_string = func_string.replace("’", "'") # noqa: RUF001
func_return = execute_func(env.app, need, func_string)
# This should never happen, but we can not be sure.
@@ -176,20 +197,30 @@ def resolve_dynamic_values(needs: dict[str, NeedsInfoType], app: Sphinx) -> None
"""
for need in needs.values():
for need_option in need:
- if need_option in ["docname", "lineno", "content", "content_node", "content_id"]:
+ if need_option in [
+ "docname",
+ "lineno",
+ "content",
+ "content_node",
+ "content_id",
+ ]:
# dynamic values in this data are not allowed.
continue
if not isinstance(need[need_option], (list, set)):
func_call: str | None = "init"
while func_call:
try:
- func_call, func_return = _detect_and_execute(need[need_option], need, app)
+ func_call, func_return = _detect_and_execute(
+ need[need_option], need, app
+ )
except FunctionParsingException:
raise SphinxError(
"Function definition of {option} in file {file}:{line} has "
"unsupported parameters. "
"supported are str, int/float, list".format(
- option=need_option, file=need["docname"], line=need["lineno"]
+ option=need_option,
+ file=need["docname"],
+ line=need["lineno"],
)
)
@@ -197,9 +228,13 @@ def resolve_dynamic_values(needs: dict[str, NeedsInfoType], app: Sphinx) -> None
continue
# Replace original function string with return value of function call
if func_return is None:
- need[need_option] = need[need_option].replace(f"[[{func_call}]]", "")
+ need[need_option] = need[need_option].replace(
+ f"[[{func_call}]]", ""
+ )
else:
- need[need_option] = need[need_option].replace(f"[[{func_call}]]", str(func_return))
+ need[need_option] = need[need_option].replace(
+ f"[[{func_call}]]", str(func_return)
+ )
if need[need_option] == "":
need[need_option] = None
@@ -213,7 +248,9 @@ def resolve_dynamic_values(needs: dict[str, NeedsInfoType], app: Sphinx) -> None
"Function definition of {option} in file {file}:{line} has "
"unsupported parameters. "
"supported are str, int/float, list".format(
- option=need_option, file=need["docname"], line=need["lineno"]
+ option=need_option,
+ file=need["docname"],
+ line=need["lineno"],
)
)
if func_call is None:
@@ -221,7 +258,9 @@ def resolve_dynamic_values(needs: dict[str, NeedsInfoType], app: Sphinx) -> None
else:
# Replace original function string with return value of function call
if isinstance(need[need_option], (str, int, float)):
- new_values.append(element.replace(f"[[{func_call}]]", str(func_return)))
+ new_values.append(
+ element.replace(f"[[{func_call}]]", str(func_return))
+ )
else:
if isinstance(need[need_option], (list, set)):
if isinstance(func_return, (list, set)):
@@ -233,7 +272,9 @@ def resolve_dynamic_values(needs: dict[str, NeedsInfoType], app: Sphinx) -> None
def resolve_variants_options(
- needs: dict[str, NeedsInfoType], needs_config: NeedsSphinxConfig, tags: dict[str, bool]
+ needs: dict[str, NeedsInfoType],
+ needs_config: NeedsSphinxConfig,
+ tags: dict[str, bool],
) -> None:
"""
Resolve variants options inside need data.
@@ -255,20 +296,28 @@ def resolve_variants_options(
for need in needs.values():
# Data to use as filter context.
need_context: dict[str, Any] = {**need}
- need_context.update(**needs_config.filter_data) # Add needs_filter_data to filter context
+ need_context.update(
+ **needs_config.filter_data
+ ) # Add needs_filter_data to filter context
need_context.update(**tags) # Add sphinx tags to filter context
for var_option in variants_options:
if var_option in need and need[var_option] not in (None, "", []):
if not isinstance(need[var_option], (list, set, tuple)):
option_value: str = need[var_option]
- need[var_option] = match_variants(option_value, need_context, needs_config.variants)
+ need[var_option] = match_variants(
+ option_value, need_context, needs_config.variants
+ )
else:
option_value = need[var_option]
- need[var_option] = match_variants(option_value, need_context, needs_config.variants)
+ need[var_option] = match_variants(
+ option_value, need_context, needs_config.variants
+ )
-def check_and_get_content(content: str, need: NeedsInfoType, env: BuildEnvironment) -> str:
+def check_and_get_content(
+ content: str, need: NeedsInfoType, env: BuildEnvironment
+) -> str:
"""
Checks if the given content is a function call.
If not, content is returned.
@@ -290,14 +339,18 @@ def check_and_get_content(content: str, need: NeedsInfoType, env: BuildEnvironme
return content
func_call = func_match.group(1) # Extract function call
- func_return = execute_func(env.app, need, func_call) # Execute function call and get return value
+ func_return = execute_func(
+ env.app, need, func_call
+ ) # Execute function call and get return value
# Replace the function_call with the calculated value
content = content.replace(f"[[{func_call}]]", func_return)
return content
-def _detect_and_execute(content: Any, need: NeedsInfoType, app: Sphinx) -> tuple[str | None, Any]:
+def _detect_and_execute(
+ content: Any, need: NeedsInfoType, app: Sphinx
+) -> tuple[str | None, Any]:
"""Detects if given content is a function call and executes it."""
try:
content = str(content)
@@ -309,12 +362,16 @@ def _detect_and_execute(content: Any, need: NeedsInfoType, app: Sphinx) -> tuple
return None, None
func_call = func_match.group(1) # Extract function call
- func_return = execute_func(app, need, func_call) # Execute function call and get return value
+ func_return = execute_func(
+ app, need, func_call
+ ) # Execute function call and get return value
return func_call, func_return
-def _analyze_func_string(func_string: str, need: NeedsInfoType | None) -> tuple[str, list[Any], dict[str, Any]]:
+def _analyze_func_string(
+ func_string: str, need: NeedsInfoType | None
+) -> tuple[str, list[Any], dict[str, Any]]:
"""
Analyze given function string and extract:
@@ -331,12 +388,16 @@ def _analyze_func_string(func_string: str, need: NeedsInfoType | None) -> tuple[
func = ast.parse(func_string)
except SyntaxError as e:
need_id = need["id"] if need else "UNKNOWN"
- raise SphinxError(f"Parsing function string failed for need {need_id}: {func_string}. {e}")
+ raise SphinxError(
+ f"Parsing function string failed for need {need_id}: {func_string}. {e}"
+ )
try:
func_call = func.body[0].value # type: ignore
func_name = func_call.func.id
except AttributeError:
- raise SphinxError(f"Given dynamic function string is not a valid python call. Got: {func_string}")
+ raise SphinxError(
+ f"Given dynamic function string is not a valid python call. Got: {func_string}"
+ )
func_args: list[Any] = []
for arg in func_call.args:
@@ -366,8 +427,8 @@ def _analyze_func_string(func_string: str, need: NeedsInfoType | None) -> tuple[
)
else:
raise FunctionParsingException(
- "Unsupported type found in function definition: {}. "
- "Supported are numbers, strings, bool and list".format(func_string)
+ f"Unsupported type found in function definition: {func_string}. "
+ "Supported are numbers, strings, bool and list"
)
func_kargs: dict[str, Any] = {}
for keyword in func_call.keywords:
diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py
index d9c573945..e7cc60e35 100644
--- a/sphinx_needs/layout.py
+++ b/sphinx_needs/layout.py
@@ -33,7 +33,11 @@
@measure_time("need")
def create_need(
- need_id: str, app: Sphinx, layout: str | None = None, style: str | None = None, docname: str | None = None
+ need_id: str,
+ app: Sphinx,
+ layout: str | None = None,
+ style: str | None = None,
+ docname: str | None = None,
) -> nodes.container:
"""
Creates a new need-node for a given layout.
@@ -78,7 +82,9 @@ def create_need(
# Overwrite the docname, which must be the original one from the reused need, as all used paths are relative
# to the original location, not to the current document.
- env.temp_data["docname"] = need_data["docname"] # Dirty, as in this phase normally no docname is set anymore in env
+ env.temp_data["docname"] = need_data[
+ "docname"
+ ] # Dirty, as in this phase normally no docname is set anymore in env
ImageCollector().process_doc(app, node_inner) # type: ignore[arg-type]
DownloadFileCollector().process_doc(app, node_inner) # type: ignore[arg-type]
@@ -102,7 +108,9 @@ def create_need(
# set the layout and style for the new need
node_container[0].attributes = node_container.parent.children[0].attributes # type: ignore
- node_container[0].children[0].attributes = node_container.parent.children[0].children[0].attributes # type: ignore
+ node_container[0].children[0].attributes = ( # type: ignore
+ node_container.parent.children[0].children[0].attributes # type: ignore
+ )
node_container.attributes["ids"] = []
@@ -129,7 +137,11 @@ def replace_pending_xref_refdoc(node: nodes.Element, new_refdoc: str) -> None:
@measure_time("need")
def build_need(
- layout: str, node: nodes.Element, app: Sphinx, style: str | None = None, fromdocname: str | None = None
+ layout: str,
+ node: nodes.Element,
+ app: Sphinx,
+ style: str | None = None,
+ fromdocname: str | None = None,
) -> None:
"""
Builds a need based on a given layout for a given need-node.
@@ -221,7 +233,11 @@ def __init__(
self.fromdocname = fromdocname
# For ReadTheDocs Theme we need to add 'rtd-exclude-wy-table'.
- classes = ["need", "needs_grid_" + self.layout["grid"], "needs_layout_" + self.layout_name]
+ classes = [
+ "need",
+ "needs_grid_" + self.layout["grid"],
+ "needs_layout_" + self.layout_name,
+ ]
classes.extend(self.needs_config.table_classes)
self.style = style or self.need["style"] or self.needs_config.default_style
@@ -241,59 +257,121 @@ def __init__(
self.grids = {
"simple": {
"func": self._grid_simple,
- "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": False},
+ "configs": {
+ "colwidths": [100],
+ "side_left": False,
+ "side_right": False,
+ "footer": False,
+ },
},
"simple_footer": {
"func": self._grid_simple,
- "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": True},
+ "configs": {
+ "colwidths": [100],
+ "side_left": False,
+ "side_right": False,
+ "footer": True,
+ },
},
"simple_side_left": {
"func": self._grid_simple,
- "configs": {"colwidths": [30, 70], "side_left": "full", "side_right": False, "footer": False},
+ "configs": {
+ "colwidths": [30, 70],
+ "side_left": "full",
+ "side_right": False,
+ "footer": False,
+ },
},
"simple_side_right": {
"func": self._grid_simple,
- "configs": {"colwidths": [70, 30], "side_left": False, "side_right": "full", "footer": False},
+ "configs": {
+ "colwidths": [70, 30],
+ "side_left": False,
+ "side_right": "full",
+ "footer": False,
+ },
},
"simple_side_left_partial": {
"func": self._grid_simple,
- "configs": {"colwidths": [20, 80], "side_left": "part", "side_right": False, "footer": False},
+ "configs": {
+ "colwidths": [20, 80],
+ "side_left": "part",
+ "side_right": False,
+ "footer": False,
+ },
},
"simple_side_right_partial": {
"func": self._grid_simple,
- "configs": {"colwidths": [80, 20], "side_left": False, "side_right": "part", "footer": False},
+ "configs": {
+ "colwidths": [80, 20],
+ "side_left": False,
+ "side_right": "part",
+ "footer": False,
+ },
},
"complex": self._grid_complex,
"content": {
"func": self._grid_content,
- "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": False},
+ "configs": {
+ "colwidths": [100],
+ "side_left": False,
+ "side_right": False,
+ "footer": False,
+ },
},
"content_footer": {
"func": self._grid_content,
- "configs": {"colwidths": [100], "side_left": False, "side_right": False, "footer": True},
+ "configs": {
+ "colwidths": [100],
+ "side_left": False,
+ "side_right": False,
+ "footer": True,
+ },
},
"content_side_left": {
"func": self._grid_content,
- "configs": {"colwidths": [5, 95], "side_left": True, "side_right": False, "footer": False},
+ "configs": {
+ "colwidths": [5, 95],
+ "side_left": True,
+ "side_right": False,
+ "footer": False,
+ },
},
"content_side_right": {
"func": self._grid_content,
- "configs": {"colwidths": [95, 5], "side_left": False, "side_right": True, "footer": False},
+ "configs": {
+ "colwidths": [95, 5],
+ "side_left": False,
+ "side_right": True,
+ "footer": False,
+ },
},
"content_footer_side_left": {
"func": self._grid_content,
- "configs": {"colwidths": [5, 95], "side_left": True, "side_right": False, "footer": True},
+ "configs": {
+ "colwidths": [5, 95],
+ "side_left": True,
+ "side_right": False,
+ "footer": True,
+ },
},
"content_footer_side_right": {
"func": self._grid_content,
- "configs": {"colwidths": [95, 5], "side_left": False, "side_right": True, "footer": True},
+ "configs": {
+ "colwidths": [95, 5],
+ "side_left": False,
+ "side_right": True,
+ "footer": True,
+ },
},
}
# Dummy Document setup
self.doc_settings, self.inline_parser = _generate_inline_parser()
self.dummy_doc = new_document("dummy", self.doc_settings)
- self.doc_language = languages.get_language(self.dummy_doc.settings.language_code)
+ self.doc_language = languages.get_language(
+ self.dummy_doc.settings.language_code
+ )
self.doc_memo = Struct(
document=self.dummy_doc,
reporter=self.dummy_doc.reporter,
@@ -304,7 +382,9 @@ def __init__(
inliner=None,
)
- self.functions: dict[str, Callable[..., None | nodes.Node | list[nodes.Node]]] = {
+ self.functions: dict[
+ str, Callable[..., None | nodes.Node | list[nodes.Node]]
+ ] = {
"meta": self.meta, # type: ignore[dict-item]
"meta_all": self.meta_all,
"meta_links": self.meta_links,
@@ -334,7 +414,9 @@ def __init__(
def get_need_table(self) -> nodes.table:
if self.layout["grid"] not in self.grids.keys():
raise SphinxNeedLayoutException(
- "Unknown layout-grid: {}. Supported are {}".format(self.layout["grid"], ", ".join(self.grids.keys()))
+ "Unknown layout-grid: {}. Supported are {}".format(
+ self.layout["grid"], ", ".join(self.grids.keys())
+ )
)
func = self.grids[self.layout["grid"]]
@@ -376,7 +458,9 @@ def _parse(self, line: str) -> list[nodes.Node]:
:param line: string to parse
:return: nodes
"""
- result, message = self.inline_parser.parse(line, 0, self.doc_memo, self.dummy_doc) # type: ignore
+ result, message = self.inline_parser.parse( # type: ignore
+ line, 0, self.doc_memo, self.dummy_doc
+ )
if message:
raise SphinxNeedLayoutException(message)
return result # type: ignore[no-any-return]
@@ -420,7 +504,9 @@ def _func_replace(self, section_nodes: list[nodes.Node]) -> list[nodes.Node]:
)
func_def_clean = func_def.replace("<<", "").replace(">>", "")
- func_name, func_args, func_kargs = _analyze_func_string(func_def_clean, None)
+ func_name, func_args, func_kargs = _analyze_func_string(
+ func_def_clean, None
+ )
# Replace place holders
# Looks for {{name}}, where name must be an option of need, and replaces it with the
@@ -552,7 +638,9 @@ def meta(
ref_item = nodes.Text(datum)
data_node += ref_item
- if (name in needs_string_links_option and index + 1 < len(data)) or index + 1 < len([data]):
+ if (
+ name in needs_string_links_option and index + 1 < len(data)
+ ) or index + 1 < len([data]):
data_node += nodes.emphasis("; ", "; ")
data_container.append(data_node)
@@ -703,7 +791,9 @@ def meta_links(self, name: str, incoming: bool = False) -> nodes.inline:
data_container.append(node_links)
return data_container
- def meta_links_all(self, prefix: str = "", postfix: str = "", exclude: list[str] | None = None) -> list[nodes.line]:
+ def meta_links_all(
+ self, prefix: str = "", postfix: str = "", exclude: list[str] | None = None
+ ) -> list[nodes.line]:
"""
Documents all used link types for the current need automatically.
@@ -718,7 +808,9 @@ def meta_links_all(self, prefix: str = "", postfix: str = "", exclude: list[str]
type_key = link_type["option"]
if self.need[type_key] and type_key not in exclude: # type: ignore[literal-required]
outgoing_line = nodes.line()
- outgoing_label = prefix + "{}:".format(link_type["outgoing"]) + postfix + " "
+ outgoing_label = (
+ prefix + "{}:".format(link_type["outgoing"]) + postfix + " "
+ )
outgoing_line += self._parse(outgoing_label)
outgoing_line += self.meta_links(link_type["option"], incoming=False)
data_container.append(outgoing_line)
@@ -726,7 +818,9 @@ def meta_links_all(self, prefix: str = "", postfix: str = "", exclude: list[str]
type_key = link_type["option"] + "_back"
if self.need[type_key] and type_key not in exclude: # type: ignore[literal-required]
incoming_line = nodes.line()
- incoming_label = prefix + "{}:".format(link_type["incoming"]) + postfix + " "
+ incoming_label = (
+ prefix + "{}:".format(link_type["incoming"]) + postfix + " "
+ )
incoming_line += self._parse(incoming_label)
incoming_line += self.meta_links(link_type["option"], incoming=True)
data_container.append(incoming_line)
@@ -791,7 +885,9 @@ def image(
options["align"] = align
if url is None or not isinstance(url, str):
- raise SphinxNeedLayoutException("not valid url given for image function in layout")
+ raise SphinxNeedLayoutException(
+ "not valid url given for image function in layout"
+ )
if url.startswith("icon:"):
if any(x in builder.name.upper() for x in ["PDF", "LATEX"]):
@@ -926,7 +1022,11 @@ def link(
return data_container
def collapse_button(
- self, target: str = "meta", collapsed: str = "Show", visible: str = "Close", initial: bool = False
+ self,
+ target: str = "meta",
+ collapsed: str = "Show",
+ visible: str = "Close",
+ initial: bool = False,
) -> nodes.inline | None:
"""
To show icons instead of text on the button, use collapse_button() like this::
@@ -952,16 +1052,28 @@ def collapse_button(
if collapsed.startswith("image:") or collapsed.startswith("icon:"):
coll_node_collapsed.append(
- self.image(collapsed.replace("image:", ""), width="17px", no_link=True, img_class="sn_collapse_img")
+ self.image(
+ collapsed.replace("image:", ""),
+ width="17px",
+ no_link=True,
+ img_class="sn_collapse_img",
+ )
)
elif collapsed.startswith("Debug view"):
- coll_node_collapsed.append(nodes.container(classes=["debug_on_layout_btn"])) # For debug layout
+ coll_node_collapsed.append(
+ nodes.container(classes=["debug_on_layout_btn"])
+ ) # For debug layout
else:
coll_node_collapsed.append(nodes.Text(collapsed))
if visible.startswith("image:") or visible.startswith("icon:"):
coll_node_visible.append(
- self.image(visible.replace("image:", ""), width="17px", no_link=True, img_class="sn_collapse_img")
+ self.image(
+ visible.replace("image:", ""),
+ width="17px",
+ no_link=True,
+ img_class="sn_collapse_img",
+ )
)
elif visible.startswith("Debug view"):
coll_node_visible.append(nodes.container(classes=["debug_off_layout_btn"]))
@@ -972,7 +1084,9 @@ def collapse_button(
# docutils doesn't allow has to add any html-attributes beside class and id to nodes.
# So we misused "id" for this and use "__" (2x _) as separator for row-target names
- if (not self.need["collapse"]) or (self.need["collapse"] is None and not initial):
+ if (not self.need["collapse"]) or (
+ self.need["collapse"] is None and not initial
+ ):
status = "show"
if (self.need["collapse"]) or (not self.need["collapse"] and initial):
@@ -1034,7 +1148,13 @@ def permalink(
prefix=prefix,
)
- def _grid_simple(self, colwidths: list[int], side_left: bool | str, side_right: bool | str, footer: bool) -> None:
+ def _grid_simple(
+ self,
+ colwidths: list[int],
+ side_left: bool | str,
+ side_right: bool | str,
+ footer: bool,
+ ) -> None:
"""
Creates most "simple" grid layouts.
Side parts and footer can be activated via config.
@@ -1104,7 +1224,9 @@ def _grid_simple(self, colwidths: list[int], side_left: bool | str, side_right:
head_row = nodes.row(classes=["need", "head"])
if side_left:
- side_entry = nodes.entry(classes=["need", "side"], morerows=side_left_morerows)
+ side_entry = nodes.entry(
+ classes=["need", "side"], morerows=side_left_morerows
+ )
side_entry += self.get_section("side")
head_row += side_entry
@@ -1113,7 +1235,9 @@ def _grid_simple(self, colwidths: list[int], side_left: bool | str, side_right:
head_row += head_entry
if side_right:
- side_entry = nodes.entry(classes=["need", "side"], morerows=side_right_morerows)
+ side_entry = nodes.entry(
+ classes=["need", "side"], morerows=side_right_morerows
+ )
side_entry += self.get_section("side")
head_row += side_entry
@@ -1125,14 +1249,18 @@ def _grid_simple(self, colwidths: list[int], side_left: bool | str, side_right:
# CONTENT row
content_row = nodes.row(classes=["need", "content"])
- content_entry = nodes.entry(classes=["need", "content"], morecols=common_more_cols)
+ content_entry = nodes.entry(
+ classes=["need", "content"], morecols=common_more_cols
+ )
content_entry.insert(0, self.node.children)
content_row += content_entry
# FOOTER row
if footer:
footer_row = nodes.row(classes=["need", "footer"])
- footer_entry = nodes.entry(classes=["need", "footer"], morecols=common_more_cols)
+ footer_entry = nodes.entry(
+ classes=["need", "footer"], morecols=common_more_cols
+ )
footer_entry += self.get_section("footer")
footer_row += footer_entry
@@ -1207,7 +1335,9 @@ def _grid_complex(self) -> None:
# Construct table
node_tgroup += self.node_tbody
- def _grid_content(self, colwidths: list[int], side_left: bool, side_right: bool, footer: bool) -> None:
+ def _grid_content(
+ self, colwidths: list[int], side_left: bool, side_right: bool, footer: bool
+ ) -> None:
"""
Creates most "content" based grid layouts.
Side parts and footer can be activated via config.
diff --git a/sphinx_needs/need_constraints.py b/sphinx_needs/need_constraints.py
index e068a6bdf..b1925ab8a 100644
--- a/sphinx_needs/need_constraints.py
+++ b/sphinx_needs/need_constraints.py
@@ -11,7 +11,9 @@
logger = get_logger(__name__)
-def process_constraints(needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig) -> None:
+def process_constraints(
+ needs: dict[str, NeedsInfoType], config: NeedsSphinxConfig
+) -> None:
"""Analyse constraints of all needs,
and set corresponding fields on the need data item:
``constraints_passed`` and ``constraints_results``.
@@ -56,7 +58,9 @@ def process_constraints(needs: dict[str, NeedsInfoType], config: NeedsSphinxConf
if "error_message" in executable_constraints:
msg = str(executable_constraints["error_message"])
- template = error_templates_cache.setdefault(msg, jinja2.Template(msg))
+ template = error_templates_cache.setdefault(
+ msg, jinja2.Template(msg)
+ )
need["constraints_error"] = template.render(**need)
if "severity" not in executable_constraints:
@@ -88,10 +92,14 @@ def process_constraints(needs: dict[str, NeedsInfoType], config: NeedsSphinxConf
# set styles
old_style = need["style"]
if old_style and len(old_style) > 0:
- new_styles = "".join(", " + x for x in failed_options.get("style", []))
+ new_styles = "".join(
+ ", " + x for x in failed_options.get("style", [])
+ )
else:
old_style = ""
- new_styles = "".join(x + "," for x in failed_options.get("style", []))
+ new_styles = "".join(
+ x + "," for x in failed_options.get("style", [])
+ )
if failed_options.get("force_style", False):
need["style"] = new_styles.strip(", ")
diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py
index e252dfc7f..4d99df291 100644
--- a/sphinx_needs/needs.py
+++ b/sphinx_needs/needs.py
@@ -109,7 +109,10 @@
__version__ = VERSION = "2.0.0"
NEEDS_FUNCTIONS.clear()
-_NODE_TYPES_T = Dict[Type[nodes.Element], Callable[[Sphinx, nodes.document, str, List[nodes.Element]], None]]
+_NODE_TYPES_T = Dict[
+ Type[nodes.Element],
+ Callable[[Sphinx, nodes.document, str, List[nodes.Element]], None],
+]
NODE_TYPES_PRIO: _NODE_TYPES_T = { # Node types to be checked before most others
Needextract: process_needextract,
@@ -150,7 +153,9 @@ def setup(app: Sphinx) -> dict[str, Any]:
NeedsSphinxConfig.add_config_values(app)
# Define nodes
- app.add_node(Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart))
+ app.add_node(
+ Need, html=(html_visit, html_depart), latex=(latex_visit, latex_depart)
+ )
app.add_node(
Needfilter,
)
@@ -167,7 +172,11 @@ def setup(app: Sphinx) -> dict[str, Any]:
app.add_node(Needextend)
app.add_node(Needuml)
app.add_node(List2Need)
- app.add_node(NeedPart, html=(visitor_dummy, visitor_dummy), latex=(visitor_dummy, visitor_dummy))
+ app.add_node(
+ NeedPart,
+ html=(visitor_dummy, visitor_dummy),
+ latex=(visitor_dummy, visitor_dummy),
+ )
########################################################################
# DIRECTIVES
@@ -195,23 +204,54 @@ def setup(app: Sphinx) -> dict[str, Any]:
# ROLES
########################################################################
# Provides :need:`ABC_123` for inline links.
- app.add_role("need", NeedsXRefRole(nodeclass=NeedRef, innernodeclass=nodes.emphasis, warn_dangling=True))
+ app.add_role(
+ "need",
+ NeedsXRefRole(
+ nodeclass=NeedRef, innernodeclass=nodes.emphasis, warn_dangling=True
+ ),
+ )
app.add_role(
- "need_incoming", NeedsXRefRole(nodeclass=NeedIncoming, innernodeclass=nodes.emphasis, warn_dangling=True)
+ "need_incoming",
+ NeedsXRefRole(
+ nodeclass=NeedIncoming, innernodeclass=nodes.emphasis, warn_dangling=True
+ ),
)
app.add_role(
- "need_outgoing", NeedsXRefRole(nodeclass=NeedOutgoing, innernodeclass=nodes.emphasis, warn_dangling=True)
+ "need_outgoing",
+ NeedsXRefRole(
+ nodeclass=NeedOutgoing, innernodeclass=nodes.emphasis, warn_dangling=True
+ ),
)
- app.add_role("need_part", NeedsXRefRole(nodeclass=NeedPart, innernodeclass=nodes.inline, warn_dangling=True))
+ app.add_role(
+ "need_part",
+ NeedsXRefRole(
+ nodeclass=NeedPart, innernodeclass=nodes.inline, warn_dangling=True
+ ),
+ )
# Shortcut for need_part
- app.add_role("np", NeedsXRefRole(nodeclass=NeedPart, innernodeclass=nodes.inline, warn_dangling=True))
+ app.add_role(
+ "np",
+ NeedsXRefRole(
+ nodeclass=NeedPart, innernodeclass=nodes.inline, warn_dangling=True
+ ),
+ )
- app.add_role("need_count", NeedsXRefRole(nodeclass=NeedCount, innernodeclass=nodes.inline, warn_dangling=True))
+ app.add_role(
+ "need_count",
+ NeedsXRefRole(
+ nodeclass=NeedCount, innernodeclass=nodes.inline, warn_dangling=True
+ ),
+ )
- app.add_role("need_func", NeedsXRefRole(nodeclass=NeedFunc, innernodeclass=nodes.inline, warn_dangling=True))
+ app.add_role(
+ "need_func",
+ NeedsXRefRole(
+ nodeclass=NeedFunc, innernodeclass=nodes.inline, warn_dangling=True
+ ),
+ )
########################################################################
# EVENTS
@@ -241,7 +281,11 @@ def setup(app: Sphinx) -> dict[str, Any]:
# doctree-read. So manipulating the doctree may result in conflicts, as e.g. images get not
# registered for sphinx. So some sphinx-internal tasks/functions may be called by hand again...
# See also https://github.com/sphinx-doc/sphinx/issues/7054#issuecomment-578019701 for an example
- app.connect("doctree-resolved", process_creator(NODE_TYPES_PRIO, "needextract"), priority=100)
+ app.connect(
+ "doctree-resolved",
+ process_creator(NODE_TYPES_PRIO, "needextract"),
+ priority=100,
+ )
app.connect("doctree-resolved", process_need_nodes)
app.connect("doctree-resolved", process_creator(NODE_TYPES))
@@ -280,7 +324,8 @@ def process_caller(app: Sphinx, doctree: nodes.document, fromdocname: str) -> No
"""
# We only need to analyse docs, which have Sphinx-Needs directives in it.
if (
- fromdocname not in SphinxNeedsData(app.env).get_or_create_docs().get(doc_category, [])
+ fromdocname
+ not in SphinxNeedsData(app.env).get_or_create_docs().get(doc_category, [])
and fromdocname != f"{app.config.root_doc}"
):
return
@@ -297,7 +342,11 @@ def process_caller(app: Sphinx, doctree: nodes.document, fromdocname: str) -> No
# Let's call the handlers
for check_node, check_func in node_list.items():
# Call the handler only, if it defined, and we found some nodes for it
- if check_node in current_nodes and check_func is not None and current_nodes[check_node]:
+ if (
+ check_node in current_nodes
+ and check_func is not None
+ and current_nodes[check_node]
+ ):
check_func(app, doctree, fromdocname, current_nodes[check_node])
return process_caller
@@ -319,7 +368,9 @@ def load_config(app: Sphinx, *_args: Any) -> None:
for option in needs_config.extra_options:
if option in extra_options:
LOGGER.warning(
- f'extra_option "{option}" already registered. [needs.config]', type="needs", subtype="config"
+ f'extra_option "{option}" already registered. [needs.config]',
+ type="needs",
+ subtype="config",
)
NEEDS_CONFIG.extra_options[option] = directives.unchanged
@@ -397,7 +448,9 @@ def load_config(app: Sphinx, *_args: Any) -> None:
NEEDS_CONFIG.warnings[name] = check
else:
LOGGER.warning(
- f"{name!r} in 'needs_warnings' is already registered. [needs.config]", type="needs", subtype="config"
+ f"{name!r} in 'needs_warnings' is already registered. [needs.config]",
+ type="needs",
+ subtype="config",
)
if needs_config.constraints_failed_color:
@@ -441,7 +494,11 @@ def prepare_env(app: Sphinx, env: BuildEnvironment, _docname: str) -> None:
# Register user defined services
for name, service in needs_config.services.items():
- if name not in services.services and "class" in service and "class_init" in service:
+ if (
+ name not in services.services
+ and "class" in service
+ and "class_init" in service
+ ):
# We found a not yet registered service
# But only register, if service-config contains class and class_init.
# Otherwise, the service may get registered later by an external sphinx-needs extension
@@ -456,7 +513,14 @@ def prepare_env(app: Sphinx, env: BuildEnvironment, _docname: str) -> None:
register_func(needs_func)
# Own extra options
- for option in ["hidden", "duration", "completion", "has_dead_links", "has_forbidden_dead_links", "constraints"]:
+ for option in [
+ "hidden",
+ "duration",
+ "completion",
+ "has_dead_links",
+ "has_forbidden_dead_links",
+ "constraints",
+ ]:
# Check if not already set by user
if option not in NEEDS_CONFIG.extra_options:
NEEDS_CONFIG.extra_options[option] = directives.unchanged
@@ -525,25 +589,29 @@ def check_configuration(_app: Sphinx, config: Config) -> None:
# Check if needs external filter and extra option are using the same name
if extern_filter in extra_options:
raise NeedsConfigException(
- "Same name for external filter and extra option: {}." " This is not allowed.".format(extern_filter)
+ f"Same name for external filter and extra option: {extern_filter}."
+ " This is not allowed."
)
# Check for usage of internal names
for internal in INTERNALS:
if internal in extra_options:
raise NeedsConfigException(
- 'Extra option "{}" already used internally. ' " Please use another name.".format(internal)
+ f'Extra option "{internal}" already used internally. '
+ " Please use another name."
)
if internal in link_types:
raise NeedsConfigException(
- 'Link type name "{}" already used internally. ' " Please use another name.".format(internal)
+ f'Link type name "{internal}" already used internally. '
+ " Please use another name."
)
# Check if option and link are using the same name
for link in link_types:
if link in extra_options:
raise NeedsConfigException(
- "Same name for link type and extra option: {}." " This is not allowed.".format(link)
+ f"Same name for link type and extra option: {link}."
+ " This is not allowed."
)
if link + "_back" in extra_options:
raise NeedsConfigException(
@@ -562,7 +630,11 @@ def check_configuration(_app: Sphinx, config: Config) -> None:
for option in external_variant_options:
# Check variant option is added in either extra options or extra links or NEED_DEFAULT_OPTIONS
- if option not in extra_options and option not in link_types and option not in NEED_DEFAULT_OPTIONS.keys():
+ if (
+ option not in extra_options
+ and option not in link_types
+ and option not in NEED_DEFAULT_OPTIONS.keys()
+ ):
raise NeedsConfigException(
"Variant option `{}` is not added in either extra options or extra links. "
"This is not allowed.".format(option)
diff --git a/sphinx_needs/needsfile.py b/sphinx_needs/needsfile.py
index ece2bbd66..cf1184fc8 100644
--- a/sphinx_needs/needsfile.py
+++ b/sphinx_needs/needsfile.py
@@ -94,16 +94,30 @@ def update_or_add_version(self, version: str) -> None:
def add_need(self, version: str, need_info: NeedsInfoType) -> None:
self.update_or_add_version(version)
- writable_needs = {key: need_info[key] for key in need_info if key not in self._exclude_need_keys} # type: ignore[literal-required]
+ writable_needs = {
+ key: need_info[key] # type: ignore[literal-required]
+ for key in need_info
+ if key not in self._exclude_need_keys
+ }
writable_needs["description"] = need_info["content"]
self.needs_list["versions"][version]["needs"][need_info["id"]] = writable_needs
- self.needs_list["versions"][version]["needs_amount"] = len(self.needs_list["versions"][version]["needs"])
+ self.needs_list["versions"][version]["needs_amount"] = len(
+ self.needs_list["versions"][version]["needs"]
+ )
def add_filter(self, version: str, need_filter: NeedsFilterType) -> None:
self.update_or_add_version(version)
- writable_filters = {key: need_filter[key] for key in need_filter if key not in self._exclude_filter_keys} # type: ignore[literal-required]
- self.needs_list["versions"][version]["filters"][need_filter["export_id"].upper()] = writable_filters
- self.needs_list["versions"][version]["filters_amount"] = len(self.needs_list["versions"][version]["filters"])
+ writable_filters = {
+ key: need_filter[key] # type: ignore[literal-required]
+ for key in need_filter
+ if key not in self._exclude_filter_keys
+ }
+ self.needs_list["versions"][version]["filters"][
+ need_filter["export_id"].upper()
+ ] = writable_filters
+ self.needs_list["versions"][version]["filters_amount"] = len(
+ self.needs_list["versions"][version]["filters"]
+ )
def wipe_version(self, version: str) -> None:
if version in self.needs_list["versions"]:
@@ -130,7 +144,9 @@ def load_json(self, file: str) -> None:
file = os.path.join(self.confdir, file)
if not os.path.exists(file):
- self.log.warning(f"Could not load needs json file {file} [needs]", type="needs")
+ self.log.warning(
+ f"Could not load needs json file {file} [needs]", type="needs"
+ )
else:
errors = check_needs_file(file)
# We only care for schema errors here, all other possible errors
@@ -144,7 +160,9 @@ def load_json(self, file: str) -> None:
try:
needs_list = json.load(needs_file)
except json.JSONDecodeError:
- self.log.warning(f"Could not decode json file {file} [needs]", type="needs")
+ self.log.warning(
+ f"Could not decode json file {file} [needs]", type="needs"
+ )
else:
self.needs_list = needs_list
diff --git a/sphinx_needs/roles/need_count.py b/sphinx_needs/roles/need_count.py
index 8ff1299a8..15275a090 100644
--- a/sphinx_needs/roles/need_count.py
+++ b/sphinx_needs/roles/need_count.py
@@ -23,7 +23,10 @@ class NeedCount(nodes.Inline, nodes.Element):
def process_need_count(
- app: Sphinx, doctree: nodes.document, _fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ _fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
needs_config = NeedsSphinxConfig(app.config)
for node_need_count in found_nodes:
diff --git a/sphinx_needs/roles/need_func.py b/sphinx_needs/roles/need_func.py
index 23daee4ac..3497f395b 100644
--- a/sphinx_needs/roles/need_func.py
+++ b/sphinx_needs/roles/need_func.py
@@ -18,11 +18,18 @@ class NeedFunc(nodes.Inline, nodes.Element):
def process_need_func(
- app: Sphinx, doctree: nodes.document, _fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ _fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
env = app.env
# for node_need_func in doctree.findall(NeedFunc):
for node_need_func in found_nodes:
- result = check_and_get_content(node_need_func.attributes["reftarget"], {"id": "need_func_dummy"}, env) # type: ignore
+ result = check_and_get_content(
+ node_need_func.attributes["reftarget"],
+ {"id": "need_func_dummy"}, # type: ignore
+ env,
+ )
new_node_func = nodes.Text(str(result))
node_need_func.replace_self(new_node_func)
diff --git a/sphinx_needs/roles/need_incoming.py b/sphinx_needs/roles/need_incoming.py
index fcdf5251b..2aa939035 100644
--- a/sphinx_needs/roles/need_incoming.py
+++ b/sphinx_needs/roles/need_incoming.py
@@ -15,7 +15,10 @@ class NeedIncoming(nodes.Inline, nodes.Element):
def process_need_incoming(
- app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
builder = app.builder
env = app.env
@@ -64,8 +67,12 @@ def process_need_incoming(
node_need_backref["reftarget"],
)
else:
- assert target_need["external_url"] is not None, "External URL must not be set"
- new_node_ref = nodes.reference(target_need["id"], target_need["id"])
+ assert (
+ target_need["external_url"] is not None
+ ), "External URL must not be set"
+ new_node_ref = nodes.reference(
+ target_need["id"], target_need["id"]
+ )
new_node_ref["refuri"] = check_and_calc_base_url_rel_path(
target_need["external_url"], fromdocname
)
@@ -82,7 +89,10 @@ def process_need_incoming(
pass
else:
- logger.warning(f"need {node_need_backref['reftarget']} not found [needs]", location=node_need_backref)
+ logger.warning(
+ f"need {node_need_backref['reftarget']} not found [needs]",
+ location=node_need_backref,
+ )
if len(node_link_container.children) == 0:
node_link_container += nodes.Text("None")
diff --git a/sphinx_needs/roles/need_outgoing.py b/sphinx_needs/roles/need_outgoing.py
index 1939b7e4e..c6391129d 100644
--- a/sphinx_needs/roles/need_outgoing.py
+++ b/sphinx_needs/roles/need_outgoing.py
@@ -18,7 +18,10 @@ class NeedOutgoing(nodes.Inline, nodes.Element):
def process_need_outgoing(
- app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
) -> None:
builder = app.builder
env = app.env
@@ -55,7 +58,11 @@ def process_need_outgoing(
target_need = needs_all_needs[need_id_main]
if need_id_part and need_id_part in target_need["parts"]:
part_content = target_need["parts"][need_id_part]["content"]
- target_title = part_content if len(part_content) < 30 else part_content[:27] + "..."
+ target_title = (
+ part_content
+ if len(part_content) < 30
+ else part_content[:27] + "..."
+ )
target_id = ".".join([need_id_main, need_id_part])
else:
target_title = target_need["title"]
@@ -84,8 +91,12 @@ def process_need_outgoing(
node_need_ref["reftarget"],
)
else:
- assert target_need["external_url"] is not None, "External URL must be set"
- new_node_ref = nodes.reference(target_need["id"], target_need["id"])
+ assert (
+ target_need["external_url"] is not None
+ ), "External URL must be set"
+ new_node_ref = nodes.reference(
+ target_need["id"], target_need["id"]
+ )
new_node_ref["refuri"] = check_and_calc_base_url_rel_path(
target_need["external_url"], fromdocname
)
diff --git a/sphinx_needs/roles/need_part.py b/sphinx_needs/roles/need_part.py
index 242d197d4..ae2b1eb89 100644
--- a/sphinx_needs/roles/need_part.py
+++ b/sphinx_needs/roles/need_part.py
@@ -27,14 +27,21 @@ class NeedPart(nodes.Inline, nodes.Element):
pass
-def process_need_part(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_need_part(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
pass
part_pattern = re.compile(r"\(([\w-]+)\)(.*)")
-def update_need_with_parts(env: BuildEnvironment, need: NeedsInfoType, part_nodes: list[NeedPart]) -> None:
+def update_need_with_parts(
+ env: BuildEnvironment, need: NeedsInfoType, part_nodes: list[NeedPart]
+) -> None:
app = env.app
builder = app.builder
for part_node in part_nodes:
@@ -45,7 +52,9 @@ def update_need_with_parts(env: BuildEnvironment, need: NeedsInfoType, part_node
part_content = result.group(2)
else:
part_content = content
- inline_id = hashlib.sha1(part_content.encode("UTF-8")).hexdigest().upper()[:3]
+ inline_id = (
+ hashlib.sha1(part_content.encode("UTF-8")).hexdigest().upper()[:3]
+ )
if "parts" not in need:
need["parts"] = {}
@@ -78,7 +87,9 @@ def update_need_with_parts(env: BuildEnvironment, need: NeedsInfoType, part_node
from sphinx.util.nodes import make_refnode
- part_ref_node = make_refnode(builder, need["docname"], need["docname"], part_id_ref, part_link_node)
+ part_ref_node = make_refnode(
+ builder, need["docname"], need["docname"], part_id_ref, part_link_node
+ )
part_ref_node["classes"] += ["needs-id"]
part_node.children = []
diff --git a/sphinx_needs/roles/need_ref.py b/sphinx_needs/roles/need_ref.py
index d817b9274..231d3c627 100644
--- a/sphinx_needs/roles/need_ref.py
+++ b/sphinx_needs/roles/need_ref.py
@@ -51,7 +51,12 @@ def transform_need_to_dict(need: NeedsInfoType) -> dict[str, str]:
return dict_need
-def process_need_ref(app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: list[nodes.Element]) -> None:
+def process_need_ref(
+ app: Sphinx,
+ doctree: nodes.document,
+ fromdocname: str,
+ found_nodes: list[nodes.Element],
+) -> None:
builder = app.builder
env = app.env
needs_config = NeedsSphinxConfig(env.config)
@@ -78,7 +83,9 @@ def process_need_ref(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
if need_id_main in all_needs:
target_need = all_needs[need_id_main]
- dict_need = transform_need_to_dict(target_need) # Transform a dict in a dict of {str, str}
+ dict_need = transform_need_to_dict(
+ target_need
+ ) # Transform a dict in a dict of {str, str}
# We set the id to the complete id maintained in node_need_ref["reftarget"]
dict_need["id"] = need_id_full
@@ -118,7 +125,8 @@ def process_need_ref(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
link_text = needs_config.role_need_template.format(**dict_need)
except KeyError as e:
link_text = (
- '"the config parameter needs_role_need_template uses not supported placeholders: %s "' % e
+ '"the config parameter needs_role_need_template uses not supported placeholders: %s "'
+ % e
)
log.warning(link_text + " [needs]", type="needs")
@@ -135,9 +143,13 @@ def process_need_ref(app: Sphinx, doctree: nodes.document, fromdocname: str, fou
node_need_ref["reftarget"],
)
else:
- assert target_need["external_url"] is not None, "external_url must be set for external needs"
+ assert (
+ target_need["external_url"] is not None
+ ), "external_url must be set for external needs"
new_node_ref = nodes.reference(target_need["id"], target_need["id"])
- new_node_ref["refuri"] = check_and_calc_base_url_rel_path(target_need["external_url"], fromdocname)
+ new_node_ref["refuri"] = check_and_calc_base_url_rel_path(
+ target_need["external_url"], fromdocname
+ )
new_node_ref["classes"].append(target_need["external_css"])
else:
diff --git a/sphinx_needs/services/config/github.py b/sphinx_needs/services/config/github.py
index ed2c2a6e2..65f40708c 100644
--- a/sphinx_needs/services/config/github.py
+++ b/sphinx_needs/services/config/github.py
@@ -3,9 +3,22 @@
EXTRA_DATA_OPTIONS = ["user", "created_at", "updated_at", "closed_at", "service"]
EXTRA_LINK_OPTIONS = ["url"]
EXTRA_IMAGE_OPTIONS = ["avatar"]
-CONFIG_OPTIONS = ["type", "query", "specific", "max_amount", "max_content_lines", "id_prefix"]
-GITHUB_DATA = ["status", "tags"] + EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS + EXTRA_IMAGE_OPTIONS
-GITHUB_DATA_STR = '"' + '","'.join(EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS + EXTRA_IMAGE_OPTIONS) + '"'
+CONFIG_OPTIONS = [
+ "type",
+ "query",
+ "specific",
+ "max_amount",
+ "max_content_lines",
+ "id_prefix",
+]
+GITHUB_DATA = (
+ ["status", "tags"] + EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS + EXTRA_IMAGE_OPTIONS
+)
+GITHUB_DATA_STR = (
+ '"'
+ + '","'.join(EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS + EXTRA_IMAGE_OPTIONS)
+ + '"'
+)
CONFIG_DATA_STR = '"' + '","'.join(CONFIG_OPTIONS) + '"'
GITHUB_LAYOUT = {
"grid": "complex",
@@ -18,14 +31,20 @@
"head": [
'**<>** ('
+ ", ".join(
- ['<>'.format(value=x) for x in EXTRA_LINK_OPTIONS]
+ [
+ f'<>'
+ for x in EXTRA_LINK_OPTIONS
+ ]
)
+ ")"
],
- "head_right": ['<>', '<>'],
- "meta_left": ['<>'.format(value=x) for x in EXTRA_DATA_OPTIONS]
+ "head_right": [
+ '<>',
+ '<>',
+ ],
+ "meta_left": [f'<>' for x in EXTRA_DATA_OPTIONS]
+ [
- '<>'.format(value=x)
+ f'<>'
for x in EXTRA_LINK_OPTIONS
],
"meta_right": [
diff --git a/sphinx_needs/services/github.py b/sphinx_needs/services/github.py
index b2fc6da72..4e5c54c84 100644
--- a/sphinx_needs/services/github.py
+++ b/sphinx_needs/services/github.py
@@ -25,9 +25,13 @@
class GithubService(BaseService):
- options = CONFIG_OPTIONS + EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS + EXTRA_IMAGE_OPTIONS
+ options = (
+ CONFIG_OPTIONS + EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS + EXTRA_IMAGE_OPTIONS
+ )
- def __init__(self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any) -> None:
+ def __init__(
+ self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any
+ ) -> None:
self.app = app
self.name = name
self.config = config
@@ -50,7 +54,11 @@ def __init__(self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any
layouts["github"] = GITHUB_LAYOUT
self.gh_type_config = {
- "issue": {"url": "search/issues", "query": "is:issue", "need_type": "issue"},
+ "issue": {
+ "url": "search/issues",
+ "query": "is:issue",
+ "need_type": "issue",
+ },
"pr": {"url": "search/issues", "query": "is:pr", "need_type": "pr"},
"commit": {"url": "search/commits", "query": "", "need_type": "commit"},
}
@@ -68,15 +76,21 @@ def __init__(self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any
if self.gh_type not in self.gh_type_config.keys():
raise KeyError(
- 'github type "{}" not supported. Use: {}'.format(self.gh_type, ", ".join(self.gh_type_config.keys()))
+ 'github type "{}" not supported. Use: {}'.format(
+ self.gh_type, ", ".join(self.gh_type_config.keys())
+ )
)
# Set need_type to use by default
- self.need_type = self.config.get("need_type", self.gh_type_config[self.gh_type]["need_type"])
+ self.need_type = self.config.get(
+ "need_type", self.gh_type_config[self.gh_type]["need_type"]
+ )
super().__init__()
- def _send(self, query: str, options: dict[str, Any], specific: bool = False) -> dict[str, Any]:
+ def _send(
+ self, query: str, options: dict[str, Any], specific: bool = False
+ ) -> dict[str, Any]:
headers = {}
if self.gh_type == "commit":
headers["Accept"] = "application/vnd.github.cloak-preview+json"
@@ -93,17 +107,20 @@ def _send(self, query: str, options: dict[str, Any], specific: bool = False) ->
single_type = "pulls"
else:
single_type = "commits"
- url = self.url + "repos/{owner}/{repo}/{single_type}/{number}".format(
- owner=owner, repo=repo, single_type=single_type, number=number
- )
+ url = self.url + f"repos/{owner}/{repo}/{single_type}/{number}"
except IndexError:
- raise NeedGithubServiceException('Single option ot valid, must follow "owner/repo/number"')
+ raise NeedGithubServiceException(
+ 'Single option ot valid, must follow "owner/repo/number"'
+ )
params = {}
else:
url = self.url + self.gh_type_config[self.gh_type]["url"]
query = "{} {}".format(query, self.gh_type_config[self.gh_type]["query"])
- params = {"q": query, "per_page": options.get("max_amount", self.max_amount)}
+ params = {
+ "q": query,
+ "per_page": options.get("max_amount", self.max_amount),
+ }
self.log.info(f"Service {self.name} requesting data for query: {query}")
@@ -122,26 +139,30 @@ def _send(self, query: str, options: dict[str, Any], specific: bool = False) ->
if "rate limit" in resp.json()["message"]:
resp_limit = requests.get(self.url + "rate_limit", auth=auth)
extra_info = resp_limit.json()
- self.log.info("GitHub: API rate limit exceeded. We need to wait 60 secs...")
+ self.log.info(
+ "GitHub: API rate limit exceeded. We need to wait 60 secs..."
+ )
self.log.info(extra_info)
time.sleep(61)
resp = requests.get(url, params=params, auth=auth, headers=headers)
if resp.status_code > 299:
if "rate limit" in resp.json()["message"]:
- raise NeedGithubServiceException("GitHub: API rate limit exceeded (twice). Stop here.")
+ raise NeedGithubServiceException(
+ "GitHub: API rate limit exceeded (twice). Stop here."
+ )
else:
raise NeedGithubServiceException(
"Github service error during request.\n"
- "Status code: {}\n"
- "Error: {}\n"
- "{}".format(resp.status_code, resp.text, extra_info)
+ f"Status code: {resp.status_code}\n"
+ f"Error: {resp.text}\n"
+ f"{extra_info}"
)
else:
raise NeedGithubServiceException(
"Github service error during request.\n"
- "Status code: {}\n"
- "Error: {}\n"
- "{}".format(resp.status_code, resp.text, extra_info)
+ f"Status code: {resp.status_code}\n"
+ f"Error: {resp.text}\n"
+ f"{extra_info}"
)
if specific:
@@ -154,9 +175,13 @@ def request(self, options: dict[str, Any] | None = None) -> list[dict[str, Any]]
self.log.debug(f"Requesting data for service {self.name}")
if "query" not in options and "specific" not in options:
- raise NeedGithubServiceException('"query" or "specific" missing as option for github service.')
+ raise NeedGithubServiceException(
+ '"query" or "specific" missing as option for github service.'
+ )
elif "query" in options and "specific" in options:
- raise NeedGithubServiceException('Only "query" or "specific" allowed for github service. Not both!')
+ raise NeedGithubServiceException(
+ 'Only "query" or "specific" allowed for github service. Not both!'
+ )
elif "query" in options:
query = options["query"]
specific = False
@@ -168,7 +193,9 @@ def request(self, options: dict[str, Any] | None = None) -> list[dict[str, Any]]
if "items" not in response:
if "errors" in response:
raise NeedGithubServiceException(
- "GitHub service query error: {}\n" "Used query: {}".format(response["errors"][0]["message"], query)
+ "GitHub service query error: {}\n" "Used query: {}".format(
+ response["errors"][0]["message"], query
+ )
)
else:
raise NeedGithubServiceException("Github service: Unknown error.")
@@ -182,7 +209,9 @@ def request(self, options: dict[str, Any] | None = None) -> list[dict[str, Any]]
return data
- def prepare_issue_data(self, items: list[dict[str, Any]], options: dict[str, Any]) -> list[dict[str, Any]]:
+ def prepare_issue_data(
+ self, items: list[dict[str, Any]], options: dict[str, Any]
+ ) -> list[dict[str, Any]]:
data = []
for item in items:
# ensure that "None" can not reach .splitlines()
@@ -191,7 +220,11 @@ def prepare_issue_data(self, items: list[dict[str, Any]], options: dict[str, Any
# wraps content lines, if they are too long. Respects already existing newlines.
content_lines = [
- "\n ".join(textwrap.wrap(line, 60, break_long_words=True, replace_whitespace=False))
+ "\n ".join(
+ textwrap.wrap(
+ line, 60, break_long_words=True, replace_whitespace=False
+ )
+ )
for line in item["body"].splitlines() # type: ignore
if line.strip()
]
@@ -199,7 +232,9 @@ def prepare_issue_data(self, items: list[dict[str, Any]], options: dict[str, Any
content = "\n\n ".join(content_lines)
# Reduce content length, if requested by config
if self.max_content_lines > 0:
- max_lines = int(options.get("max_content_lines", self.max_content_lines))
+ max_lines = int(
+ options.get("max_content_lines", self.max_content_lines)
+ )
content_lines = content.splitlines()
if len(content_lines) > max_lines:
content_lines = content_lines[0:max_lines]
@@ -242,7 +277,9 @@ def prepare_issue_data(self, items: list[dict[str, Any]], options: dict[str, Any
return data
- def prepare_commit_data(self, items: list[dict[str, Any]], options: dict[str, Any]) -> list[dict[str, Any]]:
+ def prepare_commit_data(
+ self, items: list[dict[str, Any]], options: dict[str, Any]
+ ) -> list[dict[str, Any]]:
data = []
for item in items:
@@ -253,7 +290,9 @@ def prepare_commit_data(self, items: list[dict[str, Any]], options: dict[str, An
"type": options.get("type", self.need_type),
"layout": options.get("layout", self.layout),
"id": self.id_prefix + item["sha"][:6],
- "title": item["commit"]["message"].split("\n")[0][:60], # 1. line, max length 60 chars
+ "title": item["commit"]["message"].split("\n")[0][
+ :60
+ ], # 1. line, max length 60 chars
"content": item["commit"]["message"],
"user": item["author"]["login"],
"url": item["html_url"],
@@ -278,7 +317,9 @@ def _get_avatar(self, avatar_url: str) -> str:
avatar_file_path = os.path.join(path, filename)
# Placeholder avatar, if things go wrong or avatar download is deactivated
- default_avatar_file_path = os.path.join(os.path.dirname(__file__), "../images/avatar.png")
+ default_avatar_file_path = os.path.join(
+ os.path.dirname(__file__), "../images/avatar.png"
+ )
if self.download_avatars:
# Download only, if file not downloaded yet
if not os.path.exists(avatar_file_path):
@@ -294,20 +335,20 @@ def _get_avatar(self, avatar_url: str) -> str:
f.write(response.content)
elif response.status_code == 302:
self.log.warning(
- "GitHub service {} could not download avatar image "
- "from {}.\n"
- " Status code: {}\n"
+ f"GitHub service {self.name} could not download avatar image "
+ f"from {avatar_url}.\n"
+ f" Status code: {response.status_code}\n"
" Reason: Looks like the authentication provider tries to redirect you."
" This is not supported and is a common problem, "
- "if you use GitHub Enterprise. [needs]".format(self.name, avatar_url, response.status_code),
+ "if you use GitHub Enterprise. [needs]",
type="needs",
)
avatar_file_path = default_avatar_file_path
else:
self.log.warning(
- "GitHub service {} could not download avatar image "
- "from {}.\n"
- " Status code: {} [needs]".format(self.name, avatar_url, response.status_code),
+ f"GitHub service {self.name} could not download avatar image "
+ f"from {avatar_url}.\n"
+ f" Status code: {response.status_code} [needs]",
type="needs",
)
avatar_file_path = default_avatar_file_path
@@ -316,7 +357,9 @@ def _get_avatar(self, avatar_url: str) -> str:
return avatar_file_path
- def _add_given_options(self, options: dict[str, Any], element_data: dict[str, Any]) -> None:
+ def _add_given_options(
+ self, options: dict[str, Any], element_data: dict[str, Any]
+ ) -> None:
"""
Add data from options, which was defined by user but is not set by this service
diff --git a/sphinx_needs/services/manager.py b/sphinx_needs/services/manager.py
index ecdacadaf..b95962a22 100644
--- a/sphinx_needs/services/manager.py
+++ b/sphinx_needs/services/manager.py
@@ -23,7 +23,9 @@ def register(self, name: str, klass: type[BaseService], **kwargs: Any) -> None:
try:
config = NeedsSphinxConfig(self.app.config).services[name]
except KeyError:
- self.log.debug(f"No service config found for {name}. Add it in your conf.py to needs_services dictionary.")
+ self.log.debug(
+ f"No service config found for {name}. Add it in your conf.py to needs_services dictionary."
+ )
config = {}
# Register options from service class
@@ -43,7 +45,9 @@ def get(self, name: str) -> BaseService:
return self.services[name]
else:
raise NeedsServiceException(
- "Service {} could not be found. " "Available services are {}".format(name, ", ".join(self.services))
+ "Service {} could not be found. " "Available services are {}".format(
+ name, ", ".join(self.services)
+ )
)
diff --git a/sphinx_needs/services/open_needs.py b/sphinx_needs/services/open_needs.py
index 6a9ea2195..d11e99b30 100644
--- a/sphinx_needs/services/open_needs.py
+++ b/sphinx_needs/services/open_needs.py
@@ -24,7 +24,9 @@
class OpenNeedsService(BaseService):
options = CONFIG_OPTIONS + EXTRA_DATA_OPTIONS + EXTRA_LINK_OPTIONS
- def __init__(self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any) -> None:
+ def __init__(
+ self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any
+ ) -> None:
self.app = app
self.name = name
self.config = config
@@ -41,7 +43,9 @@ def __init__(self, app: Sphinx, name: str, config: dict[str, Any], **kwargs: Any
self.query = self.config.get("query", "")
self.content = self.config.get("content", DEFAULT_CONTENT)
self.mappings: dict[str, Any] = self.config.get("mappings", {})
- self.mapping_replaces = self.config.get("mappings_replaces", MAPPINGS_REPLACES_DEFAULT)
+ self.mapping_replaces = self.config.get(
+ "mappings_replaces", MAPPINGS_REPLACES_DEFAULT
+ )
self.extra_data: dict[str, Any] = self.config.get("extra_data", {})
self.params = self.config.get("params", "skip=0,limit=100")
@@ -59,8 +63,8 @@ def _oauthorization(self) -> None:
if login_resp.status_code != 200:
raise OpenNeedsServiceException(
"ONS service error during request.\n"
- "Status code: {}\n"
- "Error: {}\n".format(login_resp.status_code, login_resp.text)
+ f"Status code: {login_resp.status_code}\n"
+ f"Error: {login_resp.text}\n"
)
oauth_credentials = dict(**login_resp.json())
self.token_type = oauth_credentials.get("token_type")
@@ -72,8 +76,13 @@ def _prepare_request(self, options: Any) -> Any:
url: str = options.get("url", self.url)
url = url + str(self.url_postfix)
- headers: dict[str, str] = {"Authorization": f"{self.token_type} {self.access_token}"}
- params: list[str] = [param.strip() for param in re.split(r";|,", options.get("params", self.params))]
+ headers: dict[str, str] = {
+ "Authorization": f"{self.token_type} {self.access_token}"
+ }
+ params: list[str] = [
+ param.strip()
+ for param in re.split(r";|,", options.get("params", self.params))
+ ]
new_params: str = "&".join(params)
url = f"{url}?{new_params}"
@@ -93,10 +102,14 @@ def _send_request(request: Any) -> Any:
result: Any = requests.get(**request)
if result.status_code >= 300:
- raise OpenNeedsServiceException(f"Problem accessing {result.url}.\nReason: {result.text}")
+ raise OpenNeedsServiceException(
+ f"Problem accessing {result.url}.\nReason: {result.text}"
+ )
return result
- def _extract_data(self, data: list[dict[str, Any]], options: dict[str, Any]) -> list[dict[str, Any]]:
+ def _extract_data(
+ self, data: list[dict[str, Any]], options: dict[str, Any]
+ ) -> list[dict[str, Any]]:
"""
Extract data of a list/dictionary, which was retrieved via send_request.
:param data: list or dict
@@ -176,7 +189,10 @@ def _extract_data(self, data: list[dict[str, Any]], options: dict[str, Any]) ->
if name == "links":
# Add a prefix to the referenced link if it is an ID of a need object in
# the data retrieved from the Open Needs Server or don't add prefix
- value = [(prefix + link if link in ids_of_needs_data else link) for link in value]
+ value = [
+ (prefix + link if link in ids_of_needs_data else link)
+ for link in value
+ ]
value = ";".join(value)
# Ensures mapping option with value == None is not implemented. E.g. the links option
# can't be == None since there will be nothing to link to and that will raise a warning
@@ -184,7 +200,9 @@ def _extract_data(self, data: list[dict[str, Any]], options: dict[str, Any]) ->
need_values[name] = value
for regex, new_str in self.mapping_replaces.items():
- need_values[name] = re.sub(regex, new_str, need_values.get(name, ""))
+ need_values[name] = re.sub(
+ regex, new_str, need_values.get(name, "")
+ )
if name == "id":
need_values[name] = str(prefix) + str(need_values.get(name, ""))
diff --git a/sphinx_needs/utils.py b/sphinx_needs/utils.py
index eb0fcccb7..4476c9bb9 100644
--- a/sphinx_needs/utils.py
+++ b/sphinx_needs/utils.py
@@ -173,8 +173,12 @@ def row_col_maker(
link_string_list = {}
for link_name, link_conf in needs_config.string_links.items():
link_string_list[link_name] = {
- "url_template": Environment(autoescape=True).from_string(link_conf["link_url"]),
- "name_template": Environment(autoescape=True).from_string(link_conf["link_name"]),
+ "url_template": Environment(autoescape=True).from_string(
+ link_conf["link_url"]
+ ),
+ "name_template": Environment(autoescape=True).from_string(
+ link_conf["link_name"]
+ ),
"regex_compiled": re.compile(link_conf["regex"]),
"options": link_conf["options"],
"name": link_name,
@@ -203,22 +207,34 @@ def row_col_maker(
if make_ref:
if need_info["is_external"]:
- assert need_info["external_url"] is not None, "external_url must be set for external needs"
- ref_col["refuri"] = check_and_calc_base_url_rel_path(need_info["external_url"], fromdocname)
+ assert (
+ need_info["external_url"] is not None
+ ), "external_url must be set for external needs"
+ ref_col["refuri"] = check_and_calc_base_url_rel_path(
+ need_info["external_url"], fromdocname
+ )
ref_col["classes"].append(need_info["external_css"])
row_col["classes"].append(need_info["external_css"])
else:
- ref_col["refuri"] = builder.get_relative_uri(fromdocname, need_info["docname"])
+ ref_col["refuri"] = builder.get_relative_uri(
+ fromdocname, need_info["docname"]
+ )
ref_col["refuri"] += "#" + datum
elif ref_lookup:
temp_need = all_needs[link_id]
if temp_need["is_external"]:
- assert temp_need["external_url"] is not None, "external_url must be set for external needs"
- ref_col["refuri"] = check_and_calc_base_url_rel_path(temp_need["external_url"], fromdocname)
+ assert (
+ temp_need["external_url"] is not None
+ ), "external_url must be set for external needs"
+ ref_col["refuri"] = check_and_calc_base_url_rel_path(
+ temp_need["external_url"], fromdocname
+ )
ref_col["classes"].append(temp_need["external_css"])
row_col["classes"].append(temp_need["external_css"])
else:
- ref_col["refuri"] = builder.get_relative_uri(fromdocname, temp_need["docname"])
+ ref_col["refuri"] = builder.get_relative_uri(
+ fromdocname, temp_need["docname"]
+ )
ref_col["refuri"] += "#" + temp_need["id"]
if link_part:
ref_col["refuri"] += "." + link_part
@@ -230,7 +246,11 @@ def row_col_maker(
para_col += ref_col
elif matching_link_confs:
para_col += match_string_link(
- datum_text, datum, need_key, matching_link_confs, render_context=needs_config.render_context
+ datum_text,
+ datum,
+ need_key,
+ matching_link_confs,
+ render_context=needs_config.render_context,
)
else:
para_col += text_col
@@ -258,7 +278,9 @@ def rstjinja(app: Sphinx, docname: str, source: list[str]) -> None:
source[0] = rendered
-def import_prefix_link_edit(needs: dict[str, Any], id_prefix: str, needs_extra_links: list[dict[str, Any]]) -> None:
+def import_prefix_link_edit(
+ needs: dict[str, Any], id_prefix: str, needs_extra_links: list[dict[str, Any]]
+) -> None:
"""
Changes existing links to support given prefix.
Only link-ids get touched, which are part of ``needs`` (so are linking them).
@@ -285,7 +307,9 @@ def import_prefix_link_edit(needs: dict[str, Any], id_prefix: str, needs_extra_l
need[extra_link["option"]][n] = f"{id_prefix}{id}"
# Manipulate descriptions
# ToDo: Use regex for better matches.
- need["description"] = need["description"].replace(id, "".join([id_prefix, id]))
+ need["description"] = need["description"].replace(
+ id, "".join([id_prefix, id])
+ )
FuncT = TypeVar("FuncT")
@@ -332,7 +356,11 @@ def check_and_calc_base_url_rel_path(external_url: str, fromdocname: str) -> str
# get path sep considering plattform dependency, '\' for Windows, '/' fro Unix
curr_path_sep = os.path.sep
# check / or \ to determine the relative path to conf.py directory
- if not parsed_url.scheme and not os.path.isabs(external_url) and curr_path_sep in fromdocname:
+ if (
+ not parsed_url.scheme
+ and not os.path.isabs(external_url)
+ and curr_path_sep in fromdocname
+ ):
sub_level = len(fromdocname.split(curr_path_sep)) - 1
ref_uri = os.path.join(sub_level * (".." + curr_path_sep), external_url)
@@ -350,7 +378,8 @@ def check_and_get_external_filter_func(filter_func_ref: str | None) -> tuple[Any
filter_module, filter_function = filter_func_ref.rsplit(".")
except ValueError:
logger.warning(
- f'Filter function not valid "{filter_func_ref}". Example: my_module:my_func [needs]', type="needs"
+ f'Filter function not valid "{filter_func_ref}". Example: my_module:my_func [needs]',
+ type="needs",
)
return filter_func, filter_args
@@ -364,7 +393,10 @@ def check_and_get_external_filter_func(filter_func_ref: str | None) -> tuple[Any
final_module = importlib.import_module(filter_module)
filter_func = getattr(final_module, filter_function)
except Exception:
- logger.warning(f"Could not import filter function: {filter_func_ref} [needs]", type="needs")
+ logger.warning(
+ f"Could not import filter function: {filter_func_ref} [needs]",
+ type="needs",
+ )
return filter_func, filter_args
return filter_func, filter_args
@@ -385,7 +417,10 @@ def jinja_parse(context: dict[str, Any], jinja_string: str) -> str:
try:
content_template = Template(jinja_string, autoescape=True)
except Exception as e:
- raise ReferenceError(f'There was an error in the jinja statement: "{jinja_string}". ' f"Error Msg: {e}")
+ raise ReferenceError(
+ f'There was an error in the jinja statement: "{jinja_string}". '
+ f"Error Msg: {e}"
+ )
content = content_template.render(**context)
return content
@@ -407,7 +442,9 @@ def import_matplotlib() -> matplotlib | None:
return matplotlib
-def save_matplotlib_figure(app: Sphinx, figure: FigureBase, basename: str, fromdocname: str) -> nodes.image:
+def save_matplotlib_figure(
+ app: Sphinx, figure: FigureBase, basename: str, fromdocname: str
+) -> nodes.image:
builder = app.builder
env = app.env
@@ -464,20 +501,34 @@ def dict_get(root: dict[str, Any], items: Any, default: Any = None) -> Any:
def match_string_link(
- text_item: str, data: str, need_key: str, matching_link_confs: list[dict[str, Any]], render_context: dict[str, Any]
+ text_item: str,
+ data: str,
+ need_key: str,
+ matching_link_confs: list[dict[str, Any]],
+ render_context: dict[str, Any],
) -> Any:
try:
link_name = None
link_url = None
- link_conf = matching_link_confs[0] # We only handle the first matching string_link
+ link_conf = matching_link_confs[
+ 0
+ ] # We only handle the first matching string_link
match = link_conf["regex_compiled"].search(data)
if match:
render_content = match.groupdict()
- link_url = link_conf["url_template"].render(**render_content, **render_context)
- link_name = link_conf["name_template"].render(**render_content, **render_context)
+ link_url = link_conf["url_template"].render(
+ **render_content, **render_context
+ )
+ link_name = link_conf["name_template"].render(
+ **render_content, **render_context
+ )
# if no string_link match was made, we handle it as normal string value
- ref_item = nodes.reference(link_name, link_name, refuri=link_url) if link_name else nodes.Text(text_item)
+ ref_item = (
+ nodes.reference(link_name, link_name, refuri=link_url)
+ if link_name
+ else nodes.Text(text_item)
+ )
except Exception as e:
logger.warning(
@@ -490,7 +541,9 @@ def match_string_link(
def match_variants(
- option_value: str | list[str], keywords: dict[str, Any], needs_variants: dict[str, str]
+ option_value: str | list[str],
+ keywords: dict[str, Any],
+ needs_variants: dict[str, str],
) -> None | str | list[str]:
"""
Function to handle variant option management.
@@ -503,7 +556,9 @@ def match_variants(
"""
def variant_handling(
- variant_definitions: list[str], variant_data: dict[str, Any], variant_pattern: Pattern # type: ignore[type-arg]
+ variant_definitions: list[str],
+ variant_data: dict[str, Any],
+ variant_pattern: Pattern, # type: ignore[type-arg]
) -> str | None:
filter_context = variant_data
# filter_result = []
@@ -515,9 +570,15 @@ def variant_handling(
if check_definition:
variants_in_option = True
# Separate variant definition from value to use for the option
- filter_string, output, _ = re.split(r"(:[\w':.\-\" ]+)$", variant_definition)
+ filter_string, output, _ = re.split(
+ r"(:[\w':.\-\" ]+)$", variant_definition
+ )
filter_string = re.sub(r"^\[|[:\]]$", "", filter_string)
- filter_string = needs_variants[filter_string] if filter_string in needs_variants else filter_string
+ filter_string = (
+ needs_variants[filter_string]
+ if filter_string in needs_variants
+ else filter_string
+ )
try:
# https://docs.python.org/3/library/functions.html?highlight=compile#compile
filter_compiled = compile(filter_string, "", "eval")
@@ -533,7 +594,8 @@ def variant_handling(
return output.lstrip(":")
except Exception as e:
logger.warning(
- f'There was an error in the filter statement: "{filter_string}". ' f"Error Msg: {e} [needs]",
+ f'There was an error in the filter statement: "{filter_string}". '
+ f"Error Msg: {e} [needs]",
type="needs",
)
else:
@@ -557,11 +619,17 @@ def variant_handling(
if isinstance(option_value, str):
multiple_variants: list[str] = variant_splitting.split(rf"""{option_value}""")
multiple_variants = [
- re.sub(r"^([;, ]+)|([;, ]+$)", "", i) for i in multiple_variants if i not in (None, ";", "", " ")
+ re.sub(r"^([;, ]+)|([;, ]+$)", "", i)
+ for i in multiple_variants
+ if i not in (None, ";", "", " ")
]
- if len(multiple_variants) == 1 and not variant_rule_matching.search(multiple_variants[0]):
+ if len(multiple_variants) == 1 and not variant_rule_matching.search(
+ multiple_variants[0]
+ ):
return option_value
- new_option_value = variant_handling(multiple_variants, keywords, variant_rule_matching)
+ new_option_value = variant_handling(
+ multiple_variants, keywords, variant_rule_matching
+ )
if new_option_value is None:
return option_value
return new_option_value
@@ -570,10 +638,14 @@ def variant_handling(
# In case an option value is a list (:tags: open; close), and does not contain any variant definition,
# then return the unmodified value
# options = all([bool(not variant_rule_matching.search(i)) for i in multiple_variants])
- options = all(bool(not variant_rule_matching.search(i)) for i in multiple_variants)
+ options = all(
+ bool(not variant_rule_matching.search(i)) for i in multiple_variants
+ )
if options:
return option_value
- new_option_value = variant_handling(multiple_variants, keywords, variant_rule_matching)
+ new_option_value = variant_handling(
+ multiple_variants, keywords, variant_rule_matching
+ )
return new_option_value
else:
return option_value
@@ -596,7 +668,9 @@ def clean_log(data: str) -> str:
return clean_credentials
-def node_match(node_types: type[nodes.Element] | list[type[nodes.Element]]) -> Callable[[nodes.Node], bool]:
+def node_match(
+ node_types: type[nodes.Element] | list[type[nodes.Element]]
+) -> Callable[[nodes.Node], bool]:
"""
Returns a condition function for doctuils.nodes.findall()
@@ -618,7 +692,9 @@ def node_match(node_types: type[nodes.Element] | list[type[nodes.Element]]) -> C
"""
node_types_list = node_types if isinstance(node_types, list) else [node_types]
- def condition(node: nodes.Node, node_types: list[type[nodes.Element]] = node_types_list) -> bool:
+ def condition(
+ node: nodes.Node, node_types: list[type[nodes.Element]] = node_types_list
+ ) -> bool:
return any(isinstance(node, x) for x in node_types)
return condition
diff --git a/sphinx_needs/warnings.py b/sphinx_needs/warnings.py
index c110e1496..1f9a47c2c 100644
--- a/sphinx_needs/warnings.py
+++ b/sphinx_needs/warnings.py
@@ -61,7 +61,9 @@ def process_warnings(app: Sphinx, exception: Exception | None) -> None:
for warning_name, warning_filter in NEEDS_CONFIG.warnings.items():
if isinstance(warning_filter, str):
# filter string used
- result = filter_needs(checked_needs.values(), needs_config, warning_filter)
+ result = filter_needs(
+ checked_needs.values(), needs_config, warning_filter
+ )
elif callable(warning_filter):
# custom defined filter code used from conf.py
result = []
@@ -69,7 +71,10 @@ def process_warnings(app: Sphinx, exception: Exception | None) -> None:
if warning_filter(need, logger):
result.append(need)
else:
- logger.warning(f"Unknown needs warnings filter {warning_filter}! [needs]", type="needs")
+ logger.warning(
+ f"Unknown needs warnings filter {warning_filter}! [needs]",
+ type="needs",
+ )
if len(result) == 0:
logger.info(f"{warning_name}: passed")
@@ -94,17 +99,26 @@ def process_warnings(app: Sphinx, exception: Exception | None) -> None:
if warnings_always_warn:
logger.warning(
"{}: failed\n\t\tfailed needs: {} ({})\n\t\tused filter: {} [needs]".format(
- warning_name, len(need_ids), ", ".join(need_ids), warning_text
+ warning_name,
+ len(need_ids),
+ ", ".join(need_ids),
+ warning_text,
),
type="needs",
)
else:
logger.info(
"{}: failed\n\t\tfailed needs: {} ({})\n\t\tused filter: {}".format(
- warning_name, len(need_ids), ", ".join(need_ids), warning_text
+ warning_name,
+ len(need_ids),
+ ", ".join(need_ids),
+ warning_text,
)
)
warning_raised = True
if warning_raised:
- logger.warning("warnings were raised. See console / log output for details. [needs]", type="needs")
+ logger.warning(
+ "warnings were raised. See console / log output for details. [needs]",
+ type="needs",
+ )
diff --git a/tests/benchmarks/test_basic.py b/tests/benchmarks/test_basic.py
index 02c329101..a45133136 100644
--- a/tests/benchmarks/test_basic.py
+++ b/tests/benchmarks/test_basic.py
@@ -8,7 +8,9 @@
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_basic"}], indirect=True
+)
def test_basic_time(test_app, benchmark):
responses.add_callback(
responses.GET,
@@ -16,7 +18,9 @@ def test_basic_time(test_app, benchmark):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
benchmark.pedantic(app.builder.build_all, rounds=1, iterations=1)
diff --git a/tests/benchmarks/test_official.py b/tests/benchmarks/test_official.py
index b2f3ba6a8..663a3ea86 100644
--- a/tests/benchmarks/test_official.py
+++ b/tests/benchmarks/test_official.py
@@ -9,7 +9,9 @@
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "../docs"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "html", "srcdir": "../docs"}], indirect=True
+)
def test_official_time(test_app, benchmark):
responses.add_callback(
responses.GET,
@@ -17,7 +19,9 @@ def test_official_time(test_app, benchmark):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
benchmark.pedantic(app.builder.build_all, rounds=1, iterations=1)
@@ -29,7 +33,11 @@ def test_official_time(test_app, benchmark):
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "../docs", "parallel": 1}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "../docs", "parallel": 1}],
+ indirect=True,
+)
def test_official_memory(test_app):
responses.add_callback(
responses.GET,
@@ -37,7 +45,9 @@ def test_official_memory(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
diff --git a/tests/conftest.py b/tests/conftest.py
index c631b27fc..e39cd8524 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -83,7 +83,16 @@ class Starter(ProcessStarter):
pattern = "Serving HTTP on [0-9.]+ port 62343|Address already in use"
timeout = 20
terminate_on_interrupt = True
- args = ["python3", "-m", "http.server", "--directory", sphinx_test_tempdir, "--bind", addr, port]
+ args = [
+ "python3",
+ "-m",
+ "http.server",
+ "--directory",
+ sphinx_test_tempdir,
+ "--bind",
+ addr,
+ port,
+ ]
env = {"PYTHONUNBUFFERED": "1"}
def check_server_connection(log_path: str):
@@ -98,13 +107,18 @@ def check_server_connection(log_path: str):
sock.close()
if result == 0:
with open(str(log_path), "wb", 0) as stdout:
- stdout.write(bytes("Serving HTTP on 127.0.0.1 port 62343 (http://127.0.0.1:62343/) ...\n", "utf8"))
+ stdout.write(
+ bytes(
+ "Serving HTTP on 127.0.0.1 port 62343 (http://127.0.0.1:62343/) ...\n",
+ "utf8",
+ )
+ )
return True
return False
if not check_server_connection(log_path=xprocess.getinfo("http_server").logpath):
# Start the process and ensure it is running
- _, logfile = xprocess.ensure("http_server", Starter, persist_logs=False) # noqa:F841
+ _, logfile = xprocess.ensure("http_server", Starter, persist_logs=False)
http_server_process = xprocess.getinfo("http_server")
server_url = f"http://{addr}:{port}"
@@ -129,7 +143,9 @@ def test_js(self) -> Dict[str, Any]:
"""
cypress_testpath = get_abspath(self.spec_pattern)
- if not cypress_testpath or not (os.path.isabs(cypress_testpath) and os.path.exists(cypress_testpath)):
+ if not cypress_testpath or not (
+ os.path.isabs(cypress_testpath) and os.path.exists(cypress_testpath)
+ ):
return {
"returncode": 1,
"stdout": None,
@@ -179,7 +195,12 @@ def test_js(self) -> Dict[str, Any]:
def pytest_addoption(parser):
- parser.addoption("--sn-build-dir", action="store", default=None, help="Base directory for sphinx-needs builds")
+ parser.addoption(
+ "--sn-build-dir",
+ action="store",
+ default=None,
+ help="Base directory for sphinx-needs builds",
+ )
@pytest.fixture(scope="session")
@@ -195,7 +216,9 @@ def sphinx_test_tempdir(request) -> path:
# We create a temp-folder on our own, as the util-functions from sphinx and pytest make troubles.
# It seems like they reuse certain-temp names
- temp_base = os.path.abspath(request.config.getoption("--sn-build-dir") or tempfile.gettempdir())
+ temp_base = os.path.abspath(
+ request.config.getoption("--sn-build-dir") or tempfile.gettempdir()
+ )
sphinx_test_tempdir = path(temp_base).joinpath("sn_test_build_data")
utils_dir = sphinx_test_tempdir.joinpath("utils")
@@ -235,7 +258,9 @@ def test_app(make_app, sphinx_test_tempdir, request):
if not builder_params.get("no_plantuml", False):
# Since we don't want copy the plantuml.jar file for each test function,
# we need to override the plantuml conf variable and set it to what we have already
- plantuml = "java -Djava.awt.headless=true -jar %s" % os.path.join(sphinx_test_tempdir, "utils", "plantuml.jar")
+ plantuml = "java -Djava.awt.headless=true -jar %s" % os.path.join(
+ sphinx_test_tempdir, "utils", "plantuml.jar"
+ )
sphinx_conf_overrides.update(plantuml=plantuml)
# copy test srcdir to test temporary directory sphinx_test_tempdir
diff --git a/tests/data/service_github.py b/tests/data/service_github.py
index fb24ab4d8..9151feb32 100644
--- a/tests/data/service_github.py
+++ b/tests/data/service_github.py
@@ -108,7 +108,8 @@
GITHUB_SPECIFIC_ISSUE_ANSWER = {
"url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/141",
"repository_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs",
- "labels_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/" "141/labels{/name}",
+ "labels_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/"
+ "141/labels{/name}",
"comments_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/141/comments",
"events_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/141/events",
"html_url": "https://github.com/useblocks/sphinxcontrib-needs/issues/141",
@@ -140,7 +141,8 @@
{
"id": 491973814,
"node_id": "MDU6TGFiZWw0OTE5NzM4MTQ=",
- "url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs" "/labels/bug",
+ "url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs"
+ "/labels/bug",
"name": "bug",
"color": "ee0701",
"default": True,
@@ -318,7 +320,8 @@
"/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/teams",
"hooks_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/hooks",
- "issue_events_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/events{" "/number}",
+ "issue_events_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues/events{"
+ "/number}",
"events_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/events",
"assignees_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/assignees{/user}",
"branches_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/branches{/branch}",
@@ -334,17 +337,22 @@
"subscribers_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/subscribers",
"subscription_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/subscription",
"commits_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/commits{/sha}",
- "git_commits_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/git" "/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/git"
+ "/commits{/sha}",
"comments_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/comments{/number}",
- "issue_comment_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues" "/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues"
+ "/comments{/number}",
"contents_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/contents/{+path}",
- "compare_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/compare/{base}...{" "head}",
+ "compare_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/compare/{base}...{"
+ "head}",
"merges_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/merges",
- "archive_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/{archive_format}{" "/ref}",
+ "archive_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/{archive_format}{"
+ "/ref}",
"downloads_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/downloads",
"issues_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/issues{/number}",
"pulls_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/pulls{/number}",
- "milestones_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/milestones{" "/number}",
+ "milestones_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/milestones{"
+ "/number}",
"notifications_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs"
"/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/useblocks/sphinxcontrib-needs/labels{/name}",
diff --git a/tests/doc_test/api_doc/conf.py b/tests/doc_test/api_doc/conf.py
index 7832f346d..df50838b8 100644
--- a/tests/doc_test/api_doc/conf.py
+++ b/tests/doc_test/api_doc/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs", "dummy_extension.dummy"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/api_doc_awesome/conf.py b/tests/doc_test/api_doc_awesome/conf.py
index 7832f346d..df50838b8 100644
--- a/tests/doc_test/api_doc_awesome/conf.py
+++ b/tests/doc_test/api_doc_awesome/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs", "dummy_extension.dummy"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/arch_doc/conf.py b/tests/doc_test/arch_doc/conf.py
index 1571c763f..70ce823f5 100644
--- a/tests/doc_test/arch_doc/conf.py
+++ b/tests/doc_test/arch_doc/conf.py
@@ -3,8 +3,32 @@
plantuml_output_format = "svg"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/broken_doc/conf.py b/tests/doc_test/broken_doc/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/broken_doc/conf.py
+++ b/tests/doc_test/broken_doc/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/broken_links/conf.py b/tests/doc_test/broken_links/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/broken_links/conf.py
+++ b/tests/doc_test/broken_links/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/broken_statuses/conf.py b/tests/doc_test/broken_statuses/conf.py
index 3706ca5ff..6e013eae5 100644
--- a/tests/doc_test/broken_statuses/conf.py
+++ b/tests/doc_test/broken_statuses/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_statuses = [
diff --git a/tests/doc_test/broken_syntax_doc/conf.py b/tests/doc_test/broken_syntax_doc/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/broken_syntax_doc/conf.py
+++ b/tests/doc_test/broken_syntax_doc/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/broken_tags/conf.py b/tests/doc_test/broken_tags/conf.py
index 7c04d916c..6559d7fe0 100644
--- a/tests/doc_test/broken_tags/conf.py
+++ b/tests/doc_test/broken_tags/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_tags = [
diff --git a/tests/doc_test/broken_tags_2/conf.py b/tests/doc_test/broken_tags_2/conf.py
index 7c04d916c..6559d7fe0 100644
--- a/tests/doc_test/broken_tags_2/conf.py
+++ b/tests/doc_test/broken_tags_2/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_tags = [
diff --git a/tests/doc_test/doc_basic/conf.py b/tests/doc_test/doc_basic/conf.py
index 0a5cb1761..2db347716 100644
--- a/tests/doc_test/doc_basic/conf.py
+++ b/tests/doc_test/doc_basic/conf.py
@@ -6,8 +6,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_basic_latex/conf.py b/tests/doc_test/doc_basic_latex/conf.py
index 32f8e8de5..1f9bcc6ed 100644
--- a/tests/doc_test/doc_basic_latex/conf.py
+++ b/tests/doc_test/doc_basic_latex/conf.py
@@ -8,8 +8,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_build_latex/conf.py b/tests/doc_test/doc_build_latex/conf.py
index 6a81ad4bb..df70aa270 100644
--- a/tests/doc_test/doc_build_latex/conf.py
+++ b/tests/doc_test/doc_build_latex/conf.py
@@ -13,8 +13,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_df_calc_sum/conf.py b/tests/doc_test/doc_df_calc_sum/conf.py
index 2e1bb2cf3..ee4795ac0 100644
--- a/tests/doc_test/doc_df_calc_sum/conf.py
+++ b/tests/doc_test/doc_df_calc_sum/conf.py
@@ -3,10 +3,38 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
-needs_extra_options = {"test_func": directives.unchanged, "hours": directives.unchanged, "amount": directives.unchanged}
+needs_extra_options = {
+ "test_func": directives.unchanged,
+ "hours": directives.unchanged,
+ "amount": directives.unchanged,
+}
diff --git a/tests/doc_test/doc_df_check_linked_values/conf.py b/tests/doc_test/doc_df_check_linked_values/conf.py
index 707f3afad..2a93cda81 100644
--- a/tests/doc_test/doc_df_check_linked_values/conf.py
+++ b/tests/doc_test/doc_df_check_linked_values/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_options = {"test_func": directives.unchanged, "hours": directives.unchanged}
diff --git a/tests/doc_test/doc_df_user_functions/conf.py b/tests/doc_test/doc_df_user_functions/conf.py
index 07958c0c0..14945940d 100644
--- a/tests/doc_test/doc_df_user_functions/conf.py
+++ b/tests/doc_test/doc_df_user_functions/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_options = {"test_func": directives.unchanged, "hours": directives.unchanged}
diff --git a/tests/doc_test/doc_dynamic_functions/conf.py b/tests/doc_test/doc_dynamic_functions/conf.py
index 5097fc12d..e474af668 100644
--- a/tests/doc_test/doc_dynamic_functions/conf.py
+++ b/tests/doc_test/doc_dynamic_functions/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_options = {"test_func": directives.unchanged}
diff --git a/tests/doc_test/doc_export_id/conf.py b/tests/doc_test/doc_export_id/conf.py
index 34095785f..d2a706459 100644
--- a/tests/doc_test/doc_export_id/conf.py
+++ b/tests/doc_test/doc_export_id/conf.py
@@ -6,10 +6,34 @@
plantuml_output_format = "svg"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_links = [
diff --git a/tests/doc_test/doc_extra_links/conf.py b/tests/doc_test/doc_extra_links/conf.py
index ad8a7f24e..863b56681 100644
--- a/tests/doc_test/doc_extra_links/conf.py
+++ b/tests/doc_test/doc_extra_links/conf.py
@@ -6,10 +6,34 @@
plantuml_output_format = "svg"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_links = [
diff --git a/tests/doc_test/doc_github_issue_21/conf.py b/tests/doc_test/doc_github_issue_21/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/doc_github_issue_21/conf.py
+++ b/tests/doc_test/doc_github_issue_21/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_github_issue_44/conf.py b/tests/doc_test/doc_github_issue_44/conf.py
index df3fe57f8..7556c0c4e 100644
--- a/tests/doc_test/doc_github_issue_44/conf.py
+++ b/tests/doc_test/doc_github_issue_44/conf.py
@@ -3,8 +3,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_global_options/conf.py b/tests/doc_test/doc_global_options/conf.py
index 46408adc5..f22187cad 100644
--- a/tests/doc_test/doc_global_options/conf.py
+++ b/tests/doc_test/doc_global_options/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_global_options = {
diff --git a/tests/doc_test/doc_layout/conf.py b/tests/doc_test/doc_layout/conf.py
index 6969f1c23..899d6306c 100644
--- a/tests/doc_test/doc_layout/conf.py
+++ b/tests/doc_test/doc_layout/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_options = {
@@ -19,7 +43,10 @@
"grid": "simple_side_right_partial",
"layout": {
"head": ['**<>** for *<>*'],
- "meta": ['**status**: <>', '**author**: <>'],
+ "meta": [
+ '**status**: <>',
+ '**author**: <>',
+ ],
"side": ['<>'],
},
},
@@ -27,14 +54,20 @@
"grid": "simple",
"layout": {
"head": ['**<>**'],
- "meta": ['**status**: <>', r'<>'],
+ "meta": [
+ '**status**: <>',
+ r'<>',
+ ],
},
},
"footer_grid": {
"grid": "simple_footer",
"layout": {
"head": ['**<>** for *<>*'],
- "meta": ['**status**: <>', '**author**: <>'],
+ "meta": [
+ '**status**: <>',
+ '**author**: <>',
+ ],
"footer": ['**custom footer for <>**'],
},
},
diff --git a/tests/doc_test/doc_list2need/conf.py b/tests/doc_test/doc_list2need/conf.py
index 009477a1b..43d93e5f4 100644
--- a/tests/doc_test/doc_list2need/conf.py
+++ b/tests/doc_test/doc_list2need/conf.py
@@ -8,10 +8,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_links = [
diff --git a/tests/doc_test/doc_measure_time/conf.py b/tests/doc_test/doc_measure_time/conf.py
index 74f164462..a4b1d4e5f 100644
--- a/tests/doc_test/doc_measure_time/conf.py
+++ b/tests/doc_test/doc_measure_time/conf.py
@@ -17,10 +17,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_need_count/conf.py b/tests/doc_test/doc_need_count/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/doc_need_count/conf.py
+++ b/tests/doc_test/doc_need_count/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_need_delete/conf.py b/tests/doc_test/doc_need_delete/conf.py
index 104609b54..3badaf917 100644
--- a/tests/doc_test/doc_need_delete/conf.py
+++ b/tests/doc_test/doc_need_delete/conf.py
@@ -6,8 +6,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "R_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_need_id_from_title/conf.py b/tests/doc_test/doc_need_id_from_title/conf.py
index e3a53e73b..d7e949123 100644
--- a/tests/doc_test/doc_need_id_from_title/conf.py
+++ b/tests/doc_test/doc_need_id_from_title/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_id_length = 20
diff --git a/tests/doc_test/doc_need_jinja_content/conf.py b/tests/doc_test/doc_need_jinja_content/conf.py
index 3f7d3cdd7..6081c7b09 100644
--- a/tests/doc_test/doc_need_jinja_content/conf.py
+++ b/tests/doc_test/doc_need_jinja_content/conf.py
@@ -6,10 +6,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "R_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_need_parts/conf.py b/tests/doc_test/doc_need_parts/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/doc_need_parts/conf.py
+++ b/tests/doc_test/doc_need_parts/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needarch/conf.py b/tests/doc_test/doc_needarch/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needarch/conf.py
+++ b/tests/doc_test/doc_needarch/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needarch_jinja_func_import/conf.py b/tests/doc_test/doc_needarch_jinja_func_import/conf.py
index dfccf97c2..f20c68b8c 100644
--- a/tests/doc_test/doc_needarch_jinja_func_import/conf.py
+++ b/tests/doc_test/doc_needarch_jinja_func_import/conf.py
@@ -20,7 +20,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -29,10 +36,34 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_links = [
@@ -41,5 +72,10 @@
"incoming": "is used by",
"outgoing": "uses",
},
- {"option": "tests", "incoming": "is tested by", "outgoing": "tests", "style": "#00AA00"},
+ {
+ "option": "tests",
+ "incoming": "is tested by",
+ "outgoing": "tests",
+ "style": "#00AA00",
+ },
]
diff --git a/tests/doc_test/doc_needarch_jinja_func_need/conf.py b/tests/doc_test/doc_needarch_jinja_func_need/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needarch_jinja_func_need/conf.py
+++ b/tests/doc_test/doc_needarch_jinja_func_need/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needarch_negative_tests/conf.py b/tests/doc_test/doc_needarch_negative_tests/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needarch_negative_tests/conf.py
+++ b/tests/doc_test/doc_needarch_negative_tests/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needbar/conf.py b/tests/doc_test/doc_needbar/conf.py
index 0d9b66fe3..c0dc66839 100644
--- a/tests/doc_test/doc_needbar/conf.py
+++ b/tests/doc_test/doc_needbar/conf.py
@@ -3,6 +3,18 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RQ_", "color": "#FEDCD2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RQ_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needextend/conf.py b/tests/doc_test/doc_needextend/conf.py
index 08df9747f..4c07658ee 100644
--- a/tests/doc_test/doc_needextend/conf.py
+++ b/tests/doc_test/doc_needextend/conf.py
@@ -3,8 +3,32 @@
needs_build_json = True
needs_id_regex = "^[A-Za-z0-9_]*"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needextend_strict/conf.py b/tests/doc_test/doc_needextend_strict/conf.py
index 6b4b9fa9d..99f842750 100644
--- a/tests/doc_test/doc_needextend_strict/conf.py
+++ b/tests/doc_test/doc_needextend_strict/conf.py
@@ -2,8 +2,32 @@
needs_id_regex = "^[A-Za-z0-9_]*"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needextract/conf.py b/tests/doc_test/doc_needextract/conf.py
index 47badfa7d..87cb4ac0e 100644
--- a/tests/doc_test/doc_needextract/conf.py
+++ b/tests/doc_test/doc_needextract/conf.py
@@ -8,8 +8,32 @@
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needflow/conf.py b/tests/doc_test/doc_needflow/conf.py
index aa6219420..aab24df0d 100644
--- a/tests/doc_test/doc_needflow/conf.py
+++ b/tests/doc_test/doc_needflow/conf.py
@@ -8,8 +8,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needflow_incl_child_needs/conf.py b/tests/doc_test/doc_needflow_incl_child_needs/conf.py
index 24b1cbd1b..96753e0bd 100644
--- a/tests/doc_test/doc_needflow_incl_child_needs/conf.py
+++ b/tests/doc_test/doc_needflow_incl_child_needs/conf.py
@@ -8,10 +8,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needimport_download_needs_json/conf.py b/tests/doc_test/doc_needimport_download_needs_json/conf.py
index 885bd47d6..814c929f3 100644
--- a/tests/doc_test/doc_needimport_download_needs_json/conf.py
+++ b/tests/doc_test/doc_needimport_download_needs_json/conf.py
@@ -3,8 +3,32 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needimport_download_needs_json_negative/conf.py b/tests/doc_test/doc_needimport_download_needs_json_negative/conf.py
index 885bd47d6..814c929f3 100644
--- a/tests/doc_test/doc_needimport_download_needs_json_negative/conf.py
+++ b/tests/doc_test/doc_needimport_download_needs_json_negative/conf.py
@@ -3,8 +3,32 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needlist/conf.py b/tests/doc_test/doc_needlist/conf.py
index 885bd47d6..814c929f3 100644
--- a/tests/doc_test/doc_needlist/conf.py
+++ b/tests/doc_test/doc_needlist/conf.py
@@ -3,8 +3,32 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needpie/conf.py b/tests/doc_test/doc_needpie/conf.py
index 86ef3ff45..2c635d301 100644
--- a/tests/doc_test/doc_needpie/conf.py
+++ b/tests/doc_test/doc_needpie/conf.py
@@ -8,10 +8,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_options = ["author"]
diff --git a/tests/doc_test/doc_needs_builder/conf.py b/tests/doc_test/doc_needs_builder/conf.py
index ce1cbf2cf..0e12a0867 100644
--- a/tests/doc_test/doc_needs_builder/conf.py
+++ b/tests/doc_test/doc_needs_builder/conf.py
@@ -5,10 +5,34 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_file = "custom_needs_test.json"
diff --git a/tests/doc_test/doc_needs_builder_negative_tests/conf.py b/tests/doc_test/doc_needs_builder_negative_tests/conf.py
index 885bd47d6..814c929f3 100644
--- a/tests/doc_test/doc_needs_builder_negative_tests/conf.py
+++ b/tests/doc_test/doc_needs_builder_negative_tests/conf.py
@@ -3,8 +3,32 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needs_builder_parallel/conf.py b/tests/doc_test/doc_needs_builder_parallel/conf.py
index 87abb2f42..dabfbcfcf 100644
--- a/tests/doc_test/doc_needs_builder_parallel/conf.py
+++ b/tests/doc_test/doc_needs_builder_parallel/conf.py
@@ -7,10 +7,34 @@
needs_build_json = True
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_file = "custom_needs_test.json"
diff --git a/tests/doc_test/doc_needs_external_needs/conf.py b/tests/doc_test/doc_needs_external_needs/conf.py
index 95e5cee80..2d787751d 100644
--- a/tests/doc_test/doc_needs_external_needs/conf.py
+++ b/tests/doc_test/doc_needs_external_needs/conf.py
@@ -6,13 +6,45 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_external_needs = [
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "ext_"},
- {"base_url": "../../_build/html", "json_path": "needs_test_small.json", "id_prefix": "ext_rel_path_"},
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "ext_",
+ },
+ {
+ "base_url": "../../_build/html",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "ext_rel_path_",
+ },
]
diff --git a/tests/doc_test/doc_needs_external_needs_remote/conf.py b/tests/doc_test/doc_needs_external_needs_remote/conf.py
index b63ea602c..460476c0b 100644
--- a/tests/doc_test/doc_needs_external_needs_remote/conf.py
+++ b/tests/doc_test/doc_needs_external_needs_remote/conf.py
@@ -6,10 +6,34 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_external_needs = [
diff --git a/tests/doc_test/doc_needs_external_needs_with_target_url/conf.py b/tests/doc_test/doc_needs_external_needs_with_target_url/conf.py
index d4c198d2d..6a45a59f8 100644
--- a/tests/doc_test/doc_needs_external_needs_with_target_url/conf.py
+++ b/tests/doc_test/doc_needs_external_needs_with_target_url/conf.py
@@ -6,10 +6,34 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_external_needs = [
@@ -31,5 +55,9 @@
"json_path": "needs_test_small.json",
"id_prefix": "ext_need_type_",
},
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "ext_default_"},
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "ext_default_",
+ },
]
diff --git a/tests/doc_test/doc_needs_filter_data/conf.py b/tests/doc_test/doc_needs_filter_data/conf.py
index 23aa68579..8c62e9c97 100644
--- a/tests/doc_test/doc_needs_filter_data/conf.py
+++ b/tests/doc_test/doc_needs_filter_data/conf.py
@@ -12,10 +12,34 @@
needs_id_regex = "^[A-Za-z0-9_]*"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py
index 6d7baed7d..3361ea436 100644
--- a/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py
+++ b/tests/doc_test/doc_needs_filter_func_allow_dirty_filter/conf.py
@@ -8,8 +8,20 @@
needs_id_regex = "^[A-Za-z0-9_]*"
needs_types = [
- {"directive": "feature", "title": "Feature", "prefix": "FE_", "color": "#FEDCD2", "style": "node"},
- {"directive": "usecase", "title": "Use Case", "prefix": "USE_", "color": "#DF744A", "style": "node"},
+ {
+ "directive": "feature",
+ "title": "Feature",
+ "prefix": "FE_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "usecase",
+ "title": "Use Case",
+ "prefix": "USE_",
+ "color": "#DF744A",
+ "style": "node",
+ },
]
needs_extra_options = ["ti", "tcl"]
diff --git a/tests/doc_test/doc_needs_warnings/conf.py b/tests/doc_test/doc_needs_warnings/conf.py
index f6b991773..cfc630c88 100644
--- a/tests/doc_test/doc_needs_warnings/conf.py
+++ b/tests/doc_test/doc_needs_warnings/conf.py
@@ -3,14 +3,42 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_external_needs = [
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "ext_"}
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "ext_",
+ }
]
@@ -38,7 +66,11 @@ def setup(app):
add_warning(app, "api_warning_filter", filter_string="status == 'example_2'")
add_warning(app, "api_warning_func", custom_warning_func)
- add_warning(app, "invalid_status", "status not in ['open', 'closed', 'done', 'example_2', 'example_3']")
+ add_warning(
+ app,
+ "invalid_status",
+ "status not in ['open', 'closed', 'done', 'example_2', 'example_3']",
+ )
# Needs option to set True or False to raise sphinx-warning for each not passed warning check
diff --git a/tests/doc_test/doc_needs_warnings_return_status_code/conf.py b/tests/doc_test/doc_needs_warnings_return_status_code/conf.py
index 490cb7534..47d7db034 100644
--- a/tests/doc_test/doc_needs_warnings_return_status_code/conf.py
+++ b/tests/doc_test/doc_needs_warnings_return_status_code/conf.py
@@ -3,10 +3,34 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needsfile/conf.py b/tests/doc_test/doc_needsfile/conf.py
index e607e1f34..457adbf2a 100644
--- a/tests/doc_test/doc_needsfile/conf.py
+++ b/tests/doc_test/doc_needsfile/conf.py
@@ -3,8 +3,32 @@
needs_file = "needs_errors.json"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needtable/conf.py b/tests/doc_test/doc_needtable/conf.py
index 73fd61077..0aef9a7d0 100644
--- a/tests/doc_test/doc_needtable/conf.py
+++ b/tests/doc_test/doc_needtable/conf.py
@@ -5,10 +5,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_options = [
diff --git a/tests/doc_test/doc_needuml/conf.py b/tests/doc_test/doc_needuml/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml/conf.py
+++ b/tests/doc_test/doc_needuml/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_diagram_allowmixing/conf.py b/tests/doc_test/doc_needuml_diagram_allowmixing/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_diagram_allowmixing/conf.py
+++ b/tests/doc_test/doc_needuml_diagram_allowmixing/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_duplicate_key/conf.py b/tests/doc_test/doc_needuml_duplicate_key/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_duplicate_key/conf.py
+++ b/tests/doc_test/doc_needuml_duplicate_key/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_filter/conf.py b/tests/doc_test/doc_needuml_filter/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_filter/conf.py
+++ b/tests/doc_test/doc_needuml_filter/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_jinja_func_flow/conf.py b/tests/doc_test/doc_needuml_jinja_func_flow/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_jinja_func_flow/conf.py
+++ b/tests/doc_test/doc_needuml_jinja_func_flow/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_jinja_func_import_negative_tests/conf.py b/tests/doc_test/doc_needuml_jinja_func_import_negative_tests/conf.py
index dfccf97c2..f20c68b8c 100644
--- a/tests/doc_test/doc_needuml_jinja_func_import_negative_tests/conf.py
+++ b/tests/doc_test/doc_needuml_jinja_func_import_negative_tests/conf.py
@@ -20,7 +20,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -29,10 +36,34 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_links = [
@@ -41,5 +72,10 @@
"incoming": "is used by",
"outgoing": "uses",
},
- {"option": "tests", "incoming": "is tested by", "outgoing": "tests", "style": "#00AA00"},
+ {
+ "option": "tests",
+ "incoming": "is tested by",
+ "outgoing": "tests",
+ "style": "#00AA00",
+ },
]
diff --git a/tests/doc_test/doc_needuml_jinja_func_need_removed/conf.py b/tests/doc_test/doc_needuml_jinja_func_need_removed/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_jinja_func_need_removed/conf.py
+++ b/tests/doc_test/doc_needuml_jinja_func_need_removed/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_jinja_func_ref/conf.py b/tests/doc_test/doc_needuml_jinja_func_ref/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_jinja_func_ref/conf.py
+++ b/tests/doc_test/doc_needuml_jinja_func_ref/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_key_name_diagram/conf.py b/tests/doc_test/doc_needuml_key_name_diagram/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_key_name_diagram/conf.py
+++ b/tests/doc_test/doc_needuml_key_name_diagram/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_needuml_save/conf.py b/tests/doc_test/doc_needuml_save/conf.py
index e4c6437fd..ad06ccaad 100644
--- a/tests/doc_test/doc_needuml_save/conf.py
+++ b/tests/doc_test/doc_needuml_save/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,10 +38,34 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_build_needumls = "my_needumls"
diff --git a/tests/doc_test/doc_needuml_save_with_abs_path/conf.py b/tests/doc_test/doc_needuml_save_with_abs_path/conf.py
index 1666acffc..208a58691 100644
--- a/tests/doc_test/doc_needuml_save_with_abs_path/conf.py
+++ b/tests/doc_test/doc_needuml_save_with_abs_path/conf.py
@@ -22,7 +22,14 @@
"color": "#BFD8D2",
"style": "card",
},
- {"directive": "sys", "content": "plantuml", "title": "System", "prefix": "S_", "color": "#FF68D2", "style": "node"},
+ {
+ "directive": "sys",
+ "content": "plantuml",
+ "title": "System",
+ "prefix": "S_",
+ "color": "#FF68D2",
+ "style": "node",
+ },
{
"directive": "prod",
"content": "plantuml",
@@ -31,8 +38,32 @@
"color": "#FF68D2",
"style": "node",
},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/doc_open_needs_service/conf.py b/tests/doc_test/doc_open_needs_service/conf.py
index be86e0012..50d1c74d3 100644
--- a/tests/doc_test/doc_open_needs_service/conf.py
+++ b/tests/doc_test/doc_open_needs_service/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "R_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "task", "title": "Task", "prefix": "T_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "R_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "task",
+ "title": "Task",
+ "prefix": "T_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_services = {
diff --git a/tests/doc_test/doc_report_dead_links_false/conf.py b/tests/doc_test/doc_report_dead_links_false/conf.py
index 813f445a4..ae1448dee 100644
--- a/tests/doc_test/doc_report_dead_links_false/conf.py
+++ b/tests/doc_test/doc_report_dead_links_false/conf.py
@@ -4,10 +4,34 @@
plantuml_output_format = "svg"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
suppress_warnings = ["needs.link_outgoing"]
diff --git a/tests/doc_test/doc_report_dead_links_true/conf.py b/tests/doc_test/doc_report_dead_links_true/conf.py
index 91467f963..e114d9518 100644
--- a/tests/doc_test/doc_report_dead_links_true/conf.py
+++ b/tests/doc_test/doc_report_dead_links_true/conf.py
@@ -4,10 +4,34 @@
plantuml_output_format = "svg"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_extra_links = [
diff --git a/tests/doc_test/doc_role_need_max_title_length/conf.py b/tests/doc_test/doc_role_need_max_title_length/conf.py
index 46b0b1685..11f882b66 100644
--- a/tests/doc_test/doc_role_need_max_title_length/conf.py
+++ b/tests/doc_test/doc_role_need_max_title_length/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_role_need_template = "[{id}] {title} ({status}) {type_name}/{type} - {tags} - {links} - {links_back} - {content}"
diff --git a/tests/doc_test/doc_role_need_max_title_length_unlimited/conf.py b/tests/doc_test/doc_role_need_max_title_length_unlimited/conf.py
index 23dec017c..0a85db025 100644
--- a/tests/doc_test/doc_role_need_max_title_length_unlimited/conf.py
+++ b/tests/doc_test/doc_role_need_max_title_length_unlimited/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_role_need_template = "[{id}] {title} ({status}) {type_name}/{type} - {tags} - {links} - {links_back} - {content}"
diff --git a/tests/doc_test/doc_role_need_template/conf.py b/tests/doc_test/doc_role_need_template/conf.py
index 4d15bdb0d..fa86a8027 100644
--- a/tests/doc_test/doc_role_need_template/conf.py
+++ b/tests/doc_test/doc_role_need_template/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_role_need_template = "[{id}] {title} ({status}) {type_name}/{type} - {tags} - {links} - {links_back} - {content}"
diff --git a/tests/doc_test/doc_style_blank/conf.py b/tests/doc_test/doc_style_blank/conf.py
index ef8a46842..959f7f07b 100644
--- a/tests/doc_test/doc_style_blank/conf.py
+++ b/tests/doc_test/doc_style_blank/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_css = "blank.css"
diff --git a/tests/doc_test/doc_style_custom/conf.py b/tests/doc_test/doc_style_custom/conf.py
index 80485dc17..ed2820a9b 100644
--- a/tests/doc_test/doc_style_custom/conf.py
+++ b/tests/doc_test/doc_style_custom/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_css = os.path.join(os.path.dirname(__file__), "my_custom.css")
diff --git a/tests/doc_test/doc_style_modern/conf.py b/tests/doc_test/doc_style_modern/conf.py
index 68f00c54c..51fd8c41c 100644
--- a/tests/doc_test/doc_style_modern/conf.py
+++ b/tests/doc_test/doc_style_modern/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_css = "modern.css"
diff --git a/tests/doc_test/doc_style_unknown/conf.py b/tests/doc_test/doc_style_unknown/conf.py
index ec0cfafe9..8ee6fe502 100644
--- a/tests/doc_test/doc_style_unknown/conf.py
+++ b/tests/doc_test/doc_style_unknown/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_css = "UNKNOWN.css"
diff --git a/tests/doc_test/external_doc/conf.py b/tests/doc_test/external_doc/conf.py
index e38367471..c884b37f9 100644
--- a/tests/doc_test/external_doc/conf.py
+++ b/tests/doc_test/external_doc/conf.py
@@ -10,11 +10,41 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
test_dir = os.path.dirname(__file__)
@@ -23,7 +53,11 @@
# needs_external_needs = [{"base_url": f"file://{test_dir}", "json_url": f"file://{test_json}", "id_prefix": "ext_"}]
needs_external_needs = [
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "EXT_"}
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "EXT_",
+ }
]
# Needed to export really ALL needs. The default entry would filter out all needs coming from external
diff --git a/tests/doc_test/filter_doc/conf.py b/tests/doc_test/filter_doc/conf.py
index 717640d49..787367095 100644
--- a/tests/doc_test/filter_doc/conf.py
+++ b/tests/doc_test/filter_doc/conf.py
@@ -8,13 +8,55 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
- {"directive": "user", "title": "User", "prefix": "U_", "color": "#777777", "style": "node"},
- {"directive": "action", "title": "Action", "prefix": "A_", "color": "#FFCC00", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
+ {
+ "directive": "user",
+ "title": "User",
+ "prefix": "U_",
+ "color": "#777777",
+ "style": "node",
+ },
+ {
+ "directive": "action",
+ "title": "Action",
+ "prefix": "A_",
+ "color": "#FFCC00",
+ "style": "node",
+ },
]
needs_extra_links = [
diff --git a/tests/doc_test/generic_doc/conf.py b/tests/doc_test/generic_doc/conf.py
index 21eab6d52..1b74e151a 100644
--- a/tests/doc_test/generic_doc/conf.py
+++ b/tests/doc_test/generic_doc/conf.py
@@ -1,8 +1,32 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/import_doc/conf.py b/tests/doc_test/import_doc/conf.py
index fcbde4dd9..5ddaeb329 100644
--- a/tests/doc_test/import_doc/conf.py
+++ b/tests/doc_test/import_doc/conf.py
@@ -5,11 +5,41 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_template = """
diff --git a/tests/doc_test/import_doc_empty/conf.py b/tests/doc_test/import_doc_empty/conf.py
index 45270f660..7e12482c6 100644
--- a/tests/doc_test/import_doc_empty/conf.py
+++ b/tests/doc_test/import_doc_empty/conf.py
@@ -3,11 +3,41 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_template = """
diff --git a/tests/doc_test/import_doc_invalid/conf.py b/tests/doc_test/import_doc_invalid/conf.py
index 45270f660..7e12482c6 100644
--- a/tests/doc_test/import_doc_invalid/conf.py
+++ b/tests/doc_test/import_doc_invalid/conf.py
@@ -3,11 +3,41 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_template = """
diff --git a/tests/doc_test/need_constraints/conf.py b/tests/doc_test/need_constraints/conf.py
index b33483a78..ab7f10295 100644
--- a/tests/doc_test/need_constraints/conf.py
+++ b/tests/doc_test/need_constraints/conf.py
@@ -4,14 +4,42 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_external_needs = [
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "ext_"}
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "ext_",
+ }
]
@@ -39,7 +67,11 @@ def setup(app):
add_warning(app, "api_warning_filter", filter_string="status == 'example_2'")
add_warning(app, "api_warning_func", custom_warning_func)
- add_warning(app, "invalid_status", "status not in ['open', 'closed', 'done', 'example_2', 'example_3']")
+ add_warning(
+ app,
+ "invalid_status",
+ "status not in ['open', 'closed', 'done', 'example_2', 'example_3']",
+ )
# Needs option to set True or False to raise sphinx-warning for each not passed warning check
diff --git a/tests/doc_test/need_constraints_failed/conf.py b/tests/doc_test/need_constraints_failed/conf.py
index 31228134f..7430e40f2 100644
--- a/tests/doc_test/need_constraints_failed/conf.py
+++ b/tests/doc_test/need_constraints_failed/conf.py
@@ -3,14 +3,42 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_external_needs = [
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "ext_"}
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "ext_",
+ }
]
@@ -38,7 +66,11 @@ def setup(app):
add_warning(app, "api_warning_filter", filter_string="status == 'example_2'")
add_warning(app, "api_warning_func", custom_warning_func)
- add_warning(app, "invalid_status", "status not in ['open', 'closed', 'done', 'example_2', 'example_3']")
+ add_warning(
+ app,
+ "invalid_status",
+ "status not in ['open', 'closed', 'done', 'example_2', 'example_3']",
+ )
# Needs option to set True or False to raise sphinx-warning for each not passed warning check
diff --git a/tests/doc_test/needextract_with_nested_needs/conf.py b/tests/doc_test/needextract_with_nested_needs/conf.py
index df3fe57f8..7556c0c4e 100644
--- a/tests/doc_test/needextract_with_nested_needs/conf.py
+++ b/tests/doc_test/needextract_with_nested_needs/conf.py
@@ -3,8 +3,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/needpie_with_zero_needs/conf.py b/tests/doc_test/needpie_with_zero_needs/conf.py
index df3fe57f8..7556c0c4e 100644
--- a/tests/doc_test/needpie_with_zero_needs/conf.py
+++ b/tests/doc_test/needpie_with_zero_needs/conf.py
@@ -3,8 +3,32 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/non_exists_file_import/conf.py b/tests/doc_test/non_exists_file_import/conf.py
index 45270f660..7e12482c6 100644
--- a/tests/doc_test/non_exists_file_import/conf.py
+++ b/tests/doc_test/non_exists_file_import/conf.py
@@ -3,11 +3,41 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_template = """
diff --git a/tests/doc_test/parallel_doc/conf.py b/tests/doc_test/parallel_doc/conf.py
index 03f708826..f6f03d869 100644
--- a/tests/doc_test/parallel_doc/conf.py
+++ b/tests/doc_test/parallel_doc/conf.py
@@ -1,10 +1,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_variants = {"change_author": "assignee == 'Randy Duodu'"}
needs_variant_options = ["status", "author"]
diff --git a/tests/doc_test/role_need_doc/conf.py b/tests/doc_test/role_need_doc/conf.py
index a3d0a4e67..b64a2a601 100644
--- a/tests/doc_test/role_need_doc/conf.py
+++ b/tests/doc_test/role_need_doc/conf.py
@@ -8,11 +8,41 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "req", "title": "Requirement", "prefix": "RE_", "color": "#BFD8D2", "style": "node"},
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "req",
+ "title": "Requirement",
+ "prefix": "RE_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
test_dir = os.path.dirname(__file__)
@@ -21,7 +51,11 @@
# needs_external_needs = [{"base_url": f"file://{test_dir}", "json_url": f"file://{test_json}", "id_prefix": "ext_"}]
needs_external_needs = [
- {"base_url": "http://my_company.com/docs/v1/", "json_path": "needs_test_small.json", "id_prefix": "EXT_"}
+ {
+ "base_url": "http://my_company.com/docs/v1/",
+ "json_path": "needs_test_small.json",
+ "id_prefix": "EXT_",
+ }
]
# Needed to export really ALL needs. The default entry would filter out all needs coming from external
diff --git a/tests/doc_test/service_doc/conf.py b/tests/doc_test/service_doc/conf.py
index b2a23705d..b931c94b1 100644
--- a/tests/doc_test/service_doc/conf.py
+++ b/tests/doc_test/service_doc/conf.py
@@ -3,10 +3,34 @@
extensions = ["sphinx_needs"]
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/unicode_support/conf.py b/tests/doc_test/unicode_support/conf.py
index 885bd47d6..814c929f3 100644
--- a/tests/doc_test/unicode_support/conf.py
+++ b/tests/doc_test/unicode_support/conf.py
@@ -3,8 +3,32 @@
needs_table_style = "TABLE"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
diff --git a/tests/doc_test/variant_doc/conf.py b/tests/doc_test/variant_doc/conf.py
index d94dd50ed..d78cd7913 100644
--- a/tests/doc_test/variant_doc/conf.py
+++ b/tests/doc_test/variant_doc/conf.py
@@ -8,10 +8,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_variants = {"change_author": "assignee == 'Randy Duodu'"}
needs_variant_options = ["status", "author", "links"]
diff --git a/tests/doc_test/variant_options/conf.py b/tests/doc_test/variant_options/conf.py
index 42108d4a1..1902a3923 100644
--- a/tests/doc_test/variant_options/conf.py
+++ b/tests/doc_test/variant_options/conf.py
@@ -8,10 +8,34 @@
needs_id_regex = "^[A-Za-z0-9_]"
needs_types = [
- {"directive": "story", "title": "User Story", "prefix": "US_", "color": "#BFD8D2", "style": "node"},
- {"directive": "spec", "title": "Specification", "prefix": "SP_", "color": "#FEDCD2", "style": "node"},
- {"directive": "impl", "title": "Implementation", "prefix": "IM_", "color": "#DF744A", "style": "node"},
- {"directive": "test", "title": "Test Case", "prefix": "TC_", "color": "#DCB239", "style": "node"},
+ {
+ "directive": "story",
+ "title": "User Story",
+ "prefix": "US_",
+ "color": "#BFD8D2",
+ "style": "node",
+ },
+ {
+ "directive": "spec",
+ "title": "Specification",
+ "prefix": "SP_",
+ "color": "#FEDCD2",
+ "style": "node",
+ },
+ {
+ "directive": "impl",
+ "title": "Implementation",
+ "prefix": "IM_",
+ "color": "#DF744A",
+ "style": "node",
+ },
+ {
+ "directive": "test",
+ "title": "Test Case",
+ "prefix": "TC_",
+ "color": "#DCB239",
+ "style": "node",
+ },
]
needs_variants = {"change_author": "assignee == 'Randy Duodu'"}
needs_variant_options = []
diff --git a/tests/no_mpl_tests.py b/tests/no_mpl_tests.py
index 95aaf0747..dfaeb30ef 100644
--- a/tests/no_mpl_tests.py
+++ b/tests/no_mpl_tests.py
@@ -3,7 +3,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_needbar"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_needbar"}],
+ indirect=True,
+)
def test_needbar(test_app):
"""Test the build fails correctly, if matplotlib is not installed."""
test_app.build()
@@ -11,7 +15,11 @@ def test_needbar(test_app):
assert expected in test_app._warning.getvalue()
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_needpie"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_needpie"}],
+ indirect=True,
+)
def test_needpie(test_app):
"""Test the build fails correctly, if matplotlib is not installed."""
test_app.build()
diff --git a/tests/test_add_sections.py b/tests/test_add_sections.py
index 77028bf84..4658beef8 100644
--- a/tests/test_add_sections.py
+++ b/tests/test_add_sections.py
@@ -4,7 +4,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/add_sections"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/add_sections"}],
+ indirect=True,
+)
def test_section_is_usable_in_filters(test_app):
app = test_app
app.builder.build_all()
diff --git a/tests/test_api_configuration.py b/tests/test_api_configuration.py
index 556c98887..c031f8e6e 100644
--- a/tests/test_api_configuration.py
+++ b/tests/test_api_configuration.py
@@ -14,7 +14,9 @@ def setup(app):
sys.modules["dummy_extension.dummy"] = dummy_extension
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/api_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "html", "srcdir": "doc_test/api_doc"}], indirect=True
+)
def test_api_get_types(test_app):
from sphinx_needs.api import get_need_types
@@ -24,7 +26,11 @@ def test_api_get_types(test_app):
assert set(need_types) == {"story", "spec", "impl", "test"}
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/api_doc_awesome"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/api_doc_awesome"}],
+ indirect=True,
+)
def test_api_add_type(test_app, snapshot):
from sphinx_needs.api import add_need_type
diff --git a/tests/test_api_usage_in_extension.py b/tests/test_api_usage_in_extension.py
index 1ff0dd801..2a434e8df 100644
--- a/tests/test_api_usage_in_extension.py
+++ b/tests/test_api_usage_in_extension.py
@@ -22,7 +22,9 @@ def after_config(app, config):
sys.modules["dummy_extension.dummy"] = dummy_extension
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/api_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "html", "srcdir": "doc_test/api_doc"}], indirect=True
+)
def test_api_configuration(test_app):
app = test_app
diff --git a/tests/test_arch.py b/tests/test_arch.py
index f17ec8887..e58389a30 100644
--- a/tests/test_arch.py
+++ b/tests/test_arch.py
@@ -3,7 +3,9 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/arch_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "html", "srcdir": "doc_test/arch_doc"}], indirect=True
+)
def test_doc_build_html(test_app):
app = test_app
app.build()
diff --git a/tests/test_basic_doc.py b/tests/test_basic_doc.py
index 3c12b8ac7..806d29147 100644
--- a/tests/test_basic_doc.py
+++ b/tests/test_basic_doc.py
@@ -31,7 +31,9 @@ def random_data_callback(request):
if re.match(r"/search/issues", request.path_url):
data = GITHUB_ISSUE_SEARCH_ANSWER
data["items"][0]["number"] = randrange(10000)
- elif re.match(r"/.+/issue/.+", request.path_url) or re.match(r"/.+/pulls/.+", request.path_url):
+ elif re.match(r"/.+/issue/.+", request.path_url) or re.match(
+ r"/.+/pulls/.+", request.path_url
+ ):
data = GITHUB_SPECIFIC_ISSUE_ANSWER
data["number"] = randrange(10000)
elif re.match(r"/search/commits", request.path_url):
@@ -49,7 +51,9 @@ def random_data_callback(request):
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_basic"}], indirect=True
+)
def test_build_html(test_app):
responses.add_callback(
responses.GET,
@@ -57,7 +61,9 @@ def test_build_html(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@@ -71,7 +77,11 @@ def test_build_html(test_app):
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/generic_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/generic_doc"}],
+ indirect=True,
+)
def test_build_html_parallel(test_app: Sphinx, snapshot_doctree):
responses.add_callback(
responses.GET,
@@ -79,7 +89,9 @@ def test_build_html_parallel(test_app: Sphinx, snapshot_doctree):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@@ -94,8 +106,14 @@ def test_build_html_parallel(test_app: Sphinx, snapshot_doctree):
assert app.env.get_doctree("index") == snapshot_doctree
-@pytest.mark.skipif(sys.platform == "win32", reason="assert fails on windows, need to fix later.")
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/generic_doc"}], indirect=True)
+@pytest.mark.skipif(
+ sys.platform == "win32", reason="assert fails on windows, need to fix later."
+)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/generic_doc"}],
+ indirect=True,
+)
def test_html_head_files(test_app):
app = test_app
app.builder.build_all()
@@ -120,7 +138,11 @@ def test_html_head_files(test_app):
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "singlehtml", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "singlehtml", "srcdir": "doc_test/doc_basic"}],
+ indirect=True,
+)
def test_build_singlehtml(test_app):
responses.add_callback(
responses.GET,
@@ -128,14 +150,20 @@ def test_build_singlehtml(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "latex", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "latex", "srcdir": "doc_test/doc_basic"}],
+ indirect=True,
+)
def test_build_latex(test_app):
responses.add_callback(
responses.GET,
@@ -143,14 +171,18 @@ def test_build_latex(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "epub", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "epub", "srcdir": "doc_test/doc_basic"}], indirect=True
+)
def test_build_epub(test_app):
responses.add_callback(
responses.GET,
@@ -158,14 +190,18 @@ def test_build_epub(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "json", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app", [{"buildername": "json", "srcdir": "doc_test/doc_basic"}], indirect=True
+)
def test_build_json(test_app):
responses.add_callback(
responses.GET,
@@ -173,14 +209,20 @@ def test_build_json(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@responses.activate
-@pytest.mark.parametrize("test_app", [{"buildername": "needs", "srcdir": "doc_test/doc_basic"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "needs", "srcdir": "doc_test/doc_basic"}],
+ indirect=True,
+)
def test_build_needs(test_app, snapshot):
responses.add_callback(
responses.GET,
@@ -188,7 +230,9 @@ def test_build_needs(test_app, snapshot):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
app = test_app
app.builder.build_all()
@@ -202,7 +246,13 @@ def test_build_needs(test_app, snapshot):
@responses.activate
@pytest.mark.parametrize(
"test_app",
- [{"buildername": "html", "srcdir": "doc_test/doc_basic", "confoverrides": {"needs_id_required": True}}],
+ [
+ {
+ "buildername": "html",
+ "srcdir": "doc_test/doc_basic",
+ "confoverrides": {"needs_id_required": True},
+ }
+ ],
indirect=True,
)
def test_id_required_build_html(test_app):
@@ -213,7 +263,11 @@ def test_id_required_build_html(test_app):
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET,
+ re.compile(r"https://avatars.githubusercontent.com/.*"),
+ body="",
+ )
app = test_app
app.builder.build_all()
@@ -231,7 +285,9 @@ def test_sphinx_api_build():
callback=random_data_callback,
content_type="application/json",
)
- responses.add(responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body="")
+ responses.add(
+ responses.GET, re.compile(r"https://avatars.githubusercontent.com/.*"), body=""
+ )
temp_dir = tempfile.mkdtemp()
src_dir = os.path.join(os.path.dirname(__file__), "doc_test", "doc_basic")
diff --git a/tests/test_broken_doc.py b/tests/test_broken_doc.py
index 4458d69ce..d203541e0 100644
--- a/tests/test_broken_doc.py
+++ b/tests/test_broken_doc.py
@@ -3,7 +3,11 @@
from sphinx_needs.api.need import NeedsDuplicatedId
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/broken_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/broken_doc"}],
+ indirect=True,
+)
def test_doc_build_html(test_app):
with pytest.raises(NeedsDuplicatedId):
app = test_app
diff --git a/tests/test_broken_links.py b/tests/test_broken_links.py
index 0bc1613b9..37944db51 100644
--- a/tests/test_broken_links.py
+++ b/tests/test_broken_links.py
@@ -3,7 +3,9 @@
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/broken_links", "no_plantuml": True}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/broken_links", "no_plantuml": True}],
+ indirect=True,
)
def test_doc_build_html(test_app):
app = test_app
diff --git a/tests/test_broken_statuses.py b/tests/test_broken_statuses.py
index dcb09237d..4efc7abff 100644
--- a/tests/test_broken_statuses.py
+++ b/tests/test_broken_statuses.py
@@ -3,7 +3,11 @@
from sphinx_needs.api.need import NeedsStatusNotAllowed
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/broken_statuses"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/broken_statuses"}],
+ indirect=True,
+)
def test_doc_build_html(test_app):
with pytest.raises(NeedsStatusNotAllowed):
app = test_app
diff --git a/tests/test_broken_syntax_doc.py b/tests/test_broken_syntax_doc.py
index 162da581a..33552793f 100644
--- a/tests/test_broken_syntax_doc.py
+++ b/tests/test_broken_syntax_doc.py
@@ -3,7 +3,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/broken_syntax_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/broken_syntax_doc"}],
+ indirect=True,
+)
def test_doc_broken_syntax(test_app):
app = test_app
diff --git a/tests/test_broken_tags.py b/tests/test_broken_tags.py
index 8a1d6896f..631c0b623 100644
--- a/tests/test_broken_tags.py
+++ b/tests/test_broken_tags.py
@@ -5,7 +5,11 @@
from sphinx_needs.api.need import NeedsTagNotAllowed
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/broken_tags"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/broken_tags"}],
+ indirect=True,
+)
def test_doc_build_html(test_app):
with pytest.raises(NeedsTagNotAllowed):
app = test_app
@@ -15,7 +19,11 @@ def test_doc_build_html(test_app):
assert "SP_TOO_003" in html
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/broken_tags_2"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/broken_tags_2"}],
+ indirect=True,
+)
def test_doc_build_html_unneeded_chars(test_app):
"""
Test for https://github.com/useblocks/sphinxcontrib-needs/issues/36
diff --git a/tests/test_clean_log.py b/tests/test_clean_log.py
index 327e8adcf..af6f25036 100644
--- a/tests/test_clean_log.py
+++ b/tests/test_clean_log.py
@@ -5,9 +5,13 @@
class CleanLogTestCase(unittest.TestCase):
def test_external_needs_clean_log(self):
- self.assertEqual(clean_log("http://user:password@host.url/"), "http://****:****@host.url/")
self.assertEqual(
- clean_log("Downloading file from https://daniel:my_password@server.com now"),
+ clean_log("http://user:password@host.url/"), "http://****:****@host.url/"
+ )
+ self.assertEqual(
+ clean_log(
+ "Downloading file from https://daniel:my_password@server.com now"
+ ),
"Downloading file from https://****:****@server.com now",
)
self.assertEqual(
diff --git a/tests/test_complex_builders.py b/tests/test_complex_builders.py
index 3c913b2c7..c937df6d4 100644
--- a/tests/test_complex_builders.py
+++ b/tests/test_complex_builders.py
@@ -10,7 +10,14 @@
@pytest.mark.parametrize(
"test_app",
- [{"buildername": "latex", "srcdir": "doc_test/doc_basic_latex", "warning": True, "parallel": 2}],
+ [
+ {
+ "buildername": "latex",
+ "srcdir": "doc_test/doc_basic_latex",
+ "warning": True,
+ "parallel": 2,
+ }
+ ],
indirect=True,
)
def test_doc_complex_latex(test_app):
@@ -23,7 +30,14 @@ def test_doc_complex_latex(test_app):
@pytest.mark.parametrize(
"test_app",
- [{"buildername": "singlehtml", "srcdir": "doc_test/doc_basic_latex", "warning": True, "parallel": 2}],
+ [
+ {
+ "buildername": "singlehtml",
+ "srcdir": "doc_test/doc_basic_latex",
+ "warning": True,
+ "parallel": 2,
+ }
+ ],
indirect=True,
)
def test_doc_complex_singlehtml(test_app):
diff --git a/tests/test_doc_build_latex.py b/tests/test_doc_build_latex.py
index a8e763ee0..11b3a89e8 100644
--- a/tests/test_doc_build_latex.py
+++ b/tests/test_doc_build_latex.py
@@ -3,7 +3,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "latex", "srcdir": "doc_test/doc_build_latex"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "latex", "srcdir": "doc_test/doc_build_latex"}],
+ indirect=True,
+)
def test_doc_build_latex(test_app):
app = test_app
diff --git a/tests/test_dynamic_functions.py b/tests/test_dynamic_functions.py
index 181cd2256..59d0a7978 100644
--- a/tests/test_dynamic_functions.py
+++ b/tests/test_dynamic_functions.py
@@ -5,7 +5,9 @@
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_dynamic_functions"}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_dynamic_functions"}],
+ indirect=True,
)
def test_doc_dynamic_functions(test_app):
app = test_app
@@ -13,22 +15,42 @@ def test_doc_dynamic_functions(test_app):
html = Path(app.outdir, "index.html").read_text()
assert "This is id SP_TOO_001" in html
- assert sum(1 for _ in re.finditer('test2', html)) == 2
- assert sum(1 for _ in re.finditer('test', html)) == 2
- assert sum(1 for _ in re.finditer('my_tag', html)) == 1
+ assert (
+ sum(1 for _ in re.finditer('test2', html)) == 2
+ )
+ assert (
+ sum(1 for _ in re.finditer('test', html)) == 2
+ )
+ assert (
+ sum(1 for _ in re.finditer('my_tag', html)) == 1
+ )
- assert sum(1 for _ in re.finditer('test_4a', html)) == 1
- assert sum(1 for _ in re.finditer('test_4b', html)) == 1
- assert sum(1 for _ in re.finditer('TEST_4', html)) == 2
+ assert (
+ sum(1 for _ in re.finditer('test_4a', html))
+ == 1
+ )
+ assert (
+ sum(1 for _ in re.finditer('test_4b', html))
+ == 1
+ )
+ assert (
+ sum(1 for _ in re.finditer('TEST_4', html)) == 2
+ )
- assert sum(1 for _ in re.finditer('TEST_5', html)) == 2
+ assert (
+ sum(1 for _ in re.finditer('TEST_5', html)) == 2
+ )
assert "Test output of need TEST_3. args:" in html
assert 'link' in html
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_df_calc_sum"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_df_calc_sum"}],
+ indirect=True,
+)
def test_doc_df_calc_sum(test_app):
app = test_app
app.build()
@@ -39,7 +61,9 @@ def test_doc_df_calc_sum(test_app):
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_df_check_linked_values"}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_df_check_linked_values"}],
+ indirect=True,
)
def test_doc_df_linked_values(test_app):
app = test_app
@@ -51,7 +75,9 @@ def test_doc_df_linked_values(test_app):
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_df_user_functions"}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_df_user_functions"}],
+ indirect=True,
)
def test_doc_df_user_functions(test_app):
app = test_app
diff --git a/tests/test_export_id.py b/tests/test_export_id.py
index dcdb7152e..19f4beccc 100644
--- a/tests/test_export_id.py
+++ b/tests/test_export_id.py
@@ -6,7 +6,11 @@
from syrupy.filters import props
-@pytest.mark.parametrize("test_app", [{"buildername": "needs", "srcdir": "doc_test/doc_export_id"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "needs", "srcdir": "doc_test/doc_export_id"}],
+ indirect=True,
+)
def test_export_id(test_app, snapshot):
app = test_app
app.build()
@@ -14,7 +18,11 @@ def test_export_id(test_app, snapshot):
assert needs_data == snapshot(exclude=props("created"))
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_export_id"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_export_id"}],
+ indirect=True,
+)
def test_export_id_html(test_app):
app = test_app
app.build()
diff --git a/tests/test_external.py b/tests/test_external.py
index 9169cf431..de705d8e2 100644
--- a/tests/test_external.py
+++ b/tests/test_external.py
@@ -5,7 +5,11 @@
from syrupy.filters import props
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/external_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/external_doc"}],
+ indirect=True,
+)
def test_external_html(test_app):
app = test_app
app.build()
@@ -17,11 +21,16 @@ def test_external_html(test_app):
assert (
'Test need ref: EXT_TEST_01
' in html
+ ' href="http://my_company.com/docs/v1/index.html#TEST_01">EXT_TEST_01
'
+ in html
)
-@pytest.mark.parametrize("test_app", [{"buildername": "needs", "srcdir": "doc_test/external_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "needs", "srcdir": "doc_test/external_doc"}],
+ indirect=True,
+)
def test_external_json(test_app, snapshot):
app = test_app
app.build()
@@ -30,7 +39,11 @@ def test_external_json(test_app, snapshot):
assert needs == snapshot(exclude=props("created"))
-@pytest.mark.parametrize("test_app", [{"buildername": "needs", "srcdir": "doc_test/external_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "needs", "srcdir": "doc_test/external_doc"}],
+ indirect=True,
+)
def test_external_needs_warnings(test_app):
import os
import subprocess
@@ -40,8 +53,11 @@ def test_external_needs_warnings(test_app):
srcdir = Path(app.srcdir)
out_dir = os.path.join(srcdir, "_build")
- out = subprocess.run(["sphinx-build", "-b", "html", srcdir, out_dir], capture_output=True)
+ out = subprocess.run(
+ ["sphinx-build", "-b", "html", srcdir, out_dir], capture_output=True
+ )
assert (
"WARNING: Couldn't create need EXT_TEST_03. Reason: The need-type (i.e. `ask`) is not"
- " set in the project's 'need_types' configuration in conf.py." in out.stderr.decode("utf-8")
+ " set in the project's 'need_types' configuration in conf.py."
+ in out.stderr.decode("utf-8")
)
diff --git a/tests/test_extra_links.py b/tests/test_extra_links.py
index b57088989..e089d38f0 100644
--- a/tests/test_extra_links.py
+++ b/tests/test_extra_links.py
@@ -3,7 +3,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_extra_links"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_extra_links"}],
+ indirect=True,
+)
def test_extra_links_html(test_app):
app = test_app
app.build()
@@ -16,11 +20,17 @@ def test_extra_links_html(test_app):
# Check for correct dead_links handling
assert 'DEAD_LINK_ALLOWED' in html
- assert 'DEAD_LINK_NOT_ALLOWED' in html
+ assert (
+ 'DEAD_LINK_NOT_ALLOWED' in html
+ )
assert 'REQ_005.invalid' in html
-@pytest.mark.parametrize("test_app", [{"buildername": "latex", "srcdir": "doc_test/doc_extra_links"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "latex", "srcdir": "doc_test/doc_extra_links"}],
+ indirect=True,
+)
def test_extra_links_latex(test_app):
app = test_app
app.build()
diff --git a/tests/test_extra_options.py b/tests/test_extra_options.py
index 4d00b6ecc..4e6921887 100644
--- a/tests/test_extra_options.py
+++ b/tests/test_extra_options.py
@@ -4,7 +4,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/extra_options"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/extra_options"}],
+ indirect=True,
+)
def test_custom_attributes_appear(test_app):
app = test_app
app.build()
@@ -37,6 +41,8 @@ def test_custom_attributes_appear(test_app):
assert "R_12346" not in tables[3]
# Need list should only have component B requirements
- items = re.findall('(' in html_5
+ 'href="#CHILD_1_STORY" title="STORY_PARENT">CHILD_1_STORY'
+ in html_5
)
assert (
'' in html_5
+ 'href="#CHILD_1_STORY" title="CHILD_2_STORY">CHILD_1_STORY'
+ in html_5
)
html_6 = Path(app.outdir, "filter_no_needs.html").read_text()
diff --git a/tests/test_github_issues.py b/tests/test_github_issues.py
index 717f37e5f..4c8862136 100644
--- a/tests/test_github_issues.py
+++ b/tests/test_github_issues.py
@@ -5,7 +5,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_github_issue_44"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_github_issue_44"}],
+ indirect=True,
+)
def test_doc_github_44(test_app):
"""
https://github.com/useblocks/sphinxcontrib-needs/issues/44
@@ -17,7 +21,9 @@ def test_doc_github_44(test_app):
app = test_app
output = subprocess.run(
- ["sphinx-build", "-a", "-E", "-b", "html", app.srcdir, app.outdir], check=True, capture_output=True
+ ["sphinx-build", "-a", "-E", "-b", "html", app.srcdir, app.outdir],
+ check=True,
+ capture_output=True,
)
# app.build() Uncomment, if build should stop on breakpoints
@@ -34,7 +40,11 @@ def test_doc_github_44(test_app):
]
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_github_issue_61"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_github_issue_61"}],
+ indirect=True,
+)
def test_doc_github_61(test_app):
"""
Test for https://github.com/useblocks/sphinxcontrib-needs/issues/61
@@ -58,7 +68,9 @@ def test_doc_github_61(test_app):
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_github_issue_160"}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_github_issue_160"}],
+ indirect=True,
)
def test_doc_github_160(test_app):
app = test_app
diff --git a/tests/test_global_options.py b/tests/test_global_options.py
index cf45c5ab8..9829f1a7c 100644
--- a/tests/test_global_options.py
+++ b/tests/test_global_options.py
@@ -3,7 +3,11 @@
import pytest
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_global_options"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_global_options"}],
+ indirect=True,
+)
def test_doc_global_option(test_app):
app = test_app
app.build()
diff --git a/tests/test_import.py b/tests/test_import.py
index e5bd1b760..0fb73e9ad 100644
--- a/tests/test_import.py
+++ b/tests/test_import.py
@@ -6,7 +6,11 @@
from syrupy.filters import props
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/import_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/import_doc"}],
+ indirect=True,
+)
def test_import_json(test_app):
app = test_app
app.build()
@@ -40,7 +44,9 @@ def test_import_json(test_app):
assert "small_rel_path_TEST_01" in rel_path_import_html
# Check deprecated relative path import based on conf.py
- deprec_rel_path_import_html = Path(app.outdir, "subdoc/deprecated_rel_path_import.html").read_text()
+ deprec_rel_path_import_html = Path(
+ app.outdir, "subdoc/deprecated_rel_path_import.html"
+ ).read_text()
assert "small_depr_rel_path_TEST_01" in deprec_rel_path_import_html
warning = app._warning
@@ -48,7 +54,11 @@ def test_import_json(test_app):
assert "Deprecation warning:" in warnings
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/import_doc_invalid"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/import_doc_invalid"}],
+ indirect=True,
+)
def test_json_schema_console_check(test_app):
"""Checks the console output for hints about json schema validation errors"""
import os
@@ -58,12 +68,18 @@ def test_json_schema_console_check(test_app):
srcdir = Path(app.srcdir)
out_dir = os.path.join(srcdir, "_build")
- out = subprocess.run(["sphinx-build", "-b", "html", srcdir, out_dir], capture_output=True)
+ out = subprocess.run(
+ ["sphinx-build", "-b", "html", srcdir, out_dir], capture_output=True
+ )
assert "Schema validation errors detected" in str(out.stdout)
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/import_doc_invalid"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/import_doc_invalid"}],
+ indirect=True,
+)
def test_json_schema_file_check(test_app):
"""Checks that an invalid json-file gets normally still imported and is used as normal (if possible)"""
app = test_app
@@ -74,7 +90,11 @@ def test_json_schema_file_check(test_app):
assert "new_tag" in html
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/import_doc_empty"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/import_doc_empty"}],
+ indirect=True,
+)
def test_empty_file_check(test_app):
"""Checks that an empty needs.json throws an exception"""
app = test_app
@@ -85,7 +105,9 @@ def test_empty_file_check(test_app):
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/non_exists_file_import"}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/non_exists_file_import"}],
+ indirect=True,
)
def test_import_non_exists_json(test_app):
# Check non exists file import
@@ -97,7 +119,11 @@ def test_import_non_exists_json(test_app):
assert "non_exists_file_import" in err.args[0]
-@pytest.mark.parametrize("test_app", [{"buildername": "needs", "srcdir": "doc_test/import_doc"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "needs", "srcdir": "doc_test/import_doc"}],
+ indirect=True,
+)
def test_import_builder(test_app, snapshot):
app = test_app
app.build()
@@ -107,7 +133,9 @@ def test_import_builder(test_app, snapshot):
@pytest.mark.parametrize(
- "test_app", [{"buildername": "needs", "srcdir": "doc_test/doc_needimport_download_needs_json"}], indirect=True
+ "test_app",
+ [{"buildername": "needs", "srcdir": "doc_test/doc_needimport_download_needs_json"}],
+ indirect=True,
)
def test_needimport_needs_json_download(test_app, snapshot):
app = test_app
@@ -175,7 +203,12 @@ def test_needimport_needs_json_download(test_app, snapshot):
@pytest.mark.parametrize(
"test_app",
- [{"buildername": "needs", "srcdir": "doc_test/doc_needimport_download_needs_json_negative"}],
+ [
+ {
+ "buildername": "needs",
+ "srcdir": "doc_test/doc_needimport_download_needs_json_negative",
+ }
+ ],
indirect=True,
)
def test_needimport_needs_json_download_negative(test_app):
@@ -210,11 +243,16 @@ def test_needimport_needs_json_download_negative(test_app):
with requests_mock.Mocker() as m:
# test with invalid url
- m.get("http://my_wrong_name_company.com/docs/v1/remote-needs.json", json=remote_json)
+ m.get(
+ "http://my_wrong_name_company.com/docs/v1/remote-needs.json",
+ json=remote_json,
+ )
src_dir = Path(app.srcdir)
out_dir = Path(app.outdir)
- output = subprocess.run(["sphinx-build", "-M", "html", src_dir, out_dir], capture_output=True)
+ output = subprocess.run(
+ ["sphinx-build", "-M", "html", src_dir, out_dir], capture_output=True
+ )
assert (
"NeedimportException: Getting http://my_wrong_name_company.com/docs/v1/remote-needs.json didn't work."
in output.stderr.decode("utf-8")
diff --git a/tests/test_jinja_content_option.py b/tests/test_jinja_content_option.py
index f9cd5f508..dbc03913e 100644
--- a/tests/test_jinja_content_option.py
+++ b/tests/test_jinja_content_option.py
@@ -4,7 +4,9 @@
@pytest.mark.parametrize(
- "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_need_jinja_content"}], indirect=True
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_need_jinja_content"}],
+ indirect=True,
)
def test_doc_need_jinja_content(test_app):
app = test_app
diff --git a/tests/test_layouts.py b/tests/test_layouts.py
index 89097855f..bed530dca 100644
--- a/tests/test_layouts.py
+++ b/tests/test_layouts.py
@@ -3,7 +3,11 @@
from tests.util import extract_needs_from_html
-@pytest.mark.parametrize("test_app", [{"buildername": "html", "srcdir": "doc_test/doc_layout"}], indirect=True)
+@pytest.mark.parametrize(
+ "test_app",
+ [{"buildername": "html", "srcdir": "doc_test/doc_layout"}],
+ indirect=True,
+)
def test_doc_build_html(test_app):
app = test_app
app.build()
@@ -17,7 +21,8 @@ def test_doc_build_html(test_app):
assert len(needs) == 6
assert (
- 'author: some author' in html
+ 'author: some author'
+ in html
)
assert '