Skip to content

Commit

Permalink
Fix python 2 activator from python 3 invalid (#1794)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaborbernat authored May 1, 2020
1 parent bb7bb71 commit 56dd662
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 15 deletions.
1 change: 1 addition & 0 deletions docs/changelog/1776.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix generating a Python 2 environment from Python 3 creates invalid python activator - by :user:`gaborbernat`.
3 changes: 2 additions & 1 deletion src/virtualenv/activation/python/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import, unicode_literals

import os
import sys
from collections import OrderedDict

from virtualenv.util.path import Path
Expand Down Expand Up @@ -29,5 +30,5 @@ def replacements(self, creator, dest_folder):
def _repr_unicode(creator, value):
py2 = creator.interpreter.version_info.major == 2
if py2: # on Python 2 we need to encode this into explicit utf-8, py3 supports unicode literals
value = ensure_text(repr(value.encode("utf-8"))[1:-1])
value = ensure_text(repr(value.encode("utf-8"))[2 if sys.version_info[0] == 3 else 1 : -1])
return value
4 changes: 3 additions & 1 deletion src/virtualenv/activation/via_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ def templates(self):
def generate(self, creator):
dest_folder = creator.bin_dir
replacements = self.replacements(creator, dest_folder)
self._generate(replacements, self.templates(), dest_folder, creator)
at_path = self._generate(replacements, self.templates(), dest_folder, creator)
if self.flag_prompt is not None:
creator.pyenv_cfg["prompt"] = self.flag_prompt
return at_path

def replacements(self, creator, dest_folder):
return {
Expand All @@ -43,6 +44,7 @@ def _generate(self, replacements, templates, to_folder, creator):
text = self.instantiate_template(replacements, template, creator)
dest = to_folder / self.as_name(template)
dest.write_text(text, encoding="utf-8")
return dest

def as_name(self, template):
return template.name
Expand Down
14 changes: 14 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import pytest
import six

from virtualenv.discovery.builtin import get_interpreter
from virtualenv.discovery.py_info import PythonInfo
from virtualenv.info import IS_PYPY, IS_WIN, fs_supports_symlink
from virtualenv.report import LOGGER
Expand Down Expand Up @@ -318,3 +319,16 @@ def temp_app_data(monkeypatch, tmp_path):
app_data = tmp_path / "app-data"
monkeypatch.setenv(str("VIRTUALENV_OVERRIDE_APP_DATA"), str(app_data))
return app_data


@pytest.fixture(scope="session")
def cross_python(is_inside_ci, session_app_data):
current = PythonInfo.current(session_app_data)
spec = "{}{}".format(current.implementation, 2 if current.version_info.major == 3 else 3)
interpreter = get_interpreter(spec, session_app_data)
if interpreter is None:
msg = "could not find {}".format(spec)
if is_inside_ci:
raise RuntimeError(msg)
pytest.skip(msg=msg)
yield interpreter
23 changes: 23 additions & 0 deletions tests/unit/activation/test_activate_this.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from virtualenv.activation import PythonActivator
from virtualenv.config.cli.parser import VirtualEnvOptions
from virtualenv.run import session_via_cli


def test_from_py3_to_py2(session_app_data, cross_python, special_name_dir):
options = VirtualEnvOptions()
cli_args = [
str(special_name_dir),
"-p",
str(cross_python.executable),
"--app-data",
str(session_app_data.path),
"--without-pip",
"--activators",
"",
]
session = session_via_cli(cli_args, options)
activator = PythonActivator(options)
session.creator.bin_dir.mkdir(parents=True)
result = activator.generate(session.creator)
content = result.read_text()
assert "\"'" not in content
13 changes: 0 additions & 13 deletions tests/unit/create/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from virtualenv.create.via_global_ref.builtin.cpython.cpython2 import CPython2PosixBase
from virtualenv.create.via_global_ref.builtin.cpython.cpython3 import CPython3Posix
from virtualenv.create.via_global_ref.builtin.python2.python2 import Python2
from virtualenv.discovery.builtin import get_interpreter
from virtualenv.discovery.py_info import PythonInfo
from virtualenv.info import IS_PYPY, IS_WIN, PY2, PY3, fs_is_case_sensitive
from virtualenv.pyenv_cfg import PyEnvCfg
Expand Down Expand Up @@ -315,18 +314,6 @@ def test_prompt_set(tmp_path, creator, prompt):
assert cfg["prompt"] == actual_prompt


@pytest.fixture(scope="session")
def cross_python(is_inside_ci, session_app_data):
spec = "{}{}".format(CURRENT.implementation, 2 if CURRENT.version_info.major == 3 else 3)
interpreter = get_interpreter(spec, session_app_data)
if interpreter is None:
msg = "could not find {}".format(spec)
if is_inside_ci:
raise RuntimeError(msg)
pytest.skip(msg=msg)
yield interpreter


@pytest.mark.slow
def test_cross_major(cross_python, coverage_env, tmp_path, session_app_data, current_fastest):
cmd = [
Expand Down

0 comments on commit 56dd662

Please sign in to comment.