1# Copyright (C) 2017-2019 PyInstaller Development Team. 2# Copyright (C) 2016 Jason R Coombs <jaraco@jaraco.com> 3# 4# This file includes an almost complete copy of 5# pkg_resources/extern/__init__.py, taken from setuptools 28.6.1. 6# For PyInstaller the inly chane is to install a sub-class of VendorImporter. 7# 8# setuptools is licensed under the MIT License (expat) license: 9# 10# Permission is hereby granted, free of charge, to any person obtaining a copy 11# of this software and associated documentation files (the "Software"), to 12# deal in the Software without restriction, including without limitation the 13# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 14# sell copies of the Software, and to permit persons to whom the Software is 15# furnished to do so, subject to the following conditions: 16# 17# The above copyright notice and this permission notice shall be included in 18# all copies or substantial portions of the Software. 19# 20# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 26# IN THE SOFTWARE. 27 28#--- Code of pkg_resources/extern/__init__.py starts here 29import sys 30 31class VendorImporter: 32 """ 33 A PEP 302 meta path importer for finding optionally-vendored 34 or otherwise naturally-installed packages from root_name. 35 """ 36 37 def __init__(self, root_name, vendored_names=(), vendor_pkg=None): 38 self.root_name = root_name 39 self.vendored_names = set(vendored_names) 40 self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') 41 42 @property 43 def search_path(self): 44 """ 45 Search first the vendor package then as a natural package. 46 """ 47 yield self.vendor_pkg + '.' 48 yield '' 49 50 def find_module(self, fullname, path=None): 51 """ 52 Return self when fullname starts with root_name and the 53 target module is one vendored through this importer. 54 """ 55 root, base, target = fullname.partition(self.root_name + '.') 56 if root: 57 return 58 if not any(map(target.startswith, self.vendored_names)): 59 return 60 return self 61 62 def load_module(self, fullname): 63 """ 64 Iterate over the search path to locate and load fullname. 65 """ 66 root, base, target = fullname.partition(self.root_name + '.') 67 for prefix in self.search_path: 68 try: 69 extant = prefix + target 70 __import__(extant) 71 mod = sys.modules[extant] 72 sys.modules[fullname] = mod 73 # mysterious hack: 74 # Remove the reference to the extant package/module 75 # on later Python versions to cause relative imports 76 # in the vendor package to resolve the same modules 77 # as those going through this importer. 78 if sys.version_info > (3, 3): 79 del sys.modules[extant] 80 return mod 81 except ImportError: 82 pass 83 else: 84 raise ImportError( 85 "The '{target}' package is required; " 86 "normally this is bundled with this package so if you get " 87 "this warning, consult the packager of your " 88 "distribution.".format(**locals()) 89 ) 90 def install(self): 91 """ 92 Install this importer into sys.meta_path if not already present. 93 """ 94 if self not in sys.meta_path: 95 sys.meta_path.append(self) 96 97#--- Code of pkg_resources/extern/__init__.py ends here 98 99class MyVendorImporter(VendorImporter): 100 @property 101 def search_path(self): 102 """ 103 Only search the vendor package, and not a natural package. 104 """ 105 yield self.vendor_pkg + '.' 106 107names = ('aaa', 'bbb', 'ccc') 108MyVendorImporter(__name__, names).install() 109