From 63e80ff9cb3adb16420d2010c8d43eca9082d1d3 Mon Sep 17 00:00:00 2001 From: Nicholas Hutchinson Date: Mon, 11 Apr 2022 08:54:23 +0100 Subject: [PATCH] Support Python 2.7 framework-style distributions on macOS 12 (#2325) --- docs/changelog/2284.feature.rst | 1 + .../via_global_ref/builtin/cpython/mac_os.py | 46 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 docs/changelog/2284.feature.rst diff --git a/docs/changelog/2284.feature.rst b/docs/changelog/2284.feature.rst new file mode 100644 index 000000000..9f93dba5a --- /dev/null +++ b/docs/changelog/2284.feature.rst @@ -0,0 +1 @@ +Support for creating a virtual environment from a Python 2.7 framework on macOS 12 - by :user:`nickhutchinson`. diff --git a/src/virtualenv/create/via_global_ref/builtin/cpython/mac_os.py b/src/virtualenv/create/via_global_ref/builtin/cpython/mac_os.py index 6024c97d1..d64f0d99b 100644 --- a/src/virtualenv/create/via_global_ref/builtin/cpython/mac_os.py +++ b/src/virtualenv/create/via_global_ref/builtin/cpython/mac_os.py @@ -25,20 +25,11 @@ class CPythonmacOsFramework(CPython): def can_describe(cls, interpreter): return is_mac_os_framework(interpreter) and super(CPythonmacOsFramework, cls).can_describe(interpreter) - @classmethod - def sources(cls, interpreter): - for src in super(CPythonmacOsFramework, cls).sources(interpreter): - yield src - # add a symlink to the host python image - exe = cls.image_ref(interpreter) - ref = PathRefToDest(exe, dest=lambda self, _: self.dest / ".Python", must=RefMust.SYMLINK) - yield ref - def create(self): super(CPythonmacOsFramework, self).create() # change the install_name of the copied python executables - target = "@executable_path/../.Python" + target = self.desired_mach_o_image_path() current = self.current_mach_o_image_path() for src in self._sources: if isinstance(src, ExePathRefToDest): @@ -62,8 +53,8 @@ def _executables(cls, interpreter): def current_mach_o_image_path(self): raise NotImplementedError - @classmethod - def image_ref(cls, interpreter): + @abstractmethod + def desired_mach_o_image_path(self): raise NotImplementedError @@ -74,13 +65,12 @@ def can_create(cls, interpreter): return super(CPython2macOsFramework, cls).can_create(interpreter) return False - @classmethod - def image_ref(cls, interpreter): - return Path(interpreter.prefix) / "Python" - def current_mach_o_image_path(self): return os.path.join(self.interpreter.prefix, "Python") + def desired_mach_o_image_path(self): + return "@executable_path/../Python" + @classmethod def sources(cls, interpreter): for src in super(CPython2macOsFramework, cls).sources(interpreter): @@ -89,6 +79,14 @@ def sources(cls, interpreter): exec_marker_file, to_path, _ = cls.from_stdlib(cls.mappings(interpreter), "lib-dynload") yield PathRefToDest(exec_marker_file, dest=to_path) + # add a copy of the host python image + exe = Path(interpreter.prefix) / "Python" + yield PathRefToDest(exe, dest=lambda self, _: self.dest / "Python", must=RefMust.COPY) + + # add a symlink to the Resources dir + resources = Path(interpreter.prefix) / "Resources" + yield PathRefToDest(resources, dest=lambda self, _: self.dest / "Resources") + @property def reload_code(self): result = super(CPython2macOsFramework, self).reload_code @@ -147,13 +145,21 @@ def fix_signature(self): class CPython3macOsFramework(CPythonmacOsFramework, CPython3, CPythonPosix): - @classmethod - def image_ref(cls, interpreter): - return Path(interpreter.prefix) / "Python3" - def current_mach_o_image_path(self): return "@executable_path/../../../../Python3" + def desired_mach_o_image_path(self): + return "@executable_path/../.Python" + + @classmethod + def sources(cls, interpreter): + for src in super(CPython3macOsFramework, cls).sources(interpreter): + yield src + + # add a symlink to the host python image + exe = Path(interpreter.prefix) / "Python3" + yield PathRefToDest(exe, dest=lambda self, _: self.dest / ".Python", must=RefMust.SYMLINK) + @property def reload_code(self): result = super(CPython3macOsFramework, self).reload_code