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