pypa / virtualenv

Virtual Python Environment builder
https://virtualenv.pypa.io
MIT License
4.8k stars 1.03k forks source link

cpython3_win_embed test failures with Python 3.13 #2671

Closed hroncok closed 9 months ago

hroncok commented 9 months ago

Issue

When I try to run the tests with Python 3.13.0a2 on Linux, I see the following 3 failures:

FAILED tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_3_exe_on_not_default_py_host[cpython3_win_embed] - AssertionError: assert False
FAILED tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_2_exe_on_default_py_host[cpython3_win_embed] - AssertionError: assert False
FAILED tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_only_shim[cpython3_win_embed] - AssertionError: assert False

The failures are:

$ tox -e py313 -- -k test_cpython3_win -v
.pkg: _optional_hooks> python .../pypa/virtualenv/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True hatchling.build
.pkg: get_requires_for_build_wheel> python .../pypa/virtualenv/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True hatchling.build
.pkg: get_requires_for_build_editable> python .../pypa/virtualenv/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True hatchling.build
.pkg: build_wheel> python .../pypa/virtualenv/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True hatchling.build
py313: install_package> python -I -m pip install --force-reinstall --no-deps .../pypa/virtualenv/.tox/.tmp/package/11/virtualenv-20.24.7.dev9+g6fbe60b-py3-none-any.whl
py313: commands[0]> coverage erase
py313: commands[1]> coverage run -m pytest -k test_cpython3_win -v
============================= test session starts ==============================
platform linux -- Python 3.13.0a2, pytest-7.4.3, pluggy-1.3.0 -- .../pypa/virtualenv/.tox/py313/bin/python
cachedir: .tox/py313/.pytest_cache
Using --randomly-seed=1001428486
rootdir: .../pypa/virtualenv
configfile: pyproject.toml
plugins: time-machine-2.13.0, flaky-3.7.0, timeout-2.2.0, randomly-3.15.0, mock-3.12.0, env-1.1.3
timeout: 600.0s
timeout method: signal
timeout func_only: False
collecting ... collected 322 items / 315 deselected / 7 selected

tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_no_python_zip_if_exists_and_not_set_in_path[cpython3_win_embed] PASSED [ 14%]
tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_2_exe_on_default_py_host[cpython3_win_embed] FAILED [ 28%]
tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_python_zip_if_exists_and_set_in_path[cpython3_win_embed] PASSED [ 42%]
tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_only_shim[cpython3_win_embed] FAILED [ 57%]
tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_no_python_zip_if_not_exists[cpython3_win_embed] PASSED [ 71%]
tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_exe_dll_pyd_without_shim[cpython3_win_embed] PASSED [ 85%]
tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_3_exe_on_not_default_py_host[cpython3_win_embed] FAILED [100%]

=================================== FAILURES ===================================
______________ test_2_exe_on_default_py_host[cpython3_win_embed] _______________

py_info = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, ...: 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807})
mock_files = <function mock_files.<locals>.<lambda> at 0x7f6df2f936a0>

    @pytest.mark.parametrize("py_info_name", ["cpython3_win_embed"])
    def test_2_exe_on_default_py_host(py_info, mock_files):
        mock_files(CPYTHON3_PATH, [py_info.system_executable])
        sources = tuple(CPython3Windows.sources(interpreter=py_info))
        # Default Python exe.
        assert contains_exe(sources, py_info.system_executable)
        # Should always exist.
>       assert contains_exe(sources, path(py_info.prefix, "pythonw.exe"))
E       AssertionError: assert False
E        +  where False = contains_exe((ExePathRefToDest(src=c:\path\to\python\python.exe, alias=[]), ExePathRefToDest(src=c:\path\to\python\python.exe, alias=[]), ExePathRefToDest(src=pythonw.exe, alias=[])), 'c:\\path\\to\\python\\pythonw.exe')
E        +    where 'c:\\path\\to\\python\\pythonw.exe' = path('c:\\path\\to\\python', 'pythonw.exe')
E        +      where 'c:\\path\\to\\python' = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, releaselevel='final', serial=0), 'architecture': 64, 'version_nodot': '310', 'version': '3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]', 'os': 'nt', 'prefix': 'c:\\path\\to\\python', 'base_prefix': 'c:\\path\\to\\python', 'real_prefix': None, 'base_exec_prefix': 'c:\\path\\to\\python', 'exec_prefix': 'c:\\path\\to\\python', 'executable': 'c:\\path\\to\\python\\python.exe', 'original_executable': 'c:\\path\\to\\python\\python.exe', 'system_executable': 'c:\\path\\to\\python\\python.exe', 'has_venv': False, 'path': ['c:\\path\\to\\python\\Scripts\\virtualenv.exe', 'c:\\path\\to\\python\\python310.zip', 'c:\\path\\to\\python', 'c:\\path\\to\\python\\Lib\\site-packages'], 'file_system_encoding': 'utf-8', 'stdout_encoding': 'utf-8', 'sysconfig_scheme': None, 'sysconfig_paths': {'stdlib': '{installed_base}/Lib', 'platstdlib': '{base}/Lib', 'purelib': '{base}/Lib/site-packages', 'platlib': '{base}/Lib/site-packages', 'include': '{installed_base}/Include', 'scripts': '{base}/Scripts', 'data': '{base}'}, 'distutils_install': {'purelib': 'Lib\\site-packages', 'platlib': 'Lib\\site-packages', 'headers': 'Include\\UNKNOWN', 'scripts': 'Scripts', 'data': ''}, 'sysconfig': {'makefile_filename': 'c:\\path\\to\\python\\Lib\\config\\Makefile'}, 'sysconfig_vars': {'PYTHONFRAMEWORK': '', 'installed_base': 'c:\\path\\to\\python', 'base': 'c:\\path\\to\\python'}, 'system_stdlib': 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807}).prefix

mock_files = <function mock_files.<locals>.<lambda> at 0x7f6df2f936a0>
py_info    = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, ...: 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807})
sources    = (ExePathRefToDest(src=c:\path\to\python\python.exe, alias=[]), ExePathRefToDest(src=c:\path\to\python\python.exe, alias=[]), ExePathRefToDest(src=pythonw.exe, alias=[]))

tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py:22: AssertionError
______________________ test_only_shim[cpython3_win_embed] ______________________

py_info = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, ...: 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807})
mock_files = <function mock_files.<locals>.<lambda> at 0x7f6df2e58d60>

    @pytest.mark.parametrize("py_info_name", ["cpython3_win_embed"])
    def test_only_shim(py_info, mock_files):
        shim = path(py_info.system_stdlib, "venv\\scripts\\nt\\python.exe")
        py_files = (
            path(py_info.prefix, "libcrypto-1_1.dll"),
            path(py_info.prefix, "libffi-7.dll"),
            path(py_info.prefix, "_asyncio.pyd"),
            path(py_info.prefix, "_bz2.pyd"),
        )
        mock_files(CPYTHON3_PATH, [shim, *py_files])
        sources = tuple(CPython3Windows.sources(interpreter=py_info))
>       assert CPython3Windows.has_shim(interpreter=py_info)
E       AssertionError: assert False
E        +  where False = <bound method CPython3Windows.has_shim of <class 'virtualenv.create.via_global_ref.builtin.cpython.cpython3.CPython3Windows'>>(interpreter=PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, releaselevel='final', serial=0), 'architecture': 64, 'version_nodot': '310', 'version': '3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]', 'os': 'nt', 'prefix': 'c:\\path\\to\\python', 'base_prefix': 'c:\\path\\to\\python', 'real_prefix': None, 'base_exec_prefix': 'c:\\path\\to\\python', 'exec_prefix': 'c:\\path\\to\\python', 'executable': 'c:\\path\\to\\python\\python.exe', 'original_executable': 'c:\\path\\to\\python\\python.exe', 'system_executable': 'c:\\path\\to\\python\\python.exe', 'has_venv': False, 'path': ['c:\\path\\to\\python\\Scripts\\virtualenv.exe', 'c:\\path\\to\\python\\python310.zip', 'c:\\path\\to\\python', 'c:\\path\\to\\python\\Lib\\site-packages'], 'file_system_encoding': 'utf-8', 'stdout_encoding': 'utf-8', 'sysconfig_scheme': None, 'sysconfig_paths': {'stdlib': '{installed_base}/Lib', 'platstdlib': '{base}/Lib', 'purelib': '{base}/Lib/site-packages', 'platlib': '{base}/Lib/site-packages', 'include': '{installed_base}/Include', 'scripts': '{base}/Scripts', 'data': '{base}'}, 'distutils_install': {'purelib': 'Lib\\site-packages', 'platlib': 'Lib\\site-packages', 'headers': 'Include\\UNKNOWN', 'scripts': 'Scripts', 'data': ''}, 'sysconfig': {'makefile_filename': 'c:\\path\\to\\python\\Lib\\config\\Makefile'}, 'sysconfig_vars': {'PYTHONFRAMEWORK': '', 'installed_base': 'c:\\path\\to\\python', 'base': 'c:\\path\\to\\python'}, 'system_stdlib': 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807}))
E        +    where <bound method CPython3Windows.has_shim of <class 'virtualenv.create.via_global_ref.builtin.cpython.cpython3.CPython3Windows'>> = CPython3Windows.has_shim

mock_files = <function mock_files.<locals>.<lambda> at 0x7f6df2e58d60>
py_files   = ('c:\\path\\to\\python\\libcrypto-1_1.dll', 'c:\\path\\to\\python\\libffi-7.dll', 'c:\\path\\to\\python\\_asyncio.pyd', 'c:\\path\\to\\python\\_bz2.pyd')
py_info    = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, ...: 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807})
shim       = 'c:\\path\\to\\python\\Lib\\venv\\scripts\\nt\\python.exe'
sources    = (ExePathRefToDest(src=c:\path\to\python\python.exe, alias=[]), ExePathRefToDest(src=c:\path\to\python\python.exe, alia...ffi-7.dll), PathRefToDest(src=c:\path\to\python\_bz2.pyd), PathRefToDest(src=c:\path\to\python\libcrypto-1_1.dll), ...)

tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py:49: AssertionError
____________ test_3_exe_on_not_default_py_host[cpython3_win_embed] _____________

py_info = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, ...: 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807})
mock_files = <function mock_files.<locals>.<lambda> at 0x7f6df2e5a0c0>

    @pytest.mark.parametrize("py_info_name", ["cpython3_win_embed"])
    def test_3_exe_on_not_default_py_host(py_info, mock_files):
        # Not default python host.
        py_info.system_executable = path(py_info.prefix, "python666.exe")
        mock_files(CPYTHON3_PATH, [py_info.system_executable])
        sources = tuple(CPython3Windows.sources(interpreter=py_info))
        # Not default Python exe linked to both the default name and origin.
        assert contains_exe(sources, py_info.system_executable, "python.exe")
>       assert contains_exe(sources, py_info.system_executable, "python666.exe")
E       AssertionError: assert False
E        +  where False = contains_exe((ExePathRefToDest(src=c:\path\to\python\python666.exe, alias=[]), ExePathRefToDest(src=c:\path\to\python\python666.exe, alias=[]), ExePathRefToDest(src=pythonw.exe, alias=[])), 'c:\\path\\to\\python\\python666.exe', 'python666.exe')
E        +    where 'c:\\path\\to\\python\\python666.exe' = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, releaselevel='final', serial=0), 'architecture': 64, 'version_nodot': '310', 'version': '3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]', 'os': 'nt', 'prefix': 'c:\\path\\to\\python', 'base_prefix': 'c:\\path\\to\\python', 'real_prefix': None, 'base_exec_prefix': 'c:\\path\\to\\python', 'exec_prefix': 'c:\\path\\to\\python', 'executable': 'c:\\path\\to\\python\\python.exe', 'original_executable': 'c:\\path\\to\\python\\python.exe', 'system_executable': 'c:\\path\\to\\python\\python666.exe', 'has_venv': False, 'path': ['c:\\path\\to\\python\\Scripts\\virtualenv.exe', 'c:\\path\\to\\python\\python310.zip', 'c:\\path\\to\\python', 'c:\\path\\to\\python\\Lib\\site-packages'], 'file_system_encoding': 'utf-8', 'stdout_encoding': 'utf-8', 'sysconfig_scheme': None, 'sysconfig_paths': {'stdlib': '{installed_base}/Lib', 'platstdlib': '{base}/Lib', 'purelib': '{base}/Lib/site-packages', 'platlib': '{base}/Lib/site-packages', 'include': '{installed_base}/Include', 'scripts': '{base}/Scripts', 'data': '{base}'}, 'distutils_install': {'purelib': 'Lib\\site-packages', 'platlib': 'Lib\\site-packages', 'headers': 'Include\\UNKNOWN', 'scripts': 'Scripts', 'data': ''}, 'sysconfig': {'makefile_filename': 'c:\\path\\to\\python\\Lib\\config\\Makefile'}, 'sysconfig_vars': {'PYTHONFRAMEWORK': '', 'installed_base': 'c:\\path\\to\\python', 'base': 'c:\\path\\to\\python'}, 'system_stdlib': 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807}).system_executable

mock_files = <function mock_files.<locals>.<lambda> at 0x7f6df2e5a0c0>
py_info    = PythonInfo({'platform': 'win32', 'implementation': 'CPython', 'version_info': VersionInfo(major=3, minor=10, micro=4, ...: 'c:\\path\\to\\python\\Lib', 'system_stdlib_platform': 'c:\\path\\to\\python\\Lib', 'max_size': 9223372036854775807})
sources    = (ExePathRefToDest(src=c:\path\to\python\python666.exe, alias=[]), ExePathRefToDest(src=c:\path\to\python\python666.exe, alias=[]), ExePathRefToDest(src=pythonw.exe, alias=[]))

tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py:33: AssertionError
=========================== short test summary info ============================
FAILED tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_2_exe_on_default_py_host[cpython3_win_embed]
FAILED tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_only_shim[cpython3_win_embed]
FAILED tests/unit/create/via_global_ref/builtin/cpython/test_cpython3_win.py::test_3_exe_on_not_default_py_host[cpython3_win_embed]
================= 3 failed, 4 passed, 315 deselected in 1.49s ==================
py313: exit 1 (2.48 seconds) .../pypa/virtualenv> coverage run -m pytest -k test_cpython3_win -v pid=3520816
.pkg: _exit> python .../pypa/virtualenv/.tox/.tox/lib/python3.11/site-packages/pyproject_api/_backend.py True hatchling.build
  py313: FAIL code 1 (10.68=setup[8.02]+cmd[0.18,2.48] seconds)
  evaluation failed :( (10.74 seconds)

I have no idea why those tests even run on Linux. I suspect this needs some support in tests/unit/discovery/windows/winreg-mock-values.py but the values there are cryptic to me.

Environment

Provide at least:

Package                    Version
-------------------------- ---------------------
covdefaults                2.3.0
coverage                   7.3.2
coverage-enable-subprocess 1.0
distlib                    0.3.7
filelock                   3.13.1
flaky                      3.7.0
iniconfig                  2.0.0
packaging                  23.2
pip                        23.3.1
platformdirs               4.0.0
pluggy                     1.3.0
pytest                     7.4.3
pytest-env                 1.1.3
pytest-mock                3.12.0
pytest-randomly            3.15.0
pytest-timeout             2.2.0
python-dateutil            2.8.2
setuptools                 69.0.2
six                        1.16.0
time-machine               2.13.0
virtualenv                 20.24.7.dev9+g6fbe60b
gaborbernat commented 9 months ago

Seems like a bug, why is windows running on Linux?

hroncok commented 9 months ago

I had the same idea. However, with Python 3.12 it passes.

hroncok commented 9 months ago

In Python 3.12, this code:

https://github.com/pypa/virtualenv/blob/c7e57f33a7c8679441cb3edab074ea2e778c6686/tests/unit/create/via_global_ref/builtin/testing/path.py#L59

Checks whether c:/path/to/python/python.exe is in {PathMock('c:/path/to/python/python.exe')}

In Python 3.13, it checks whether c:\path\to\python\python.exe is in {PathMock('c:\\path\\to\\python\\python.exe')}

hroncok commented 9 months ago
$ python3.12 -c 'import pathlib; print(pathlib.Path()._flavour.altsep)'
None

$ python3.13 -c 'import pathlib; print(pathlib.Path()._flavour.altsep)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import pathlib; print(pathlib.Path()._flavour.altsep)
                          ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'PosixPath' object has no attribute '_flavour'
hroncok commented 9 months ago

https://github.com/python/cpython/commit/c6c5665ee0c0a5ddc96da255c9a62daa332c32b3

This renames _flavour to pathmod.

befeleme commented 5 months ago

Python 3.13.0a6 renamed pathmod to parser (https://github.com/python/cpython/commit/752e18389ed03087b51b38eac9769ef8dfd167b7) - it's resolvable by a simple string replacement, will post a PR.