From 8423e1ed14ac1691c2863c6e8cac9230cf558d7b Mon Sep 17 00:00:00 2001 From: PJ Eby Date: Fri, 19 Mar 2004 20:53:14 +0000 Subject: Initial checkin of setuptools 0.0.1. --HG-- branch : setuptools extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4040869 --- setuptools/depends.py | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 setuptools/depends.py (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py new file mode 100644 index 00000000..c3bc3334 --- /dev/null +++ b/setuptools/depends.py @@ -0,0 +1,246 @@ +from __future__ import generators +import sys, imp, marshal +from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN +from distutils.version import StrictVersion, LooseVersion + +__all__ = [ + 'Require', 'find_module', 'get_module_constant', 'extract_constant' +] + +class Require: + """A prerequisite to building or installing a distribution""" + + def __init__(self,name,requested_version,module,attribute=None,format=None): + + if format is None and requested_version is not None: + format = StrictVersion + + if format is not None: + requested_version = format(requested_version) + if attribute is None: + attribute = '__version__' + + self.name = name + self.requested_version = requested_version + self.module = module + self.attribute = attribute + self.format = format + + + + + + + + + + + + + + + def get_version(self, paths=None, default="unknown"): + + """Get version number of installed module, 'None', or 'default' + + Search 'paths' for module. If not found, return 'None'. If found, + return the extracted version attribute, or 'default' if no version + attribute was specified, or the value cannot be determined without + importing the module. The version is formatted according to the + requirement's version format (if any), unless it is 'None' or the + supplied 'default'. + """ + + if self.attribute is None: + try: + f,p,i = find_module(self.module,paths) + if f: f.close() + return default + except ImportError: + return None + + v = get_module_constant(self.module,self.attribute,default,paths) + + if v is not None and v is not default and self.format is not None: + return self.format(v) + + return v + + def is_present(self,paths=None): + """Return true if dependency is present on 'paths'""" + return self.get_version(paths) is not None + + def is_current(self,paths=None): + """Return true if dependency is present and up-to-date on 'paths'""" + version = self.get_version(paths) + if version is None: + return False + return self.attribute is None or self.format is None or \ + version >= self.requested_version + + + +def _iter_code(code): + + """Yield '(op,arg)' pair for each operation in code object 'code'""" + + from array import array + from dis import HAVE_ARGUMENT, EXTENDED_ARG + + bytes = array('b',code.co_code) + eof = len(code.co_code) + + ptr = 0 + extended_arg = 0 + + while ptr=HAVE_ARGUMENT: + + arg = bytes[ptr+1] + bytes[ptr+2]*256 + extended_arg + ptr += 3 + + if op==EXTENDED_ARG: + extended_arg = arg * 65536L + continue + + else: + arg = None + ptr += 1 + + yield op,arg + + + + + + + + + + +def find_module(module, paths=None): + """Just like 'imp.find_module()', but with package support""" + + parts = module.split('.') + + while parts: + part = parts.pop(0) + f, path, (suffix,mode,kind) = info = imp.find_module(part, paths) + + if kind==PKG_DIRECTORY: + parts = parts or ['__init__'] + paths = [path] + + elif parts: + raise ImportError("Can't find %r in %s" % (parts,module)) + + return info + + + + + + + + + + + + + + + + + + + + + + + + +def get_module_constant(module, symbol, default=-1, paths=None): + + """Find 'module' by searching 'paths', and extract 'symbol' + + Return 'None' if 'module' does not exist on 'paths', or it does not define + 'symbol'. If the module defines 'symbol' as a constant, return the + constant. Otherwise, return 'default'.""" + + try: + f, path, (suffix,mode,kind) = find_module(module,paths) + except ImportError: + # Module doesn't exist + return None + + try: + if kind==PY_COMPILED: + f.read(8) # skip magic & date + code = marshal.load(f) + elif kind==PY_FROZEN: + code = imp.get_frozen_object(module) + elif kind==PY_SOURCE: + code = compile(f.read(), path, 'exec') + else: + # Not something we can parse; we'll have to import it. :( + if module not in sys.modules: + imp.load_module(module,f,path,(suffix,mode,kind)) + return getattr(sys.modules[module],symbol,None) + + finally: + if f: + f.close() + + return extract_constant(code,symbol,default) + + + + + + + + +def extract_constant(code,symbol,default=-1): + + """Extract the constant value of 'symbol' from 'code' + + If the name 'symbol' is bound to a constant value by the Python code + object 'code', return that value. If 'symbol' is bound to an expression, + return 'default'. Otherwise, return 'None'. + + Return value is based on the first assignment to 'symbol'. 'symbol' must + be a global, or at least a non-"fast" local in the code block. That is, + only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' + must be present in 'code.co_names'. + """ + + if symbol not in code.co_names: + # name's not there, can't possibly be an assigment + return None + + name_idx = list(code.co_names).index(symbol) + + STORE_NAME = 90 + STORE_GLOBAL = 97 + LOAD_CONST = 100 + + const = default + + for op, arg in _iter_code(code): + + if op==LOAD_CONST: + const = code.co_consts[arg] + elif arg==name_idx and (op==STORE_NAME or op==STORE_GLOBAL): + return const + else: + const = default + + + + + + + -- cgit v1.2.1 From 7ce55cabc53fe2c1378446ba0557e5f716c0cd31 Mon Sep 17 00:00:00 2001 From: PJ Eby Date: Sat, 20 Mar 2004 20:52:12 +0000 Subject: Flesh out 'depends' command to display dependencies' status, and halt if all requirements aren't met. (Also, check planned install location for the dependencies, as well as checking sys.path.) Also: * Allow 'Feature()' objects to include 'Require()' objects, so that dependencies can be optional * 'Require()' objects can set a homepage, whose URL will be displayed by the 'depends' command if the dependency needs to be installed. * Misc. fixes/refactoring of version validation to properly handle "unknown" versions, and to decouple version fetching from version checking. * Updated TODO to remove various completed items. --HG-- branch : setuptools extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4040876 --- setuptools/depends.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index c3bc3334..20e5cecb 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -10,7 +10,9 @@ __all__ = [ class Require: """A prerequisite to building or installing a distribution""" - def __init__(self,name,requested_version,module,attribute=None,format=None): + def __init__(self,name,requested_version,module,homepage='', + attribute=None,format=None + ): if format is None and requested_version is not None: format = StrictVersion @@ -20,23 +22,21 @@ class Require: if attribute is None: attribute = '__version__' - self.name = name - self.requested_version = requested_version - self.module = module - self.attribute = attribute - self.format = format - - - - - - - - + self.__dict__.update(locals()) + del self.self + def full_name(self): + """Return full package/distribution name, w/version""" + if self.requested_version is not None: + return '%s-%s' % (self.name,self.requested_version) + return self.name + def version_ok(self,version): + """Is 'version' sufficiently up-to-date?""" + return self.attribute is None or self.format is None or \ + str(version)<>"unknown" and version >= self.requested_version def get_version(self, paths=None, default="unknown"): @@ -66,18 +66,18 @@ class Require: return v + def is_present(self,paths=None): """Return true if dependency is present on 'paths'""" return self.get_version(paths) is not None + def is_current(self,paths=None): """Return true if dependency is present and up-to-date on 'paths'""" version = self.get_version(paths) if version is None: return False - return self.attribute is None or self.format is None or \ - version >= self.requested_version - + return self.version_ok(version) def _iter_code(code): -- cgit v1.2.1 From 49dfb4a17843282fa7359247b68d857d737847fd Mon Sep 17 00:00:00 2001 From: PJ Eby Date: Thu, 21 Aug 2008 18:36:39 +0000 Subject: Fix http://bugs.python.org/setuptools/issue31 (backport from trunk) --HG-- branch : setuptools-0.6 extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/branches/setuptools-0.6%4065948 --- setuptools/depends.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 20e5cecb..4b7b3437 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -204,7 +204,6 @@ def get_module_constant(module, symbol, default=-1, paths=None): def extract_constant(code,symbol,default=-1): - """Extract the constant value of 'symbol' from 'code' If the name 'symbol' is bound to a constant value by the Python code @@ -237,10 +236,11 @@ def extract_constant(code,symbol,default=-1): return const else: const = default - - - - - + +if sys.platform.startswith('java') or sys.platform == 'cli': + # XXX it'd be better to test assertions about bytecode instead... + del extract_constant, get_module_constant + __all__.remove('extract_constant') + __all__.remove('get_module_constant') -- cgit v1.2.1 From 58a658b26d1c95b31d02050dcccd648d2e4ce27b Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Mon, 20 Jun 2011 22:55:16 +0100 Subject: Changes to support 2.x and 3.x in the same codebase. --HG-- branch : distribute extra : rebase_source : 7d3608edee54a43789f0574d702fb839628b5071 --- setuptools/depends.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 4b7b3437..8b9d1217 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -36,7 +36,7 @@ class Require: def version_ok(self,version): """Is 'version' sufficiently up-to-date?""" return self.attribute is None or self.format is None or \ - str(version)<>"unknown" and version >= self.requested_version + str(version) != "unknown" and version >= self.requested_version def get_version(self, paths=None, default="unknown"): @@ -103,7 +103,7 @@ def _iter_code(code): ptr += 3 if op==EXTENDED_ARG: - extended_arg = arg * 65536L + extended_arg = arg * long_type(65536) continue else: -- cgit v1.2.1 From e6e3b8dfd12cb96b3abc7b34bda56c6431956719 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 May 2014 23:33:56 -0400 Subject: Modernize syntax --HG-- extra : amend_source : eeaee0372ea8d1d39475a722234c03f6a0247722 --- setuptools/depends.py | 75 +++++++++++---------------------------------------- 1 file changed, 16 insertions(+), 59 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 8b9d1217..f6628799 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,7 +1,8 @@ -from __future__ import generators -import sys, imp, marshal +import sys +import imp +import marshal from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN -from distutils.version import StrictVersion, LooseVersion +from distutils.version import StrictVersion __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -10,9 +11,8 @@ __all__ = [ class Require: """A prerequisite to building or installing a distribution""" - def __init__(self,name,requested_version,module,homepage='', - attribute=None,format=None - ): + def __init__(self, name, requested_version, module, homepage='', + attribute=None, format=None): if format is None and requested_version is not None: format = StrictVersion @@ -25,20 +25,17 @@ class Require: self.__dict__.update(locals()) del self.self - def full_name(self): """Return full package/distribution name, w/version""" if self.requested_version is not None: return '%s-%s' % (self.name,self.requested_version) return self.name - - def version_ok(self,version): + def version_ok(self, version): """Is 'version' sufficiently up-to-date?""" return self.attribute is None or self.format is None or \ str(version) != "unknown" and version >= self.requested_version - def get_version(self, paths=None, default="unknown"): """Get version number of installed module, 'None', or 'default' @@ -59,20 +56,18 @@ class Require: except ImportError: return None - v = get_module_constant(self.module,self.attribute,default,paths) + v = get_module_constant(self.module, self.attribute, default, paths) if v is not None and v is not default and self.format is not None: return self.format(v) return v - - def is_present(self,paths=None): + def is_present(self, paths=None): """Return true if dependency is present on 'paths'""" return self.get_version(paths) is not None - - def is_current(self,paths=None): + def is_current(self, paths=None): """Return true if dependency is present and up-to-date on 'paths'""" version = self.get_version(paths) if version is None: @@ -113,14 +108,6 @@ def _iter_code(code): yield op,arg - - - - - - - - def find_module(module, paths=None): """Just like 'imp.find_module()', but with package support""" @@ -140,28 +127,6 @@ def find_module(module, paths=None): return info - - - - - - - - - - - - - - - - - - - - - - def get_module_constant(module, symbol, default=-1, paths=None): """Find 'module' by searching 'paths', and extract 'symbol' @@ -171,7 +136,7 @@ def get_module_constant(module, symbol, default=-1, paths=None): constant. Otherwise, return 'default'.""" try: - f, path, (suffix,mode,kind) = find_module(module,paths) + f, path, (suffix, mode, kind) = find_module(module, paths) except ImportError: # Module doesn't exist return None @@ -187,23 +152,17 @@ def get_module_constant(module, symbol, default=-1, paths=None): else: # Not something we can parse; we'll have to import it. :( if module not in sys.modules: - imp.load_module(module,f,path,(suffix,mode,kind)) - return getattr(sys.modules[module],symbol,None) + imp.load_module(module, f, path, (suffix, mode, kind)) + return getattr(sys.modules[module], symbol, None) finally: if f: f.close() - return extract_constant(code,symbol,default) - - - - + return extract_constant(code, symbol, default) - - -def extract_constant(code,symbol,default=-1): +def extract_constant(code, symbol, default=-1): """Extract the constant value of 'symbol' from 'code' If the name 'symbol' is bound to a constant value by the Python code @@ -236,11 +195,9 @@ def extract_constant(code,symbol,default=-1): return const else: const = default - + if sys.platform.startswith('java') or sys.platform == 'cli': # XXX it'd be better to test assertions about bytecode instead... del extract_constant, get_module_constant __all__.remove('extract_constant') __all__.remove('get_module_constant') - - -- cgit v1.2.1 From ac86a30d6f4bc4ed403ea668d4a904d8ae933850 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 May 2014 23:37:43 -0400 Subject: Fix NameError (is this code ever used?). --HG-- extra : amend_source : 4361459883522692c4d70715135439819d981d7a --- setuptools/depends.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index f6628799..49fb8b37 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -3,6 +3,7 @@ import imp import marshal from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from distutils.version import StrictVersion +from setuptools import compat __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -98,7 +99,7 @@ def _iter_code(code): ptr += 3 if op==EXTENDED_ARG: - extended_arg = arg * long_type(65536) + extended_arg = arg * compat.long_type(65536) continue else: -- cgit v1.2.1 From 032cd636116a821d20a590d87afa99626de9bff6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 17 May 2014 23:42:35 -0400 Subject: Patch globals in a function. This technique bypasses the linter warnings about the names not being present, and allows for better documentation. --- setuptools/depends.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 49fb8b37..e87ef3f3 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -197,8 +197,19 @@ def extract_constant(code, symbol, default=-1): else: const = default -if sys.platform.startswith('java') or sys.platform == 'cli': - # XXX it'd be better to test assertions about bytecode instead... - del extract_constant, get_module_constant - __all__.remove('extract_constant') - __all__.remove('get_module_constant') + +def _update_globals(): + """ + Patch the globals to remove the objects not available on some platforms. + + XXX it'd be better to test assertions about bytecode instead. + """ + + if not sys.platform.startswith('java') and sys.platform != 'cli': + return + incompatible = 'extract_constant', 'get_module_constant' + for name in incompatible: + del globals()[name] + __all__.remove(name) + +_update_globals() -- cgit v1.2.1 From b49435397a5094f94678adf3549cc8941aa469b7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 5 Jul 2014 15:06:51 -0400 Subject: Use six for Python 2 compatibility --HG-- branch : feature/issue-229 extra : source : 7b1997ececc5772798ce33a0f8e77387cb55a977 --- setuptools/depends.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index e87ef3f3..43617e6d 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -3,7 +3,8 @@ import imp import marshal from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from distutils.version import StrictVersion -from setuptools import compat + +import six __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -99,7 +100,8 @@ def _iter_code(code): ptr += 3 if op==EXTENDED_ARG: - extended_arg = arg * compat.long_type(65536) + long_type = six.integer_types[-1] + extended_arg = arg * long_type(65536) continue else: -- cgit v1.2.1 From 06872bb0bbbeb953e90bd0941444b0d499056557 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 31 Dec 2015 11:51:01 -0500 Subject: Update vendoring technique to match that used for packaging. Ref #229. --HG-- branch : feature/issue-229 --- setuptools/depends.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 43617e6d..e633c05b 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -4,7 +4,12 @@ import marshal from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from distutils.version import StrictVersion -import six +try: + from setuptools._vendor import six +except ImportError: + # fallback to naturally-installed version; allows system packagers to + # omit vendored packages. + import six __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' -- cgit v1.2.1 From 952c1bafda1929c74c737646aa025e6ffad6632e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 31 Dec 2015 16:30:47 -0500 Subject: Modeling after Astropy's technique for bundling libraries, the imports are now much cleaner. Thanks @embray. Ref #229. --HG-- branch : feature/issue-229 --- setuptools/depends.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index e633c05b..9f7c9a35 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -4,12 +4,7 @@ import marshal from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from distutils.version import StrictVersion -try: - from setuptools._vendor import six -except ImportError: - # fallback to naturally-installed version; allows system packagers to - # omit vendored packages. - import six +from setuptools.extern import six __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' -- cgit v1.2.1 From 6d11e88f938f09ef16db4c6064b6e74acba4db1d Mon Sep 17 00:00:00 2001 From: stepshal Date: Tue, 12 Jul 2016 22:00:43 +0700 Subject: Fix quantity of blank lines after code object. --- setuptools/depends.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 9f7c9a35..ef3dbb91 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -10,6 +10,7 @@ __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' ] + class Require: """A prerequisite to building or installing a distribution""" @@ -39,7 +40,6 @@ class Require: str(version) != "unknown" and version >= self.requested_version def get_version(self, paths=None, default="unknown"): - """Get version number of installed module, 'None', or 'default' Search 'paths' for module. If not found, return 'None'. If found, @@ -78,7 +78,6 @@ class Require: def _iter_code(code): - """Yield '(op,arg)' pair for each operation in code object 'code'""" from array import array @@ -131,7 +130,6 @@ def find_module(module, paths=None): def get_module_constant(module, symbol, default=-1, paths=None): - """Find 'module' by searching 'paths', and extract 'symbol' Return 'None' if 'module' does not exist on 'paths', or it does not define -- cgit v1.2.1 From f749ccab1e55723848946c9aba5c3eddebe0b24e Mon Sep 17 00:00:00 2001 From: stepshal Date: Thu, 14 Jul 2016 09:26:06 +0700 Subject: Add missing whitespace. --- setuptools/depends.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index ef3dbb91..eb1d7b13 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -31,7 +31,7 @@ class Require: def full_name(self): """Return full package/distribution name, w/version""" if self.requested_version is not None: - return '%s-%s' % (self.name,self.requested_version) + return '%s-%s' % (self.name, self.requested_version) return self.name def version_ok(self, version): @@ -52,7 +52,7 @@ class Require: if self.attribute is None: try: - f,p,i = find_module(self.module,paths) + f, p, i = find_module(self.module, paths) if f: f.close() return default except ImportError: @@ -83,7 +83,7 @@ def _iter_code(code): from array import array from dis import HAVE_ARGUMENT, EXTENDED_ARG - bytes = array('b',code.co_code) + bytes = array('b', code.co_code) eof = len(code.co_code) ptr = 0 @@ -107,7 +107,7 @@ def _iter_code(code): arg = None ptr += 1 - yield op,arg + yield op, arg def find_module(module, paths=None): @@ -117,14 +117,14 @@ def find_module(module, paths=None): while parts: part = parts.pop(0) - f, path, (suffix,mode,kind) = info = imp.find_module(part, paths) + f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) if kind==PKG_DIRECTORY: parts = parts or ['__init__'] paths = [path] elif parts: - raise ImportError("Can't find %r in %s" % (parts,module)) + raise ImportError("Can't find %r in %s" % (parts, module)) return info -- cgit v1.2.1 From dc2d1dc249bec8e3a864e2aa6002a8e27adc4b7c Mon Sep 17 00:00:00 2001 From: stepshal Date: Thu, 14 Jul 2016 12:11:49 +0700 Subject: Fix missing whitespace around operator. --- setuptools/depends.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index eb1d7b13..01f4a23a 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -89,16 +89,16 @@ def _iter_code(code): ptr = 0 extended_arg = 0 - while ptr=HAVE_ARGUMENT: + if op >= HAVE_ARGUMENT: - arg = bytes[ptr+1] + bytes[ptr+2]*256 + extended_arg + arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg ptr += 3 - if op==EXTENDED_ARG: + if op == EXTENDED_ARG: long_type = six.integer_types[-1] extended_arg = arg * long_type(65536) continue @@ -119,7 +119,7 @@ def find_module(module, paths=None): part = parts.pop(0) f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) - if kind==PKG_DIRECTORY: + if kind == PKG_DIRECTORY: parts = parts or ['__init__'] paths = [path] @@ -143,12 +143,12 @@ def get_module_constant(module, symbol, default=-1, paths=None): return None try: - if kind==PY_COMPILED: + if kind == PY_COMPILED: f.read(8) # skip magic & date code = marshal.load(f) - elif kind==PY_FROZEN: + elif kind == PY_FROZEN: code = imp.get_frozen_object(module) - elif kind==PY_SOURCE: + elif kind == PY_SOURCE: code = compile(f.read(), path, 'exec') else: # Not something we can parse; we'll have to import it. :( @@ -190,9 +190,9 @@ def extract_constant(code, symbol, default=-1): for op, arg in _iter_code(code): - if op==LOAD_CONST: + if op == LOAD_CONST: const = code.co_consts[arg] - elif arg==name_idx and (op==STORE_NAME or op==STORE_GLOBAL): + elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL): return const else: const = default -- cgit v1.2.1 From 01de794bc829cc9eb0c1512b3570acec970e1acf Mon Sep 17 00:00:00 2001 From: stepshal Date: Thu, 14 Jul 2016 21:45:22 +0700 Subject: Put imports in same block alphabeticaly. --- setuptools/depends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index eb1d7b13..865d4151 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,8 +1,8 @@ import sys import imp import marshal -from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from distutils.version import StrictVersion +from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from setuptools.extern import six -- cgit v1.2.1 From 64335b63f9e03e71d0acd885b8bfd0b4b7a60aa8 Mon Sep 17 00:00:00 2001 From: stepshal Date: Thu, 21 Jul 2016 04:13:28 +0700 Subject: Put colon-separated compound statement on separate lines. --- setuptools/depends.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 48c20156..75344590 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -53,7 +53,8 @@ class Require: if self.attribute is None: try: f, p, i = find_module(self.module, paths) - if f: f.close() + if f: + f.close() return default except ImportError: return None -- cgit v1.2.1 From 39bf3155d47c0024240be414a611dcb6d549f53c Mon Sep 17 00:00:00 2001 From: stepshal Date: Thu, 21 Jul 2016 09:37:34 +0700 Subject: Add missing blank lines after class or function definition. --- setuptools/depends.py | 1 + 1 file changed, 1 insertion(+) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 75344590..d5a344ad 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -213,4 +213,5 @@ def _update_globals(): del globals()[name] __all__.remove(name) + _update_globals() -- cgit v1.2.1 From df1bd4e17a082b9b634f62d799807a18e526a7c0 Mon Sep 17 00:00:00 2001 From: stepshal Date: Wed, 19 Oct 2016 00:10:40 +0700 Subject: Fix spacing after comment hash. --- setuptools/depends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index d5a344ad..89d39a50 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -145,7 +145,7 @@ def get_module_constant(module, symbol, default=-1, paths=None): try: if kind == PY_COMPILED: - f.read(8) # skip magic & date + f.read(8) # skip magic & date code = marshal.load(f) elif kind == PY_FROZEN: code = imp.get_frozen_object(module) -- cgit v1.2.1 From 1bd827efdf08b77f8a0a29c58dfc805368466964 Mon Sep 17 00:00:00 2001 From: Preston Landers Date: Wed, 28 Dec 2016 13:14:53 -0600 Subject: Attempt to fix issue #866 by iterating over code with `dis.Bytecode` instead of the internal `_iter_code`. The `dis` module was already used in `_iter_code` so I figured it was safe to use `Bytecode` from it. Not sure how this assumption holds up across all supported Python releases. I can only assume `Bytecode` wasn't there before when `_iter_code` was originally written? Note that `_iter_code` doesn't appear to be called anywhere in light of this change so I removed it. I should also note that `get_module_constant` has never worked with `setuptools.__version__` (returns -1) because it's not a string literal; it gets that attribute from another module. But this change does work in cases where a string literal is requested. https://github.com/pypa/setuptools/issues/866 --- setuptools/depends.py | 43 ++++++------------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 89d39a50..d8496ef8 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -4,7 +4,6 @@ import marshal from distutils.version import StrictVersion from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN -from setuptools.extern import six __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -78,39 +77,6 @@ class Require: return self.version_ok(version) -def _iter_code(code): - """Yield '(op,arg)' pair for each operation in code object 'code'""" - - from array import array - from dis import HAVE_ARGUMENT, EXTENDED_ARG - - bytes = array('b', code.co_code) - eof = len(code.co_code) - - ptr = 0 - extended_arg = 0 - - while ptr < eof: - - op = bytes[ptr] - - if op >= HAVE_ARGUMENT: - - arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg - ptr += 3 - - if op == EXTENDED_ARG: - long_type = six.integer_types[-1] - extended_arg = arg * long_type(65536) - continue - - else: - arg = None - ptr += 1 - - yield op, arg - - def find_module(module, paths=None): """Just like 'imp.find_module()', but with package support""" @@ -176,11 +142,12 @@ def extract_constant(code, symbol, default=-1): only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' must be present in 'code.co_names'. """ - if symbol not in code.co_names: - # name's not there, can't possibly be an assigment + # name's not there, can't possibly be an assignment return None + from dis import Bytecode + name_idx = list(code.co_names).index(symbol) STORE_NAME = 90 @@ -189,7 +156,9 @@ def extract_constant(code, symbol, default=-1): const = default - for op, arg in _iter_code(code): + for byte_code in Bytecode(code): + op = byte_code.opcode + arg = byte_code.arg if op == LOAD_CONST: const = code.co_consts[arg] -- cgit v1.2.1 From a29c9a4de0c8cf75b89582a0bf718056d58b0c10 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 28 Dec 2016 20:10:39 -0500 Subject: Use dis module rather than manually disassembling the bytecode. Fixes #866. --- setuptools/depends.py | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 89d39a50..c150c52b 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,11 +1,10 @@ import sys import imp import marshal +import dis from distutils.version import StrictVersion from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN -from setuptools.extern import six - __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' ] @@ -80,35 +79,10 @@ class Require: def _iter_code(code): """Yield '(op,arg)' pair for each operation in code object 'code'""" - - from array import array - from dis import HAVE_ARGUMENT, EXTENDED_ARG - - bytes = array('b', code.co_code) - eof = len(code.co_code) - - ptr = 0 - extended_arg = 0 - - while ptr < eof: - - op = bytes[ptr] - - if op >= HAVE_ARGUMENT: - - arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg - ptr += 3 - - if op == EXTENDED_ARG: - long_type = six.integer_types[-1] - extended_arg = arg * long_type(65536) - continue - - else: - arg = None - ptr += 1 - - yield op, arg + return ( + (op.opcode, op.arg) + for op in dis.Bytecode(code) + ) def find_module(module, paths=None): -- cgit v1.2.1 From 3000d975dbb11430be5c79498a461d33a5522a40 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 28 Dec 2016 20:52:09 -0500 Subject: Re-introduce _iter_code functionality as a Bytecode backport. Fixes failing tests. Ref #866. --- setuptools/depends.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index d417fa32..45e7052d 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,10 +1,11 @@ import sys import imp import marshal -import dis from distutils.version import StrictVersion from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN +from .py33compat import Bytecode + __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -155,7 +156,7 @@ def extract_constant(code, symbol, default=-1): const = default - for byte_code in dis.Bytecode(code): + for byte_code in Bytecode(code): op = byte_code.opcode arg = byte_code.arg -- cgit v1.2.1 From 1410d87f8abb5bb28bf97f53219ee0db7b6340a3 Mon Sep 17 00:00:00 2001 From: isidentical Date: Fri, 4 Oct 2019 19:18:54 +0300 Subject: Upgrade setuptools.depends to importlib from depracated imp --- setuptools/depends.py | 89 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 14 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 45e7052d..97f0ed9d 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,11 +1,23 @@ import sys -import imp import marshal from distutils.version import StrictVersion -from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN +from setuptools.extern import six from .py33compat import Bytecode +if six.PY2: + import imp + from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN +else: + import os.path + from importlib.util import find_spec, spec_from_loader + from importlib.machinery import SOURCE_SUFFIXES, BYTECODE_SUFFIXES, EXTENSION_SUFFIXES, BuiltinImporter, FrozenImporter + PY_SOURCE = 1 + PY_COMPILED = 2 + C_EXTENSION = 3 + C_BUILTIN = 6 + PY_FROZEN = 7 + __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -81,21 +93,59 @@ class Require: def find_module(module, paths=None): """Just like 'imp.find_module()', but with package support""" + if six.PY3: + spec = find_spec(module, paths) + if spec is None: + raise ImportError("Can't find %s" % module) + if not spec.has_location and hasattr(spec, 'submodule_search_locations'): + spec = spec_from_loader('__init__.py', spec.loader) + + kind = -1 + file = None + static = isinstance(spec.loader, type) + if spec.origin == 'frozen' or static and issubclass(spec.loader, FrozenImporter): + kind = PY_FROZEN + path = None # imp compabilty + suffix = mode = '' # imp compability + elif spec.origin == 'built-in' or static and issubclass(spec.loader, BuiltinImporter): + kind = C_BUILTIN + path = None # imp compabilty + suffix = mode = '' # imp compability + elif spec.has_location: + frozen = False + path = spec.origin + suffix = os.path.splitext(path)[1] + mode = 'r' if suffix in SOURCE_SUFFIXES else 'rb' + + if suffix in SOURCE_SUFFIXES: + kind = PY_SOURCE + elif suffix in BYTECODE_SUFFIXES: + kind = PY_COMPILED + elif suffix in EXTENSION_SUFFIXES: + kind = C_EXTENSION + + if kind in {PY_SOURCE, PY_COMPILED}: + file = open(path, mode) + else: + path = None + suffix = mode= '' - parts = module.split('.') + return file, path, (suffix, mode, kind) - while parts: - part = parts.pop(0) - f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) + else: + parts = module.split('.') + while parts: + part = parts.pop(0) + f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) - if kind == PKG_DIRECTORY: - parts = parts or ['__init__'] - paths = [path] + if kind == PKG_DIRECTORY: + parts = parts or ['__init__'] + paths = [path] - elif parts: - raise ImportError("Can't find %r in %s" % (parts, module)) + elif parts: + raise ImportError("Can't find %r in %s" % (parts, module)) - return info + return info def get_module_constant(module, symbol, default=-1, paths=None): @@ -111,18 +161,29 @@ def get_module_constant(module, symbol, default=-1, paths=None): # Module doesn't exist return None + if six.PY3: + spec = find_spec(module, paths) + if hasattr(spec, 'submodule_search_locations'): + spec = spec_from_loader('__init__.py', spec.loader) + try: if kind == PY_COMPILED: f.read(8) # skip magic & date code = marshal.load(f) elif kind == PY_FROZEN: - code = imp.get_frozen_object(module) + if six.PY2: + code = imp.get_frozen_object(module) + else: + code = spec.loader.get_code(module) elif kind == PY_SOURCE: code = compile(f.read(), path, 'exec') else: # Not something we can parse; we'll have to import it. :( if module not in sys.modules: - imp.load_module(module, f, path, (suffix, mode, kind)) + if six.PY2: + imp.load_module(module, f, path, (suffix, mode, kind)) + else: + sys.modules[module] = module_from_spec(spec) return getattr(sys.modules[module], symbol, None) finally: -- cgit v1.2.1 From 85a9ca5e75abf00e0dde55dde4e2b0a11f93c04a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 27 Oct 2019 19:50:53 -0400 Subject: Extract 'imp' re-implementation to setuptools._imp and wrap it in py27compat for compatibility. --- setuptools/depends.py | 95 +++++---------------------------------------------- 1 file changed, 8 insertions(+), 87 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index 97f0ed9d..eed4913a 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,22 +1,11 @@ import sys import marshal from distutils.version import StrictVersion -from setuptools.extern import six from .py33compat import Bytecode -if six.PY2: - import imp - from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN -else: - import os.path - from importlib.util import find_spec, spec_from_loader - from importlib.machinery import SOURCE_SUFFIXES, BYTECODE_SUFFIXES, EXTENSION_SUFFIXES, BuiltinImporter, FrozenImporter - PY_SOURCE = 1 - PY_COMPILED = 2 - C_EXTENSION = 3 - C_BUILTIN = 6 - PY_FROZEN = 7 +from .py27compat import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE +from . import py27compat __all__ = [ @@ -27,7 +16,8 @@ __all__ = [ class Require: """A prerequisite to building or installing a distribution""" - def __init__(self, name, requested_version, module, homepage='', + def __init__( + self, name, requested_version, module, homepage='', attribute=None, format=None): if format is None and requested_version is not None: @@ -91,63 +81,6 @@ class Require: return self.version_ok(version) -def find_module(module, paths=None): - """Just like 'imp.find_module()', but with package support""" - if six.PY3: - spec = find_spec(module, paths) - if spec is None: - raise ImportError("Can't find %s" % module) - if not spec.has_location and hasattr(spec, 'submodule_search_locations'): - spec = spec_from_loader('__init__.py', spec.loader) - - kind = -1 - file = None - static = isinstance(spec.loader, type) - if spec.origin == 'frozen' or static and issubclass(spec.loader, FrozenImporter): - kind = PY_FROZEN - path = None # imp compabilty - suffix = mode = '' # imp compability - elif spec.origin == 'built-in' or static and issubclass(spec.loader, BuiltinImporter): - kind = C_BUILTIN - path = None # imp compabilty - suffix = mode = '' # imp compability - elif spec.has_location: - frozen = False - path = spec.origin - suffix = os.path.splitext(path)[1] - mode = 'r' if suffix in SOURCE_SUFFIXES else 'rb' - - if suffix in SOURCE_SUFFIXES: - kind = PY_SOURCE - elif suffix in BYTECODE_SUFFIXES: - kind = PY_COMPILED - elif suffix in EXTENSION_SUFFIXES: - kind = C_EXTENSION - - if kind in {PY_SOURCE, PY_COMPILED}: - file = open(path, mode) - else: - path = None - suffix = mode= '' - - return file, path, (suffix, mode, kind) - - else: - parts = module.split('.') - while parts: - part = parts.pop(0) - f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) - - if kind == PKG_DIRECTORY: - parts = parts or ['__init__'] - paths = [path] - - elif parts: - raise ImportError("Can't find %r in %s" % (parts, module)) - - return info - - def get_module_constant(module, symbol, default=-1, paths=None): """Find 'module' by searching 'paths', and extract 'symbol' @@ -156,35 +89,23 @@ def get_module_constant(module, symbol, default=-1, paths=None): constant. Otherwise, return 'default'.""" try: - f, path, (suffix, mode, kind) = find_module(module, paths) + f, path, (suffix, mode, kind) = info = find_module(module, paths) except ImportError: # Module doesn't exist return None - if six.PY3: - spec = find_spec(module, paths) - if hasattr(spec, 'submodule_search_locations'): - spec = spec_from_loader('__init__.py', spec.loader) - try: if kind == PY_COMPILED: f.read(8) # skip magic & date code = marshal.load(f) elif kind == PY_FROZEN: - if six.PY2: - code = imp.get_frozen_object(module) - else: - code = spec.loader.get_code(module) + code = py27compat.get_frozen_object(module, paths) elif kind == PY_SOURCE: code = compile(f.read(), path, 'exec') else: # Not something we can parse; we'll have to import it. :( - if module not in sys.modules: - if six.PY2: - imp.load_module(module, f, path, (suffix, mode, kind)) - else: - sys.modules[module] = module_from_spec(spec) - return getattr(sys.modules[module], symbol, None) + imported = py27compat.get_module(module, paths, info) + return getattr(imported, symbol, None) finally: if f: -- cgit v1.2.1 From 773f1ec3c2622a78ee0280eb1d2b03c60871c52b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 27 Oct 2019 19:54:42 -0400 Subject: Rely on contextlib.closing for brevity. --- setuptools/depends.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index eed4913a..a37675cb 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,5 +1,6 @@ import sys import marshal +import contextlib from distutils.version import StrictVersion from .py33compat import Bytecode @@ -81,6 +82,17 @@ class Require: return self.version_ok(version) +def maybe_close(f): + @contextlib.contextmanager + def empty(): + yield + return + if not f: + return empty() + + return contextlib.closing(f) + + def get_module_constant(module, symbol, default=-1, paths=None): """Find 'module' by searching 'paths', and extract 'symbol' @@ -94,7 +106,7 @@ def get_module_constant(module, symbol, default=-1, paths=None): # Module doesn't exist return None - try: + with maybe_close(f): if kind == PY_COMPILED: f.read(8) # skip magic & date code = marshal.load(f) @@ -107,10 +119,6 @@ def get_module_constant(module, symbol, default=-1, paths=None): imported = py27compat.get_module(module, paths, info) return getattr(imported, symbol, None) - finally: - if f: - f.close() - return extract_constant(code, symbol, default) -- cgit v1.2.1 From fb7ab81a3d080422687bad71f9ae9d36eeefbee2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 16 Aug 2020 00:29:24 -0400 Subject: Remove Python 2 compatibility --- setuptools/depends.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'setuptools/depends.py') diff --git a/setuptools/depends.py b/setuptools/depends.py index a37675cb..8be6928a 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -1,12 +1,11 @@ import sys import marshal import contextlib +import dis from distutils.version import StrictVersion -from .py33compat import Bytecode - -from .py27compat import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE -from . import py27compat +from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE +from . import _imp __all__ = [ @@ -111,12 +110,12 @@ def get_module_constant(module, symbol, default=-1, paths=None): f.read(8) # skip magic & date code = marshal.load(f) elif kind == PY_FROZEN: - code = py27compat.get_frozen_object(module, paths) + code = _imp.get_frozen_object(module, paths) elif kind == PY_SOURCE: code = compile(f.read(), path, 'exec') else: # Not something we can parse; we'll have to import it. :( - imported = py27compat.get_module(module, paths, info) + imported = _imp.get_module(module, paths, info) return getattr(imported, symbol, None) return extract_constant(code, symbol, default) @@ -146,7 +145,7 @@ def extract_constant(code, symbol, default=-1): const = default - for byte_code in Bytecode(code): + for byte_code in dis.Bytecode(code): op = byte_code.opcode arg = byte_code.arg -- cgit v1.2.1