pip Interface eric7

Tue, 12 Jul 2022 16:26:22 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 12 Jul 2022 16:26:22 +0200
branch
eric7
changeset 9218
71cf3979a6c9
parent 9217
0c34da0d7b76
child 9219
964a326c58d4

pip Interface
- included a copy of pipdeptree and patched it to work with Python 3.11+

docs/changelog file | annotate | diff | comparison | revisions
eric7.epj file | annotate | diff | comparison | revisions
pyproject.toml file | annotate | diff | comparison | revisions
scripts/install.py file | annotate | diff | comparison | revisions
src/eric7/APIs/Python3/eric7.api file | annotate | diff | comparison | revisions
src/eric7/APIs/Python3/eric7.bas file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.PipInterface.pipdeptree.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/index-eric7.PipInterface.html file | annotate | diff | comparison | revisions
src/eric7/PipInterface/Pip.py 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
--- a/docs/changelog	Mon Jul 11 17:56:42 2022 +0200
+++ b/docs/changelog	Tue Jul 12 16:26:22 2022 +0200
@@ -10,6 +10,8 @@
      generation process
 - Code Formatting
   -- added an interface to reformat Python source code with the 'Black' utility
+- pip Interface
+  -- included a copy of pipdeptree and patched it to work with Python 3.11+
 - setup Wizard
   -- added support for 'project_urls'
   -- added support for 'entry_points'
--- a/eric7.epj	Mon Jul 11 17:56:42 2022 +0200
+++ b/eric7.epj	Tue Jul 12 16:26:22 2022 +0200
@@ -61,7 +61,7 @@
         "CopyrightMinFileSize": 0,
         "DocstringType": "eric",
         "EnabledCheckerCategories": "C, D, E, M, N, Y, W",
-        "ExcludeFiles": "*/ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */pycodestyle.py,*/pyflakes/checker.py,*/mccabe.py,*/eradicate.py,*/ast_unparse.py,*/piplicenses.py",
+        "ExcludeFiles": "*/ThirdParty/*, */coverage/*, */Ui_*.py, */Examples/*, */pycodestyle.py,*/pyflakes/checker.py,*/mccabe.py,*/eradicate.py,*/ast_unparse.py,*/piplicenses.py,*/pipdeptree.py",
         "ExcludeMessages": "C101,E203,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W503,Y119,Y401,Y402",
         "FixCodes": "",
         "FixIssues": false,
@@ -963,6 +963,22 @@
       "src/eric7/pixmaps"
     ],
     "OTHERTOOLSPARMS": {
+      "Black": {
+        "exclude": "/(\\.direnv|\\.eggs|\\.git|\\.hg|\\.mypy_cache|\\.nox|\\.tox|\\.venv|venv|\\.svn|_build|buck-out|build|dist|__pypackages__)/",
+        "extend-exclude": "/(\n\tExamples/\n\t| ThirdParty/\n\t| coverage/\n\t| Ui_.*\\.py\n\t| pycodestyle\\.py\n\t| pyflakes/checker\\.py\n\t| mccabe\\.py\n\t| eradicate\\.py\n\t| ast_unparse\\.py\n\t| piplicenses\\.py\n\t| pipdeptree\\.py\n)",
+        "force-exclude": "",
+        "line-length": 88,
+        "skip-magic-trailing-comma": false,
+        "skip-string-normalization": false,
+        "source": "dialog",
+        "target-version": [
+          "py37",
+          "py38",
+          "py39",
+          "py310",
+          "py311"
+        ]
+      },
       "CodeMetrics": {
         "ExcludeFiles": "Examples/*, */ThirdParty/*, */coverage/*, Ui_*.py"
       },
@@ -1308,6 +1324,7 @@
       "src/eric7/PipInterface/PipPackagesWidget.py",
       "src/eric7/PipInterface/PipVulnerabilityChecker.py",
       "src/eric7/PipInterface/__init__.py",
+      "src/eric7/PipInterface/pipdeptree.py",
       "src/eric7/PipInterface/piplicenses.py",
       "src/eric7/PluginManager/PluginDetailsDialog.py",
       "src/eric7/PluginManager/PluginExceptions.py",
@@ -2396,7 +2413,7 @@
       "src/eric7/i18n/eric7_zh_CN.qm",
       "src/eric7/i18n/eric7_zh_CN.ts"
     ],
-    "TRANSLATIONSBINPATH": "",
+    "TRANSLATIONSBINPATH": ".",
     "UICPARAMS": {
       "Package": "",
       "PackagesRoot": "src/eric7",
@@ -2444,4 +2461,4 @@
     "VCSOTHERDATA": {},
     "VERSION": "7.x"
   }
-}
\ No newline at end of file
+}
--- a/pyproject.toml	Mon Jul 11 17:56:42 2022 +0200
+++ b/pyproject.toml	Tue Jul 12 16:26:22 2022 +0200
@@ -47,30 +47,29 @@
 ]
 requires-python = ">=3.7, <3.12"
 dependencies = [
-  "pip>=21.1",
-  "wheel",
-  "PyQt6>=6.2.0",
-  "PyQt6-Charts>=6.2.0",
-  "PyQt6-WebEngine>=6.2.0",
-  "PyQt6-QScintilla>=2.13.0",
-  "docutils",
-  "Markdown",
-  "pyyaml",
-  "tomlkit",
-  "chardet",
-  "asttokens",
-  "EditorConfig",
-  "Send2Trash",
-  "Pygments",
-  "parso",
-  "jedi",
-  "packaging",
-  "pipdeptree",
-  "cyclonedx-python-lib",
-  "cyclonedx-bom",
-  "trove-classifiers",
-  "black>=22.6.0",
-  "pywin32>=1.0;platform_system=='Windows'",
+    "pip>=21.1",
+    "wheel",
+    "PyQt6>=6.2.0",
+    "PyQt6-Charts>=6.2.0",
+    "PyQt6-WebEngine>=6.2.0",
+    "PyQt6-QScintilla>=2.13.0",
+    "docutils",
+    "Markdown",
+    "pyyaml",
+    "tomlkit",
+    "chardet",
+    "asttokens",
+    "EditorConfig",
+    "Send2Trash",
+    "Pygments",
+    "parso",
+    "jedi",
+    "packaging",
+    "cyclonedx-python-lib",
+    "cyclonedx-bom",
+    "trove-classifiers",
+    "black>=22.6.0",
+    "pywin32>=1.0;platform_system=='Windows'",
 ]
 dynamic = ["version"]
 
@@ -128,36 +127,55 @@
 
 [tool.setuptools.package-data]
 "*" = [
-  "*.png",
-  "*.svg",
-  "*.xpm",
-  "*.ico",
-  "*.gif",
-  "*.icns",
-  "*.txt",
-  "*.md",
-  "*.rst",
-  "*.tmpl",
-  "*.html",
-  "*.qch",
-  "*.css",
-  "*.scss",
-  "*.qss",
-  "*.ehj",
-  "*.ethj",
-  "*.api",
-  "*.bas",
-  "*.dat",
-  "*.xbel",
-  "*.xml",
-  "*.js",
-  "*.json",
-  "*.desktop",
+    "*.png",
+    "*.svg",
+    "*.xpm",
+    "*.ico",
+    "*.gif",
+    "*.icns",
+    "*.txt",
+    "*.md",
+    "*.rst",
+    "*.tmpl",
+    "*.html",
+    "*.qch",
+    "*.css",
+    "*.scss",
+    "*.qss",
+    "*.ehj",
+    "*.ethj",
+    "*.api",
+    "*.bas",
+    "*.dat",
+    "*.xbel",
+    "*.xml",
+    "*.js",
+    "*.json",
+    "*.desktop",
 ]
 # complete translation files only
 "eric7.i18n" = [
-  "eric7_de.qm",
-  "eric7_en.qm",
-  "eric7_es.qm",
-  "eric7_ru.qm",
+    "eric7_de.qm",
+    "eric7_en.qm",
+    "eric7_es.qm",
+    "eric7_ru.qm",
 ]
+
+[tool.black]
+target-version = ["py37", "py38", "py39", "py310", "py311"]
+line-length = 88
+extend-exclude = '''
+/(
+    Examples/
+    | ThirdParty/
+    | coverage/
+    | Ui_.*\.py
+    | pycodestyle\.py
+    | pyflakes/checker\.py
+    | mccabe\.py
+    | eradicate\.py
+    | ast_unparse\.py
+    | piplicenses\.py
+    | pipdeptree\.py
+)
+'''
--- a/scripts/install.py	Mon Jul 11 17:56:42 2022 +0200
+++ b/scripts/install.py	Tue Jul 12 16:26:22 2022 +0200
@@ -1628,7 +1628,6 @@
         "parso": ("parso", ""),
         "jedi": ("jedi", ""),
         "packaging": ("packaging", ""),
-        "pipdeptree": ("pipdeptree", ""),
         "cyclonedx-python-lib": ("cyclonedx", ""),
         "cyclonedx-bom": ("cyclonedx_py", ""),
         "trove-classifiers": ("trove_classifiers", ""),
--- a/src/eric7/APIs/Python3/eric7.api	Mon Jul 11 17:56:42 2022 +0200
+++ b/src/eric7/APIs/Python3/eric7.api	Tue Jul 12 16:26:22 2022 +0200
@@ -3189,6 +3189,54 @@
 eric7.PipInterface.PipVulnerabilityChecker.VulnerabilityCheckError.FullDbUnavailable?7
 eric7.PipInterface.PipVulnerabilityChecker.VulnerabilityCheckError.OK?7
 eric7.PipInterface.PipVulnerabilityChecker.VulnerabilityCheckError.SummaryDbUnavailable?7
+eric7.PipInterface.pipdeptree.DistPackage.as_dict?4()
+eric7.PipInterface.pipdeptree.DistPackage.as_parent_of?4(req)
+eric7.PipInterface.pipdeptree.DistPackage.as_requirement?4()
+eric7.PipInterface.pipdeptree.DistPackage.render_as_branch?4(frozen)
+eric7.PipInterface.pipdeptree.DistPackage.render_as_root?4(frozen)
+eric7.PipInterface.pipdeptree.DistPackage?1(obj, req=None)
+eric7.PipInterface.pipdeptree.Package.frozen_repr?4()
+eric7.PipInterface.pipdeptree.Package.render?4(parent=None, frozen=False)
+eric7.PipInterface.pipdeptree.Package.render_as_branch?4(frozen)
+eric7.PipInterface.pipdeptree.Package.render_as_root?4(frozen)
+eric7.PipInterface.pipdeptree.Package?1(obj)
+eric7.PipInterface.pipdeptree.PackageDAG.filter?4(include, exclude)
+eric7.PipInterface.pipdeptree.PackageDAG.from_pkgs?4(pkgs)
+eric7.PipInterface.pipdeptree.PackageDAG.get_children?4(node_key)
+eric7.PipInterface.pipdeptree.PackageDAG.get_node_as_parent?4(node_key)
+eric7.PipInterface.pipdeptree.PackageDAG.reverse?4()
+eric7.PipInterface.pipdeptree.PackageDAG.sort?4()
+eric7.PipInterface.pipdeptree.PackageDAG?1(m)
+eric7.PipInterface.pipdeptree.ReqPackage.UNKNOWN_VERSION?7
+eric7.PipInterface.pipdeptree.ReqPackage.as_dict?4()
+eric7.PipInterface.pipdeptree.ReqPackage.installed_version?4()
+eric7.PipInterface.pipdeptree.ReqPackage.is_conflicting?4()
+eric7.PipInterface.pipdeptree.ReqPackage.is_missing?4()
+eric7.PipInterface.pipdeptree.ReqPackage.render_as_branch?4(frozen)
+eric7.PipInterface.pipdeptree.ReqPackage.render_as_root?4(frozen)
+eric7.PipInterface.pipdeptree.ReqPackage.version_spec?4()
+eric7.PipInterface.pipdeptree.ReqPackage?1(obj, dist=None)
+eric7.PipInterface.pipdeptree.ReversedPackageDAG.reverse?4()
+eric7.PipInterface.pipdeptree._get_args?5()
+eric7.PipInterface.pipdeptree.aux?4(node, parent=None, chain=None)
+eric7.PipInterface.pipdeptree.aux?4(node, parent=None, indent=0, chain=None)
+eric7.PipInterface.pipdeptree.conflicting_deps?4(tree)
+eric7.PipInterface.pipdeptree.cyclic_deps?4(tree)
+eric7.PipInterface.pipdeptree.dump_graphviz?4(tree, output_format='dot', is_reverse=False)
+eric7.PipInterface.pipdeptree.flatten?7
+eric7.PipInterface.pipdeptree.frozen_req_from_dist?4(dist)
+eric7.PipInterface.pipdeptree.get_installed_distributions?4(local_only=False, user_only=False)
+eric7.PipInterface.pipdeptree.get_parser?4()
+eric7.PipInterface.pipdeptree.guess_version?4(pkg_key, default='?')
+eric7.PipInterface.pipdeptree.handle_non_host_target?4(args)
+eric7.PipInterface.pipdeptree.main?4()
+eric7.PipInterface.pipdeptree.print_graphviz?4(dump_output)
+eric7.PipInterface.pipdeptree.render_conflicts_text?4(conflicts)
+eric7.PipInterface.pipdeptree.render_cycles_text?4(cycles)
+eric7.PipInterface.pipdeptree.render_json?4(tree, indent)
+eric7.PipInterface.pipdeptree.render_json_tree?4(tree, indent)
+eric7.PipInterface.pipdeptree.render_text?4(tree, list_all=True, frozen=False)
+eric7.PipInterface.pipdeptree.sorted_tree?4(tree)
 eric7.PipInterface.piplicenses.CompatibleArgumentParser._verify_args?5(args: CustomNamespace)
 eric7.PipInterface.piplicenses.CompatibleArgumentParser.parse_args?4(args: Optional[Sequence[Text]] = None, namespace: CustomNamespace = None)
 eric7.PipInterface.piplicenses.CustomHelpFormatter._expand_help?5(action: argparse.Action)
--- a/src/eric7/APIs/Python3/eric7.bas	Mon Jul 11 17:56:42 2022 +0200
+++ b/src/eric7/APIs/Python3/eric7.bas	Tue Jul 12 16:26:22 2022 +0200
@@ -164,6 +164,7 @@
 DiffReport StandardReport
 DiffWindow EricMainWindow
 DirectorySyncHandler SyncHandler
+DistPackage Package
 DocstringMenuForEnterOnly QMenu
 DocumentationViewerWidget QWidget
 DotDesktopListSelectionDialog QDialog Ui_DotDesktopListSelectionDialog
@@ -698,6 +699,7 @@
 OpenSearchWriter QXmlStreamWriter
 OperaImporter BookmarksImporter
 OrderArg NoValueEnum
+PackageDAG Mapping
 PackageDiagramBuilder UMLDiagramBuilder
 PackageItem UMLItem
 PackageModel UMLModel
@@ -838,8 +840,10 @@
 RefactoringPreviewDialog QDialog Ui_RefactoringPreviewDialog
 ReloadStopButton EricToolButton
 RemoveBookmarksCommand QUndoCommand
+ReqPackage Package
 RestructuredTextProvider MarkupBase
 ReturnVisitor ast.NodeVisitor
+ReversedPackageDAG PackageDAG
 SafariImporter BookmarksImporter
 SafeBrowsingAPIClient QObject
 SafeBrowsingCache QObject
Binary file src/eric7/Documentation/Help/source.qch has changed
--- a/src/eric7/Documentation/Help/source.qhp	Mon Jul 11 17:56:42 2022 +0200
+++ b/src/eric7/Documentation/Help/source.qhp	Tue Jul 12 16:26:22 2022 +0200
@@ -317,6 +317,7 @@
             <section title="eric7.PipInterface.PipPackagesInputDialog" ref="eric7.PipInterface.PipPackagesInputDialog.html" />
             <section title="eric7.PipInterface.PipPackagesWidget" ref="eric7.PipInterface.PipPackagesWidget.html" />
             <section title="eric7.PipInterface.PipVulnerabilityChecker" ref="eric7.PipInterface.PipVulnerabilityChecker.html" />
+            <section title="eric7.PipInterface.pipdeptree" ref="eric7.PipInterface.pipdeptree.html" />
             <section title="eric7.PipInterface.piplicenses" ref="eric7.PipInterface.piplicenses.html" />
           </section>
           <section title="eric7.PluginManager" ref="index-eric7.PluginManager.html">
@@ -3902,6 +3903,13 @@
       <keyword name="DirectorySyncHandler.syncPasswords" id="DirectorySyncHandler.syncPasswords" ref="eric7.WebBrowser.Sync.DirectorySyncHandler.html#DirectorySyncHandler.syncPasswords" />
       <keyword name="DirectorySyncHandler.syncSpeedDial" id="DirectorySyncHandler.syncSpeedDial" ref="eric7.WebBrowser.Sync.DirectorySyncHandler.html#DirectorySyncHandler.syncSpeedDial" />
       <keyword name="DirectorySyncHandler.syncUserAgents" id="DirectorySyncHandler.syncUserAgents" ref="eric7.WebBrowser.Sync.DirectorySyncHandler.html#DirectorySyncHandler.syncUserAgents" />
+      <keyword name="DistPackage" id="DistPackage" ref="eric7.PipInterface.pipdeptree.html#DistPackage" />
+      <keyword name="DistPackage (Constructor)" id="DistPackage (Constructor)" ref="eric7.PipInterface.pipdeptree.html#DistPackage.__init__" />
+      <keyword name="DistPackage.as_dict" id="DistPackage.as_dict" ref="eric7.PipInterface.pipdeptree.html#DistPackage.as_dict" />
+      <keyword name="DistPackage.as_parent_of" id="DistPackage.as_parent_of" ref="eric7.PipInterface.pipdeptree.html#DistPackage.as_parent_of" />
+      <keyword name="DistPackage.as_requirement" id="DistPackage.as_requirement" ref="eric7.PipInterface.pipdeptree.html#DistPackage.as_requirement" />
+      <keyword name="DistPackage.render_as_branch" id="DistPackage.render_as_branch" ref="eric7.PipInterface.pipdeptree.html#DistPackage.render_as_branch" />
+      <keyword name="DistPackage.render_as_root" id="DistPackage.render_as_root" ref="eric7.PipInterface.pipdeptree.html#DistPackage.render_as_root" />
       <keyword name="DocStyle (Package)" id="DocStyle (Package)" ref="index-eric7.Plugins.CheckerPlugins.CodeStyleChecker.DocStyle.html" />
       <keyword name="DocStyleChecker" id="DocStyleChecker" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.DocStyle.DocStyleChecker.html#DocStyleChecker" />
       <keyword name="DocStyleChecker (Constructor)" id="DocStyleChecker (Constructor)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.DocStyle.DocStyleChecker.html#DocStyleChecker.__init__" />
@@ -11161,6 +11169,26 @@
       <keyword name="PDFStyle" id="PDFStyle" ref="eric7.QScintilla.Exporters.ExporterPDF.html#PDFStyle" />
       <keyword name="PDFStyle (Constructor)" id="PDFStyle (Constructor)" ref="eric7.QScintilla.Exporters.ExporterPDF.html#PDFStyle.__init__" />
       <keyword name="Package" id="Package" ref="eric7.PipInterface.PipVulnerabilityChecker.html#Package" />
+      <keyword name="Package" id="Package" ref="eric7.PipInterface.pipdeptree.html#Package" />
+      <keyword name="Package (Constructor)" id="Package (Constructor)" ref="eric7.PipInterface.pipdeptree.html#Package.__init__" />
+      <keyword name="Package.__getattr__" id="Package.__getattr__" ref="eric7.PipInterface.pipdeptree.html#Package.__getattr__" />
+      <keyword name="Package.__lt__" id="Package.__lt__" ref="eric7.PipInterface.pipdeptree.html#Package.__lt__" />
+      <keyword name="Package.__repr__" id="Package.__repr__" ref="eric7.PipInterface.pipdeptree.html#Package.__repr__" />
+      <keyword name="Package.frozen_repr" id="Package.frozen_repr" ref="eric7.PipInterface.pipdeptree.html#Package.frozen_repr" />
+      <keyword name="Package.render" id="Package.render" ref="eric7.PipInterface.pipdeptree.html#Package.render" />
+      <keyword name="Package.render_as_branch" id="Package.render_as_branch" ref="eric7.PipInterface.pipdeptree.html#Package.render_as_branch" />
+      <keyword name="Package.render_as_root" id="Package.render_as_root" ref="eric7.PipInterface.pipdeptree.html#Package.render_as_root" />
+      <keyword name="PackageDAG" id="PackageDAG" ref="eric7.PipInterface.pipdeptree.html#PackageDAG" />
+      <keyword name="PackageDAG (Constructor)" id="PackageDAG (Constructor)" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.__init__" />
+      <keyword name="PackageDAG.__getitem__" id="PackageDAG.__getitem__" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.__getitem__" />
+      <keyword name="PackageDAG.__iter__" id="PackageDAG.__iter__" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.__iter__" />
+      <keyword name="PackageDAG.__len__" id="PackageDAG.__len__" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.__len__" />
+      <keyword name="PackageDAG.filter" id="PackageDAG.filter" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.filter" />
+      <keyword name="PackageDAG.from_pkgs" id="PackageDAG.from_pkgs" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.from_pkgs" />
+      <keyword name="PackageDAG.get_children" id="PackageDAG.get_children" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.get_children" />
+      <keyword name="PackageDAG.get_node_as_parent" id="PackageDAG.get_node_as_parent" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.get_node_as_parent" />
+      <keyword name="PackageDAG.reverse" id="PackageDAG.reverse" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.reverse" />
+      <keyword name="PackageDAG.sort" id="PackageDAG.sort" ref="eric7.PipInterface.pipdeptree.html#PackageDAG.sort" />
       <keyword name="PackageDiagramBuilder" id="PackageDiagramBuilder" ref="eric7.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder" />
       <keyword name="PackageDiagramBuilder (Constructor)" id="PackageDiagramBuilder (Constructor)" ref="eric7.Graphics.PackageDiagramBuilder.html#PackageDiagramBuilder.__init__" />
       <keyword name="PackageDiagramBuilder (Module)" id="PackageDiagramBuilder (Module)" ref="eric7.Graphics.PackageDiagramBuilder.html" />
@@ -13252,6 +13280,15 @@
       <keyword name="RemoveBookmarksCommand.redo" id="RemoveBookmarksCommand.redo" ref="eric7.WebBrowser.Bookmarks.BookmarksManager.html#RemoveBookmarksCommand.redo" />
       <keyword name="RemoveBookmarksCommand.undo" id="RemoveBookmarksCommand.undo" ref="eric7.WebBrowser.Bookmarks.BookmarksManager.html#RemoveBookmarksCommand.undo" />
       <keyword name="RepositoryInfoDialog (Module)" id="RepositoryInfoDialog (Module)" ref="eric7.VCS.RepositoryInfoDialog.html" />
+      <keyword name="ReqPackage" id="ReqPackage" ref="eric7.PipInterface.pipdeptree.html#ReqPackage" />
+      <keyword name="ReqPackage (Constructor)" id="ReqPackage (Constructor)" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.__init__" />
+      <keyword name="ReqPackage.as_dict" id="ReqPackage.as_dict" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.as_dict" />
+      <keyword name="ReqPackage.installed_version" id="ReqPackage.installed_version" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.installed_version" />
+      <keyword name="ReqPackage.is_conflicting" id="ReqPackage.is_conflicting" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.is_conflicting" />
+      <keyword name="ReqPackage.is_missing" id="ReqPackage.is_missing" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.is_missing" />
+      <keyword name="ReqPackage.render_as_branch" id="ReqPackage.render_as_branch" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.render_as_branch" />
+      <keyword name="ReqPackage.render_as_root" id="ReqPackage.render_as_root" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.render_as_root" />
+      <keyword name="ReqPackage.version_spec" id="ReqPackage.version_spec" ref="eric7.PipInterface.pipdeptree.html#ReqPackage.version_spec" />
       <keyword name="RestructuredTextProvider" id="RestructuredTextProvider" ref="eric7.QScintilla.MarkupProviders.RestructuredTextProvider.html#RestructuredTextProvider" />
       <keyword name="RestructuredTextProvider (Constructor)" id="RestructuredTextProvider (Constructor)" ref="eric7.QScintilla.MarkupProviders.RestructuredTextProvider.html#RestructuredTextProvider.__init__" />
       <keyword name="RestructuredTextProvider (Module)" id="RestructuredTextProvider (Module)" ref="eric7.QScintilla.MarkupProviders.RestructuredTextProvider.html" />
@@ -13310,6 +13347,8 @@
       <keyword name="ReturnVisitor.visit_Return" id="ReturnVisitor.visit_Return" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Annotations.AnnotationsFunctionVisitor.html#ReturnVisitor.visit_Return" />
       <keyword name="ReturnVisitor.visit_Return" id="ReturnVisitor.visit_Return" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#ReturnVisitor.visit_Return" />
       <keyword name="ReturnVisitor.visit_While" id="ReturnVisitor.visit_While" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#ReturnVisitor.visit_While" />
+      <keyword name="ReversedPackageDAG" id="ReversedPackageDAG" ref="eric7.PipInterface.pipdeptree.html#ReversedPackageDAG" />
+      <keyword name="ReversedPackageDAG.reverse" id="ReversedPackageDAG.reverse" ref="eric7.PipInterface.pipdeptree.html#ReversedPackageDAG.reverse" />
       <keyword name="SafariImporter" id="SafariImporter" ref="eric7.WebBrowser.Bookmarks.BookmarksImporters.SafariImporter.html#SafariImporter" />
       <keyword name="SafariImporter (Constructor)" id="SafariImporter (Constructor)" ref="eric7.WebBrowser.Bookmarks.BookmarksImporters.SafariImporter.html#SafariImporter.__init__" />
       <keyword name="SafariImporter (Module)" id="SafariImporter (Module)" ref="eric7.WebBrowser.Bookmarks.BookmarksImporters.SafariImporter.html" />
@@ -18255,6 +18294,7 @@
       <keyword name="_evaluateAst" id="_evaluateAst" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionSql.html#_evaluateAst" />
       <keyword name="_evaluateShellCall" id="_evaluateShellCall" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionShell.html#_evaluateShellCall" />
       <keyword name="_get" id="_get" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.SecurityUtils.html#_get" />
+      <keyword name="_get_args" id="_get_args" ref="eric7.PipInterface.pipdeptree.html#_get_args" />
       <keyword name="_get_parameters" id="_get_parameters" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#_get_parameters" />
       <keyword name="_getfullargs" id="_getfullargs" ref="eric7.DebugClients.Python.DebugUtilities.html#_getfullargs" />
       <keyword name="_indent" id="_indent" ref="eric7.Utilities.ClassBrowsers.pyclbr.html#_indent" />
@@ -18284,6 +18324,8 @@
       <keyword name="append_PKCS7_padding" id="append_PKCS7_padding" ref="eric7.Utilities.crypto.py3AES.html#append_PKCS7_padding" />
       <keyword name="assert (Module)" id="assert (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.assert.html" />
       <keyword name="ast_unparse (Module)" id="ast_unparse (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Simplify.ast_unparse.html" />
+      <keyword name="aux" id="aux" ref="eric7.PipInterface.pipdeptree.html#aux" />
+      <keyword name="aux_1" id="aux_1" ref="eric7.PipInterface.pipdeptree.html#aux_1" />
       <keyword name="awsHardcodedPassword (Module)" id="awsHardcodedPassword (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.awsHardcodedPassword.html" />
       <keyword name="bare_except" id="bare_except" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#bare_except" />
       <keyword name="blackListCalls (Module)" id="blackListCalls (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.blackListCalls.html" />
@@ -18357,6 +18399,7 @@
       <keyword name="condaVersion" id="condaVersion" ref="eric7.CondaInterface.__init__.html#condaVersion" />
       <keyword name="condaVersionStr" id="condaVersionStr" ref="eric7.CondaInterface.__init__.html#condaVersionStr" />
       <keyword name="confirmOverwrite" id="confirmOverwrite" ref="eric7.EricWidgets.EricFileSaveConfirmDialog.html#confirmOverwrite" />
+      <keyword name="conflicting_deps" id="conflicting_deps" ref="eric7.PipInterface.pipdeptree.html#conflicting_deps" />
       <keyword name="containsSpace" id="containsSpace" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#containsSpace" />
       <keyword name="continued_indentation" id="continued_indentation" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#continued_indentation" />
       <keyword name="convertLineEnds" id="convertLineEnds" ref="eric7.Utilities.__init__.html#convertLineEnds" />
@@ -18478,6 +18521,7 @@
       <keyword name="critical" id="critical" ref="eric7.EricWidgets.EricMessageBox.html#critical" />
       <keyword name="crypto (Package)" id="crypto (Package)" ref="index-eric7.Utilities.crypto.html" />
       <keyword name="cursors (Package)" id="cursors (Package)" ref="index-eric7.IconEditor.cursors.html" />
+      <keyword name="cyclic_deps" id="cyclic_deps" ref="eric7.PipInterface.pipdeptree.html#cyclic_deps" />
       <keyword name="data (Package)" id="data (Package)" ref="index-eric7.EricNetwork.data.html" />
       <keyword name="data (Package)" id="data (Package)" ref="index-eric7.UI.data.html" />
       <keyword name="data (Package)" id="data (Package)" ref="index-eric7.WebBrowser.data.html" />
@@ -18504,6 +18548,7 @@
       <keyword name="doUpgrade" id="doUpgrade" ref="eric7.UI.upgrader.html#doUpgrade" />
       <keyword name="drawPolygon" id="drawPolygon" ref="eric7.Snapshot.SnapshotFreehandGrabber.html#drawPolygon" />
       <keyword name="drawRect" id="drawRect" ref="eric7.Snapshot.SnapshotRegionGrabber.html#drawRect" />
+      <keyword name="dump_graphviz" id="dump_graphviz" ref="eric7.PipInterface.pipdeptree.html#dump_graphviz" />
       <keyword name="editMessageFilters" id="editMessageFilters" ref="eric7.EricWidgets.EricErrorMessage.html#editMessageFilters" />
       <keyword name="encode" id="encode" ref="eric7.Utilities.__init__.html#encode" />
       <keyword name="encryptData" id="encryptData" ref="eric7.Utilities.crypto.py3AES.html#encryptData" />
@@ -18577,6 +18622,7 @@
       <keyword name="formatTime" id="formatTime" ref="eric7.Plugins.VcsPlugins.vcsPySvn.SvnUtilities.html#formatTime" />
       <keyword name="formatargvalues" id="formatargvalues" ref="eric7.DebugClients.Python.DebugUtilities.html#formatargvalues" />
       <keyword name="fromNativeSeparators" id="fromNativeSeparators" ref="eric7.Utilities.__init__.html#fromNativeSeparators" />
+      <keyword name="frozen_req_from_dist" id="frozen_req_from_dist" ref="eric7.PipInterface.pipdeptree.html#frozen_req_from_dist" />
       <keyword name="fstat" id="fstat" ref="eric7.MicroPython.MicroPythonFileSystemUtilities.html#fstat" />
       <keyword name="generalBindAllInterfaces (Module)" id="generalBindAllInterfaces (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.generalBindAllInterfaces.html" />
       <keyword name="generalFilePermissions (Module)" id="generalFilePermissions (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.generalFilePermissions.html" />
@@ -18792,9 +18838,11 @@
       <keyword name="get_class_members" id="get_class_members" ref="eric7.DebugClients.Python.FlexCompleter.html#get_class_members" />
       <keyword name="get_coding" id="get_coding" ref="eric7.Utilities.__init__.html#get_coding" />
       <keyword name="get_codingBytes" id="get_codingBytes" ref="eric7.Utilities.__init__.html#get_codingBytes" />
+      <keyword name="get_installed_distributions" id="get_installed_distributions" ref="eric7.PipInterface.pipdeptree.html#get_installed_distributions" />
       <keyword name="get_installed_distributions" id="get_installed_distributions" ref="eric7.PipInterface.piplicenses.html#get_installed_distributions" />
       <keyword name="get_output_fields" id="get_output_fields" ref="eric7.PipInterface.piplicenses.html#get_output_fields" />
       <keyword name="get_packages" id="get_packages" ref="eric7.PipInterface.piplicenses.html#get_packages" />
+      <keyword name="get_parser" id="get_parser" ref="eric7.PipInterface.pipdeptree.html#get_parser" />
       <keyword name="get_parser" id="get_parser" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#get_parser" />
       <keyword name="get_pkg_included_file" id="get_pkg_included_file" ref="eric7.PipInterface.piplicenses.html#get_pkg_included_file" />
       <keyword name="get_pkg_info" id="get_pkg_info" ref="eric7.PipInterface.piplicenses.html#get_pkg_info" />
@@ -18804,8 +18852,10 @@
       <keyword name="getuser" id="getuser" ref="eric7.DebugClients.Python.getpass.html#getuser" />
       <keyword name="git (Module)" id="git (Module)" ref="eric7.Plugins.VcsPlugins.vcsGit.git.html" />
       <keyword name="gpg (Module)" id="gpg (Module)" ref="eric7.Plugins.VcsPlugins.vcsMercurial.GpgExtension.gpg.html" />
+      <keyword name="guess_version" id="guess_version" ref="eric7.PipInterface.pipdeptree.html#guess_version" />
       <keyword name="handleArgs" id="handleArgs" ref="eric7.Toolbox.Startup.html#handleArgs" />
       <keyword name="handleSingleApplication" id="handleSingleApplication" ref="eric7.eric7.html#handleSingleApplication" />
+      <keyword name="handle_non_host_target" id="handle_non_host_target" ref="eric7.PipInterface.pipdeptree.html#handle_non_host_target" />
       <keyword name="hasEnvironmentEntry" id="hasEnvironmentEntry" ref="eric7.Utilities.__init__.html#hasEnvironmentEntry" />
       <keyword name="hasEric6Configuration" id="hasEric6Configuration" ref="eric7.Preferences.__init__.html#hasEric6Configuration" />
       <keyword name="hasShell" id="hasShell" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionShell.html#hasShell" />
@@ -18905,6 +18955,7 @@
       <keyword name="loadTranslatorForLocale" id="loadTranslatorForLocale" ref="eric7.Toolbox.Startup.html#loadTranslatorForLocale" />
       <keyword name="loadTranslators" id="loadTranslators" ref="eric7.Toolbox.Startup.html#loadTranslators" />
       <keyword name="lru_cache" id="lru_cache" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#lru_cache" />
+      <keyword name="main" id="main" ref="eric7.PipInterface.pipdeptree.html#main" />
       <keyword name="main" id="main" ref="eric7.PipInterface.piplicenses.html#main" />
       <keyword name="main" id="main" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.eradicate.html#main" />
       <keyword name="main" id="main" ref="eric7.Plugins.VcsPlugins.vcsMercurial.HisteditExtension.HgHisteditEditor.html#main" />
@@ -18988,6 +19039,7 @@
       <keyword name="patchQProcess" id="patchQProcess" ref="eric7.DebugClients.Python.QProcessExtension.html#patchQProcess" />
       <keyword name="patchSubprocess" id="patchSubprocess" ref="eric7.DebugClients.Python.SubprocessExtension.html#patchSubprocess" />
       <keyword name="pbkdf2" id="pbkdf2" ref="eric7.Utilities.crypto.py3PBKDF2.html#pbkdf2" />
+      <keyword name="pipdeptree (Module)" id="pipdeptree (Module)" ref="eric7.PipInterface.pipdeptree.html" />
       <keyword name="piplicenses (Module)" id="piplicenses (Module)" ref="eric7.PipInterface.piplicenses.html" />
       <keyword name="pixmapFileToDataUrl" id="pixmapFileToDataUrl" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#pixmapFileToDataUrl" />
       <keyword name="pixmapFromByteArray" id="pixmapFromByteArray" ref="eric7.WebBrowser.Tools.WebBrowserTools.html#pixmapFromByteArray" />
@@ -19007,6 +19059,7 @@
       <keyword name="prepareUninstall" id="prepareUninstall" ref="eric7.Plugins.PluginVcsSubversion.html#prepareUninstall" />
       <keyword name="previewPix" id="previewPix" ref="eric7.Plugins.PluginVmListspace.html#previewPix" />
       <keyword name="previewPix" id="previewPix" ref="eric7.Plugins.PluginVmTabview.html#previewPix" />
+      <keyword name="print_graphviz" id="print_graphviz" ref="eric7.PipInterface.pipdeptree.html#print_graphviz" />
       <keyword name="printerr" id="printerr" ref="eric7.DebugClients.Python.DebugBase.html#printerr" />
       <keyword name="process_options" id="process_options" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#process_options" />
       <keyword name="protoclbr (Module)" id="protoclbr (Module)" ref="eric7.Utilities.ClassBrowsers.protoclbr.html" />
@@ -19065,6 +19118,11 @@
       <keyword name="removeQuotesFromArgs" id="removeQuotesFromArgs" ref="eric7.DebugClients.Python.DebugUtilities.html#removeQuotesFromArgs" />
       <keyword name="removeSearchPath" id="removeSearchPath" ref="eric7.UI.PixmapCache.html#removeSearchPath" />
       <keyword name="renderTabPreview" id="renderTabPreview" ref="eric7.WebBrowser.WebBrowserSnap.html#renderTabPreview" />
+      <keyword name="render_conflicts_text" id="render_conflicts_text" ref="eric7.PipInterface.pipdeptree.html#render_conflicts_text" />
+      <keyword name="render_cycles_text" id="render_cycles_text" ref="eric7.PipInterface.pipdeptree.html#render_cycles_text" />
+      <keyword name="render_json" id="render_json" ref="eric7.PipInterface.pipdeptree.html#render_json" />
+      <keyword name="render_json_tree" id="render_json_tree" ref="eric7.PipInterface.pipdeptree.html#render_json_tree" />
+      <keyword name="render_text" id="render_text" ref="eric7.PipInterface.pipdeptree.html#render_text" />
       <keyword name="resetInterface" id="resetInterface" ref="eric7.CondaInterface.__init__.html#resetInterface" />
       <keyword name="resetLayout" id="resetLayout" ref="eric7.Preferences.__init__.html#resetLayout" />
       <keyword name="resetParsedModule" id="resetParsedModule" ref="eric7.Utilities.ModuleParser.html#resetParsedModule" />
@@ -19160,6 +19218,7 @@
       <keyword name="signatures" id="signatures" ref="eric7.Project.UicLoadUi6.html#signatures" />
       <keyword name="simpleAppStartup" id="simpleAppStartup" ref="eric7.Toolbox.Startup.html#simpleAppStartup" />
       <keyword name="sort" id="sort" ref="eric7.Graphics.GraphicsUtilities.html#sort" />
+      <keyword name="sorted_tree" id="sorted_tree" ref="eric7.PipInterface.pipdeptree.html#sorted_tree" />
       <keyword name="speedString" id="speedString" ref="eric7.WebBrowser.Download.DownloadUtilities.html#speedString" />
       <keyword name="splitPath" id="splitPath" ref="eric7.Utilities.__init__.html#splitPath" />
       <keyword name="sshNoHostKeyVerification (Module)" id="sshNoHostKeyVerification (Module)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.sshNoHostKeyVerification.html" />
@@ -19514,6 +19573,7 @@
       <file>eric7.PipInterface.PipPackagesInputDialog.html</file>
       <file>eric7.PipInterface.PipPackagesWidget.html</file>
       <file>eric7.PipInterface.PipVulnerabilityChecker.html</file>
+      <file>eric7.PipInterface.pipdeptree.html</file>
       <file>eric7.PipInterface.piplicenses.html</file>
       <file>eric7.PluginManager.PluginDetailsDialog.html</file>
       <file>eric7.PluginManager.PluginExceptions.html</file>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.PipInterface.pipdeptree.html	Tue Jul 12 16:26:22 2022 +0200
@@ -0,0 +1,1012 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.PipInterface.pipdeptree</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.PipInterface.pipdeptree</h1>
+
+<p>
+Copyright (c) 2015 Vineet Naik (naikvin@gmail.com)
+</p>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+</p>
+<p>
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+</p>
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>__version__</td></tr><tr><td>flatten</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#DistPackage">DistPackage</a></td>
+<td>Wrapper class for pkg_resources.Distribution instances</td>
+</tr>
+<tr>
+<td><a href="#Package">Package</a></td>
+<td>Abstract class for wrappers around objects that pip returns.</td>
+</tr>
+<tr>
+<td><a href="#PackageDAG">PackageDAG</a></td>
+<td>Representation of Package dependencies as directed acyclic graph using a dict (Mapping) as the underlying datastructure.</td>
+</tr>
+<tr>
+<td><a href="#ReqPackage">ReqPackage</a></td>
+<td>Wrapper class for Requirements instance</td>
+</tr>
+<tr>
+<td><a href="#ReversedPackageDAG">ReversedPackageDAG</a></td>
+<td>Representation of Package dependencies in the reverse order.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+
+<tr>
+<td><a href="#_get_args">_get_args</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#aux">aux</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#aux_1">aux</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#conflicting_deps">conflicting_deps</a></td>
+<td>Returns dependencies which are not present or conflict with the requirements of other packages.</td>
+</tr>
+<tr>
+<td><a href="#cyclic_deps">cyclic_deps</a></td>
+<td>Return cyclic dependencies as list of tuples</td>
+</tr>
+<tr>
+<td><a href="#dump_graphviz">dump_graphviz</a></td>
+<td>Output dependency graph as one of the supported GraphViz output formats.</td>
+</tr>
+<tr>
+<td><a href="#frozen_req_from_dist">frozen_req_from_dist</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#get_installed_distributions">get_installed_distributions</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#get_parser">get_parser</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#guess_version">guess_version</a></td>
+<td>Guess the version of a pkg when pip doesn't provide it</td>
+</tr>
+<tr>
+<td><a href="#handle_non_host_target">handle_non_host_target</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#main">main</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#print_graphviz">print_graphviz</a></td>
+<td>Dump the data generated by GraphViz to stdout.</td>
+</tr>
+<tr>
+<td><a href="#render_conflicts_text">render_conflicts_text</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#render_cycles_text">render_cycles_text</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#render_json">render_json</a></td>
+<td>Converts the tree into a flat json representation.</td>
+</tr>
+<tr>
+<td><a href="#render_json_tree">render_json_tree</a></td>
+<td>Converts the tree into a nested json representation.</td>
+</tr>
+<tr>
+<td><a href="#render_text">render_text</a></td>
+<td>Print tree as text on console</td>
+</tr>
+<tr>
+<td><a href="#sorted_tree">sorted_tree</a></td>
+<td>Sorts the dict representation of the tree</td>
+</tr>
+</table>
+<hr />
+<hr />
+<a NAME="DistPackage" ID="DistPackage"></a>
+<h2>DistPackage</h2>
+
+<p>
+Wrapper class for pkg_resources.Distribution instances
+</p>
+<p>
+      :param obj: pkg_resources.Distribution to wrap over
+      :param req: optional ReqPackage object to associate this
+                  DistPackage with. This is useful for displaying the
+                  tree in reverse
+</p>
+<h3>Derived from</h3>
+Package
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#DistPackage.__init__">DistPackage</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#DistPackage.as_dict">as_dict</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#DistPackage.as_parent_of">as_parent_of</a></td>
+<td>Return a DistPackage instance associated to a requirement</td>
+</tr>
+<tr>
+<td><a href="#DistPackage.as_requirement">as_requirement</a></td>
+<td>Return a ReqPackage representation of this DistPackage</td>
+</tr>
+<tr>
+<td><a href="#DistPackage.render_as_branch">render_as_branch</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#DistPackage.render_as_root">render_as_root</a></td>
+<td></td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="DistPackage.__init__" ID="DistPackage.__init__"></a>
+<h4>DistPackage (Constructor)</h4>
+<b>DistPackage</b>(<i>obj, req=None</i>)
+
+<a NAME="DistPackage.as_dict" ID="DistPackage.as_dict"></a>
+<h4>DistPackage.as_dict</h4>
+<b>as_dict</b>(<i></i>)
+
+<a NAME="DistPackage.as_parent_of" ID="DistPackage.as_parent_of"></a>
+<h4>DistPackage.as_parent_of</h4>
+<b>as_parent_of</b>(<i>req</i>)
+
+<p>
+Return a DistPackage instance associated to a requirement
+</p>
+<p>
+        This association is necessary for reversing the PackageDAG.
+</p>
+<p>
+        If `req` is None, and the `req` attribute of the current
+        instance is also None, then the same instance will be
+        returned.
+</p>
+<p>
+        :param ReqPackage req: the requirement to associate with
+        :returns: DistPackage instance
+</p>
+<p>
+
+</p>
+<a NAME="DistPackage.as_requirement" ID="DistPackage.as_requirement"></a>
+<h4>DistPackage.as_requirement</h4>
+<b>as_requirement</b>(<i></i>)
+
+<p>
+Return a ReqPackage representation of this DistPackage
+</p>
+<a NAME="DistPackage.render_as_branch" ID="DistPackage.render_as_branch"></a>
+<h4>DistPackage.render_as_branch</h4>
+<b>render_as_branch</b>(<i>frozen</i>)
+
+<a NAME="DistPackage.render_as_root" ID="DistPackage.render_as_root"></a>
+<h4>DistPackage.render_as_root</h4>
+<b>render_as_root</b>(<i>frozen</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="Package" ID="Package"></a>
+<h2>Package</h2>
+
+<p>
+Abstract class for wrappers around objects that pip returns.
+</p>
+<p>
+    This class needs to be subclassed with implementations for
+    `render_as_root` and `render_as_branch` methods.
+</p>
+<p>
+
+</p>
+<h3>Derived from</h3>
+object
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#Package.__init__">Package</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#Package.__getattr__">__getattr__</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#Package.__lt__">__lt__</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#Package.__repr__">__repr__</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#Package.render">render</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#Package.render_as_branch">render_as_branch</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#Package.render_as_root">render_as_root</a></td>
+<td></td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#Package.frozen_repr">frozen_repr</a></td>
+<td></td>
+</tr>
+</table>
+
+<a NAME="Package.__init__" ID="Package.__init__"></a>
+<h4>Package (Constructor)</h4>
+<b>Package</b>(<i>obj</i>)
+
+<a NAME="Package.__getattr__" ID="Package.__getattr__"></a>
+<h4>Package.__getattr__</h4>
+<b>__getattr__</b>(<i>key</i>)
+
+<a NAME="Package.__lt__" ID="Package.__lt__"></a>
+<h4>Package.__lt__</h4>
+<b>__lt__</b>(<i>rhs</i>)
+
+<a NAME="Package.__repr__" ID="Package.__repr__"></a>
+<h4>Package.__repr__</h4>
+<b>__repr__</b>(<i></i>)
+
+<a NAME="Package.render" ID="Package.render"></a>
+<h4>Package.render</h4>
+<b>render</b>(<i>parent=None, frozen=False</i>)
+
+<a NAME="Package.render_as_branch" ID="Package.render_as_branch"></a>
+<h4>Package.render_as_branch</h4>
+<b>render_as_branch</b>(<i>frozen</i>)
+
+<a NAME="Package.render_as_root" ID="Package.render_as_root"></a>
+<h4>Package.render_as_root</h4>
+<b>render_as_root</b>(<i>frozen</i>)
+
+<a NAME="Package.frozen_repr" ID="Package.frozen_repr"></a>
+<h4>Package.frozen_repr (static)</h4>
+<b>frozen_repr</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="PackageDAG" ID="PackageDAG"></a>
+<h2>PackageDAG</h2>
+
+<p>
+Representation of Package dependencies as directed acyclic graph
+    using a dict (Mapping) as the underlying datastructure.
+</p>
+<p>
+    The nodes and their relationships (edges) are internally
+    stored using a map as follows,
+</p>
+<p>
+    {a: [b, c],
+     b: [d],
+     c: [d, e],
+     d: [e],
+     e: [],
+     f: [b],
+     g: [e, f]}
+</p>
+<p>
+    Here, node `a` has 2 children nodes `b` and `c`. Consider edge
+    direction from `a` -> `b` and `a` -> `c` respectively.
+</p>
+<p>
+    A node is expected to be an instance of a subclass of
+    `Package`. The keys are must be of class `DistPackage` and each
+    item in values must be of class `ReqPackage`. (See also
+    ReversedPackageDAG where the key and value types are
+    interchanged).
+</p>
+<p>
+
+</p>
+<h3>Derived from</h3>
+Mapping
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#PackageDAG.from_pkgs">from_pkgs</a></td>
+<td></td>
+</tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#PackageDAG.__init__">PackageDAG</a></td>
+<td>Initialize the PackageDAG object</td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.__getitem__">__getitem__</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.__iter__">__iter__</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.__len__">__len__</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.filter">filter</a></td>
+<td>Filters nodes in a graph by given parameters</td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.get_children">get_children</a></td>
+<td>Get child nodes for a node by it's key</td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.get_node_as_parent">get_node_as_parent</a></td>
+<td>Get the node from the keys of the dict representing the DAG.</td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.reverse">reverse</a></td>
+<td>Reverse the DAG, or turn it upside-down</td>
+</tr>
+<tr>
+<td><a href="#PackageDAG.sort">sort</a></td>
+<td>Return sorted tree in which the underlying _obj dict is an OrderedDict, sorted alphabetically by the keys</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="PackageDAG.from_pkgs" ID="PackageDAG.from_pkgs"></a>
+<h4>PackageDAG.from_pkgs (class method)</h4>
+<b>from_pkgs</b>(<i>pkgs</i>)
+
+<a NAME="PackageDAG.__init__" ID="PackageDAG.__init__"></a>
+<h4>PackageDAG (Constructor)</h4>
+<b>PackageDAG</b>(<i>m</i>)
+
+<p>
+Initialize the PackageDAG object
+</p>
+<p>
+        :param dict m: dict of node objects (refer class docstring)
+        :returns: None
+        :rtype: NoneType
+</p>
+<p>
+
+</p>
+<a NAME="PackageDAG.__getitem__" ID="PackageDAG.__getitem__"></a>
+<h4>PackageDAG.__getitem__</h4>
+<b>__getitem__</b>(<i>*args</i>)
+
+<a NAME="PackageDAG.__iter__" ID="PackageDAG.__iter__"></a>
+<h4>PackageDAG.__iter__</h4>
+<b>__iter__</b>(<i></i>)
+
+<a NAME="PackageDAG.__len__" ID="PackageDAG.__len__"></a>
+<h4>PackageDAG.__len__</h4>
+<b>__len__</b>(<i></i>)
+
+<a NAME="PackageDAG.filter" ID="PackageDAG.filter"></a>
+<h4>PackageDAG.filter</h4>
+<b>filter</b>(<i>include, exclude</i>)
+
+<p>
+Filters nodes in a graph by given parameters
+</p>
+<p>
+        If a node is included, then all it's children are also
+        included.
+</p>
+<p>
+        :param set include: set of node keys to include (or None)
+        :param set exclude: set of node keys to exclude (or None)
+        :returns: filtered version of the graph
+        :rtype: PackageDAG
+</p>
+<p>
+
+</p>
+<a NAME="PackageDAG.get_children" ID="PackageDAG.get_children"></a>
+<h4>PackageDAG.get_children</h4>
+<b>get_children</b>(<i>node_key</i>)
+
+<p>
+Get child nodes for a node by it's key
+</p>
+<p>
+        :param str node_key: key of the node to get children of
+        :returns: list of child nodes
+        :rtype: ReqPackage[]
+</p>
+<p>
+
+</p>
+<a NAME="PackageDAG.get_node_as_parent" ID="PackageDAG.get_node_as_parent"></a>
+<h4>PackageDAG.get_node_as_parent</h4>
+<b>get_node_as_parent</b>(<i>node_key</i>)
+
+<p>
+Get the node from the keys of the dict representing the DAG.
+</p>
+<p>
+        This method is useful if the dict representing the DAG
+        contains different kind of objects in keys and values. Use
+        this method to lookup a node obj as a parent (from the keys of
+        the dict) given a node key.
+</p>
+<p>
+        :param node_key: identifier corresponding to key attr of node obj
+        :returns: node obj (as present in the keys of the dict)
+        :rtype: Object
+</p>
+<p>
+
+</p>
+<a NAME="PackageDAG.reverse" ID="PackageDAG.reverse"></a>
+<h4>PackageDAG.reverse</h4>
+<b>reverse</b>(<i></i>)
+
+<p>
+Reverse the DAG, or turn it upside-down
+</p>
+<p>
+        In other words, the directions of edges of the nodes in the
+        DAG will be reversed.
+</p>
+<p>
+        Note that this function purely works on the nodes in the
+        graph. This implies that to perform a combination of filtering
+        and reversing, the order in which `filter` and `reverse`
+        methods should be applied is important. For eg. if reverse is
+        called on a filtered graph, then only the filtered nodes and
+        it's children will be considered when reversing. On the other
+        hand, if filter is called on reversed DAG, then the definition
+        of "child" nodes is as per the reversed DAG.
+</p>
+<p>
+        :returns: DAG in the reversed form
+        :rtype: ReversedPackageDAG
+</p>
+<p>
+
+</p>
+<a NAME="PackageDAG.sort" ID="PackageDAG.sort"></a>
+<h4>PackageDAG.sort</h4>
+<b>sort</b>(<i></i>)
+
+<p>
+Return sorted tree in which the underlying _obj dict is an
+        OrderedDict, sorted alphabetically by the keys
+</p>
+<p>
+        :returns: Instance of same class with OrderedDict
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="ReqPackage" ID="ReqPackage"></a>
+<h2>ReqPackage</h2>
+
+<p>
+Wrapper class for Requirements instance
+</p>
+<p>
+      :param obj: The `Requirements` instance to wrap over
+      :param dist: optional `pkg_resources.Distribution` instance for
+                   this requirement
+</p>
+<h3>Derived from</h3>
+Package
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>UNKNOWN_VERSION</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#ReqPackage.__init__">ReqPackage</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.as_dict">as_dict</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.installed_version">installed_version</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.is_conflicting">is_conflicting</a></td>
+<td>If installed version conflicts with required version</td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.is_missing">is_missing</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.render_as_branch">render_as_branch</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.render_as_root">render_as_root</a></td>
+<td></td>
+</tr>
+<tr>
+<td><a href="#ReqPackage.version_spec">version_spec</a></td>
+<td></td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="ReqPackage.__init__" ID="ReqPackage.__init__"></a>
+<h4>ReqPackage (Constructor)</h4>
+<b>ReqPackage</b>(<i>obj, dist=None</i>)
+
+<a NAME="ReqPackage.as_dict" ID="ReqPackage.as_dict"></a>
+<h4>ReqPackage.as_dict</h4>
+<b>as_dict</b>(<i></i>)
+
+<a NAME="ReqPackage.installed_version" ID="ReqPackage.installed_version"></a>
+<h4>ReqPackage.installed_version</h4>
+<b>installed_version</b>(<i></i>)
+
+<a NAME="ReqPackage.is_conflicting" ID="ReqPackage.is_conflicting"></a>
+<h4>ReqPackage.is_conflicting</h4>
+<b>is_conflicting</b>(<i></i>)
+
+<p>
+If installed version conflicts with required version
+</p>
+<a NAME="ReqPackage.is_missing" ID="ReqPackage.is_missing"></a>
+<h4>ReqPackage.is_missing</h4>
+<b>is_missing</b>(<i></i>)
+
+<a NAME="ReqPackage.render_as_branch" ID="ReqPackage.render_as_branch"></a>
+<h4>ReqPackage.render_as_branch</h4>
+<b>render_as_branch</b>(<i>frozen</i>)
+
+<a NAME="ReqPackage.render_as_root" ID="ReqPackage.render_as_root"></a>
+<h4>ReqPackage.render_as_root</h4>
+<b>render_as_root</b>(<i>frozen</i>)
+
+<a NAME="ReqPackage.version_spec" ID="ReqPackage.version_spec"></a>
+<h4>ReqPackage.version_spec</h4>
+<b>version_spec</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="ReversedPackageDAG" ID="ReversedPackageDAG"></a>
+<h2>ReversedPackageDAG</h2>
+
+<p>
+Representation of Package dependencies in the reverse
+    order.
+</p>
+<p>
+    Similar to it's super class `PackageDAG`, the underlying
+    datastructure is a dict, but here the keys are expected to be of
+    type `ReqPackage` and each item in the values of type
+    `DistPackage`.
+</p>
+<p>
+    Typically, this object will be obtained by calling
+    `PackageDAG.reverse`.
+</p>
+<p>
+
+</p>
+<h3>Derived from</h3>
+PackageDAG
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#ReversedPackageDAG.reverse">reverse</a></td>
+<td>Reverse the already reversed DAG to get the PackageDAG again</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="ReversedPackageDAG.reverse" ID="ReversedPackageDAG.reverse"></a>
+<h4>ReversedPackageDAG.reverse</h4>
+<b>reverse</b>(<i></i>)
+
+<p>
+Reverse the already reversed DAG to get the PackageDAG again
+</p>
+<p>
+        :returns: reverse of the reversed DAG
+        :rtype: PackageDAG
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="_get_args" ID="_get_args"></a>
+<h2>_get_args</h2>
+<b>_get_args</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="aux" ID="aux"></a>
+<h2>aux</h2>
+<b>aux</b>(<i>node, parent=None, indent=0, chain=None</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="aux_1" ID="aux_1"></a>
+<h2>aux</h2>
+<b>aux</b>(<i>node, parent=None, chain=None</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="conflicting_deps" ID="conflicting_deps"></a>
+<h2>conflicting_deps</h2>
+<b>conflicting_deps</b>(<i>tree</i>)
+
+<p>
+Returns dependencies which are not present or conflict with the
+    requirements of other packages.
+</p>
+<p>
+    e.g. will warn if pkg1 requires pkg2==2.0 and pkg2==1.0 is installed
+</p>
+<p>
+    :param tree: the requirements tree (dict)
+    :returns: dict of DistPackage -> list of unsatisfied/unknown ReqPackage
+    :rtype: dict
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="cyclic_deps" ID="cyclic_deps"></a>
+<h2>cyclic_deps</h2>
+<b>cyclic_deps</b>(<i>tree</i>)
+
+<p>
+Return cyclic dependencies as list of tuples
+</p>
+<p>
+    :param PackageDAG pkgs: package tree/dag
+    :returns: list of tuples representing cyclic dependencies
+    :rtype: list
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="dump_graphviz" ID="dump_graphviz"></a>
+<h2>dump_graphviz</h2>
+<b>dump_graphviz</b>(<i>tree, output_format='dot', is_reverse=False</i>)
+
+<p>
+Output dependency graph as one of the supported GraphViz output formats.
+</p>
+<p>
+    :param dict tree: dependency graph
+    :param string output_format: output format
+    :returns: representation of tree in the specified output format
+    :rtype: str or binary representation depending on the output format
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="frozen_req_from_dist" ID="frozen_req_from_dist"></a>
+<h2>frozen_req_from_dist</h2>
+<b>frozen_req_from_dist</b>(<i>dist</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="get_installed_distributions" ID="get_installed_distributions"></a>
+<h2>get_installed_distributions</h2>
+<b>get_installed_distributions</b>(<i>local_only=False, user_only=False</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="get_parser" ID="get_parser"></a>
+<h2>get_parser</h2>
+<b>get_parser</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="guess_version" ID="guess_version"></a>
+<h2>guess_version</h2>
+<b>guess_version</b>(<i>pkg_key, default='?'</i>)
+
+<p>
+Guess the version of a pkg when pip doesn't provide it
+</p>
+<p>
+    :param str pkg_key: key of the package
+    :param str default: default version to return if unable to find
+    :returns: version
+    :rtype: string
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="handle_non_host_target" ID="handle_non_host_target"></a>
+<h2>handle_non_host_target</h2>
+<b>handle_non_host_target</b>(<i>args</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="main" ID="main"></a>
+<h2>main</h2>
+<b>main</b>(<i></i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="print_graphviz" ID="print_graphviz"></a>
+<h2>print_graphviz</h2>
+<b>print_graphviz</b>(<i>dump_output</i>)
+
+<p>
+Dump the data generated by GraphViz to stdout.
+</p>
+<p>
+    :param dump_output: The output from dump_graphviz
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="render_conflicts_text" ID="render_conflicts_text"></a>
+<h2>render_conflicts_text</h2>
+<b>render_conflicts_text</b>(<i>conflicts</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="render_cycles_text" ID="render_cycles_text"></a>
+<h2>render_cycles_text</h2>
+<b>render_cycles_text</b>(<i>cycles</i>)
+
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="render_json" ID="render_json"></a>
+<h2>render_json</h2>
+<b>render_json</b>(<i>tree, indent</i>)
+
+<p>
+Converts the tree into a flat json representation.
+</p>
+<p>
+    The json repr will be a list of hashes, each hash having 2 fields:
+      - package
+      - dependencies: list of dependencies
+</p>
+<p>
+    :param dict tree: dependency tree
+    :param int indent: no. of spaces to indent json
+    :returns: json representation of the tree
+    :rtype: str
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="render_json_tree" ID="render_json_tree"></a>
+<h2>render_json_tree</h2>
+<b>render_json_tree</b>(<i>tree, indent</i>)
+
+<p>
+Converts the tree into a nested json representation.
+</p>
+<p>
+    The json repr will be a list of hashes, each hash having the following fields:
+      - package_name
+      - key
+      - required_version
+      - installed_version
+      - dependencies: list of dependencies
+</p>
+<p>
+    :param dict tree: dependency tree
+    :param int indent: no. of spaces to indent json
+    :returns: json representation of the tree
+    :rtype: str
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="render_text" ID="render_text"></a>
+<h2>render_text</h2>
+<b>render_text</b>(<i>tree, list_all=True, frozen=False</i>)
+
+<p>
+Print tree as text on console
+</p>
+<p>
+    :param dict tree: the package tree
+    :param bool list_all: whether to list all the pgks at the root
+                          level or only those that are the
+                          sub-dependencies
+    :param bool frozen: whether or not show the names of the pkgs in
+                        the output that's favourable to pip --freeze
+    :returns: None
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="sorted_tree" ID="sorted_tree"></a>
+<h2>sorted_tree</h2>
+<b>sorted_tree</b>(<i>tree</i>)
+
+<p>
+Sorts the dict representation of the tree
+</p>
+<p>
+    The root packages as well as the intermediate packages are sorted
+    in the alphabetical order of the package names.
+</p>
+<p>
+    :param dict tree: the pkg dependency tree obtained by calling
+                     `construct_tree` function
+    :returns: sorted tree
+    :rtype: collections.OrderedDict
+</p>
+<p>
+
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/index-eric7.PipInterface.html	Mon Jul 11 17:56:42 2022 +0200
+++ b/src/eric7/Documentation/Source/index-eric7.PipInterface.html	Tue Jul 12 16:26:22 2022 +0200
@@ -52,6 +52,10 @@
 <td>Module implementing a Python package vulnerability checker.</td>
 </tr>
 <tr>
+<td><a href="eric7.PipInterface.pipdeptree.html">pipdeptree</a></td>
+<td>Copyright (c) 2015 Vineet Naik (naikvin@gmail.com)</td>
+</tr>
+<tr>
 <td><a href="eric7.PipInterface.piplicenses.html">piplicenses</a></td>
 <td>pip-licenses</td>
 </tr>
--- a/src/eric7/PipInterface/Pip.py	Mon Jul 11 17:56:42 2022 +0200
+++ b/src/eric7/PipInterface/Pip.py	Tue Jul 12 16:26:22 2022 +0200
@@ -943,10 +943,13 @@
         if envName:
             interpreter = self.getVirtualenvInterpreter(envName)
             if interpreter:
+                from . import pipdeptree
+                with open(pipdeptree.__file__, "r") as f:
+                    content = f.read()
                 args = [
-                    "-m", "pipdeptree",
+                    "-c",
+                    content,
                     "--json-tree",
-                    "--python", interpreter,
                 ]
                 if localPackages:
                     args.append("--local-only")
@@ -956,7 +959,7 @@
                     args.append("--reverse")
                 
                 proc = QProcess()
-                proc.start(Globals.getPythonExecutable(), args)
+                proc.start(interpreter, args)
                 if proc.waitForStarted(15000) and proc.waitForFinished(30000):
                     output = str(proc.readAllStandardOutput(),
                                  Preferences.getSystem("IOEncoding"),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/PipInterface/pipdeptree.py	Tue Jul 12 16:26:22 2022 +0200
@@ -0,0 +1,960 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Copyright (c) 2015 Vineet Naik (naikvin@gmail.com)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""
+
+#
+# Modified to be used within the eric-ide project.
+#
+# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+from __future__ import print_function
+import os
+import inspect
+import sys
+import subprocess
+from itertools import chain
+from collections import defaultdict, deque
+import argparse
+import json
+from importlib import import_module
+import tempfile
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict
+
+try:
+    from collections.abc import Mapping
+except ImportError:
+    from collections import Mapping
+
+from pip._vendor import pkg_resources
+try:
+    from pip._internal.operations.freeze import FrozenRequirement
+except ImportError:
+    from pip import FrozenRequirement
+
+
+__version__ = '2.2.1'
+
+
+flatten = chain.from_iterable
+
+
+def sorted_tree(tree):
+    """Sorts the dict representation of the tree
+
+    The root packages as well as the intermediate packages are sorted
+    in the alphabetical order of the package names.
+
+    :param dict tree: the pkg dependency tree obtained by calling
+                     `construct_tree` function
+    :returns: sorted tree
+    :rtype: collections.OrderedDict
+
+    """
+    return OrderedDict([(k, sorted(v)) for k, v in sorted(tree.items())])
+
+
+def guess_version(pkg_key, default='?'):
+    """Guess the version of a pkg when pip doesn't provide it
+
+    :param str pkg_key: key of the package
+    :param str default: default version to return if unable to find
+    :returns: version
+    :rtype: string
+
+    """
+    try:
+        m = import_module(pkg_key)
+    except ImportError:
+        return default
+    else:
+        v = getattr(m, '__version__', default)
+        if inspect.ismodule(v):
+            return getattr(v, '__version__', default)
+        else:
+            return v
+
+
+def frozen_req_from_dist(dist):
+    # The `pip._internal.metadata` modules were introduced in 21.1.1
+    # and the `pip._internal.operations.freeze.FrozenRequirement`
+    # class now expects dist to be a subclass of
+    # `pip._internal.metadata.BaseDistribution`, however the
+    # `pip._internal.utils.misc.get_installed_distributions` continues
+    # to return objects of type
+    # pip._vendor.pkg_resources.DistInfoDistribution.
+    #
+    # This is a hacky backward compatible (with older versions of pip)
+    # fix.
+    try:
+        from pip._internal import metadata
+    except ImportError:
+        pass
+    else:
+        dist = metadata.pkg_resources.Distribution(dist)
+
+    try:
+        return FrozenRequirement.from_dist(dist)
+    except TypeError:
+        return FrozenRequirement.from_dist(dist, [])
+
+
+class Package(object):
+    """Abstract class for wrappers around objects that pip returns.
+
+    This class needs to be subclassed with implementations for
+    `render_as_root` and `render_as_branch` methods.
+
+    """
+
+    def __init__(self, obj):
+        self._obj = obj
+        self.project_name = obj.project_name
+        self.key = obj.key
+
+    def render_as_root(self, frozen):
+        return NotImplementedError
+
+    def render_as_branch(self, frozen):
+        return NotImplementedError
+
+    def render(self, parent=None, frozen=False):
+        if not parent:
+            return self.render_as_root(frozen)
+        else:
+            return self.render_as_branch(frozen)
+
+    @staticmethod
+    def frozen_repr(obj):
+        fr = frozen_req_from_dist(obj)
+        return str(fr).strip()
+
+    def __getattr__(self, key):
+        return getattr(self._obj, key)
+
+    def __repr__(self):
+        return '<{0}("{1}")>'.format(self.__class__.__name__, self.key)
+
+    def __lt__(self, rhs):
+        return self.key < rhs.key
+
+
+class DistPackage(Package):
+    """Wrapper class for pkg_resources.Distribution instances
+
+      :param obj: pkg_resources.Distribution to wrap over
+      :param req: optional ReqPackage object to associate this
+                  DistPackage with. This is useful for displaying the
+                  tree in reverse
+    """
+
+    def __init__(self, obj, req=None):
+        super(DistPackage, self).__init__(obj)
+        self.version_spec = None
+        self.req = req
+
+    def render_as_root(self, frozen):
+        if not frozen:
+            return '{0}=={1}'.format(self.project_name, self.version)
+        else:
+            return self.__class__.frozen_repr(self._obj)
+
+    def render_as_branch(self, frozen):
+        assert self.req is not None
+        if not frozen:
+            parent_ver_spec = self.req.version_spec
+            parent_str = self.req.project_name
+            if parent_ver_spec:
+                parent_str += parent_ver_spec
+            return (
+                '{0}=={1} [requires: {2}]'
+            ).format(self.project_name, self.version, parent_str)
+        else:
+            return self.render_as_root(frozen)
+
+    def as_requirement(self):
+        """Return a ReqPackage representation of this DistPackage"""
+        return ReqPackage(self._obj.as_requirement(), dist=self)
+
+    def as_parent_of(self, req):
+        """Return a DistPackage instance associated to a requirement
+
+        This association is necessary for reversing the PackageDAG.
+
+        If `req` is None, and the `req` attribute of the current
+        instance is also None, then the same instance will be
+        returned.
+
+        :param ReqPackage req: the requirement to associate with
+        :returns: DistPackage instance
+
+        """
+        if req is None and self.req is None:
+            return self
+        return self.__class__(self._obj, req)
+
+    def as_dict(self):
+        return {'key': self.key,
+                'package_name': self.project_name,
+                'installed_version': self.version}
+
+
+class ReqPackage(Package):
+    """Wrapper class for Requirements instance
+
+      :param obj: The `Requirements` instance to wrap over
+      :param dist: optional `pkg_resources.Distribution` instance for
+                   this requirement
+    """
+
+    UNKNOWN_VERSION = '?'
+
+    def __init__(self, obj, dist=None):
+        super(ReqPackage, self).__init__(obj)
+        self.dist = dist
+
+    @property
+    def version_spec(self):
+        specs = sorted(self._obj.specs, reverse=True)  # `reverse` makes '>' prior to '<'
+        return ','.join([''.join(sp) for sp in specs]) if specs else None
+
+    @property
+    def installed_version(self):
+        if not self.dist:
+            return guess_version(self.key, self.UNKNOWN_VERSION)
+        return self.dist.version
+
+    @property
+    def is_missing(self):
+        return self.installed_version == self.UNKNOWN_VERSION
+
+    def is_conflicting(self):
+        """If installed version conflicts with required version"""
+        # unknown installed version is also considered conflicting
+        if self.installed_version == self.UNKNOWN_VERSION:
+            return True
+        ver_spec = (self.version_spec if self.version_spec else '')
+        req_version_str = '{0}{1}'.format(self.project_name, ver_spec)
+        req_obj = pkg_resources.Requirement.parse(req_version_str)
+        return self.installed_version not in req_obj
+
+    def render_as_root(self, frozen):
+        if not frozen:
+            return '{0}=={1}'.format(self.project_name, self.installed_version)
+        elif self.dist:
+            return self.__class__.frozen_repr(self.dist._obj)
+        else:
+            return self.project_name
+
+    def render_as_branch(self, frozen):
+        if not frozen:
+            req_ver = self.version_spec if self.version_spec else 'Any'
+            return (
+                '{0} [required: {1}, installed: {2}]'
+                ).format(self.project_name, req_ver, self.installed_version)
+        else:
+            return self.render_as_root(frozen)
+
+    def as_dict(self):
+        return {'key': self.key,
+                'package_name': self.project_name,
+                'installed_version': self.installed_version,
+                'required_version': self.version_spec}
+
+
+class PackageDAG(Mapping):
+    """Representation of Package dependencies as directed acyclic graph
+    using a dict (Mapping) as the underlying datastructure.
+
+    The nodes and their relationships (edges) are internally
+    stored using a map as follows,
+
+    {a: [b, c],
+     b: [d],
+     c: [d, e],
+     d: [e],
+     e: [],
+     f: [b],
+     g: [e, f]}
+
+    Here, node `a` has 2 children nodes `b` and `c`. Consider edge
+    direction from `a` -> `b` and `a` -> `c` respectively.
+
+    A node is expected to be an instance of a subclass of
+    `Package`. The keys are must be of class `DistPackage` and each
+    item in values must be of class `ReqPackage`. (See also
+    ReversedPackageDAG where the key and value types are
+    interchanged).
+
+    """
+
+    @classmethod
+    def from_pkgs(cls, pkgs):
+        pkgs = [DistPackage(p) for p in pkgs]
+        idx = {p.key: p for p in pkgs}
+        m = {p: [ReqPackage(r, idx.get(r.key))
+                 for r in p.requires()]
+             for p in pkgs}
+        return cls(m)
+
+    def __init__(self, m):
+        """Initialize the PackageDAG object
+
+        :param dict m: dict of node objects (refer class docstring)
+        :returns: None
+        :rtype: NoneType
+
+        """
+        self._obj = m
+        self._index = {p.key: p for p in list(self._obj)}
+
+    def get_node_as_parent(self, node_key):
+        """Get the node from the keys of the dict representing the DAG.
+
+        This method is useful if the dict representing the DAG
+        contains different kind of objects in keys and values. Use
+        this method to lookup a node obj as a parent (from the keys of
+        the dict) given a node key.
+
+        :param node_key: identifier corresponding to key attr of node obj
+        :returns: node obj (as present in the keys of the dict)
+        :rtype: Object
+
+        """
+        try:
+            return self._index[node_key]
+        except KeyError:
+            return None
+
+    def get_children(self, node_key):
+        """Get child nodes for a node by it's key
+
+        :param str node_key: key of the node to get children of
+        :returns: list of child nodes
+        :rtype: ReqPackage[]
+
+        """
+        node = self.get_node_as_parent(node_key)
+        return self._obj[node] if node else []
+
+    def filter(self, include, exclude):
+        """Filters nodes in a graph by given parameters
+
+        If a node is included, then all it's children are also
+        included.
+
+        :param set include: set of node keys to include (or None)
+        :param set exclude: set of node keys to exclude (or None)
+        :returns: filtered version of the graph
+        :rtype: PackageDAG
+
+        """
+        # If neither of the filters are specified, short circuit
+        if include is None and exclude is None:
+            return self
+
+        # Note: In following comparisons, we use lower cased values so
+        # that user may specify `key` or `project_name`. As per the
+        # documentation, `key` is simply
+        # `project_name.lower()`. Refer:
+        # https://setuptools.readthedocs.io/en/latest/pkg_resources.html#distribution-objects
+        if include:
+            include = set([s.lower() for s in include])
+        if exclude:
+            exclude = set([s.lower() for s in exclude])
+        else:
+            exclude = set([])
+
+        # Check for mutual exclusion of show_only and exclude sets
+        # after normalizing the values to lowercase
+        if include and exclude:
+            assert not (include & exclude)
+
+        # Traverse the graph in a depth first manner and filter the
+        # nodes according to `show_only` and `exclude` sets
+        stack = deque()
+        m = {}
+        seen = set([])
+        for node in self._obj.keys():
+            if node.key in exclude:
+                continue
+            if include is None or node.key in include:
+                stack.append(node)
+            while True:
+                if len(stack) > 0:
+                    n = stack.pop()
+                    cldn = [c for c in self._obj[n]
+                            if c.key not 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
+                                # ie. a dependency is missing
+                                continue
+                else:
+                    break
+
+        return self.__class__(m)
+
+    def reverse(self):
+        """Reverse the DAG, or turn it upside-down
+
+        In other words, the directions of edges of the nodes in the
+        DAG will be reversed.
+
+        Note that this function purely works on the nodes in the
+        graph. This implies that to perform a combination of filtering
+        and reversing, the order in which `filter` and `reverse`
+        methods should be applied is important. For eg. if reverse is
+        called on a filtered graph, then only the filtered nodes and
+        it's children will be considered when reversing. On the other
+        hand, if filter is called on reversed DAG, then the definition
+        of "child" nodes is as per the reversed DAG.
+
+        :returns: DAG in the reversed form
+        :rtype: ReversedPackageDAG
+
+        """
+        m = defaultdict(list)
+        child_keys = set(r.key for r in flatten(self._obj.values()))
+        for k, vs in self._obj.items():
+            for v in vs:
+                # 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 = [p for p in m.keys() if p.key == v.key][0]
+                except IndexError:
+                    node = v
+                m[node].append(k.as_parent_of(v))
+            if k.key not in child_keys:
+                m[k.as_requirement()] = []
+        return ReversedPackageDAG(dict(m))
+
+    def sort(self):
+        """Return sorted tree in which the underlying _obj dict is an
+        OrderedDict, sorted alphabetically by the keys
+
+        :returns: Instance of same class with OrderedDict
+
+        """
+        return self.__class__(sorted_tree(self._obj))
+
+    # Methods required by the abstract base class Mapping
+    def __getitem__(self, *args):
+        return self._obj.get(*args)
+
+    def __iter__(self):
+        return self._obj.__iter__()
+
+    def __len__(self):
+        return len(self._obj)
+
+
+class ReversedPackageDAG(PackageDAG):
+    """Representation of Package dependencies in the reverse
+    order.
+
+    Similar to it's super class `PackageDAG`, the underlying
+    datastructure is a dict, but here the keys are expected to be of
+    type `ReqPackage` and each item in the values of type
+    `DistPackage`.
+
+    Typically, this object will be obtained by calling
+    `PackageDAG.reverse`.
+
+    """
+
+    def reverse(self):
+        """Reverse the already reversed DAG to get the PackageDAG again
+
+        :returns: reverse of the reversed DAG
+        :rtype: PackageDAG
+
+        """
+        m = defaultdict(list)
+        child_keys = set(r.key for r in flatten(self._obj.values()))
+        for k, vs in self._obj.items():
+            for v in vs:
+                try:
+                    node = [p for p in m.keys() if p.key == v.key][0]
+                except IndexError:
+                    node = v.as_parent_of(None)
+                m[node].append(k)
+            if k.key not in child_keys:
+                m[k.dist] = []
+        return PackageDAG(dict(m))
+
+
+def render_text(tree, list_all=True, frozen=False):
+    """Print tree as text on console
+
+    :param dict tree: the package tree
+    :param bool list_all: whether to list all the pgks at the root
+                          level or only those that are the
+                          sub-dependencies
+    :param bool frozen: whether or not show the names of the pkgs in
+                        the output that's favourable to pip --freeze
+    :returns: None
+
+    """
+    tree = tree.sort()
+    nodes = tree.keys()
+    branch_keys = set(r.key for r in flatten(tree.values()))
+    use_bullets = not frozen
+
+    if not list_all:
+        nodes = [p for p in nodes if p.key not in branch_keys]
+
+    def aux(node, parent=None, indent=0, chain=None):
+        chain = chain or []
+        node_str = node.render(parent, frozen)
+        if parent:
+            prefix = ' '*indent + ('- ' if use_bullets else '')
+            node_str = prefix + node_str
+        result = [node_str]
+        children = [aux(c, node, indent=indent+2,
+                        chain=chain+[c.project_name])
+                    for c in tree.get_children(node.key)
+                    if c.project_name not in chain]
+        result += list(flatten(children))
+        return result
+
+    lines = flatten([aux(p) for p in nodes])
+    print('\n'.join(lines))
+
+
+def render_json(tree, indent):
+    """Converts the tree into a flat json representation.
+
+    The json repr will be a list of hashes, each hash having 2 fields:
+      - package
+      - dependencies: list of dependencies
+
+    :param dict tree: dependency tree
+    :param int indent: no. of spaces to indent json
+    :returns: json representation of the tree
+    :rtype: str
+
+    """
+    tree = tree.sort()
+    return json.dumps([{'package': k.as_dict(),
+                        'dependencies': [v.as_dict() for v in vs]}
+                       for k, vs in tree.items()],
+                      indent=indent)
+
+
+def render_json_tree(tree, indent):
+    """Converts the tree into a nested json representation.
+
+    The json repr will be a list of hashes, each hash having the following fields:
+      - package_name
+      - key
+      - required_version
+      - installed_version
+      - dependencies: list of dependencies
+
+    :param dict tree: dependency tree
+    :param int indent: no. of spaces to indent json
+    :returns: json representation of the tree
+    :rtype: str
+
+    """
+    tree = tree.sort()
+    branch_keys = set(r.key for r in flatten(tree.values()))
+    nodes = [p for p in tree.keys() if p.key not in branch_keys]
+
+    def aux(node, parent=None, chain=None):
+        if chain is None:
+            chain = [node.project_name]
+
+        d = node.as_dict()
+        if parent:
+            d['required_version'] = node.version_spec if node.version_spec else 'Any'
+        else:
+            d['required_version'] = d['installed_version']
+
+        d['dependencies'] = [
+            aux(c, parent=node, chain=chain+[c.project_name])
+            for c in tree.get_children(node.key)
+            if c.project_name not in chain
+        ]
+
+        return d
+
+    return json.dumps([aux(p) for p in nodes], indent=indent)
+
+
+def dump_graphviz(tree, output_format='dot', is_reverse=False):
+    """Output dependency graph as one of the supported GraphViz output formats.
+
+    :param dict tree: dependency graph
+    :param string output_format: output format
+    :returns: representation of tree in the specified output format
+    :rtype: str or binary representation depending on the output format
+
+    """
+    try:
+        from graphviz import Digraph
+    except ImportError:
+        print('graphviz is not available, but necessary for the output '
+              'option. Please install it.', file=sys.stderr)
+        sys.exit(1)
+
+    try:
+        from graphviz import parameters
+    except ImportError:
+        from graphviz import backend
+        valid_formats = backend.FORMATS
+        print('Deprecation warning! Please upgrade graphviz to version >=0.18.0 '
+              'Support for older versions will be removed in upcoming release',
+              file=sys.stderr)
+    else:
+        valid_formats = parameters.FORMATS
+
+    if output_format not in valid_formats:
+        print('{0} is not a supported output format.'.format(output_format),
+              file=sys.stderr)
+        print('Supported formats are: {0}'.format(
+            ', '.join(sorted(valid_formats))), file=sys.stderr)
+        sys.exit(1)
+
+    graph = Digraph(format=output_format)
+
+    if not is_reverse:
+        for pkg, deps in tree.items():
+            pkg_label = '{0}\\n{1}'.format(pkg.project_name, pkg.version)
+            graph.node(pkg.key, label=pkg_label)
+            for dep in deps:
+                edge_label = dep.version_spec or 'any'
+                if dep.is_missing:
+                    dep_label = '{0}\\n(missing)'.format(dep.project_name)
+                    graph.node(dep.key, label=dep_label, style='dashed')
+                    graph.edge(pkg.key, dep.key, style='dashed')
+                else:
+                    graph.edge(pkg.key, dep.key, label=edge_label)
+    else:
+        for dep, parents in tree.items():
+            dep_label = '{0}\\n{1}'.format(dep.project_name,
+                                          dep.installed_version)
+            graph.node(dep.key, label=dep_label)
+            for parent in parents:
+                # req reference of the dep associated with this
+                # particular parent package
+                req_ref = parent.req
+                edge_label = req_ref.version_spec or 'any'
+                graph.edge(dep.key, parent.key, label=edge_label)
+
+    # Allow output of dot format, even if GraphViz isn't installed.
+    if output_format == 'dot':
+        return graph.source
+
+    # 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.
+    try:
+        return graph.pipe().decode('utf-8')
+    except UnicodeDecodeError:
+        return graph.pipe()
+
+
+def print_graphviz(dump_output):
+    """Dump the data generated by GraphViz to stdout.
+
+    :param dump_output: The output from dump_graphviz
+    """
+    if hasattr(dump_output, 'encode'):
+        print(dump_output)
+    else:
+        with os.fdopen(sys.stdout.fileno(), 'wb') as bytestream:
+            bytestream.write(dump_output)
+
+
+def conflicting_deps(tree):
+    """Returns dependencies which are not present or conflict with the
+    requirements of other packages.
+
+    e.g. will warn if pkg1 requires pkg2==2.0 and pkg2==1.0 is installed
+
+    :param tree: the requirements tree (dict)
+    :returns: dict of DistPackage -> list of unsatisfied/unknown ReqPackage
+    :rtype: dict
+
+    """
+    conflicting = defaultdict(list)
+    for p, rs in tree.items():
+        for req in rs:
+            if req.is_conflicting():
+                conflicting[p].append(req)
+    return conflicting
+
+
+def render_conflicts_text(conflicts):
+    if conflicts:
+        print('Warning!!! Possibly conflicting dependencies found:',
+              file=sys.stderr)
+        # Enforce alphabetical order when listing conflicts
+        pkgs = sorted(conflicts.keys())
+        for p in pkgs:
+            pkg = p.render_as_root(False)
+            print('* {}'.format(pkg), file=sys.stderr)
+            for req in conflicts[p]:
+                req_str = req.render_as_branch(False)
+                print(' - {}'.format(req_str), file=sys.stderr)
+
+
+def cyclic_deps(tree):
+    """Return cyclic dependencies as list of tuples
+
+    :param PackageDAG pkgs: package tree/dag
+    :returns: list of tuples representing cyclic dependencies
+    :rtype: list
+
+    """
+    index = {p.key: set([r.key for r in rs]) for p, rs in tree.items()}
+    cyclic = []
+    for p, rs in tree.items():
+        for r in rs:
+            if p.key in index.get(r.key, []):
+                p_as_dep_of_r = [x for x
+                                 in tree.get(tree.get_node_as_parent(r.key))
+                                 if x.key == p.key][0]
+                cyclic.append((p, r, p_as_dep_of_r))
+    return cyclic
+
+
+def render_cycles_text(cycles):
+    if cycles:
+        print('Warning!! Cyclic dependencies found:', file=sys.stderr)
+        # List in alphabetical order of the dependency that's cycling
+        # (2nd item in the tuple)
+        cycles = sorted(cycles, key=lambda xs: xs[1].key)
+        for a, b, c in cycles:
+            print('* {0} => {1} => {2}'.format(a.project_name,
+                                               b.project_name,
+                                               c.project_name),
+                  file=sys.stderr)
+
+
+def get_parser():
+    parser = argparse.ArgumentParser(description=(
+        'Dependency tree of the installed python packages'
+    ))
+    parser.add_argument('-v', '--version', action='version',
+                        version='{0}'.format(__version__))
+    parser.add_argument('-f', '--freeze', action='store_true',
+                        help='Print names so as to write freeze files')
+    parser.add_argument('--python', default=sys.executable,
+                        help='Python to use to look for packages in it (default: where'
+                             ' installed)')
+    parser.add_argument('-a', '--all', action='store_true',
+                        help='list all deps at top level')
+    parser.add_argument('-l', '--local-only',
+                        action='store_true', help=(
+                            'If in a virtualenv that has global access '
+                            'do not show globally installed packages'
+                        ))
+    parser.add_argument('-u', '--user-only', action='store_true',
+                        help=(
+                            'Only show installations in the user site dir'
+                        ))
+    parser.add_argument('-w', '--warn', action='store', dest='warn',
+                        nargs='?', default='suppress',
+                        choices=('silence', 'suppress', 'fail'),
+                        help=(
+                            'Warning control. "suppress" will show warnings '
+                            'but return 0 whether or not they are present. '
+                            '"silence" will not show warnings at all and '
+                            'always return 0. "fail" will show warnings and '
+                            'return 1 if any are present. The default is '
+                            '"suppress".'
+                        ))
+    parser.add_argument('-r', '--reverse', action='store_true',
+                        default=False, help=(
+                            'Shows the dependency tree in the reverse fashion '
+                            'ie. the sub-dependencies are listed with the '
+                            'list of packages that need them under them.'
+                        ))
+    parser.add_argument('-p', '--packages',
+                        help=(
+                            'Comma separated list of select packages to show '
+                            'in the output. If set, --all will be ignored.'
+                        ))
+    parser.add_argument('-e', '--exclude',
+                        help=(
+                            'Comma separated list of select packages to exclude '
+                            'from the output. If set, --all will be ignored.'
+                        ), metavar='PACKAGES')
+    parser.add_argument('-j', '--json', action='store_true', default=False,
+                        help=(
+                            'Display dependency tree as json. This will yield '
+                            '"raw" output that may be used by external tools. '
+                            'This option overrides all other options.'
+                        ))
+    parser.add_argument('--json-tree', action='store_true', default=False,
+                        help=(
+                            'Display dependency tree as json which is nested '
+                            'the same way as the plain text output printed by default. '
+                            'This option overrides all other options (except --json).'
+                        ))
+    parser.add_argument('--graph-output', dest='output_format',
+                        help=(
+                            'Print a dependency graph in the specified output '
+                            'format. Available are all formats supported by '
+                            'GraphViz, e.g.: dot, jpeg, pdf, png, svg'
+                        ))
+    return parser
+
+
+def _get_args():
+    parser = get_parser()
+    return parser.parse_args()
+
+
+def handle_non_host_target(args):
+    of_python = os.path.abspath(args.python)
+    # if target is not current python re-invoke it under the actual host
+    if of_python != os.path.abspath(sys.executable):
+        # there's no way to guarantee that graphviz is available, so refuse
+        if args.output_format:
+            print("graphviz functionality is not supported when querying"
+                  " non-host python", file=sys.stderr)
+            raise SystemExit(1)
+        argv = sys.argv[1:]  # remove current python executable
+        for py_at, value in enumerate(argv):
+            if value == "--python":
+                del argv[py_at]
+                del argv[py_at]
+            elif value.startswith("--python"):
+                del argv[py_at]
+        # feed the file as argument, instead of file
+        # to avoid adding the file path to sys.path, that can affect result
+        file_path = inspect.getsourcefile(sys.modules[__name__])
+        with open(file_path, 'rt') as file_handler:
+            content = file_handler.read()
+        cmd = [of_python, "-c", content]
+        cmd.extend(argv)
+        # invoke from an empty folder to avoid cwd altering sys.path
+        cwd = tempfile.mkdtemp()
+        try:
+            return subprocess.call(cmd, cwd=cwd)
+        finally:
+            os.removedirs(cwd)
+    return None
+
+
+def get_installed_distributions(local_only=False, user_only=False):
+    try:
+        from pip._internal.metadata import get_environment
+    except ImportError:
+        # For backward compatibility with python ver. 2.7 and pip
+        # version 20.3.4 (latest pip version that works with python
+        # version 2.7)
+        from pip._internal.utils import misc
+        return misc.get_installed_distributions(
+            local_only=local_only,
+            user_only=user_only
+        )
+    else:
+        dists = get_environment(None).iter_installed_distributions(
+            local_only=local_only,
+            skip=(),
+            user_only=user_only
+        )
+        return [d._dist for d in dists]
+
+
+def main():
+    os.environ["_PIP_USE_IMPORTLIB_METADATA"] = "False"
+    # patched for 3.11+ compatibility
+    
+    args = _get_args()
+    result = handle_non_host_target(args)
+    if result is not None:
+        return result
+
+    pkgs = get_installed_distributions(local_only=args.local_only,
+                                       user_only=args.user_only)
+
+    tree = PackageDAG.from_pkgs(pkgs)
+
+    is_text_output = not any([args.json, args.json_tree, args.output_format])
+
+    return_code = 0
+
+    # Before any reversing or filtering, show warnings to console
+    # about possibly conflicting or cyclic deps if found and warnings
+    # are enabled (ie. only if output is to be printed to console)
+    if is_text_output and args.warn != 'silence':
+        conflicts = conflicting_deps(tree)
+        if conflicts:
+            render_conflicts_text(conflicts)
+            print('-'*72, file=sys.stderr)
+
+        cycles = cyclic_deps(tree)
+        if cycles:
+            render_cycles_text(cycles)
+            print('-'*72, file=sys.stderr)
+
+        if args.warn == 'fail' and (conflicts or cycles):
+            return_code = 1
+
+    # Reverse the tree (if applicable) before filtering, thus ensuring
+    # that the filter will be applied on ReverseTree
+    if args.reverse:
+        tree = tree.reverse()
+
+    show_only = set(args.packages.split(',')) if args.packages else None
+    exclude = set(args.exclude.split(',')) if args.exclude else None
+
+    if show_only is not None or exclude is not None:
+        tree = tree.filter(show_only, exclude)
+
+    if args.json:
+        print(render_json(tree, indent=4))
+    elif args.json_tree:
+        print(render_json_tree(tree, indent=4))
+    elif args.output_format:
+        output = dump_graphviz(tree,
+                               output_format=args.output_format,
+                               is_reverse=args.reverse)
+        print_graphviz(output)
+    else:
+        render_text(tree, args.all, args.freeze)
+
+    return return_code
+
+
+if __name__ == '__main__':
+    sys.exit(main())
--- a/src/eric7/PipInterface/piplicenses.py	Mon Jul 11 17:56:42 2022 +0200
+++ b/src/eric7/PipInterface/piplicenses.py	Tue Jul 12 16:26:22 2022 +0200
@@ -652,6 +652,9 @@
 
 
 def main():  # pragma: no cover
+    os.environ["_PIP_USE_IMPORTLIB_METADATA"] = "False"
+    # patched for 3.11+ compatibility
+    
     parser = create_parser()
     args = parser.parse_args()
 

eric ide

mercurial