diff options
| author | Jason R. Coombs <jaraco@jaraco.com> | 2016-01-04 21:00:47 -0500 |
|---|---|---|
| committer | Jason R. Coombs <jaraco@jaraco.com> | 2016-01-04 21:00:47 -0500 |
| commit | d9184f7b8f0b9405f68ea45dbd574aad6a08666d (patch) | |
| tree | e93b4d6ca527f8b22c4a11b978864f61ebe02405 /pkg_resources/extern/__init__.py | |
| parent | 6bdbe8957d8c8d293e3fea3fa4baf45eb7c3a3a4 (diff) | |
| parent | b639cf0fa905f6fda3879c991197b759aaa20091 (diff) | |
| download | python-setuptools-git-19.3b1.tar.gz | |
Merge feature/issue-22919.3b1
Diffstat (limited to 'pkg_resources/extern/__init__.py')
| -rw-r--r-- | pkg_resources/extern/__init__.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/pkg_resources/extern/__init__.py b/pkg_resources/extern/__init__.py new file mode 100644 index 00000000..317f4b8d --- /dev/null +++ b/pkg_resources/extern/__init__.py @@ -0,0 +1,71 @@ +import sys + + +class VendorImporter: + """ + A PEP 302 meta path importer for finding optionally-vendored + or otherwise naturally-installed packages from root_name. + """ + def __init__(self, root_name, vendored_names=(), vendor_pkg=None): + self.root_name = root_name + self.vendored_names = set(vendored_names) + self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') + + @property + def search_path(self): + """ + Search first the vendor package then as a natural package. + """ + yield self.vendor_pkg + '.' + yield '' + + def find_module(self, fullname, path=None): + """ + Return self when fullname starts with root_name and the + target module is one vendored through this importer. + """ + root, base, target = fullname.partition(self.root_name + '.') + if root: + return + if not any(map(target.startswith, self.vendored_names)): + return + return self + + def load_module(self, fullname): + """ + Iterate over the search path to locate and load fullname. + """ + root, base, target = fullname.partition(self.root_name + '.') + for prefix in self.search_path: + try: + extant = prefix + target + __import__(extant) + mod = sys.modules[extant] + sys.modules[fullname] = mod + # mysterious hack: + # Remove the reference to the extant package/module + # on later Python versions to cause relative imports + # in the vendor package to resolve the same modules + # as those going through this importer. + if sys.version_info > (3, 3): + del sys.modules[extant] + return mod + except ImportError: + pass + else: + raise ImportError( + "The '{target}' package is required; " + "normally this is bundled with this package so if you get " + "this warning, consult the packager of your " + "distribution.".format(**locals()) + ) + + def install(self): + """ + Install this importer into sys.meta_path if not already present. + """ + if self not in sys.meta_path: + sys.meta_path.append(self) + +names = 'packaging', 'six' +VendorImporter(__name__, names).install() |
