Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for Windows PyPy 3.6 #2363

Merged
merged 1 commit into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ source =
src
.tox/*/lib/python*/site-packages
.tox/pypy*/site-packages
.tox\*\Lib\site-packages\
.tox\*\Lib\site-packages
.tox\py\site-packages
*/src
*\src

Expand Down
8 changes: 7 additions & 1 deletion src/virtualenv/create/creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,13 @@ def get_env_debug_info(env_exe, debug_script, app_data, env):
# noinspection PyBroadException
try:
if code != 0:
result = literal_eval(out)
if out:
result = literal_eval(out)
else:
if code == 2 and "file" in err:
# Re-raise FileNotFoundError from `run_cmd()`
raise OSError(err)
raise Exception(err)
else:
result = json.loads(out)
if err:
Expand Down
9 changes: 7 additions & 2 deletions src/virtualenv/create/via_global_ref/builtin/pypy/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ def _executables(cls, interpreter):
must = RefMust.COPY if interpreter.version_info.major == 2 else RefMust.NA
yield host, targets, must, RefWhen.ANY

@classmethod
def executables(cls, interpreter):
for src in super(PyPy, cls).sources(interpreter):
yield src

@classmethod
def exe_names(cls, interpreter):
return {
Expand All @@ -34,8 +39,8 @@ def exe_names(cls, interpreter):

@classmethod
def sources(cls, interpreter):
for src in super(PyPy, cls).sources(interpreter):
yield src
for exe in cls.executables(interpreter):
yield exe
for host in cls._add_shared_libs(interpreter):
yield PathRefToDest(host, dest=lambda self, s: self.bin_dir / s.name)

Expand Down
6 changes: 6 additions & 0 deletions src/virtualenv/create/via_global_ref/builtin/pypy/pypy3.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,15 @@ def sources(cls, interpreter):
class Pypy3Windows(PyPy3, WindowsSupports):
"""PyPy 3 on Windows"""

@property
def less_v37(self):
return self.interpreter.version_info.minor < 7

@property
def stdlib(self):
"""PyPy3 respects sysconfig only for the host python, virtual envs is instead Lib/site-packages"""
if self.less_v37:
return self.dest / "site-packages"
return self.dest / "Lib" / "site-packages"

@property
Expand Down
13 changes: 13 additions & 0 deletions src/virtualenv/create/via_global_ref/venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from virtualenv.util.subprocess import run_cmd

from .api import ViaGlobalRefApi, ViaGlobalRefMeta
from .builtin.pypy.pypy3 import Pypy3Windows


class Venv(ViaGlobalRefApi):
Expand Down Expand Up @@ -41,6 +42,18 @@ def create(self):
for lib in self.libs:
ensure_dir(lib)
super(Venv, self).create()
self.executables_for_win_pypy_less_v37()

def executables_for_win_pypy_less_v37(self):
"""
PyPy <= 3.6 (v7.3.3) for Windows contains only pypy3.exe and pypy3w.exe
Venv does not handle non-existing exe sources, e.g. python.exe, so this
patch does it.
"""
creator = self.describe
if isinstance(creator, Pypy3Windows) and creator.less_v37:
for exe in creator.executables(self.interpreter):
exe.run(creator, self.symlinks)

def create_inline(self):
from venv import EnvBuilder
Expand Down
7 changes: 5 additions & 2 deletions src/virtualenv/util/subprocess/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ def run_cmd(cmd):
)
out, err = process.communicate() # input disabled
code = process.returncode
except OSError as os_error:
code, out, err = os_error.errno, "", os_error.strerror
except OSError as error:
code, out, err = error.errno, "", error.strerror
if code == 2 and "file" in err:
# FileNotFoundError in Python >= 3.3
err = str(error)
return code, out, err


Expand Down