Skip to content

Commit e60ab77

Browse files
committed
fix(nodeenv): warn when -p picks the activated virtualenv over its own
The activated VIRTUAL_ENV and the virtualenv nodeenv is installed in can only differ when nodeenv is installed elsewhere, and then the choice is ambiguous, so log which one is used and how to override it. The three sys.prefix branches all resolved to the same value, they are folded into a single check reused by the warning.
1 parent e1f884e commit e60ab77

2 files changed

Lines changed: 46 additions & 6 deletions

File tree

nodeenv.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,11 @@ def resolve_node_version(spec):
13821382

13831383
def get_env_dir(args):
13841384
if args.python_virtualenv:
1385+
# whether nodeenv itself is running inside a python virtualenv
1386+
in_virtualenv = (
1387+
hasattr(sys, 'real_prefix') or
1388+
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) or
1389+
'CONDA_PREFIX' in os.environ)
13851390
if args.python_virtualenv is not True:
13861391
res = args.python_virtualenv
13871392
if not os.path.isdir(res):
@@ -1391,11 +1396,12 @@ def get_env_dir(args):
13911396
# (pipx, pipsi, uv tool), so the activated one wins over sys.prefix
13921397
elif os.environ.get('VIRTUAL_ENV'):
13931398
res = os.environ['VIRTUAL_ENV']
1394-
elif hasattr(sys, 'real_prefix'):
1395-
res = sys.prefix
1396-
elif hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix:
1397-
res = sys.prefix
1398-
elif 'CONDA_PREFIX' in os.environ:
1399+
if in_virtualenv and res != sys.prefix:
1400+
logger.warning(
1401+
' * Using activated virtualenv %s, not %s where nodeenv '
1402+
'is installed, pass a directory to -p to override',
1403+
res, sys.prefix)
1404+
elif in_virtualenv:
13991405
res = sys.prefix
14001406
else:
14011407
logger.error('No python virtualenv is available')

tests/nodeenv_test.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1761,9 +1761,43 @@ def test_with_python_virtualenv_prefers_virtual_env(self):
17611761
env_dict = {'VIRTUAL_ENV': virtual_env}
17621762
with mock.patch.object(sys, 'real_prefix', test_prefix, create=True), \
17631763
mock.patch.object(sys, 'prefix', test_prefix), \
1764-
mock.patch.dict(os.environ, env_dict, clear=True):
1764+
mock.patch.dict(os.environ, env_dict, clear=True), \
1765+
mock.patch.object(nodeenv.logger, 'warning') as mck:
17651766
result = nodeenv.get_env_dir(args)
17661767
assert result == virtual_env
1768+
# the ignored virtualenv is not silently dropped
1769+
assert mck.call_count == 1
1770+
assert mck.call_args[0][1:] == (virtual_env, test_prefix)
1771+
1772+
def test_with_python_virtualenv_same_venv_is_quiet(self):
1773+
"""Test get_env_dir doesn't warn when both point to the same venv"""
1774+
args = mock.Mock()
1775+
args.python_virtualenv = True
1776+
test_prefix = '/path/to/venv'
1777+
1778+
env_dict = {'VIRTUAL_ENV': test_prefix}
1779+
with mock.patch.object(sys, 'real_prefix', test_prefix, create=True), \
1780+
mock.patch.object(sys, 'prefix', test_prefix), \
1781+
mock.patch.dict(os.environ, env_dict, clear=True), \
1782+
mock.patch.object(nodeenv.logger, 'warning') as mck:
1783+
result = nodeenv.get_env_dir(args)
1784+
assert result == test_prefix
1785+
mck.assert_not_called()
1786+
1787+
def test_with_python_virtualenv_system_python_is_quiet(self):
1788+
"""Test get_env_dir doesn't warn when nodeenv runs system-wide"""
1789+
args = mock.Mock()
1790+
args.python_virtualenv = True
1791+
virtual_env = '/path/to/activated/venv'
1792+
1793+
env_dict = {'VIRTUAL_ENV': virtual_env}
1794+
with mock.patch.object(sys, 'prefix', '/usr'), \
1795+
mock.patch.object(sys, 'base_prefix', '/usr'), \
1796+
mock.patch.dict(os.environ, env_dict, clear=True), \
1797+
mock.patch.object(nodeenv.logger, 'warning') as mck:
1798+
result = nodeenv.get_env_dir(args)
1799+
assert result == virtual_env
1800+
mck.assert_not_called()
17671801

17681802
def test_without_python_virtualenv(self):
17691803
"""Test get_env_dir when not using python virtualenv"""

0 commit comments

Comments
 (0)