Skip to content

Commit

Permalink
Merge pull request #4828 from pypy/branch/issue4003
Browse files Browse the repository at this point in the history
Init sys.executable from GetModuleFileName on win32
  • Loading branch information
mattip committed Jan 4, 2024
2 parents 85125f6 + 4a85088 commit 1e8cc85
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
20 changes: 20 additions & 0 deletions extra_tests/test_startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,23 @@ def test_platform_not_imported():
modules = [x.strip(' "\'') for x in out.strip().strip('[]').split(',')]
assert 'platform' not in modules
assert 'threading' not in modules


def test_executable_win32():
# issue #4003
import os
import subprocess
import sys

out = subprocess.check_output([r'*', '-c',
'import sys; print (repr(sys.executable))'], universal_newlines=True, executable=sys.executable)
if sys.platform == 'win32':
assert out.strip() == repr(sys.executable)

fake_executable = r'C:\Windows\System32\cmd.exe'
assert os.path.isfile(fake_executable) # should exist always
out = subprocess.check_output([fake_executable, '-c',
'import sys; print (repr(sys.executable))'], universal_newlines=True, executable=sys.executable)
assert out.strip() == repr(sys.executable)
else:
assert out.strip() == repr('')
30 changes: 30 additions & 0 deletions pypy/module/sys/initpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ def compute_stdlib_path_maybe(state, prefix):

@unwrap_spec(executable='fsencode')
def pypy_find_executable(space, executable):
if _WIN32:
module_filename = pypy_init_executable()
if module_filename:
module_path = rffi.charp2str(module_filename)
pypy_init_free(module_filename)
module_path = rpath.rabspath(module_path)
if _exists_and_is_executable(module_path):
return space.newtext(module_path)
return space.newtext(find_executable(executable))


Expand Down Expand Up @@ -215,6 +223,23 @@ def pypy_find_stdlib(space, executable):
}
return p;
}
char *_pypy_init_executable(void)
{
DWORD res;
char *p;
p = malloc(_MAX_PATH);
if (p == NULL)
return NULL;
res = GetModuleFileName(NULL, p, _MAX_PATH);
if (res >= _MAX_PATH || res <= 0) {
free(p);
fprintf(stderr, "PyPy initialization: GetModuleFileName() failed\n");
return NULL;
}
return p;
}
"""

else:
Expand Down Expand Up @@ -257,6 +282,8 @@ def pypy_find_stdlib(space, executable):
post_include_bits=['RPY_EXPORTED char *_pypy_init_home(void);',
'RPY_EXPORTED void _pypy_init_free(char*);',
]
if _WIN32:
post_include_bits.append('RPY_EXPORTED char *_pypy_init_executable(void);')

_eci = ExternalCompilationInfo(separate_module_sources=[_source_code],
post_include_bits=post_include_bits)
Expand All @@ -266,3 +293,6 @@ def pypy_find_stdlib(space, executable):
_nowrapper=True, compilation_info=_eci)
pypy_init_free = rffi.llexternal("_pypy_init_free", [rffi.CCHARP], lltype.Void,
_nowrapper=True, compilation_info=_eci)
if _WIN32:
pypy_init_executable = rffi.llexternal("_pypy_init_executable", [], rffi.CCHARP,
_nowrapper=True, compilation_info=_eci)
14 changes: 14 additions & 0 deletions pypy/module/sys/test/apptest_initpath.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# spaceconfig = {"usemodules":["sys"]}

def test_pypy_find_executable():
# issue #4003
import sys

executable = sys.pypy_find_executable('*')
if sys.platform == 'win32':
assert executable.endswith('.exe')

fake_executable = r'C:\Windows\System32\cmd.exe' # should exist always
assert executable == sys.pypy_find_executable(fake_executable)
else:
assert executable == ''

0 comments on commit 1e8cc85

Please sign in to comment.