Describe the bug
Although xbuild provides a virtualenv optional extra, xvenv is not currently compatible with virtualenv.
xvenv's conversion logic (xvenv/convert.py) reads the target venv's Python version from pyvenv.cfg using a regex:
match = re.search("version = (.*)", venv_config)
This regex matches the first substring in the file that looks like version = .... When the venv was created by the third-party virtualenv package (as opposed to stdlib venv), pyvenv.cfg contains two lines ending in version = :
implementation = CPython
python-version = 3.13
version_info = 3.13.15.final.0
version = 3.13.15
Because "python-version = 3.13" itself contains the substring "version = 3.13", and python-version appears before version in the file, re.search matches the python-version line instead of the intended version line. This yields a two-component version string ("3.13") instead of the expected three-component string ("3.13.15").
The subsequent check then always fails, because "3.13".startswith("3.13.15.") is False — even though the venv and the build-details/sysconfigdata file are for the exact same Python version. The resulting error message is self-contradictory, e.g.:
ValueError: target venv is Python 3.13; build details file is for Python 3.13
(both sides print the same truncated value, making the message confusing to debug).
This breaks xvenv/xbuild/xpython conversion for any venv created via the third-party virtualenv package. This is a common scenario for consumers who manage their own virtualenv-based tooling (we hit it via cibuildwheel, which uses virtualenv.pyz to create its build venv)
How to reproduce the bug
$ python -m venv /tmp/outer && /tmp/outer/bin/python -m pip install virtualenv xbuild
$ /tmp/outer/bin/python -m virtualenv /tmp/testvenv --python python3.13
$ cat /tmp/testvenv/pyvenv.cfg
implementation = CPython
python-version = 3.13
version_info = 3.13.15.final.0
version = 3.13.15
...
$ /tmp/outer/bin/python -m xvenv --platform android /tmp/testvenv
ERROR target venv is Python 3.13; build details file is for Python 3.13
Minimum example code
Screenshots
No response
Environment details
- Operating system and version: All (tested on macOS 26)
- Python version: All (tested on 3.13, 3.14)
- Software versions:
Logs
Additional context
Parse pyvenv.cfg as proper key = value pairs using configparser with a synthetic section header rather than a free-text regex search.
Testing for this should involve a "live" test that creates a venv with virtualenv and then converts it.
Describe the bug
Although
xbuildprovides avirtualenvoptional extra,xvenvis not currently compatible withvirtualenv.xvenv's conversion logic (xvenv/convert.py) reads the target venv's Python version frompyvenv.cfgusing a regex:match = re.search("version = (.*)", venv_config)This regex matches the first substring in the file that looks like
version = .... When the venv was created by the third-partyvirtualenvpackage (as opposed to stdlibvenv),pyvenv.cfgcontains two lines ending inversion =:Because "python-version = 3.13" itself contains the substring "version = 3.13", and
python-versionappears beforeversionin the file,re.searchmatches the python-version line instead of the intended version line. This yields a two-component version string ("3.13") instead of the expected three-component string ("3.13.15").The subsequent check then always fails, because "3.13".startswith("3.13.15.") is False — even though the venv and the build-details/sysconfigdata file are for the exact same Python version. The resulting error message is self-contradictory, e.g.:
(both sides print the same truncated value, making the message confusing to debug).
This breaks
xvenv/xbuild/xpythonconversion for anyvenvcreated via the third-partyvirtualenvpackage. This is a common scenario for consumers who manage their own virtualenv-based tooling (we hit it via cibuildwheel, which uses virtualenv.pyz to create its build venv)How to reproduce the bug
Minimum example code
Screenshots
No response
Environment details
Logs
Additional context
Parse
pyvenv.cfgas properkey = valuepairs using configparser with a synthetic section header rather than a free-text regex search.Testing for this should involve a "live" test that creates a venv with virtualenv and then converts it.