Coverage for src/pymyinstall/installhelper/module_dependencies.py: 97%
30 statements
« prev ^ index » next coverage.py v7.1.0, created at 2023-07-19 01:47 +0200
« prev ^ index » next coverage.py v7.1.0, created at 2023-07-19 01:47 +0200
1"""
2@file
3@brief Guess missing dependencies
4"""
5from .pip_helper import get_installed_distributions
8def get_default_ignore_modules():
9 """
10 A couple of modules have some dependencies on not supported modules
11 or modules integrated to the standard distributiion such
12 `enum34 <https://pypi.python.org/pypi/enum34>`_.
13 This function returns this list.
14 Skips errors such as ``Module 'cachecontrol' misses 'msgpack_python'``.
15 """
16 return [
17 "argparse", # standard distribution (>= 3.5)
18 "backports.weakref", # standard distribution (>= 3.4)
19 "distribute", # standard distribution
20 "enum", # standard distribution (>= 3.4)
21 "enum34", # standard distribution (>= 3.4)
22 "enum_compat", # standard distribution (>= 3.4)
23 "enum-compat", # standard distribution (>= 3.4)
24 "fasttsne", # deprecated module
25 "futures", # standard distribution (>= 3.5)
26 "holoviews", # needed by geoviews but still marked as missing
27 "hypertemp", # temporary solution, should disappear
28 "keyrings.alt", # weird this one on Windows
29 # "guidata",
30 # "monotonic",
31 "msgpack_python", # Called msgpack now.
32 "msgpack-python", # Called msgpack now.
33 "onnx", # working on it
34 "ordereddict", # standard distribution (>= 3.4)
35 "path", # subfolder of existing module
36 "path.py", # weird
37 "pathlib", # standard distribution (>= 3.5)
38 "pip", # almost standard distribution, should be rare
39 "pipdeptree", # weird
40 # manny names for this one (PTable, not maintained anymore)
41 "prettytable",
42 "pycryptodome", # many names for this one
43 "pydocstyle", # does not seem to be maintained
44 "pyopengl", # weird this one
45 "pypiwin32", # manny names for this one
46 "pythonnet", # weird
47 "pywin32", # manny names for this one
48 "pywin32_ctypes", # manny names for this one
49 "rope", # for spyder
50 "setuptools", # standard distribution
51 ]
54def _main_pipdeptree(local_only=False):
55 """
56 The function relies on module
57 `pipdeptree.main <https://pypi.python.org/pypi/pipdeptree>`_.
58 """
59 default_skip = ['setuptools', 'pip', 'python', 'distribute', 'hypertemp']
60 skip = default_skip + ['pipdeptree']
61 pkgs = get_installed_distributions(local_only=local_only, skip=skip)
62 req_map = dict((p.key, (p, p.requires())) for p in pkgs)
63 return req_map
66def missing_dependencies(specific=None, ignore_module=get_default_ignore_modules()):
67 """
68 Returns the list of missing dependencies for the installed modules.
70 @param specific look dependencies only for a specific module
71 @param ignore_module list of modules not to consider as a missing dependency
72 even if they are installed
73 @return list of missing dependencies as dictionary (module, missing dependencies)
75 .. versionchanged:: 1.5
76 Parameters *ignore_module*.
77 """
78 skip = set(ignore_module)
79 tree = _main_pipdeptree()
80 stack = {}
81 for k, v in tree.items():
82 if specific is not None and specific != k:
83 continue
84 for mod in v[1]:
85 dep = mod.key
86 if dep in skip:
87 continue
88 if dep not in tree:
89 if "-" in dep:
90 dep = dep.replace("-", "_")
91 elif "_" in dep:
92 dep = dep.replace("_", "_")
93 if dep not in tree:
94 if k not in stack:
95 stack[k] = []
96 stack[k].append(dep)
97 return stack