Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/setuptools/depends.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:32:28 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:d30785e31577 | 1:56ad4e20f292 |
---|---|
1 import sys | |
2 import imp | |
3 import marshal | |
4 from distutils.version import StrictVersion | |
5 from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN | |
6 | |
7 from .py33compat import Bytecode | |
8 | |
9 | |
10 __all__ = [ | |
11 'Require', 'find_module', 'get_module_constant', 'extract_constant' | |
12 ] | |
13 | |
14 | |
15 class Require: | |
16 """A prerequisite to building or installing a distribution""" | |
17 | |
18 def __init__(self, name, requested_version, module, homepage='', | |
19 attribute=None, format=None): | |
20 | |
21 if format is None and requested_version is not None: | |
22 format = StrictVersion | |
23 | |
24 if format is not None: | |
25 requested_version = format(requested_version) | |
26 if attribute is None: | |
27 attribute = '__version__' | |
28 | |
29 self.__dict__.update(locals()) | |
30 del self.self | |
31 | |
32 def full_name(self): | |
33 """Return full package/distribution name, w/version""" | |
34 if self.requested_version is not None: | |
35 return '%s-%s' % (self.name, self.requested_version) | |
36 return self.name | |
37 | |
38 def version_ok(self, version): | |
39 """Is 'version' sufficiently up-to-date?""" | |
40 return self.attribute is None or self.format is None or \ | |
41 str(version) != "unknown" and version >= self.requested_version | |
42 | |
43 def get_version(self, paths=None, default="unknown"): | |
44 """Get version number of installed module, 'None', or 'default' | |
45 | |
46 Search 'paths' for module. If not found, return 'None'. If found, | |
47 return the extracted version attribute, or 'default' if no version | |
48 attribute was specified, or the value cannot be determined without | |
49 importing the module. The version is formatted according to the | |
50 requirement's version format (if any), unless it is 'None' or the | |
51 supplied 'default'. | |
52 """ | |
53 | |
54 if self.attribute is None: | |
55 try: | |
56 f, p, i = find_module(self.module, paths) | |
57 if f: | |
58 f.close() | |
59 return default | |
60 except ImportError: | |
61 return None | |
62 | |
63 v = get_module_constant(self.module, self.attribute, default, paths) | |
64 | |
65 if v is not None and v is not default and self.format is not None: | |
66 return self.format(v) | |
67 | |
68 return v | |
69 | |
70 def is_present(self, paths=None): | |
71 """Return true if dependency is present on 'paths'""" | |
72 return self.get_version(paths) is not None | |
73 | |
74 def is_current(self, paths=None): | |
75 """Return true if dependency is present and up-to-date on 'paths'""" | |
76 version = self.get_version(paths) | |
77 if version is None: | |
78 return False | |
79 return self.version_ok(version) | |
80 | |
81 | |
82 def find_module(module, paths=None): | |
83 """Just like 'imp.find_module()', but with package support""" | |
84 | |
85 parts = module.split('.') | |
86 | |
87 while parts: | |
88 part = parts.pop(0) | |
89 f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) | |
90 | |
91 if kind == PKG_DIRECTORY: | |
92 parts = parts or ['__init__'] | |
93 paths = [path] | |
94 | |
95 elif parts: | |
96 raise ImportError("Can't find %r in %s" % (parts, module)) | |
97 | |
98 return info | |
99 | |
100 | |
101 def get_module_constant(module, symbol, default=-1, paths=None): | |
102 """Find 'module' by searching 'paths', and extract 'symbol' | |
103 | |
104 Return 'None' if 'module' does not exist on 'paths', or it does not define | |
105 'symbol'. If the module defines 'symbol' as a constant, return the | |
106 constant. Otherwise, return 'default'.""" | |
107 | |
108 try: | |
109 f, path, (suffix, mode, kind) = find_module(module, paths) | |
110 except ImportError: | |
111 # Module doesn't exist | |
112 return None | |
113 | |
114 try: | |
115 if kind == PY_COMPILED: | |
116 f.read(8) # skip magic & date | |
117 code = marshal.load(f) | |
118 elif kind == PY_FROZEN: | |
119 code = imp.get_frozen_object(module) | |
120 elif kind == PY_SOURCE: | |
121 code = compile(f.read(), path, 'exec') | |
122 else: | |
123 # Not something we can parse; we'll have to import it. :( | |
124 if module not in sys.modules: | |
125 imp.load_module(module, f, path, (suffix, mode, kind)) | |
126 return getattr(sys.modules[module], symbol, None) | |
127 | |
128 finally: | |
129 if f: | |
130 f.close() | |
131 | |
132 return extract_constant(code, symbol, default) | |
133 | |
134 | |
135 def extract_constant(code, symbol, default=-1): | |
136 """Extract the constant value of 'symbol' from 'code' | |
137 | |
138 If the name 'symbol' is bound to a constant value by the Python code | |
139 object 'code', return that value. If 'symbol' is bound to an expression, | |
140 return 'default'. Otherwise, return 'None'. | |
141 | |
142 Return value is based on the first assignment to 'symbol'. 'symbol' must | |
143 be a global, or at least a non-"fast" local in the code block. That is, | |
144 only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' | |
145 must be present in 'code.co_names'. | |
146 """ | |
147 if symbol not in code.co_names: | |
148 # name's not there, can't possibly be an assignment | |
149 return None | |
150 | |
151 name_idx = list(code.co_names).index(symbol) | |
152 | |
153 STORE_NAME = 90 | |
154 STORE_GLOBAL = 97 | |
155 LOAD_CONST = 100 | |
156 | |
157 const = default | |
158 | |
159 for byte_code in Bytecode(code): | |
160 op = byte_code.opcode | |
161 arg = byte_code.arg | |
162 | |
163 if op == LOAD_CONST: | |
164 const = code.co_consts[arg] | |
165 elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL): | |
166 return const | |
167 else: | |
168 const = default | |
169 | |
170 | |
171 def _update_globals(): | |
172 """ | |
173 Patch the globals to remove the objects not available on some platforms. | |
174 | |
175 XXX it'd be better to test assertions about bytecode instead. | |
176 """ | |
177 | |
178 if not sys.platform.startswith('java') and sys.platform != 'cli': | |
179 return | |
180 incompatible = 'extract_constant', 'get_module_constant' | |
181 for name in incompatible: | |
182 del globals()[name] | |
183 __all__.remove(name) | |
184 | |
185 | |
186 _update_globals() |