src/eric7/PipInterface/pipdeptree.py

Sat, 31 Dec 2022 16:23:21 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 31 Dec 2022 16:23:21 +0100
branch
eric7
changeset 9653
e67609152c5e
parent 9589
09218eb3ae21
child 9849
99782ca569ed
permissions
-rw-r--r--

Updated copyright for 2023.

9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
1 #!/usr/bin/env python
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
3
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
4 #
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
5 # eric-ide modification: Copyright from file "LICENSE"
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
6 #
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
7
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
8 """
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
9 Copyright (c) The pipdeptree developers
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
10
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
11 Permission is hereby granted, free of charge, to any person obtaining
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
12 a copy of this software and associated documentation files (the
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
13 "Software"), to deal in the Software without restriction, including
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
14 without limitation the rights to use, copy, modify, merge, publish,
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
15 distribute, sublicense, and/or sell copies of the Software, and to
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
16 permit persons to whom the Software is furnished to do so, subject to
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
17 the following conditions:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
18
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
19 The above copyright notice and this permission notice shall be
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
20 included in all copies or substantial portions of the Software.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
21
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
29 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
30
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
31 #
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
32 # Slightly modified to be used within the eric-ide project.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
33 #
9653
e67609152c5e Updated copyright for 2023.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9589
diff changeset
34 # Copyright (c) 2022 - 2023 Detlev Offenbach <detlev@die-offenbachs.de>
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
35 #
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
36
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
37 import argparse
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
38 import inspect
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
39 import json
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
40 import os
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
41 import shutil
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
42 import subprocess
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
43 import sys
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
44 import tempfile
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
45 from collections import defaultdict, deque
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
46 from collections.abc import Mapping
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
47 from importlib import import_module
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
48 from itertools import chain
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
49
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
50 from pip._vendor import pkg_resources
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
51
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
52 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
53 from pip._internal.operations.freeze import FrozenRequirement
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
54 except ImportError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
55 from pip import FrozenRequirement
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
56
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
57
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
58 __version__ = '2.3.3' # eric-ide modification: from version.py
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
59
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
60
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
61 flatten = chain.from_iterable
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
62
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
63
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
64 def sorted_tree(tree):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
65 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
66 Sorts the dict representation of the tree. The root packages as well as the intermediate packages are sorted in the
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
67 alphabetical order of the package names.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
68
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
69 :param dict tree: the pkg dependency tree obtained by calling `construct_tree` function
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
70 :returns: sorted tree
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
71 :rtype: dict
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
72 """
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
73 return {k: sorted(v) for k, v in sorted(tree.items())}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
74
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
75
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
76 def guess_version(pkg_key, default="?"):
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
77 """Guess the version of a pkg when pip doesn't provide it
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
78
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
79 :param str pkg_key: key of the package
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
80 :param str default: default version to return if unable to find
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
81 :returns: version
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
82 :rtype: string
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
83 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
84 try:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
85 if sys.version_info >= (3, 8): # pragma: >=3.8 cover
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
86 import importlib.metadata as importlib_metadata
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
87 else: # pragma: <3.8 cover
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
88 import importlib_metadata
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
89 return importlib_metadata.version(pkg_key)
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
90 except ImportError:
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
91 pass
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
92 # Avoid AssertionError with setuptools, see https://github.com/tox-dev/pipdeptree/issues/162
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
93 if pkg_key in {"setuptools"}:
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
94 return default
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
95 try:
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
96 m = import_module(pkg_key)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
97 except ImportError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
98 return default
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
99 else:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
100 v = getattr(m, "__version__", default)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
101 if inspect.ismodule(v):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
102 return getattr(v, "__version__", default)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
103 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
104 return v
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
105
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
106
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
107 def frozen_req_from_dist(dist):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
108 # The `pip._internal.metadata` modules were introduced in 21.1.1
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
109 # and the `pip._internal.operations.freeze.FrozenRequirement`
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
110 # class now expects dist to be a subclass of
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
111 # `pip._internal.metadata.BaseDistribution`, however the
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
112 # `pip._internal.utils.misc.get_installed_distributions` continues
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
113 # to return objects of type
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
114 # pip._vendor.pkg_resources.DistInfoDistribution.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
115 #
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
116 # This is a hacky backward compatible (with older versions of pip)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
117 # fix.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
118 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
119 from pip._internal import metadata
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
120 except ImportError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
121 pass
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
122 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
123 dist = metadata.pkg_resources.Distribution(dist)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
124
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
125 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
126 return FrozenRequirement.from_dist(dist)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
127 except TypeError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
128 return FrozenRequirement.from_dist(dist, [])
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
129
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
130
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
131 class Package:
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
132 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
133 Abstract class for wrappers around objects that pip returns. This class needs to be subclassed with implementations
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
134 for `render_as_root` and `render_as_branch` methods.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
135 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
136
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
137 def __init__(self, obj):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
138 self._obj = obj
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
139 self.project_name = obj.project_name
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
140 self.key = obj.key
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
141
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
142 def render_as_root(self, frozen): # noqa: U100
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
143 return NotImplementedError
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
144
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
145 def render_as_branch(self, frozen): # noqa: U100
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
146 return NotImplementedError
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
147
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
148 def render(self, parent=None, frozen=False):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
149 if not parent:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
150 return self.render_as_root(frozen)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
151 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
152 return self.render_as_branch(frozen)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
153
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
154 @staticmethod
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
155 def frozen_repr(obj):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
156 fr = frozen_req_from_dist(obj)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
157 return str(fr).strip()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
158
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
159 def __getattr__(self, key):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
160 return getattr(self._obj, key)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
161
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
162 def __repr__(self):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
163 return f'<{self.__class__.__name__}("{self.key}")>'
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
164
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
165 def __lt__(self, rhs):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
166 return self.key < rhs.key
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
167
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
168
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
169 class DistPackage(Package):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
170 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
171 Wrapper class for pkg_resources.Distribution instances
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
172
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
173 :param obj: pkg_resources.Distribution to wrap over
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
174 :param req: optional ReqPackage object to associate this DistPackage with. This is useful for displaying the tree
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
175 in reverse
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
176 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
177
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
178 def __init__(self, obj, req=None):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
179 super().__init__(obj)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
180 self.version_spec = None
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
181 self.req = req
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
182
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
183 def render_as_root(self, frozen):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
184 if not frozen:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
185 return f"{self.project_name}=={self.version}"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
186 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
187 return self.__class__.frozen_repr(self._obj)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
188
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
189 def render_as_branch(self, frozen):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
190 assert self.req is not None
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
191 if not frozen:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
192 parent_ver_spec = self.req.version_spec
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
193 parent_str = self.req.project_name
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
194 if parent_ver_spec:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
195 parent_str += parent_ver_spec
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
196 return f"{self.project_name}=={self.version} [requires: {parent_str}]"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
197 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
198 return self.render_as_root(frozen)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
199
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
200 def as_requirement(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
201 """Return a ReqPackage representation of this DistPackage"""
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
202 return ReqPackage(self._obj.as_requirement(), dist=self)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
203
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
204 def as_parent_of(self, req):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
205 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
206 Return a DistPackage instance associated to a requirement. This association is necessary for reversing the
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
207 PackageDAG.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
208
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
209 If `req` is None, and the `req` attribute of the current instance is also None, then the same instance will be
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
210 returned.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
211
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
212 :param ReqPackage req: the requirement to associate with
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
213 :returns: DistPackage instance
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
214 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
215 if req is None and self.req is None:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
216 return self
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
217 return self.__class__(self._obj, req)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
219 def as_dict(self):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
220 return {"key": self.key, "package_name": self.project_name, "installed_version": self.version}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
221
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
222
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
223 class ReqPackage(Package):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
224 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
225 Wrapper class for Requirements instance
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
226
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
227 :param obj: The `Requirements` instance to wrap over
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
228 :param dist: optional `pkg_resources.Distribution` instance for this requirement
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
229 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
230
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
231 UNKNOWN_VERSION = "?"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
232
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
233 def __init__(self, obj, dist=None):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
234 super().__init__(obj)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
235 self.dist = dist
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
236
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
237 @property
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
238 def version_spec(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
239 specs = sorted(self._obj.specs, reverse=True) # `reverse` makes '>' prior to '<'
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
240 return ",".join(["".join(sp) for sp in specs]) if specs else None
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
241
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
242 @property
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
243 def installed_version(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
244 if not self.dist:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
245 return guess_version(self.key, self.UNKNOWN_VERSION)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
246 return self.dist.version
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
247
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
248 @property
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
249 def is_missing(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
250 return self.installed_version == self.UNKNOWN_VERSION
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
251
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
252 def is_conflicting(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
253 """If installed version conflicts with required version"""
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
254 # unknown installed version is also considered conflicting
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
255 if self.installed_version == self.UNKNOWN_VERSION:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
256 return True
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
257 ver_spec = self.version_spec if self.version_spec else ""
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
258 req_version_str = f"{self.project_name}{ver_spec}"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
259 req_obj = pkg_resources.Requirement.parse(req_version_str)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
260 return self.installed_version not in req_obj
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
261
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
262 def render_as_root(self, frozen):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
263 if not frozen:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
264 return f"{self.project_name}=={self.installed_version}"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
265 elif self.dist:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
266 return self.__class__.frozen_repr(self.dist._obj)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
267 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
268 return self.project_name
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
269
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
270 def render_as_branch(self, frozen):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
271 if not frozen:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
272 req_ver = self.version_spec if self.version_spec else "Any"
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
273 return f"{self.project_name} [required: {req_ver}, installed: {self.installed_version}]"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
274 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
275 return self.render_as_root(frozen)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
276
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
277 def as_dict(self):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
278 return {
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
279 "key": self.key,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
280 "package_name": self.project_name,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
281 "installed_version": self.installed_version,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
282 "required_version": self.version_spec,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
283 }
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
284
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
285
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
286 class PackageDAG(Mapping):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
287 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
288 Representation of Package dependencies as directed acyclic graph using a dict (Mapping) as the underlying
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
289 datastructure.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
290
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
291 The nodes and their relationships (edges) are internally stored using a map as follows,
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
292
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
293 {a: [b, c],
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
294 b: [d],
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
295 c: [d, e],
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
296 d: [e],
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
297 e: [],
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
298 f: [b],
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
299 g: [e, f]}
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
300
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
301 Here, node `a` has 2 children nodes `b` and `c`. Consider edge direction from `a` -> `b` and `a` -> `c`
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
302 respectively.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
303
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
304 A node is expected to be an instance of a subclass of `Package`. The keys are must be of class `DistPackage` and
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
305 each item in values must be of class `ReqPackage`. (See also ReversedPackageDAG where the key and value types are
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
306 interchanged).
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
307 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
308
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
309 @classmethod
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
310 def from_pkgs(cls, pkgs):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
311 pkgs = [DistPackage(p) for p in pkgs]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
312 idx = {p.key: p for p in pkgs}
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
313 m = {p: [ReqPackage(r, idx.get(r.key)) for r in p.requires()] for p in pkgs}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
314 return cls(m)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
315
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
316 def __init__(self, m):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
317 """Initialize the PackageDAG object
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
318
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
319 :param dict m: dict of node objects (refer class docstring)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
320 :returns: None
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
321 :rtype: NoneType
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
322
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
323 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
324 self._obj = m
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
325 self._index = {p.key: p for p in list(self._obj)}
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
326
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
327 def get_node_as_parent(self, node_key):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
328 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
329 Get the node from the keys of the dict representing the DAG.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
330
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
331 This method is useful if the dict representing the DAG contains different kind of objects in keys and values.
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
332 Use this method to look up a node obj as a parent (from the keys of the dict) given a node key.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
333
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
334 :param node_key: identifier corresponding to key attr of node obj
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
335 :returns: node obj (as present in the keys of the dict)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
336 :rtype: Object
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
337 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
338 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
339 return self._index[node_key]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
340 except KeyError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
341 return None
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
342
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
343 def get_children(self, node_key):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
344 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
345 Get child nodes for a node by its key
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
346
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
347 :param str node_key: key of the node to get children of
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
348 :returns: list of child nodes
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
349 :rtype: ReqPackage[]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
350 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
351 node = self.get_node_as_parent(node_key)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
352 return self._obj[node] if node else []
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
353
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
354 def filter(self, include, exclude):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
355 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
356 Filters nodes in a graph by given parameters
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
357
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
358 If a node is included, then all it's children are also included.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
359
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
360 :param set include: set of node keys to include (or None)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
361 :param set exclude: set of node keys to exclude (or None)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
362 :returns: filtered version of the graph
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
363 :rtype: PackageDAG
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
364 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
365 # If neither of the filters are specified, short circuit
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
366 if include is None and exclude is None:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
367 return self
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
368
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
369 # Note: In following comparisons, we use lower cased values so
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
370 # that user may specify `key` or `project_name`. As per the
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
371 # documentation, `key` is simply
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
372 # `project_name.lower()`. Refer:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
373 # https://setuptools.readthedocs.io/en/latest/pkg_resources.html#distribution-objects
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
374 if include:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
375 include = {s.lower() for s in include}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
376 if exclude:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
377 exclude = {s.lower() for s in exclude}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
378 else:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
379 exclude = set()
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
380
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
381 # Check for mutual exclusion of show_only and exclude sets
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
382 # after normalizing the values to lowercase
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
383 if include and exclude:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
384 assert not (include & exclude)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
385
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
386 # Traverse the graph in a depth first manner and filter the
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
387 # nodes according to `show_only` and `exclude` sets
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
388 stack = deque()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
389 m = {}
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
390 seen = set()
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
391 for node in self._obj.keys():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
392 if node.key in exclude:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
393 continue
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
394 if include is None or node.key in include:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
395 stack.append(node)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
396 while True:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
397 if len(stack) > 0:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
398 n = stack.pop()
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
399 cldn = [c for c in self._obj[n] if c.key not in exclude]
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
400 m[n] = cldn
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
401 seen.add(n.key)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
402 for c in cldn:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
403 if c.key not in seen:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
404 cld_node = self.get_node_as_parent(c.key)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
405 if cld_node:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
406 stack.append(cld_node)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
407 else:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
408 # It means there's no root node corresponding to the child node i.e.
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
409 # a dependency is missing
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
410 continue
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
411 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
412 break
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
413
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
414 return self.__class__(m)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
415
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
416 def reverse(self):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
417 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
418 Reverse the DAG, or turn it upside-down.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
419
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
420 In other words, the directions of edges of the nodes in the DAG will be reversed.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
421
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
422 Note that this function purely works on the nodes in the graph. This implies that to perform a combination of
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
423 filtering and reversing, the order in which `filter` and `reverse` methods should be applied is important. For
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
424 e.g., if reverse is called on a filtered graph, then only the filtered nodes and it's children will be
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
425 considered when reversing. On the other hand, if filter is called on reversed DAG, then the definition of
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
426 "child" nodes is as per the reversed DAG.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
427
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
428 :returns: DAG in the reversed form
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
429 :rtype: ReversedPackageDAG
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
430 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
431 m = defaultdict(list)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
432 child_keys = {r.key for r in chain.from_iterable(self._obj.values())}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
433 for k, vs in self._obj.items():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
434 for v in vs:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
435 # if v is already added to the dict, then ensure that
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
436 # we are using the same object. This check is required
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
437 # as we're using array mutation
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
438 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
439 node = [p for p in m.keys() if p.key == v.key][0]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
440 except IndexError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
441 node = v
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
442 m[node].append(k.as_parent_of(v))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
443 if k.key not in child_keys:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
444 m[k.as_requirement()] = []
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
445 return ReversedPackageDAG(dict(m))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
446
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
447 def sort(self):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
448 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
449 Return sorted tree in which the underlying _obj dict is an dict, sorted alphabetically by the keys.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
450
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
451 :returns: Instance of same class with dict
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
452 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
453 return self.__class__(sorted_tree(self._obj))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
454
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
455 # Methods required by the abstract base class Mapping
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
456 def __getitem__(self, *args):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
457 return self._obj.get(*args)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
458
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
459 def __iter__(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
460 return self._obj.__iter__()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
461
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
462 def __len__(self):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
463 return len(self._obj)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
464
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
465
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
466 class ReversedPackageDAG(PackageDAG):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
467 """Representation of Package dependencies in the reverse order.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
468
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
469 Similar to it's super class `PackageDAG`, the underlying datastructure is a dict, but here the keys are expected to
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
470 be of type `ReqPackage` and each item in the values of type `DistPackage`.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
471
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
472 Typically, this object will be obtained by calling `PackageDAG.reverse`.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
473 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
474
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
475 def reverse(self):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
476 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
477 Reverse the already reversed DAG to get the PackageDAG again
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
478
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
479 :returns: reverse of the reversed DAG
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
480 :rtype: PackageDAG
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
481 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
482 m = defaultdict(list)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
483 child_keys = {r.key for r in chain.from_iterable(self._obj.values())}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
484 for k, vs in self._obj.items():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
485 for v in vs:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
486 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
487 node = [p for p in m.keys() if p.key == v.key][0]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
488 except IndexError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
489 node = v.as_parent_of(None)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
490 m[node].append(k)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
491 if k.key not in child_keys:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
492 m[k.dist] = []
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
493 return PackageDAG(dict(m))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
494
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
495
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
496 def render_text(tree, list_all=True, frozen=False):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
497 """Print tree as text on console
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
498
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
499 :param dict tree: the package tree
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
500 :param bool list_all: whether to list all the pgks at the root level or only those that are the sub-dependencies
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
501 :param bool frozen: show the names of the pkgs in the output that's favourable to pip --freeze
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
502 :returns: None
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
503
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
504 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
505 tree = tree.sort()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
506 nodes = tree.keys()
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
507 branch_keys = {r.key for r in chain.from_iterable(tree.values())}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
508 use_bullets = not frozen
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
509
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
510 if not list_all:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
511 nodes = [p for p in nodes if p.key not in branch_keys]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
512
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
513 def aux(node, parent=None, indent=0, cur_chain=None):
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
514 cur_chain = cur_chain or []
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
515 node_str = node.render(parent, frozen)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
516 if parent:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
517 prefix = " " * indent + ("- " if use_bullets else "")
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
518 node_str = prefix + node_str
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
519 result = [node_str]
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
520 children = [
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
521 aux(c, node, indent=indent + 2, cur_chain=cur_chain + [c.project_name])
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
522 for c in tree.get_children(node.key)
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
523 if c.project_name not in cur_chain
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
524 ]
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
525 result += list(chain.from_iterable(children))
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
526 return result
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
527
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
528 lines = chain.from_iterable([aux(p) for p in nodes])
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
529 print("\n".join(lines))
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
530
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
531
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
532 def render_json(tree, indent):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
533 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
534 Converts the tree into a flat json representation.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
535
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
536 The json repr will be a list of hashes, each hash having 2 fields:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
537 - package
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
538 - dependencies: list of dependencies
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
539
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
540 :param dict tree: dependency tree
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
541 :param int indent: no. of spaces to indent json
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
542 :returns: json representation of the tree
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
543 :rtype: str
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
544 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
545 tree = tree.sort()
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
546 return json.dumps(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
547 [{"package": k.as_dict(), "dependencies": [v.as_dict() for v in vs]} for k, vs in tree.items()], indent=indent
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
548 )
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
549
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
550
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
551 def render_json_tree(tree, indent):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
552 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
553 Converts the tree into a nested json representation.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
554
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
555 The json repr will be a list of hashes, each hash having the following fields:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
556
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
557 - package_name
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
558 - key
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
559 - required_version
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
560 - installed_version
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
561 - dependencies: list of dependencies
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
562
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
563 :param dict tree: dependency tree
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
564 :param int indent: no. of spaces to indent json
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
565 :returns: json representation of the tree
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
566 :rtype: str
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
567 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
568 tree = tree.sort()
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
569 branch_keys = {r.key for r in chain.from_iterable(tree.values())}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
570 nodes = [p for p in tree.keys() if p.key not in branch_keys]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
571
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
572 def aux(node, parent=None, cur_chain=None):
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
573 if cur_chain is None:
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
574 cur_chain = [node.project_name]
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
575
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
576 d = node.as_dict()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
577 if parent:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
578 d["required_version"] = node.version_spec if node.version_spec else "Any"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
579 else:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
580 d["required_version"] = d["installed_version"]
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
581
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
582 d["dependencies"] = [
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
583 aux(c, parent=node, cur_chain=cur_chain + [c.project_name])
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
584 for c in tree.get_children(node.key)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
585 if c.project_name not in cur_chain
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
586 ]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
587
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
588 return d
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
589
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
590 return json.dumps([aux(p) for p in nodes], indent=indent)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
591
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
592
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
593 def dump_graphviz(tree, output_format="dot", is_reverse=False):
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
594 """Output dependency graph as one of the supported GraphViz output formats.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
595
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
596 :param dict tree: dependency graph
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
597 :param string output_format: output format
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
598 :param bool is_reverse: reverse or not
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
599 :returns: representation of tree in the specified output format
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
600 :rtype: str or binary representation depending on the output format
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
601
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
602 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
603 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
604 from graphviz import Digraph
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
605 except ImportError:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
606 print("graphviz is not available, but necessary for the output " "option. Please install it.", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
607 sys.exit(1)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
608
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
609 try:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
610 from graphviz import parameters
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
611 except ImportError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
612 from graphviz import backend
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
613
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
614 valid_formats = backend.FORMATS
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
615 print(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
616 "Deprecation warning! Please upgrade graphviz to version >=0.18.0 "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
617 "Support for older versions will be removed in upcoming release",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
618 file=sys.stderr,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
619 )
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
620 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
621 valid_formats = parameters.FORMATS
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
622
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
623 if output_format not in valid_formats:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
624 print(f"{output_format} is not a supported output format.", file=sys.stderr)
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
625 print(f"Supported formats are: {', '.join(sorted(valid_formats))}", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
626 sys.exit(1)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
627
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
628 graph = Digraph(format=output_format)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
629
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
630 if not is_reverse:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
631 for pkg, deps in tree.items():
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
632 pkg_label = f"{pkg.project_name}\\n{pkg.version}"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
633 graph.node(pkg.key, label=pkg_label)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
634 for dep in deps:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
635 edge_label = dep.version_spec or "any"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
636 if dep.is_missing:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
637 dep_label = f"{dep.project_name}\\n(missing)"
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
638 graph.node(dep.key, label=dep_label, style="dashed")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
639 graph.edge(pkg.key, dep.key, style="dashed")
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
640 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
641 graph.edge(pkg.key, dep.key, label=edge_label)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
642 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
643 for dep, parents in tree.items():
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
644 dep_label = f"{dep.project_name}\\n{dep.installed_version}"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
645 graph.node(dep.key, label=dep_label)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
646 for parent in parents:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
647 # req reference of the dep associated with this
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
648 # particular parent package
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
649 req_ref = parent.req
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
650 edge_label = req_ref.version_spec or "any"
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
651 graph.edge(dep.key, parent.key, label=edge_label)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
652
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
653 # Allow output of dot format, even if GraphViz isn't installed.
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
654 if output_format == "dot":
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
655 return graph.source
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
656
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
657 # As it's unknown if the selected output format is binary or not, try to
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
658 # decode it as UTF8 and only print it out in binary if that's not possible.
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
659 try:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
660 return graph.pipe().decode("utf-8")
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
661 except UnicodeDecodeError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
662 return graph.pipe()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
663
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
664
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
665 def print_graphviz(dump_output):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
666 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
667 Dump the data generated by GraphViz to stdout.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
668
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
669 :param dump_output: The output from dump_graphviz
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
670 """
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
671 if hasattr(dump_output, "encode"):
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
672 print(dump_output)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
673 else:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
674 with os.fdopen(sys.stdout.fileno(), "wb") as bytestream:
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
675 bytestream.write(dump_output)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
676
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
677
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
678 def conflicting_deps(tree):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
679 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
680 Returns dependencies which are not present or conflict with the requirements of other packages.
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
681
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
682 e.g. will warn if pkg1 requires pkg2==2.0 and pkg2==1.0 is installed
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
683
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
684 :param tree: the requirements tree (dict)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
685 :returns: dict of DistPackage -> list of unsatisfied/unknown ReqPackage
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
686 :rtype: dict
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
687 """
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
688 conflicting = defaultdict(list)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
689 for p, rs in tree.items():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
690 for req in rs:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
691 if req.is_conflicting():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
692 conflicting[p].append(req)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
693 return conflicting
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
694
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
695
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
696 def render_conflicts_text(conflicts):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
697 if conflicts:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
698 print("Warning!!! Possibly conflicting dependencies found:", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
699 # Enforce alphabetical order when listing conflicts
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
700 pkgs = sorted(conflicts.keys())
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
701 for p in pkgs:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
702 pkg = p.render_as_root(False)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
703 print(f"* {pkg}", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
704 for req in conflicts[p]:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
705 req_str = req.render_as_branch(False)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
706 print(f" - {req_str}", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
707
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
708
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
709 def cyclic_deps(tree):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
710 """
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
711 Return cyclic dependencies as list of tuples
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
712
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
713 :param PackageDAG tree: package tree/dag
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
714 :returns: list of tuples representing cyclic dependencies
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
715 :rtype: list
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
716 """
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
717 index = {p.key: {r.key for r in rs} for p, rs in tree.items()}
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
718 cyclic = []
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
719 for p, rs in tree.items():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
720 for r in rs:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
721 if p.key in index.get(r.key, []):
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
722 p_as_dep_of_r = [x for x in tree.get(tree.get_node_as_parent(r.key)) if x.key == p.key][0]
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
723 cyclic.append((p, r, p_as_dep_of_r))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
724 return cyclic
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
725
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
726
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
727 def render_cycles_text(cycles):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
728 if cycles:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
729 print("Warning!! Cyclic dependencies found:", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
730 # List in alphabetical order of the dependency that's cycling
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
731 # (2nd item in the tuple)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
732 cycles = sorted(cycles, key=lambda xs: xs[1].key)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
733 for a, b, c in cycles:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
734 print(f"* {a.project_name} => {b.project_name} => {c.project_name}", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
735
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
736
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
737 def get_parser():
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
738 parser = argparse.ArgumentParser(description="Dependency tree of the installed python packages")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
739 parser.add_argument("-v", "--version", action="version", version=f"{__version__}")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
740 parser.add_argument("-f", "--freeze", action="store_true", help="Print names so as to write freeze files")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
741 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
742 "--python",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
743 default=sys.executable,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
744 help="Python to use to look for packages in it (default: where" " installed)",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
745 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
746 parser.add_argument("-a", "--all", action="store_true", help="list all deps at top level")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
747 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
748 "-l",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
749 "--local-only",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
750 action="store_true",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
751 help="If in a virtualenv that has global access " "do not show globally installed packages",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
752 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
753 parser.add_argument("-u", "--user-only", action="store_true", help="Only show installations in the user site dir")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
754 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
755 "-w",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
756 "--warn",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
757 action="store",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
758 dest="warn",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
759 nargs="?",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
760 default="suppress",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
761 choices=("silence", "suppress", "fail"),
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
762 help=(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
763 'Warning control. "suppress" will show warnings '
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
764 "but return 0 whether or not they are present. "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
765 '"silence" will not show warnings at all and '
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
766 'always return 0. "fail" will show warnings and '
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
767 "return 1 if any are present. The default is "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
768 '"suppress".'
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
769 ),
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
770 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
771 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
772 "-r",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
773 "--reverse",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
774 action="store_true",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
775 default=False,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
776 help=(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
777 "Shows the dependency tree in the reverse fashion "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
778 "ie. the sub-dependencies are listed with the "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
779 "list of packages that need them under them."
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
780 ),
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
781 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
782 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
783 "-p",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
784 "--packages",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
785 help="Comma separated list of select packages to show " "in the output. If set, --all will be ignored.",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
786 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
787 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
788 "-e",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
789 "--exclude",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
790 help="Comma separated list of select packages to exclude " "from the output. If set, --all will be ignored.",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
791 metavar="PACKAGES",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
792 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
793 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
794 "-j",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
795 "--json",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
796 action="store_true",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
797 default=False,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
798 help=(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
799 "Display dependency tree as json. This will yield "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
800 '"raw" output that may be used by external tools. '
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
801 "This option overrides all other options."
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
802 ),
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
803 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
804 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
805 "--json-tree",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
806 action="store_true",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
807 default=False,
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
808 help=(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
809 "Display dependency tree as json which is nested "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
810 "the same way as the plain text output printed by default. "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
811 "This option overrides all other options (except --json)."
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
812 ),
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
813 )
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
814 parser.add_argument(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
815 "--graph-output",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
816 dest="output_format",
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
817 help=(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
818 "Print a dependency graph in the specified output "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
819 "format. Available are all formats supported by "
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
820 "GraphViz, e.g.: dot, jpeg, pdf, png, svg"
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
821 ),
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
822 )
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
823 return parser
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
824
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
825
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
826 def _get_args():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
827 parser = get_parser()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
828 return parser.parse_args()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
829
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
830
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
831 def handle_non_host_target(args):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
832 of_python = os.path.abspath(args.python)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
833 # if target is not current python re-invoke it under the actual host
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
834 if of_python != os.path.abspath(sys.executable):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
835 # there's no way to guarantee that graphviz is available, so refuse
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
836 if args.output_format:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
837 print("graphviz functionality is not supported when querying" " non-host python", file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
838 raise SystemExit(1)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
839 argv = sys.argv[1:] # remove current python executable
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
840 for py_at, value in enumerate(argv):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
841 if value == "--python":
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
842 del argv[py_at]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
843 del argv[py_at]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
844 elif value.startswith("--python"):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
845 del argv[py_at]
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
846
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
847 main_file = inspect.getsourcefile(sys.modules[__name__])
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
848 with tempfile.TemporaryDirectory() as project:
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
849 dest = os.path.join(project, "pipdeptree")
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
850 shutil.copytree(os.path.dirname(main_file), dest)
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
851 # invoke from an empty folder to avoid cwd altering sys.path
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
852 env = os.environ.copy()
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
853 env["PYTHONPATH"] = project
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
854 cmd = [of_python, "-m", "pipdeptree"]
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
855 cmd.extend(argv)
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
856 return subprocess.call(cmd, cwd=project, env=env)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
857 return None
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
858
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
859
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
860 def get_installed_distributions(local_only=False, user_only=False):
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
861 try:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
862 from pip._internal.metadata import pkg_resources
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
863 except ImportError:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
864 # For backward compatibility with python ver. 2.7 and pip
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
865 # version 20.3.4 (the latest pip version that works with python
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
866 # version 2.7)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
867 from pip._internal.utils import misc
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
868
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
869 return misc.get_installed_distributions(local_only=local_only, user_only=user_only)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
870 else:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
871 dists = pkg_resources.Environment.from_paths(None).iter_installed_distributions(
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
872 local_only=local_only, skip=(), user_only=user_only
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
873 )
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
874 return [d._dist for d in dists]
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
875
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
876
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
877 def main():
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
878 args = _get_args()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
879 result = handle_non_host_target(args)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
880 if result is not None:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
881 return result
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
882
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
883 pkgs = get_installed_distributions(local_only=args.local_only, user_only=args.user_only)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
884
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
885 tree = PackageDAG.from_pkgs(pkgs)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
886
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
887 is_text_output = not any([args.json, args.json_tree, args.output_format])
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
888
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
889 return_code = 0
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
890
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
891 # Before any reversing or filtering, show warnings to console
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
892 # about possibly conflicting or cyclic deps if found and warnings
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
893 # are enabled (i.e. only if output is to be printed to console)
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
894 if is_text_output and args.warn != "silence":
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
895 conflicts = conflicting_deps(tree)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
896 if conflicts:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
897 render_conflicts_text(conflicts)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
898 print("-" * 72, file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
899
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
900 cycles = cyclic_deps(tree)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
901 if cycles:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
902 render_cycles_text(cycles)
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
903 print("-" * 72, file=sys.stderr)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
904
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
905 if args.warn == "fail" and (conflicts or cycles):
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
906 return_code = 1
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
907
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
908 # Reverse the tree (if applicable) before filtering, thus ensuring
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
909 # that the filter will be applied on ReverseTree
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
910 if args.reverse:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
911 tree = tree.reverse()
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
912
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
913 show_only = set(args.packages.split(",")) if args.packages else None
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
914 exclude = set(args.exclude.split(",")) if args.exclude else None
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
915
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
916 if show_only is not None or exclude is not None:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
917 tree = tree.filter(show_only, exclude)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
918
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
919 if args.json:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
920 print(render_json(tree, indent=4))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
921 elif args.json_tree:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
922 print(render_json_tree(tree, indent=4))
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
923 elif args.output_format:
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
924 output = dump_graphviz(tree, output_format=args.output_format, is_reverse=args.reverse)
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
925 print_graphviz(output)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
926 else:
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
927 render_text(tree, args.all, args.freeze)
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
928
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
929 return return_code
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
930
9589
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
931 #
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
932 # eric-ide modification: entry point to get one self-contained script
09218eb3ae21 Third Party packages
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 9218
diff changeset
933 #
9218
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
934
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
935 if __name__ == '__main__':
71cf3979a6c9 pip Interface
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
936 sys.exit(main())

eric ide

mercurial