forked from mirrors/gecko-dev
Backed out changeset 09f7f3d1c6dd (bug 1766497) Backed out changeset 6bb5f754957a (bug 1766497) Backed out changeset aedf2d7af408 (bug 1766497) Backed out changeset 394555265c86 (bug 1766497) Backed out changeset 41be40696e00 (bug 1766497)
168 lines
5.7 KiB
Python
168 lines
5.7 KiB
Python
import json
|
|
import os
|
|
import sys
|
|
import zipfile
|
|
|
|
ABS_HERE = os.path.abspath(os.path.dirname(__file__))
|
|
NEW_IMPORT_SYSTEM = sys.version_info[0] == 3
|
|
|
|
|
|
class VersionPlatformSelect(object):
|
|
def __init__(self):
|
|
self.archive = ABS_HERE
|
|
self._zip_file = zipfile.ZipFile(ABS_HERE, "r")
|
|
self.modules = self._load("modules.json")
|
|
self.distributions = self._load("distributions.json")
|
|
self.__cache = {}
|
|
|
|
def _load(self, of_file):
|
|
version = ".".join(str(i) for i in sys.version_info[0:2])
|
|
per_version = json.loads(self.get_data(of_file).decode("utf-8"))
|
|
all_platforms = per_version[version] if version in per_version else per_version["3.9"]
|
|
content = all_platforms.get("==any", {}) # start will all platforms
|
|
not_us = "!={}".format(sys.platform)
|
|
for key, value in all_platforms.items(): # now override that with not platform
|
|
if key.startswith("!=") and key != not_us:
|
|
content.update(value)
|
|
content.update(all_platforms.get("=={}".format(sys.platform), {})) # and finish it off with our platform
|
|
return content
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
self._zip_file.close()
|
|
|
|
def find_mod(self, fullname):
|
|
if fullname in self.modules:
|
|
result = self.modules[fullname]
|
|
return result
|
|
|
|
def get_filename(self, fullname):
|
|
zip_path = self.find_mod(fullname)
|
|
return None if zip_path is None else os.path.join(ABS_HERE, zip_path)
|
|
|
|
def get_data(self, filename):
|
|
if filename.startswith(ABS_HERE):
|
|
# keep paths relative from the zipfile
|
|
filename = filename[len(ABS_HERE) + 1 :]
|
|
filename = filename.lstrip(os.sep)
|
|
if sys.platform == "win32":
|
|
# paths within the zipfile is always /, fixup on Windows to transform \ to /
|
|
filename = "/".join(filename.split(os.sep))
|
|
with self._zip_file.open(filename) as file_handler:
|
|
return file_handler.read()
|
|
|
|
def find_distributions(self, context):
|
|
dist_class = versioned_distribution_class()
|
|
name = context.name
|
|
if name in self.distributions:
|
|
result = dist_class(file_loader=self.get_data, dist_path=self.distributions[name])
|
|
yield result
|
|
|
|
def __repr__(self):
|
|
return "{}(path={})".format(self.__class__.__name__, ABS_HERE)
|
|
|
|
def _register_distutils_finder(self):
|
|
if "distlib" not in self.modules:
|
|
return
|
|
|
|
class DistlibFinder(object):
|
|
def __init__(self, path, loader):
|
|
self.path = path
|
|
self.loader = loader
|
|
|
|
def find(self, name):
|
|
class Resource(object):
|
|
def __init__(self, content):
|
|
self.bytes = content
|
|
|
|
full_path = os.path.join(self.path, name)
|
|
return Resource(self.loader.get_data(full_path))
|
|
|
|
# noinspection PyPackageRequirements
|
|
from distlib.resources import register_finder
|
|
|
|
register_finder(self, lambda module: DistlibFinder(os.path.dirname(module.__file__), self))
|
|
|
|
|
|
_VER_DISTRIBUTION_CLASS = None
|
|
|
|
|
|
def versioned_distribution_class():
|
|
global _VER_DISTRIBUTION_CLASS
|
|
if _VER_DISTRIBUTION_CLASS is None:
|
|
if sys.version_info >= (3, 8):
|
|
# noinspection PyCompatibility
|
|
from importlib.metadata import Distribution
|
|
else:
|
|
# noinspection PyUnresolvedReferences
|
|
from importlib_metadata import Distribution
|
|
|
|
class VersionedDistribution(Distribution):
|
|
def __init__(self, file_loader, dist_path):
|
|
self.file_loader = file_loader
|
|
self.dist_path = dist_path
|
|
|
|
def read_text(self, filename):
|
|
return self.file_loader(self.locate_file(filename)).decode("utf-8")
|
|
|
|
def locate_file(self, path):
|
|
return os.path.join(self.dist_path, path)
|
|
|
|
_VER_DISTRIBUTION_CLASS = VersionedDistribution
|
|
return _VER_DISTRIBUTION_CLASS
|
|
|
|
|
|
if NEW_IMPORT_SYSTEM:
|
|
# noinspection PyCompatibility
|
|
# noinspection PyCompatibility
|
|
from importlib.abc import SourceLoader
|
|
from importlib.util import spec_from_file_location
|
|
|
|
class VersionedFindLoad(VersionPlatformSelect, SourceLoader):
|
|
def find_spec(self, fullname, path, target=None):
|
|
zip_path = self.find_mod(fullname)
|
|
if zip_path is not None:
|
|
spec = spec_from_file_location(name=fullname, loader=self)
|
|
return spec
|
|
|
|
def module_repr(self, module):
|
|
raise NotImplementedError
|
|
|
|
|
|
else:
|
|
# noinspection PyDeprecation
|
|
from imp import new_module
|
|
|
|
class VersionedFindLoad(VersionPlatformSelect):
|
|
def find_module(self, fullname, path=None):
|
|
return self if self.find_mod(fullname) else None
|
|
|
|
def load_module(self, fullname):
|
|
filename = self.get_filename(fullname)
|
|
code = self.get_data(filename)
|
|
mod = sys.modules.setdefault(fullname, new_module(fullname))
|
|
mod.__file__ = filename
|
|
mod.__loader__ = self
|
|
is_package = filename.endswith("__init__.py")
|
|
if is_package:
|
|
mod.__path__ = [os.path.dirname(filename)]
|
|
mod.__package__ = fullname
|
|
else:
|
|
mod.__package__ = fullname.rpartition(".")[0]
|
|
exec(code, mod.__dict__)
|
|
return mod
|
|
|
|
|
|
def run():
|
|
with VersionedFindLoad() as finder:
|
|
sys.meta_path.insert(0, finder)
|
|
finder._register_distutils_finder()
|
|
from virtualenv.__main__ import run as run_virtualenv
|
|
|
|
run_virtualenv()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|