Skip to content

Commit 4f9b649

Browse files
committed
Show a warning when non-str is given to Monkeypatch.setenv
1 parent 9d971d3 commit 4f9b649

File tree

5 files changed

+39
-18
lines changed

5 files changed

+39
-18
lines changed

src/_pytest/monkeypatch.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,15 @@ def setenv(self, name, value, prepend=None):
225225
""" Set environment variable ``name`` to ``value``. If ``prepend``
226226
is a character, read the current environment variable value
227227
and prepend the ``value`` adjoined with the ``prepend`` character."""
228-
value = str(value)
228+
if not isinstance(value, str):
229+
warnings.warn(
230+
pytest.PytestWarning(
231+
"Environment variable value {!r} should be str, converted to str implicitly".format(
232+
value
233+
)
234+
)
235+
)
236+
value = str(value)
229237
if prepend and name in os.environ:
230238
value = value + prepend + os.environ[name]
231239
self._warn_if_env_name_is_not_str(name)

testing/acceptance_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ def join_pythonpath(what):
577577
return what
578578

579579
empty_package = testdir.mkpydir("empty_package")
580-
monkeypatch.setenv("PYTHONPATH", join_pythonpath(empty_package))
580+
monkeypatch.setenv("PYTHONPATH", str(join_pythonpath(empty_package)))
581581
# the path which is not a package raises a warning on pypy;
582582
# no idea why only pypy and not normal python warn about it here
583583
with warnings.catch_warnings():
@@ -586,7 +586,7 @@ def join_pythonpath(what):
586586
assert result.ret == 0
587587
result.stdout.fnmatch_lines(["*2 passed*"])
588588

589-
monkeypatch.setenv("PYTHONPATH", join_pythonpath(testdir))
589+
monkeypatch.setenv("PYTHONPATH", str(join_pythonpath(testdir)))
590590
result = testdir.runpytest("--pyargs", "tpkg.test_missing", syspathinsert=True)
591591
assert result.ret != 0
592592
result.stderr.fnmatch_lines(["*not*found*test_missing*"])

testing/test_cacheprovider.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def pytest_configure(config):
215215

216216
class TestLastFailed(object):
217217
def test_lastfailed_usecase(self, testdir, monkeypatch):
218-
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1)
218+
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
219219
p = testdir.makepyfile(
220220
"""
221221
def test_1():
@@ -301,7 +301,7 @@ def test_always_fails():
301301
assert "test_a.py" not in result.stdout.str()
302302

303303
def test_lastfailed_difference_invocations(self, testdir, monkeypatch):
304-
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1)
304+
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
305305
testdir.makepyfile(
306306
test_a="""\
307307
def test_a1():
@@ -335,7 +335,7 @@ def test_b1():
335335
result.stdout.fnmatch_lines(["*1 failed*1 desel*"])
336336

337337
def test_lastfailed_usecase_splice(self, testdir, monkeypatch):
338-
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1)
338+
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
339339
testdir.makepyfile(
340340
"""\
341341
def test_1():
@@ -474,8 +474,8 @@ def test_hello():
474474
)
475475

476476
def rlf(fail_import, fail_run):
477-
monkeypatch.setenv("FAILIMPORT", fail_import)
478-
monkeypatch.setenv("FAILTEST", fail_run)
477+
monkeypatch.setenv("FAILIMPORT", str(fail_import))
478+
monkeypatch.setenv("FAILTEST", str(fail_run))
479479

480480
testdir.runpytest("-q")
481481
config = testdir.parseconfigure()
@@ -519,8 +519,8 @@ def test_pass():
519519
)
520520

521521
def rlf(fail_import, fail_run, args=()):
522-
monkeypatch.setenv("FAILIMPORT", fail_import)
523-
monkeypatch.setenv("FAILTEST", fail_run)
522+
monkeypatch.setenv("FAILIMPORT", str(fail_import))
523+
monkeypatch.setenv("FAILTEST", str(fail_run))
524524

525525
result = testdir.runpytest("-q", "--lf", *args)
526526
config = testdir.parseconfigure()

testing/test_junitxml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ def test_logxml_path_expansion(tmpdir, monkeypatch):
850850
assert xml_tilde.logfile == home_tilde
851851

852852
# this is here for when $HOME is not set correct
853-
monkeypatch.setenv("HOME", tmpdir)
853+
monkeypatch.setenv("HOME", str(tmpdir))
854854
home_var = os.path.normpath(os.path.expandvars("$HOME/test.xml"))
855855

856856
xml_var = LogXML("$HOME%stest.xml" % tmpdir.sep, None)

testing/test_monkeypatch.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ def test_delitem():
165165

166166
def test_setenv():
167167
monkeypatch = MonkeyPatch()
168-
monkeypatch.setenv("XYZ123", 2)
168+
with pytest.warns(pytest.PytestWarning):
169+
monkeypatch.setenv("XYZ123", 2)
169170
import os
170171

171172
assert os.environ["XYZ123"] == "2"
@@ -194,37 +195,49 @@ def test_delenv():
194195
del os.environ[name]
195196

196197

197-
@pytest.mark.skipif(six.PY3, reason="Python 2 only test")
198-
class TestEnvironKeysWarning(object):
198+
class TestEnvironWarnings(object):
199199
"""
200-
os.environ needs keys to be native strings, otherwise it will cause problems with other modules (notably
201-
subprocess). We only test this behavior on Python 2, because Python 3 raises an error right away.
200+
os.environ keys and values should be native strings, otherwise it will cause problems with other modules (notably
201+
subprocess). On Python 2 os.environ accepts anything without complaining, while Python 3 does the right thing
202+
and raises an error.
202203
"""
203204

204205
VAR_NAME = u"PYTEST_INTERNAL_MY_VAR"
205206

207+
@pytest.mark.skipif(six.PY3, reason="Python 2 only test")
206208
def test_setenv_unicode_key(self, monkeypatch):
207209
with pytest.warns(
208210
pytest.PytestWarning,
209211
match="Environment variable name {!r} should be str".format(self.VAR_NAME),
210212
):
211213
monkeypatch.setenv(self.VAR_NAME, "2")
212214

215+
@pytest.mark.skipif(six.PY3, reason="Python 2 only test")
213216
def test_delenv_unicode_key(self, monkeypatch):
214217
with pytest.warns(
215218
pytest.PytestWarning,
216219
match="Environment variable name {!r} should be str".format(self.VAR_NAME),
217220
):
218221
monkeypatch.delenv(self.VAR_NAME, raising=False)
219222

223+
def test_setenv_non_str_warning(self, monkeypatch):
224+
value = u"2" if six.PY2 else b"2"
225+
msg = (
226+
"Environment variable value {!r} should be str, converted to str implicitly"
227+
)
228+
with pytest.warns(pytest.PytestWarning, match=msg.format(value)):
229+
monkeypatch.setenv(str(self.VAR_NAME), value)
230+
220231

221232
def test_setenv_prepend():
222233
import os
223234

224235
monkeypatch = MonkeyPatch()
225-
monkeypatch.setenv("XYZ123", 2, prepend="-")
236+
with pytest.warns(pytest.PytestWarning):
237+
monkeypatch.setenv("XYZ123", 2, prepend="-")
226238
assert os.environ["XYZ123"] == "2"
227-
monkeypatch.setenv("XYZ123", 3, prepend="-")
239+
with pytest.warns(pytest.PytestWarning):
240+
monkeypatch.setenv("XYZ123", 3, prepend="-")
228241
assert os.environ["XYZ123"] == "3-2"
229242
monkeypatch.undo()
230243
assert "XYZ123" not in os.environ

0 commit comments

Comments
 (0)