Support venv on python>=3.3
I know that the docs state a dependency on
virtualenv, 1.10 or later (this is true even with Python 3.3, where virtualenv is included as venv, since venv is not compatible with other versions of Python).
but would it be possible to just replace
import virtualenv
by
try: import venv as virtualenv
except ImportError: import virtualenv
everywhere, so that virtualenv becomes unneeded on Python>=3.3?
(Basically, I don't know if the two have APIs compatible enough for asv.)
Want to try if it works? Patches are welcome in principle. All relevant code is in asv/plugins/virtualenv.py
Ah, I think that won't work because you want to be able to use the current python to create virtualenvs for other pythons, which venv doesn't support.
I think that's probably not so crucial, it would probably also be fine to shell out to a subprocess for the env creation.
The workaround to the nested virtualenv/venv case apparently requires finding the "real" Python executable: from https://github.com/berdario/pew/blob/c25f19e9bb0bc94f696407378fc104706b5dd3b5/pew/_venv.py#L68-L104
def find_real_python():
# We need to run venv on the Python we want to use. sys.executable is not
# enough because it might come from a venv itself. venv can be easily
# confused if it is nested inside another venv.
# https://bugs.python.org/issue30811
python = ('python.exe' if windows else 'python')
# If we're in a venv, excellent! The config file has this information.
pyvenv_cfg = pathlib.Path(sys.prefix, 'pyvenv.cfg')
if pyvenv_cfg.exists():
return Cfg(pyvenv_cfg).bindir.joinpath(python)
# Or we can try looking this up from the build configuration. This is
# usually good enough, unless we're in a virtualenv (i.e. sys.real_prefix
# is set), and sysconfig reports the wrong Python (i.e. in the virtualenv).
import sysconfig
bindir = sysconfig.get_config_var('BINDIR')
try:
real_prefix = sys.real_prefix
except AttributeError:
return pathlib.Path(bindir, python)
if not os.path.realpath(bindir).startswith(real_prefix):
return pathlib.Path(bindir, python)
# OK, so we're in a virtualenv, and sysconfig lied. At this point there's
# no definitive way to tell where the real Python is, so let's make an
# educated guess. This works if the user isn't using a very exotic build.
for rel in ['', os.path.relpath(str(bindir), real_prefix), env_bin_dir]:
try:
path = pathlib.Path(real_prefix, rel, python).resolve()
except FileNotFoundError:
continue
if path.exists(): # On 3.6+ resolve() doesn't check for existence.
return path
# We've tried everything. Sorry.
raise BrokenEnvironmentError
It would be great to push this forward. venv is in the standard library since Python 3.3, and we support only version of python with a stable version of venv which is also the recommended way to use virtual environment.