Show a warning when non-str is given to Monkeypatch.setenv

This commit is contained in:
Bruno Oliveira 2018-10-01 18:48:41 -03:00
parent 9d971d33be
commit 1a323fbd3c
5 changed files with 39 additions and 18 deletions

View File

@ -225,7 +225,15 @@ class MonkeyPatch(object):
""" Set environment variable ``name`` to ``value``. If ``prepend`` """ Set environment variable ``name`` to ``value``. If ``prepend``
is a character, read the current environment variable value is a character, read the current environment variable value
and prepend the ``value`` adjoined with the ``prepend`` character.""" and prepend the ``value`` adjoined with the ``prepend`` character."""
value = str(value) if not isinstance(value, str):
warnings.warn(
pytest.PytestWarning(
"Environment variable value {!r} should be str, converted to str implicitly".format(
value
)
)
)
value = str(value)
if prepend and name in os.environ: if prepend and name in os.environ:
value = value + prepend + os.environ[name] value = value + prepend + os.environ[name]
self._warn_if_env_name_is_not_str(name) self._warn_if_env_name_is_not_str(name)

View File

@ -577,7 +577,7 @@ class TestInvocationVariants(object):
return what return what
empty_package = testdir.mkpydir("empty_package") empty_package = testdir.mkpydir("empty_package")
monkeypatch.setenv("PYTHONPATH", join_pythonpath(empty_package)) monkeypatch.setenv("PYTHONPATH", str(join_pythonpath(empty_package)))
# the path which is not a package raises a warning on pypy; # the path which is not a package raises a warning on pypy;
# no idea why only pypy and not normal python warn about it here # no idea why only pypy and not normal python warn about it here
with warnings.catch_warnings(): with warnings.catch_warnings():
@ -586,7 +586,7 @@ class TestInvocationVariants(object):
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*2 passed*"]) result.stdout.fnmatch_lines(["*2 passed*"])
monkeypatch.setenv("PYTHONPATH", join_pythonpath(testdir)) monkeypatch.setenv("PYTHONPATH", str(join_pythonpath(testdir)))
result = testdir.runpytest("--pyargs", "tpkg.test_missing", syspathinsert=True) result = testdir.runpytest("--pyargs", "tpkg.test_missing", syspathinsert=True)
assert result.ret != 0 assert result.ret != 0
result.stderr.fnmatch_lines(["*not*found*test_missing*"]) result.stderr.fnmatch_lines(["*not*found*test_missing*"])

View File

@ -215,7 +215,7 @@ def test_cache_show(testdir):
class TestLastFailed(object): class TestLastFailed(object):
def test_lastfailed_usecase(self, testdir, monkeypatch): def test_lastfailed_usecase(self, testdir, monkeypatch):
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
def test_1(): def test_1():
@ -301,7 +301,7 @@ class TestLastFailed(object):
assert "test_a.py" not in result.stdout.str() assert "test_a.py" not in result.stdout.str()
def test_lastfailed_difference_invocations(self, testdir, monkeypatch): def test_lastfailed_difference_invocations(self, testdir, monkeypatch):
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
testdir.makepyfile( testdir.makepyfile(
test_a="""\ test_a="""\
def test_a1(): def test_a1():
@ -335,7 +335,7 @@ class TestLastFailed(object):
result.stdout.fnmatch_lines(["*1 failed*1 desel*"]) result.stdout.fnmatch_lines(["*1 failed*1 desel*"])
def test_lastfailed_usecase_splice(self, testdir, monkeypatch): def test_lastfailed_usecase_splice(self, testdir, monkeypatch):
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
testdir.makepyfile( testdir.makepyfile(
"""\ """\
def test_1(): def test_1():
@ -474,8 +474,8 @@ class TestLastFailed(object):
) )
def rlf(fail_import, fail_run): def rlf(fail_import, fail_run):
monkeypatch.setenv("FAILIMPORT", fail_import) monkeypatch.setenv("FAILIMPORT", str(fail_import))
monkeypatch.setenv("FAILTEST", fail_run) monkeypatch.setenv("FAILTEST", str(fail_run))
testdir.runpytest("-q") testdir.runpytest("-q")
config = testdir.parseconfigure() config = testdir.parseconfigure()
@ -519,8 +519,8 @@ class TestLastFailed(object):
) )
def rlf(fail_import, fail_run, args=()): def rlf(fail_import, fail_run, args=()):
monkeypatch.setenv("FAILIMPORT", fail_import) monkeypatch.setenv("FAILIMPORT", str(fail_import))
monkeypatch.setenv("FAILTEST", fail_run) monkeypatch.setenv("FAILTEST", str(fail_run))
result = testdir.runpytest("-q", "--lf", *args) result = testdir.runpytest("-q", "--lf", *args)
config = testdir.parseconfigure() config = testdir.parseconfigure()

View File

@ -850,7 +850,7 @@ def test_logxml_path_expansion(tmpdir, monkeypatch):
assert xml_tilde.logfile == home_tilde assert xml_tilde.logfile == home_tilde
# this is here for when $HOME is not set correct # this is here for when $HOME is not set correct
monkeypatch.setenv("HOME", tmpdir) monkeypatch.setenv("HOME", str(tmpdir))
home_var = os.path.normpath(os.path.expandvars("$HOME/test.xml")) home_var = os.path.normpath(os.path.expandvars("$HOME/test.xml"))
xml_var = LogXML("$HOME%stest.xml" % tmpdir.sep, None) xml_var = LogXML("$HOME%stest.xml" % tmpdir.sep, None)

View File

@ -165,7 +165,8 @@ def test_delitem():
def test_setenv(): def test_setenv():
monkeypatch = MonkeyPatch() monkeypatch = MonkeyPatch()
monkeypatch.setenv("XYZ123", 2) with pytest.warns(pytest.PytestWarning):
monkeypatch.setenv("XYZ123", 2)
import os import os
assert os.environ["XYZ123"] == "2" assert os.environ["XYZ123"] == "2"
@ -194,15 +195,16 @@ def test_delenv():
del os.environ[name] del os.environ[name]
@pytest.mark.skipif(six.PY3, reason="Python 2 only test") class TestEnvironWarnings(object):
class TestEnvironKeysWarning(object):
""" """
os.environ needs keys to be native strings, otherwise it will cause problems with other modules (notably os.environ keys and values should be native strings, otherwise it will cause problems with other modules (notably
subprocess). We only test this behavior on Python 2, because Python 3 raises an error right away. subprocess). On Python 2 os.environ accepts anything without complaining, while Python 3 does the right thing
and raises an error.
""" """
VAR_NAME = u"PYTEST_INTERNAL_MY_VAR" VAR_NAME = u"PYTEST_INTERNAL_MY_VAR"
@pytest.mark.skipif(six.PY3, reason="Python 2 only test")
def test_setenv_unicode_key(self, monkeypatch): def test_setenv_unicode_key(self, monkeypatch):
with pytest.warns( with pytest.warns(
pytest.PytestWarning, pytest.PytestWarning,
@ -210,6 +212,7 @@ class TestEnvironKeysWarning(object):
): ):
monkeypatch.setenv(self.VAR_NAME, "2") monkeypatch.setenv(self.VAR_NAME, "2")
@pytest.mark.skipif(six.PY3, reason="Python 2 only test")
def test_delenv_unicode_key(self, monkeypatch): def test_delenv_unicode_key(self, monkeypatch):
with pytest.warns( with pytest.warns(
pytest.PytestWarning, pytest.PytestWarning,
@ -217,14 +220,24 @@ class TestEnvironKeysWarning(object):
): ):
monkeypatch.delenv(self.VAR_NAME, raising=False) monkeypatch.delenv(self.VAR_NAME, raising=False)
def test_setenv_non_str_warning(self, monkeypatch):
value = 2
msg = (
"Environment variable value {!r} should be str, converted to str implicitly"
)
with pytest.warns(pytest.PytestWarning, match=msg.format(value)):
monkeypatch.setenv(str(self.VAR_NAME), value)
def test_setenv_prepend(): def test_setenv_prepend():
import os import os
monkeypatch = MonkeyPatch() monkeypatch = MonkeyPatch()
monkeypatch.setenv("XYZ123", 2, prepend="-") with pytest.warns(pytest.PytestWarning):
monkeypatch.setenv("XYZ123", 2, prepend="-")
assert os.environ["XYZ123"] == "2" assert os.environ["XYZ123"] == "2"
monkeypatch.setenv("XYZ123", 3, prepend="-") with pytest.warns(pytest.PytestWarning):
monkeypatch.setenv("XYZ123", 3, prepend="-")
assert os.environ["XYZ123"] == "3-2" assert os.environ["XYZ123"] == "3-2"
monkeypatch.undo() monkeypatch.undo()
assert "XYZ123" not in os.environ assert "XYZ123" not in os.environ