Skip to content

Commit

Permalink
Simplify loops (#267)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bernát Gábor <bgabor8@bloomberg.net>
  • Loading branch information
3 people committed Jul 15, 2023
1 parent 94682d2 commit e861826
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 47 deletions.
43 changes: 17 additions & 26 deletions src/pipdeptree/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def get_children(self, node_key: str) -> list[ReqPackage]:
node = self.get_node_as_parent(node_key)
return self._obj[node] if node else []

def filter_nodes(self, include: set[str] | None, exclude: set[str] | None) -> PackageDAG: # noqa: C901, PLR0912
def filter_nodes(self, include: set[str] | None, exclude: set[str] | None) -> PackageDAG: # noqa: C901
"""
Filters nodes in a graph by given parameters.
Expand Down Expand Up @@ -294,23 +294,20 @@ def filter_nodes(self, include: set[str] | None, exclude: set[str] | None) -> Pa
continue
if include is None or any(fnmatch(node.key, i) for i in include):
stack.append(node)
while True:
if len(stack) > 0:
n = stack.pop()
cldn = [c for c in self._obj[n] if not any(fnmatch(c.key, e) for e in exclude)]
m[n] = cldn
seen.add(n.key)
for c in cldn:
if c.key not in seen:
cld_node = self.get_node_as_parent(c.key)
if cld_node:
stack.append(cld_node)
else:
# It means there's no root node corresponding to the child node i.e.
# a dependency is missing
continue
else:
break
while stack:
n = stack.pop()
cldn = [c for c in self._obj[n] if not any(fnmatch(c.key, e) for e in exclude)]
m[n] = cldn
seen.add(n.key)
for c in cldn:
if c.key not in seen:
cld_node = self.get_node_as_parent(c.key)
if cld_node:
stack.append(cld_node)
else:
# It means there's no root node corresponding to the child node i.e.
# a dependency is missing
continue

return self.__class__(m)

Expand All @@ -335,10 +332,7 @@ def reverse(self) -> ReversedPackageDAG:
# if v is already added to the dict, then ensure that
# we are using the same object. This check is required
# as we're using array mutation
try:
node: ReqPackage = [p for p in m if p.key == v.key][0]
except IndexError: # noqa: PERF203
node = v
node: ReqPackage = next((p for p in m if p.key == v.key), v)
m[node].append(k.as_parent_of(v))
if k.key not in child_keys:
m[k.as_requirement()] = []
Expand Down Expand Up @@ -383,10 +377,7 @@ def reverse(self) -> PackageDAG: # type: ignore[override]
child_keys = {r.key for r in chain.from_iterable(self._obj.values())}
for k, vs in self._obj.items():
for v in vs:
try:
node = [p for p in m if p.key == v.key][0]
except IndexError: # noqa: PERF203
node = v.as_parent_of(None)
node = next((p for p in m if p.key == v.key), v.as_parent_of(None))
m[node].append(k) # type: ignore[arg-type]
if k.key not in child_keys:
m[k.dist] = []
Expand Down
28 changes: 10 additions & 18 deletions src/pipdeptree/_render/mermaid.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from textwrap import dedent
import itertools as it
from typing import TYPE_CHECKING, Final

from pipdeptree._models import ReversedPackageDAG
Expand Down Expand Up @@ -56,13 +56,12 @@ def mermaid_id(key: str) -> str:
node_ids_map[key] = key
return key
# If the key is a reserved keyword, append a number to it.
number = 0
while True:
for number in it.count():
new_id = f"{key}_{number}"
if new_id not in node_ids_map:
node_ids_map[key] = new_id
return new_id
number += 1
raise NotImplementedError

# Use a sets to avoid duplicate entries.
nodes: set[str] = set()
Expand Down Expand Up @@ -95,20 +94,13 @@ def mermaid_id(key: str) -> str:
edges.add(f'{package_key} -- "{edge_label}" --> {dependency_key}')

# Produce the Mermaid Markdown.
indent = " " * 4
output = dedent(
f"""\
flowchart TD
{indent}classDef missing stroke-dasharray: 5
""",
)
# Sort the nodes and edges to make the output deterministic.
output += indent
output += f"\n{indent}".join(node for node in sorted(nodes))
output += "\n" + indent
output += f"\n{indent}".join(edge for edge in sorted(edges))
output += "\n"
return output
lines = [
"flowchart TD",
"classDef missing stroke-dasharray: 5",
*sorted(nodes),
*sorted(edges),
]
return "".join(f"{' ' if i else ''}{line}\n" for i, line in enumerate(lines))


__all__ = [
Expand Down
2 changes: 1 addition & 1 deletion src/pipdeptree/_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def cyclic_deps(tree: PackageDAG) -> list[tuple[DistPackage, ReqPackage, ReqPack
if val is not None:
entry = tree.get(val)
if entry is not None:
p_as_dep_of_r = [x for x in entry if x.key == p.key][0]
p_as_dep_of_r = next(x for x in entry if x.key == p.key)
cyclic.append((p, r, p_as_dep_of_r))
return cyclic

Expand Down
3 changes: 1 addition & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ def func(simple_graph: MockGraph) -> Iterator[Mock]:
as_req = Mock(key=nk, project_name=nk, specs=[("==", nv)])
m.as_requirement = Mock(return_value=as_req)
reqs = []
for child in children:
ck, cv = child
for ck, cv in children:
r = Mock(key=ck, project_name=ck, specs=cv)
reqs.append(r)
m.requires = Mock(return_value=reqs)
Expand Down

0 comments on commit e861826

Please sign in to comment.