diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index f2b1f237f..f7b8cbb9c 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -34,9 +34,11 @@ jobs: - 3.7 - 3.6 - 3.5 - - pypy3 + - pypy-3.6 + - pypy-3.7-v7.3.6rc3 + - pypy-3.8-v7.3.6rc3 - 2.7 - - pypy2 + - pypy-2.7 include: - { os: macos-latest, py: brew@py3 } steps: diff --git a/docs/changelog/2182.bugfix.txt b/docs/changelog/2182.bugfix.txt new file mode 100644 index 000000000..0f26a202b --- /dev/null +++ b/docs/changelog/2182.bugfix.txt @@ -0,0 +1,2 @@ +Fixed path collision that could lead to a PermissionError or writing to system +directories when using PyPy3.8 - by :user:`mgorny`. diff --git a/src/virtualenv/create/via_global_ref/builtin/pypy/pypy3.py b/src/virtualenv/create/via_global_ref/builtin/pypy/pypy3.py index 2e7e10c82..25d8e1680 100644 --- a/src/virtualenv/create/via_global_ref/builtin/pypy/pypy3.py +++ b/src/virtualenv/create/via_global_ref/builtin/pypy/pypy3.py @@ -28,7 +28,7 @@ class PyPy3Posix(PyPy3, PosixSupports): @property def stdlib(self): """PyPy3 respects sysconfig only for the host python, virtual envs is instead lib/pythonx.y/site-packages""" - return self.dest / "lib" / "python{}".format(self.interpreter.version_release_str) / "site-packages" + return self.dest / "lib" / "pypy{}".format(self.interpreter.version_release_str) / "site-packages" @classmethod def _shared_libs(cls): @@ -41,9 +41,19 @@ def to_lib(self, src): def sources(cls, interpreter): for src in super(PyPy3Posix, cls).sources(interpreter): yield src + # Also copy/symlink anything under prefix/lib, which, for "portable" + # PyPy builds, includes the tk,tcl runtime and a number of shared + # objects. In distro-specific builds or on conda this should be empty + # (on PyPy3.8+ it will, like on CPython, hold the stdlib). host_lib = Path(interpreter.system_prefix) / "lib" + stdlib = Path(interpreter.system_stdlib) if host_lib.exists() and host_lib.is_dir(): for path in host_lib.iterdir(): + if stdlib == path: + # For PyPy3.8+ the stdlib lives in lib/pypy3.8 + # We need to avoid creating a symlink to it since that + # will defeat the purpose of a virtualenv + continue yield PathRefToDest(path, dest=cls.to_lib)