Third Party packages eric7

Sun, 05 Mar 2023 12:26:12 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 05 Mar 2023 12:26:12 +0100
branch
eric7
changeset 9849
99782ca569ed
parent 9848
3d750b2e012c
child 9850
20c49b517679

Third Party packages
- Upgraded eradicate to version 2.2.0.
- Upgraded pipdeptree to version 2.5.2.
- Upgraded pip-licenses to version 4.1.0.

docs/ThirdParty.md file | annotate | diff | comparison | revisions
docs/changelog.md file | annotate | diff | comparison | revisions
src/eric7/PipInterface/pipdeptree.py file | annotate | diff | comparison | revisions
src/eric7/PipInterface/piplicenses.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/eradicate.py file | annotate | diff | comparison | revisions
--- a/docs/ThirdParty.md	Sat Mar 04 18:09:08 2023 +0100
+++ b/docs/ThirdParty.md	Sun Mar 05 12:26:12 2023 +0100
@@ -5,11 +5,11 @@
 
 | Name         |  Version  | License                     |
 |:------------:|:---------:|:----------------------------|
-| eradicate    |   2.1.0   | MIT License (Expat License) |
+| eradicate    |   2.2.0   | MIT License (Expat License) |
 | jasy         | 1.5-beta6 | MIT License (MIT)           |
 | mccabe       |   0.7.0   | MIT License (Expat License) |
-| pipdeptree   |   2.3.3   | MIT License (MIT)           |
-| pip-licenses |   4.0.2   | MIT License (MIT)           |
+| pipdeptree   |   2.5.2   | MIT License (MIT)           |
+| pip-licenses |   4.1.0   | MIT License (MIT)           |
 | pycodestyle  |   2.10.0  | MIT License (Expat License) |
 | pyflakes     |   3.0.1   | MIT License (MIT)           |
 |              |           |                             |
--- a/docs/changelog.md	Sat Mar 04 18:09:08 2023 +0100
+++ b/docs/changelog.md	Sun Mar 05 12:26:12 2023 +0100
@@ -6,6 +6,10 @@
     - Added functionality to search for known boot volumes in the UF2 flash dialog.
     - Added functionality to install packages using `mip` or `upip`.
     - Added support for WiFi enabled boards.
+- Third Party packages
+    - Upgraded eradicate to version 2.2.0.
+    - Upgraded pipdeptree to version 2.5.2.
+    - Upgraded pip-licenses to version 4.1.0.
 
 ### Version 23.3
 - bug fixes
--- a/src/eric7/PipInterface/pipdeptree.py	Sat Mar 04 18:09:08 2023 +0100
+++ b/src/eric7/PipInterface/pipdeptree.py	Sun Mar 05 12:26:12 2023 +0100
@@ -46,6 +46,7 @@
 from collections.abc import Mapping
 from importlib import import_module
 from itertools import chain
+from textwrap import dedent
 
 from pip._vendor import pkg_resources
 
@@ -55,7 +56,7 @@
     from pip import FrozenRequirement
 
 
-__version__ = '2.3.3'  # eric-ide modification: from version.py
+__version__ = '2.5.2'  # eric-ide modification: from version.py
 
 
 flatten = chain.from_iterable
@@ -590,6 +591,91 @@
     return json.dumps([aux(p) for p in nodes], indent=indent)
 
 
+def render_mermaid(tree) -> str:
+    """Produce a Mermaid flowchart from the dependency graph.
+
+    :param dict 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] = {
+        "C4Component",
+        "C4Container",
+        "C4Deployment",
+        "C4Dynamic",
+        "_blank",
+        "_parent",
+        "_self",
+        "_top",
+        "call",
+        "class",
+        "classDef",
+        "click",
+        "end",
+        "flowchart",
+        "flowchart-v2",
+        "graph",
+        "interpolate",
+        "linkStyle",
+        "style",
+        "subgraph",
+    }
+    node_ids_map: dict[str:str] = {}
+
+    def mermaid_id(key: str) -> str:
+        """Returns a valid Mermaid node ID from a string."""
+        # If we have already seen this key, return the canonical ID.
+        canonical_id = node_ids_map.get(key)
+        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:
+            node_ids_map[key] = key
+            return key
+        # If the key is a reserved keyword, append a number to it.
+        number = 0
+        while True:
+            new_id = f"{key}_{number}"
+            if new_id not in node_ids_map:
+                node_ids_map[key] = new_id
+                return new_id
+            number += 1
+
+    # Use a sets to avoid duplicate entries.
+    nodes: set[str] = set()
+    edges: set[str] = set()
+
+    for pkg, deps in tree.items():
+        pkg_label = f"{pkg.project_name}\\n{pkg.version}"
+        pkg_key = mermaid_id(pkg.key)
+        nodes.add(f'{pkg_key}["{pkg_label}"]')
+        for dep in deps:
+            edge_label = dep.version_spec or "any"
+            dep_key = mermaid_id(dep.key)
+            if dep.is_missing:
+                dep_label = f"{dep.project_name}\\n(missing)"
+                nodes.add(f'{dep_key}["{dep_label}"]:::missing')
+                edges.add(f"{pkg_key} -.-> {dep_key}")
+            else:
+                edges.add(f'{pkg_key} -- "{edge_label}" --> {dep_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
+
+
 def dump_graphviz(tree, output_format="dot", is_reverse=False):
     """Output dependency graph as one of the supported GraphViz output formats.
 
@@ -652,7 +738,11 @@
 
     # Allow output of dot format, even if GraphViz isn't installed.
     if output_format == "dot":
-        return graph.source
+        # Emulates graphviz.dot.Dot.__iter__() to force the sorting of graph.body.
+        # Fixes https://github.com/tox-dev/pipdeptree/issues/188
+        # That way we can guarantee the output of the dot format is deterministic
+        # and stable.
+        return "".join([tuple(graph)[0]] + sorted(graph.body) + [graph._tail])
 
     # As it's unknown if the selected output format is binary or not, try to
     # decode it as UTF8 and only print it out in binary if that's not possible.
@@ -812,6 +902,12 @@
         ),
     )
     parser.add_argument(
+        "--mermaid",
+        action="store_true",
+        default=False,
+        help=("Display dependency tree as a Maermaid graph. " "This option overrides all other options."),
+    )
+    parser.add_argument(
         "--graph-output",
         dest="output_format",
         help=(
@@ -920,6 +1016,8 @@
         print(render_json(tree, indent=4))
     elif args.json_tree:
         print(render_json_tree(tree, indent=4))
+    elif args.mermaid:
+        print(render_mermaid(tree))
     elif args.output_format:
         output = dump_graphviz(tree, output_format=args.output_format, is_reverse=args.reverse)
         print_graphviz(output)
--- a/src/eric7/PipInterface/piplicenses.py	Sat Mar 04 18:09:08 2023 +0100
+++ b/src/eric7/PipInterface/piplicenses.py	Sun Mar 05 12:26:12 2023 +0100
@@ -97,7 +97,7 @@
 
 
 __pkgname__ = "pip-licenses"
-__version__ = "4.0.2"
+__version__ = "4.1.0"
 __author__ = "raimon"
 __license__ = "MIT"
 __summary__ = (
@@ -269,7 +269,9 @@
         )
 
         if fail_on_licenses:
-            failed_licenses = license_names.intersection(fail_on_licenses)
+            failed_licenses = case_insensitive_set_intersect(
+                license_names, fail_on_licenses
+            )
             if failed_licenses:
                 sys.stderr.write(
                     "fail-on license {} was found for package "
@@ -282,7 +284,9 @@
                 sys.exit(1)
 
         if allow_only_licenses:
-            uncommon_licenses = license_names.difference(allow_only_licenses)
+            uncommon_licenses = case_insensitive_set_diff(
+                license_names, allow_only_licenses
+            )
             if len(uncommon_licenses) == len(license_names):
                 sys.stderr.write(
                     "license {} not in allow-only licenses was found"
@@ -367,6 +371,26 @@
     return licenses
 
 
+def case_insensitive_set_intersect(set_a, set_b):
+    """Same as set.intersection() but case-insensitive"""
+    common_items = set()
+    set_b_lower = {item.lower() for item in set_b}
+    for elem in set_a:
+        if elem.lower() in set_b_lower:
+            common_items.add(elem)
+    return common_items
+
+
+def case_insensitive_set_diff(set_a, set_b):
+    """Same as set.difference() but case-insensitive"""
+    uncommon_items = set()
+    set_b_lower = {item.lower() for item in set_b}
+    for elem in set_a:
+        if not elem.lower() in set_b_lower:
+            uncommon_items.add(elem)
+    return uncommon_items
+
+
 def find_license_from_classifier(classifiers: list[str]) -> list[str]:
     licenses = []
     for classifier in filter(lambda c: c.startswith("License"), classifiers):
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/eradicate.py	Sat Mar 04 18:09:08 2023 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/eradicate.py	Sun Mar 05 12:26:12 2023 +0100
@@ -30,7 +30,7 @@
 import re
 import tokenize
 
-__version__ = '2.1.0'
+__version__ = '2.2.0'
 
 
 class Eradicator(object):
@@ -57,7 +57,9 @@
         r'noqa',
         r'nosec',
         r'type:\s*ignore',
+        r'mypy:',
         r'fmt:\s*(on|off)',
+        r'yapf:\s*(enable|disable)',
         r'isort:\s*(on|off|skip|skip_file|split|dont-add-imports(:\s*\[.*?\])?)',
         r'TODO',
         r'FIXME',

eric ide

mercurial