Skip to content

Commit

Permalink
🔧 Add better typing for extra_links config variable (#1131)
Browse files Browse the repository at this point in the history
To detail all possible dict keys
  • Loading branch information
chrisjsewell committed Feb 28, 2024
1 parent 63e1169 commit 166a0e3
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 26 deletions.
37 changes: 28 additions & 9 deletions sphinx_needs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

if TYPE_CHECKING:
from sphinx.util.logging import SphinxLoggerAdapter
from typing_extensions import Required

from sphinx_needs.data import NeedsInfoType

Expand Down Expand Up @@ -115,6 +116,31 @@ class ExternalSource(TypedDict, total=False):
"""


class LinkOptionsType(TypedDict, total=False):
"""Options for links between needs"""

option: Required[str]
"""The name of the link option"""
incoming: str
"""The incoming link title"""
outgoing: str
"""The outgoing link title"""
copy: bool
"""Copy to common links data. Default: True"""
color: str
"""Used for needflow. Default: #000000"""
style: str
"""Used for needflow. Default: solid"""
style_part: str
"""Used for needflow. Default: '[dotted]'"""
style_start: str
"""Used for needflow. Default: '-'"""
style_end: str
"""Used for needflow. Default: '->'"""
allow_dead_links: bool
"""If True, add a 'forbidden' class to dead links"""


@dataclass
class NeedsSphinxConfig:
"""A wrapper around the Sphinx configuration,
Expand Down Expand Up @@ -291,17 +317,10 @@ def __setattr__(self, name: str, value: Any) -> None:
default="→\xa0", metadata={"rebuild": "html", "types": (str,)}
)
"""Prefix for need_part output in tables"""
extra_links: list[dict[str, Any]] = field(
extra_links: list[LinkOptionsType] = 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)
* incoming
* copy_link (copy to common links data. Default: True)
* color (used for needflow. Default: #000000)
Example: [{"name": "blocks, "incoming": "is blocked by", "copy_link": True, "color": "#ffcc00"}]
"""
"""List of additional link types between needs"""
report_dead_links: bool = field(
default=True, metadata={"rebuild": "html", "types": (bool,)}
)
Expand Down
20 changes: 8 additions & 12 deletions sphinx_needs/directives/needflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,8 @@ def process_needflow(
else:
comment = ""

if link_type.get("style_part"):
link_style = "[{style}]".format(
style=link_type["style_part"]
)
if _style_part := link_type.get("style_part"):
link_style = f"[{_style_part}]"
else:
link_style = "[dotted]"
else:
Expand All @@ -414,10 +412,8 @@ def process_needflow(
else:
comment = ""

if link_type.get("style"):
link_style = "[{style}]".format(
style=link_type["style"]
)
if _style := link_type.get("style"):
link_style = f"[{_style}]"
else:
link_style = ""

Expand All @@ -429,13 +425,13 @@ def process_needflow(
]:
continue

if link_type.get("style_start"):
style_start = link_type["style_start"]
if _style_start := link_type.get("style_start"):
style_start = _style_start
else:
style_start = "-"

if link_type.get("style_end"):
style_end = link_type["style_end"]
if _style_end := link_type.get("style_end"):
style_end = _style_end
else:
style_end = "->"

Expand Down
4 changes: 2 additions & 2 deletions sphinx_needs/needs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
build_needs_json,
build_needumls_pumls,
)
from sphinx_needs.config import NEEDS_CONFIG, NeedsSphinxConfig
from sphinx_needs.config import NEEDS_CONFIG, LinkOptionsType, NeedsSphinxConfig
from sphinx_needs.data import SphinxNeedsData, merge_data
from sphinx_needs.defaults import (
LAYOUTS,
Expand Down Expand Up @@ -518,7 +518,7 @@ def prepare_env(app: Sphinx, env: BuildEnvironment, _docname: str) -> None:

# The default link name. Must exist in all configurations. Therefore we set it here
# for the user.
common_links = []
common_links: list[LinkOptionsType] = []
link_types = needs_config.extra_links
basic_link_type_found = False
parent_needs_link_type_found = False
Expand Down
2 changes: 1 addition & 1 deletion sphinx_needs/roles/need_outgoing.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def process_need_outgoing(
# add a CSS class for disallowed unknown links
# note a warning is already emitted when validating the needs list
# so we don't need to do it here
if not link_lookup.get(link_type, {}).get("allow_dead_links", False):
if not link_lookup.get(link_type, {}).get("allow_dead_links", False): # type: ignore
dead_link_para.attributes["classes"].append("forbidden")

# If we have several links, we add an empty text between them
Expand Down
4 changes: 2 additions & 2 deletions sphinx_needs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from jinja2 import Environment, Template
from sphinx.application import BuildEnvironment, Sphinx

from sphinx_needs.config import NeedsSphinxConfig
from sphinx_needs.config import LinkOptionsType, NeedsSphinxConfig
from sphinx_needs.data import NeedsInfoType, SphinxNeedsData
from sphinx_needs.defaults import NEEDS_PROFILING
from sphinx_needs.logging import get_logger
Expand Down Expand Up @@ -279,7 +279,7 @@ def rstjinja(app: Sphinx, docname: str, source: list[str]) -> None:


def import_prefix_link_edit(
needs: dict[str, Any], id_prefix: str, needs_extra_links: list[dict[str, Any]]
needs: dict[str, Any], id_prefix: str, needs_extra_links: list[LinkOptionsType]
) -> None:
"""
Changes existing links to support given prefix.
Expand Down

0 comments on commit 166a0e3

Please sign in to comment.