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