diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e15936d..54a78bb 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -64,6 +64,7 @@ jobs: fail-fast: false matrix: tox_env: + - type - dev - readme steps: diff --git a/src/pipdeptree/_discovery.py b/src/pipdeptree/_discovery.py index 591bb35..1cce91e 100644 --- a/src/pipdeptree/_discovery.py +++ b/src/pipdeptree/_discovery.py @@ -2,12 +2,6 @@ from __future__ import annotations from typing import TYPE_CHECKING -try: # noqa: SIM105 - from pip._internal.operations.freeze import FrozenRequirement # noqa: F401 -except ImportError: - pass # type: ignore[attr-defined, no-redef] - - if TYPE_CHECKING: from pip._vendor.pkg_resources import DistInfoDistribution diff --git a/src/pipdeptree/_render/__init__.py b/src/pipdeptree/_render/__init__.py index bcbc30b..da3e058 100644 --- a/src/pipdeptree/_render/__init__.py +++ b/src/pipdeptree/_render/__init__.py @@ -10,9 +10,10 @@ from .text import render_text if TYPE_CHECKING: from pipdeptree._cli import Options + from pipdeptree._models import PackageDAG -def render(options: Options, tree: PackageDAG) -> None: # noqa: F821 +def render(options: Options, tree: PackageDAG) -> None: if options.json: print(render_json(tree)) # noqa: T201 elif options.json_tree: @@ -20,6 +21,7 @@ def render(options: Options, tree: PackageDAG) -> None: # noqa: F821 elif options.mermaid: print(render_mermaid(tree)) # noqa: T201 elif options.output_format: + assert options.graph_output is not None # noqa: S101 render_graphviz(tree, output_format=options.graph_output, reverse=options.reverse) else: render_text(tree, options.depth, options.encoding_type, options.all, options.freeze) diff --git a/src/pipdeptree/_render/mermaid.py b/src/pipdeptree/_render/mermaid.py index 1d96db4..f5b52c7 100644 --- a/src/pipdeptree/_render/mermaid.py +++ b/src/pipdeptree/_render/mermaid.py @@ -1,23 +1,15 @@ from __future__ import annotations from textwrap import dedent -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Final from pipdeptree._models import ReversedPackageDAG if TYPE_CHECKING: from pipdeptree._models import PackageDAG - -def render_mermaid(tree: PackageDAG) -> str: # noqa: C901 - """ - Produce a Mermaid flowchart from the dependency graph. - - :param tree: dependency graph - """ - # List of reserved keywords in Mermaid that cannot be used as node names. - # See: https://github.com/mermaid-js/mermaid/issues/4182#issuecomment-1454787806 - reserved_ids: set[str] = { +_RESERVED_IDS: Final[frozenset[str]] = frozenset( + [ "C4Component", "C4Container", "C4Deployment", @@ -38,7 +30,19 @@ def render_mermaid(tree: PackageDAG) -> str: # noqa: C901 "linkStyle", "style", "subgraph", - } + ], +) + + +def render_mermaid(tree: PackageDAG) -> str: # noqa: C901 + """ + Produce a Mermaid flowchart from the dependency graph. + + :param tree: dependency graph + """ + # List of reserved keywords in Mermaid that cannot be used as node names. + # See: https://github.com/mermaid-js/mermaid/issues/4182#issuecomment-1454787806 + node_ids_map: dict[str, str] = {} def mermaid_id(key: str) -> str: @@ -48,7 +52,7 @@ def render_mermaid(tree: PackageDAG) -> str: # noqa: C901 if canonical_id is not None: return canonical_id # If the key is not a reserved keyword, return it as is, and update the map. - if key not in reserved_ids: + if key not in _RESERVED_IDS: node_ids_map[key] = key return key # If the key is a reserved keyword, append a number to it. diff --git a/tests/conftest.py b/tests/conftest.py index 0f26518..b38d427 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -33,7 +33,7 @@ def mock_pkgs() -> Callable[[MockGraph], Iterator[Mock]]: @pytest.fixture() def example_dag(mock_pkgs: Callable[[MockGraph], Iterator[Mock]]) -> PackageDAG: - packages = { + packages: MockGraph = { ("a", "3.4.0"): [("b", [(">=", "2.0.0")]), ("c", [(">=", "5.7.1")])], ("b", "2.3.1"): [("d", [(">=", "2.30"), ("<", "2.42")])], ("c", "5.10.0"): [("d", [(">=", "2.30")]), ("e", [(">=", "0.12.1")])], diff --git a/tests/render/test_mermaid.py b/tests/render/test_mermaid.py index 7706481..e59e352 100644 --- a/tests/render/test_mermaid.py +++ b/tests/render/test_mermaid.py @@ -4,7 +4,7 @@ from textwrap import dedent, indent from typing import TYPE_CHECKING, Callable, Iterator from pipdeptree._models import PackageDAG -from pipdeptree._render import render_mermaid +from pipdeptree._render.mermaid import render_mermaid if TYPE_CHECKING: from unittest.mock import Mock diff --git a/tests/render/test_text.py b/tests/render/test_text.py index 49d8245..220d9db 100644 --- a/tests/render/test_text.py +++ b/tests/render/test_text.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING import pytest -from pipdeptree._render import render_text +from pipdeptree._render.text import render_text if TYPE_CHECKING: from pipdeptree._models import PackageDAG diff --git a/tests/test_models.py b/tests/test_models.py index a3f30ce..8660682 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -65,7 +65,7 @@ def test_package_dag_filter(example_dag: PackageDAG) -> None: @pytest.fixture(scope="session") def t_fnmatch(mock_pkgs: Callable[[MockGraph], Iterator[Mock]]) -> Any: - graph = { + graph: MockGraph = { ("a.a", "1"): [("a.b", []), ("a.c", [])], ("a.b", "1"): [("a.c", [])], ("b.a", "1"): [("b.b", [])],