Bug 2336936

Summary: python-virtualenv fails to build with Python 3.14: AssertionError: common, "\n".join(difflib.unified_diff(list_to_str(sys_path), list_to_str(system_sys_path)))
Product: [Fedora] Fedora Reporter: Karolina Surma <ksurma>
Component: python-virtualenvAssignee: Lumír Balhar <lbalhar>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 42CC: cstratak, ksurma, lbalhar, mhroncok, mrunge, python-packagers-sig
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2025-02-26 13:16:21 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2322407    

Description Karolina Surma 2025-01-10 15:03:43 UTC
python-virtualenv fails to build with Python 3.14.0a3.

9 tests fail with a very similar errors:

___________ test_create_no_seed[root-cpython3-posix-symlinks-global] ___________

python = '/usr/bin/python3'
creator = CPython3Posix(dest=/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/'";&&e-$ èрт🚒♞中片-j, clear=False, no_vcs_ignore=False, global=True)
isolated = 'global'
system = {'datetime': "<module 'datetime' from '/usr/lib64/python3.14/datetime.py'>", 'json': "<module 'json' from '/usr/lib64/...akefile', 'math': "<module 'math' from '/usr/lib64/python3.14/lib-dynload/math.cpython-314-x86_64-linux-gnu.so'>", ...}
coverage_env = <function coverage_env.<locals>.finish at 0x7f964c4e6fb0>
special_name_dir = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j')

    @pytest.mark.parametrize(
        ("creator", "isolated"),
        [pytest.param(*i, id=f"{'-'.join(i[0])}-{i[1]}") for i in product(CREATE_METHODS, ["isolated", "global"])],
    )
    def test_create_no_seed(  # noqa: C901, PLR0912, PLR0913, PLR0915
        python,
        creator,
        isolated,
        system,
        coverage_env,
        special_name_dir,
    ):
        dest = special_name_dir
        creator_key, method = creator
        cmd = [
            "-v",
            "-v",
            "-p",
            str(python),
            str(dest),
            "--without-pip",
            "--activators",
            "",
            "--creator",
            creator_key,
            f"--{method}",
        ]
        if isolated == "global":
            cmd.append("--system-site-packages")
        result = cli_run(cmd)
        creator = result.creator
        coverage_env()
        if IS_PYPY:
            # pypy cleans up file descriptors periodically so our (many) subprocess calls impact file descriptor limits
            # force a close of these on system where the limit is low-ish (e.g. MacOS 256)
            gc.collect()
        purelib = creator.purelib
        patch_files = {purelib / f"{'_virtualenv'}.{i}" for i in ("py", "pyc", "pth")}
        patch_files.add(purelib / "__pycache__")
        content = set(creator.purelib.iterdir()) - patch_files
        assert not content, "\n".join(str(i) for i in content)
        assert creator.env_name == str(dest.name)
        debug = creator.debug
        assert "exception" not in debug, f"{debug.get('exception')}\n{debug.get('out')}\n{debug.get('err')}"
        sys_path = cleanup_sys_path(debug["sys"]["path"])
        system_sys_path = cleanup_sys_path(system["sys"]["path"])
        our_paths = set(sys_path) - set(system_sys_path)
        our_paths_repr = "\n".join(repr(i) for i in our_paths)
    
        # ensure we have at least one extra path added
        assert len(our_paths) >= 1, our_paths_repr
        # ensure all additional paths are related to the virtual environment
        for path in our_paths:
            msg = "\n".join(str(p) for p in system_sys_path)
            msg = f"\n{path!s}\ndoes not start with {dest!s}\nhas:\n{msg}"
            assert str(path).startswith(str(dest)), msg
        # ensure there's at least a site-packages folder as part of the virtual environment added
        assert any(p for p in our_paths if p.parts[-1] == "site-packages"), our_paths_repr
    
        # ensure the global site package is added or not, depending on flag
        global_sys_path = system_sys_path[-1]
        if isolated == "isolated":
            msg = "\n".join(str(j) for j in sys_path)
            msg = f"global sys path {global_sys_path!s} is in virtual environment sys path:\n{msg}"
            assert global_sys_path not in sys_path, msg
        else:
            common = []
            for left, right in zip(reversed(system_sys_path), reversed(sys_path)):
                if left == right:
                    common.append(left)
                else:
                    break
    
            def list_to_str(iterable):
                return [str(i) for i in iterable]
    
>           assert common, "\n".join(difflib.unified_diff(list_to_str(sys_path), list_to_str(system_sys_path)))
E           AssertionError: --- 
E             
E             +++ 
E             
E             @@ -1,5 +1,5 @@
E             
E              /builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib/python3.14/site-packages
E              /usr/lib64/python3.14
E              /usr/lib64/python3.14/lib-dynload
E             -/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/'";&&e-$ èрт🚒♞中片-j/lib64/python3.14/site-packages
E             -/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages
E             +/usr/lib64/python3.14/site-packages
E             +/usr/lib/python3.14/site-packages
E           assert []

cmd        = ['-v',
 '-v',
 '-p',
 '/usr/bin/python3',
 '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
 'èрт🚒♞中片-j',
 '--without-pip',
 '--activators',
 '',
 '--creator',
 'cpython3-posix',
 '--symlinks',
 '--system-site-packages']
common     = []
content    = set()
coverage_env = <function coverage_env.<locals>.finish at 0x7f964c4e6fb0>
creator    = CPython3Posix(dest=/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/'";&&e-$ èрт🚒♞中片-j, clear=False, no_vcs_ignore=False, global=True)
creator_key = 'cpython3-posix'
debug      = {'datetime': "<module 'datetime' from '/usr/lib64/python3.14/datetime.py'>",
 'json': "<module 'json' from '/usr/lib64/python3.14/json/__init__.py'>",
 'makefile_filename': '/usr/lib64/python3.14/config-3.14-x86_64-linux-gnu/Makefile',
 'math': "<module 'math' from "
         "'/usr/lib64/python3.14/lib-dynload/math.cpython-314-x86_64-linux-gnu.so'>",
 'os': "<module 'os' (frozen)>",
 'site': "<module 'site' (frozen)>",
 'sys': {'_base_executable': '/usr/bin/python3.14',
         'base_exec_prefix': '/usr',
         'base_prefix': '/usr',
         'exec_prefix': '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
                        'èрт🚒♞中片-j',
         'executable': '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
                       'èрт🚒♞中片-j/bin/python',
         'fs_encoding': 'utf-8',
         'io_encoding': 'utf-8',
         'meta_path': ["<class '_virtualenv._Finder'>",
                       "<class '_frozen_importlib.BuiltinImporter'>",
                       "<class '_frozen_importlib.FrozenImporter'>",
                       "<class '_frozen_importlib_external.PathFinder'>"],
         'path': ['/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib64/python3.14/site-packages',
                  '/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib/python3.14/site-packages',
                  '/usr/lib64/python314.zip',
                  '/usr/lib64/python3.14',
                  '/usr/lib64/python3.14/lib-dynload',
                  '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
                  'èрт🚒♞中片-j/lib64/python3.14/site-packages',
                  '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
                  'èрт🚒♞中片-j/lib/python3.14/site-packages'],
         'prefix': '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
                   'èрт🚒♞中片-j',
         'real_prefix': None},
 'version': '3.14.0a3 (main, Dec 17 2024, 00:00:00) [GCC 14.2.1 20241104 (Red '
            'Hat 14.2.1-6)]'}
dest       = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j')
global_sys_path = PosixPath('/usr/lib/python3.14/site-packages')
isolated   = 'global'
left       = PosixPath('/usr/lib/python3.14/site-packages')
list_to_str = <function test_create_no_seed.<locals>.list_to_str at 0x7f964c482090>
method     = 'symlinks'
msg        = ('\n'
 '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
 'èрт🚒♞中片-j/lib/python3.14/site-packages\n'
 'does not start with '
 '/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ '
 'èрт🚒♞中片-j\n'
 'has:\n'
 '/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib/python3.14/site-packages\n'
 '/usr/lib64/python3.14\n'
 '/usr/lib64/python3.14/lib-dynload\n'
 '/usr/lib64/python3.14/site-packages\n'
 '/usr/lib/python3.14/site-packages')
our_paths  = {PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages'),
 PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib64/python3.14/site-packages')}
our_paths_repr = ('PosixPath(\'/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\\\'";&&e-$ '
 "èрт🚒♞中片-j/lib64/python3.14/site-packages')\n"
 'PosixPath(\'/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\\\'";&&e-$ '
 "èрт🚒♞中片-j/lib/python3.14/site-packages')")
patch_files = {PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages/__pycache__'),
 PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages/_virtualenv.pth'),
 PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages/_virtualenv.py'),
 PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages/_virtualenv.pyc')}
path       = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages')
purelib    = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages')
python     = '/usr/bin/python3'
result     = <virtualenv.run.session.Session object at 0x7f964c499590>
right      = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages')
special_name_dir = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j')
sys_path   = [PosixPath('/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib/python3.14/site-packages'),
 PosixPath('/usr/lib64/python3.14'),
 PosixPath('/usr/lib64/python3.14/lib-dynload'),
 PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib64/python3.14/site-packages'),
 PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_no_seed_root_cpyth0/\'";&&e-$ èрт🚒♞中片-j/lib/python3.14/site-packages')]
system     = {'datetime': "<module 'datetime' from '/usr/lib64/python3.14/datetime.py'>",
 'json': "<module 'json' from '/usr/lib64/python3.14/json/__init__.py'>",
 'makefile_filename': '/usr/lib64/python3.14/config-3.14-x86_64-linux-gnu/Makefile',
 'math': "<module 'math' from "
         "'/usr/lib64/python3.14/lib-dynload/math.cpython-314-x86_64-linux-gnu.so'>",
 'os': "<module 'os' (frozen)>",
 'site': "<module 'site' (frozen)>",
 'sys': {'_base_executable': '/usr/bin/python3',
         'base_exec_prefix': '/usr',
         'base_prefix': '/usr',
         'exec_prefix': '/usr',
         'executable': '/usr/bin/python3',
         'fs_encoding': 'utf-8',
         'io_encoding': 'utf-8',
         'meta_path': ["<class '_distutils_hack.DistutilsMetaFinder'>",
                       "<class '_frozen_importlib.BuiltinImporter'>",
                       "<class '_frozen_importlib.FrozenImporter'>",
                       "<class '_frozen_importlib_external.PathFinder'>"],
         'path': ['/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib64/python3.14/site-packages',
                  '/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib/python3.14/site-packages',
                  '/usr/lib64/python314.zip',
                  '/usr/lib64/python3.14',
                  '/usr/lib64/python3.14/lib-dynload',
                  '/usr/lib64/python3.14/site-packages',
                  '/usr/lib/python3.14/site-packages'],
         'prefix': '/usr',
         'real_prefix': None},
 'version': '3.14.0a3 (main, Dec 17 2024, 00:00:00) [GCC 14.2.1 20241104 (Red '
            'Hat 14.2.1-6)]'}
system_sys_path = [PosixPath('/builddir/build/BUILD/python-virtualenv-20.28.1-build/BUILDROOT/usr/lib/python3.14/site-packages'),
 PosixPath('/usr/lib64/python3.14'),
 PosixPath('/usr/lib64/python3.14/lib-dynload'),
 PosixPath('/usr/lib64/python3.14/site-packages'),
 PosixPath('/usr/lib/python3.14/site-packages')]

https://docs.python.org/3.14/whatsnew/3.14.html

For the build logs, see:
https://copr-be.cloud.fedoraproject.org/results/@python/python3.14/fedora-rawhide-x86_64/08480327-python-virtualenv/

For all our attempts to build python-virtualenv with Python 3.14, see:
https://copr.fedorainfracloud.org/coprs/g/python/python3.14/package/python-virtualenv/

Testing and mass rebuild of packages is happening in copr.
You can follow these instructions to test locally in mock if your package builds with Python 3.14:
https://copr.fedorainfracloud.org/coprs/g/python/python3.14/

Let us know here if you have any questions.

Python 3.14 is planned to be included in Fedora 43.
To make that update smoother, we're building Fedora packages with all pre-releases of Python 3.14.
A build failure prevents us from testing all dependent packages (transitive [Build]Requires),
so if this package is required a lot, it's important for us to get it fixed soon.

We'd appreciate help from the people who know this package best,
but if you don't want to work on this now, let us know so we can try to work around it on our side.

Comment 1 Miro Hrončok 2025-02-26 13:16:21 UTC
this was fixed in python

Comment 2 Aoife Moloney 2025-02-26 13:22:15 UTC
This bug appears to have been reported against 'rawhide' during the Fedora Linux 42 development cycle.
Changing version to 42.