Pier Angelo Vendrame pushed to branch tor-browser-128.5.0esr-14.5-1 at The Tor Project / Applications / Tor Browser

Commits:

1 changed file:

Changes:

  • python/mach/mach/site.py
    ... ... @@ -17,6 +17,7 @@ import subprocess
    17 17
     import sys
    
    18 18
     import sysconfig
    
    19 19
     import tempfile
    
    20
    +import warnings
    
    20 21
     from contextlib import contextmanager
    
    21 22
     from pathlib import Path
    
    22 23
     from typing import Callable, Optional
    
    ... ... @@ -817,33 +818,75 @@ class PythonVirtualenv:
    817 818
         """Calculates paths of interest for general python virtual environments"""
    
    818 819
     
    
    819 820
         def __init__(self, prefix):
    
    820
    -        if _is_windows:
    
    821
    -            self.bin_path = os.path.join(prefix, "Scripts")
    
    822
    -            self.python_path = os.path.join(self.bin_path, "python.exe")
    
    823
    -        else:
    
    824
    -            self.bin_path = os.path.join(prefix, "bin")
    
    825
    -            self.python_path = os.path.join(self.bin_path, "python")
    
    826 821
             self.prefix = os.path.realpath(prefix)
    
    822
    +        self.paths = self._get_sysconfig_paths(self.prefix)
    
    827 823
     
    
    828
    -    @functools.lru_cache(maxsize=None)
    
    829
    -    def resolve_sysconfig_packages_path(self, sysconfig_path):
    
    830
    -        # macOS uses a different default sysconfig scheme based on whether it's using the
    
    831
    -        # system Python or running in a virtualenv.
    
    832
    -        # Manually define the scheme (following the implementation in
    
    833
    -        # "sysconfig._get_default_scheme()") so that we're always following the
    
    834
    -        # code path for a virtualenv directory structure.
    
    835
    -        if os.name == "posix":
    
    836
    -            scheme = "posix_prefix"
    
    837
    -        else:
    
    838
    -            scheme = os.name
    
    824
    +        # Name of the Python executable to use in virtual environments.
    
    825
    +        # An executable with the same name as sys.executable might not exist in
    
    826
    +        # virtual environments. An executable with 'python' as the steam —
    
    827
    +        # without version numbers or ABI flags — will always be present in
    
    828
    +        # virtual environments, so we use that.
    
    829
    +        python_exe_name = "python" + sysconfig.get_config_var("EXE")
    
    830
    +
    
    831
    +        self.bin_path = self.paths["scripts"]
    
    832
    +        self.python_path = os.path.join(self.bin_path, python_exe_name)
    
    839 833
     
    
    840
    -        sysconfig_paths = sysconfig.get_paths(scheme)
    
    841
    -        data_path = Path(sysconfig_paths["data"])
    
    842
    -        path = Path(sysconfig_paths[sysconfig_path])
    
    843
    -        relative_path = path.relative_to(data_path)
    
    834
    +    @staticmethod
    
    835
    +    def _get_sysconfig_paths(prefix):
    
    836
    +        """Calculate the sysconfig paths of a virtual environment in the given prefix.
    
    844 837
     
    
    845
    -        # Path to virtualenv's "site-packages" directory for provided sysconfig path
    
    846
    -        return os.path.normpath(os.path.normcase(Path(self.prefix) / relative_path))
    
    838
    +        The virtual environment MUST be using the same Python distribution as us.
    
    839
    +        """
    
    840
    +        # Determine the sysconfig scheme used in virtual environments
    
    841
    +        if "venv" in sysconfig.get_scheme_names():
    
    842
    +            # A 'venv' scheme was added in Python 3.11 to allow users to
    
    843
    +            # calculate the paths for a virtual environment, since the default
    
    844
    +            # scheme may not always be the same as used on virtual environments.
    
    845
    +            # Some common examples are the system Python distributed by macOS,
    
    846
    +            # Debian, and Fedora.
    
    847
    +            # For more information, see https://github.com/python/cpython/issues/89576
    
    848
    +            venv_scheme = "venv"
    
    849
    +        elif os.name == "nt":
    
    850
    +            # We know that before the 'venv' scheme was added, on Windows,
    
    851
    +            # the 'nt' scheme was used in virtual environments.
    
    852
    +            venv_scheme = "nt"
    
    853
    +        elif os.name == "posix":
    
    854
    +            # We know that before the 'venv' scheme was added, on POSIX,
    
    855
    +            # the 'posix_prefix' scheme was used in virtual environments.
    
    856
    +            venv_scheme = "posix_prefix"
    
    857
    +        else:
    
    858
    +            # This should never happen with upstream Python, as the 'venv'
    
    859
    +            # scheme should always be available on >=3.11, and no other
    
    860
    +            # platforms are supported by the upstream on older Python versions.
    
    861
    +            #
    
    862
    +            # Since the 'venv' scheme isn't available, and we have no knowledge
    
    863
    +            # of this platform/distribution, fallback to the default scheme.
    
    864
    +            #
    
    865
    +            # Hitting this will likely be the result of running a custom Python
    
    866
    +            # distribution targetting a platform that is not supported by the
    
    867
    +            # upstream.
    
    868
    +            # In this case, unless the Python vendor patched the Python
    
    869
    +            # distribution in such a way as the default scheme may not always be
    
    870
    +            # the same scheme, using the default scheme should be correct.
    
    871
    +            # If the vendor did patch Python as such, to work around this issue,
    
    872
    +            # I would recommend them to define a 'venv' scheme that matches
    
    873
    +            # the layout used on virtual environments in their Python distribution.
    
    874
    +            # (rec. signed Filipe Laíns — upstream sysconfig maintainer)
    
    875
    +            venv_scheme = sysconfig.get_default_scheme()
    
    876
    +            warnings.warn(
    
    877
    +                f"Unknown platform '{os.name}', using the default install scheme '{venv_scheme}'. "
    
    878
    +                "If this is incorrect, please ask your Python vendor to add a 'venv' sysconfig scheme "
    
    879
    +                "(see https://github.com/python/cpython/issues/89576, or check the code comment).",
    
    880
    +                stacklevel=2,
    
    881
    +            )
    
    882
    +        # Build the sysconfig config_vars dictionary for the virtual environment.
    
    883
    +        venv_vars = sysconfig.get_config_vars().copy()
    
    884
    +        venv_vars["base"] = venv_vars["platbase"] = prefix
    
    885
    +        # Get sysconfig paths for the virtual environment.
    
    886
    +        return sysconfig.get_paths(venv_scheme, vars=venv_vars)
    
    887
    +
    
    888
    +    def resolve_sysconfig_packages_path(self, sysconfig_path):
    
    889
    +        return self.paths[sysconfig_path]
    
    847 890
     
    
    848 891
         def site_packages_dirs(self):
    
    849 892
             dirs = []