Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/_virtualenv.py @ 0:9e54283cc701 draft
"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
author | guerler |
---|---|
date | Mon, 27 Jul 2020 03:47:31 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9e54283cc701 |
---|---|
1 """Patches that are applied at runtime to the virtual environment""" | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 import os | |
5 import sys | |
6 | |
7 VIRTUALENV_PATCH_FILE = os.path.join(__file__) | |
8 | |
9 | |
10 def patch_dist(dist): | |
11 """ | |
12 Distutils allows user to configure some arguments via a configuration file: | |
13 https://docs.python.org/3/install/index.html#distutils-configuration-files | |
14 | |
15 Some of this arguments though don't make sense in context of the virtual environment files, let's fix them up. | |
16 """ | |
17 # we cannot allow some install config as that would get packages installed outside of the virtual environment | |
18 old_parse_config_files = dist.Distribution.parse_config_files | |
19 | |
20 def parse_config_files(self, *args, **kwargs): | |
21 result = old_parse_config_files(self, *args, **kwargs) | |
22 install = self.get_option_dict("install") | |
23 | |
24 if "prefix" in install: # the prefix governs where to install the libraries | |
25 install["prefix"] = VIRTUALENV_PATCH_FILE, os.path.abspath(sys.prefix) | |
26 for base in ("purelib", "platlib", "headers", "scripts", "data"): | |
27 key = "install_{}".format(base) | |
28 if key in install: # do not allow global configs to hijack venv paths | |
29 install.pop(key, None) | |
30 return result | |
31 | |
32 dist.Distribution.parse_config_files = parse_config_files | |
33 | |
34 | |
35 # Import hook that patches some modules to ignore configuration values that break package installation in case | |
36 # of virtual environments. | |
37 _DISTUTILS_PATCH = "distutils.dist", "setuptools.dist" | |
38 if sys.version_info > (3, 4): | |
39 # https://docs.python.org/3/library/importlib.html#setting-up-an-importer | |
40 from importlib.abc import MetaPathFinder | |
41 from importlib.util import find_spec | |
42 from threading import Lock | |
43 from functools import partial | |
44 | |
45 class _Finder(MetaPathFinder): | |
46 """A meta path finder that allows patching the imported distutils modules""" | |
47 | |
48 fullname = None | |
49 lock = Lock() | |
50 | |
51 def find_spec(self, fullname, path, target=None): | |
52 if fullname in _DISTUTILS_PATCH and self.fullname is None: | |
53 with self.lock: | |
54 self.fullname = fullname | |
55 try: | |
56 spec = find_spec(fullname, path) | |
57 if spec is not None: | |
58 # https://www.python.org/dev/peps/pep-0451/#how-loading-will-work | |
59 is_new_api = hasattr(spec.loader, "exec_module") | |
60 func_name = "exec_module" if is_new_api else "load_module" | |
61 old = getattr(spec.loader, func_name) | |
62 func = self.exec_module if is_new_api else self.load_module | |
63 if old is not func: | |
64 setattr(spec.loader, func_name, partial(func, old)) | |
65 return spec | |
66 finally: | |
67 self.fullname = None | |
68 | |
69 @staticmethod | |
70 def exec_module(old, module): | |
71 old(module) | |
72 if module.__name__ in _DISTUTILS_PATCH: | |
73 patch_dist(module) | |
74 | |
75 @staticmethod | |
76 def load_module(old, name): | |
77 module = old(name) | |
78 if module.__name__ in _DISTUTILS_PATCH: | |
79 patch_dist(module) | |
80 return module | |
81 | |
82 sys.meta_path.insert(0, _Finder()) | |
83 else: | |
84 # https://www.python.org/dev/peps/pep-0302/ | |
85 from imp import find_module | |
86 from pkgutil import ImpImporter, ImpLoader | |
87 | |
88 class _VirtualenvImporter(object, ImpImporter): | |
89 def __init__(self, path=None): | |
90 object.__init__(self) | |
91 ImpImporter.__init__(self, path) | |
92 | |
93 def find_module(self, fullname, path=None): | |
94 if fullname in _DISTUTILS_PATCH: | |
95 try: | |
96 return _VirtualenvLoader(fullname, *find_module(fullname.split(".")[-1], path)) | |
97 except ImportError: | |
98 pass | |
99 return None | |
100 | |
101 class _VirtualenvLoader(object, ImpLoader): | |
102 def __init__(self, fullname, file, filename, etc): | |
103 object.__init__(self) | |
104 ImpLoader.__init__(self, fullname, file, filename, etc) | |
105 | |
106 def load_module(self, fullname): | |
107 module = super(_VirtualenvLoader, self).load_module(fullname) | |
108 patch_dist(module) | |
109 module.__loader__ = None # distlib fallback | |
110 return module | |
111 | |
112 sys.meta_path.append(_VirtualenvImporter()) |