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() |
