diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 2d2683574..fc9b8d9cb 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -480,29 +480,24 @@ class Testdir: if not hasattr(self, '_olddir'): self._olddir = old - def _makefile(self, ext, args, kwargs, encoding="utf-8"): + def _makefile(self, ext, args, kwargs, encoding='utf-8'): items = list(kwargs.items()) + + def to_text(s): + return s.decode(encoding) if isinstance(s, bytes) else six.text_type(s) + if args: - source = six.text_type("\n").join( - map(six.text_type, args)) + six.text_type("\n") + source = u"\n".join(to_text(x) for x in args) basename = self.request.function.__name__ items.insert(0, (basename, source)) + ret = None - for name, value in items: - p = self.tmpdir.join(name).new(ext=ext) + for basename, value in items: + p = self.tmpdir.join(basename).new(ext=ext) p.dirpath().ensure_dir() source = Source(value) - - def my_totext(s, encoding="utf-8"): - if isinstance(s, six.binary_type): - s = six.text_type(s, encoding=encoding) - return s - - source_unicode = "\n".join([my_totext(line) for line in source.lines]) - source = six.text_type(source_unicode) - content = source.strip().encode(encoding) # + "\n" - # content = content.rstrip() + "\n" - p.write(content, "wb") + source = u"\n".join(to_text(line) for line in source.lines) + p.write(source.strip().encode(encoding), "wb") if ret is None: ret = p return ret diff --git a/changelog/2738.bugfix b/changelog/2738.bugfix new file mode 100644 index 000000000..c53869f49 --- /dev/null +++ b/changelog/2738.bugfix @@ -0,0 +1 @@ +Internal ``pytester`` plugin properly encodes ``bytes`` arguments to ``utf-8``. diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 0e8669698..9508c2954 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function import pytest import os @@ -120,6 +121,16 @@ def test_makepyfile_unicode(testdir): testdir.makepyfile(unichr(0xfffd)) +def test_makepyfile_utf8(testdir): + """Ensure makepyfile accepts utf-8 bytes as input (#2738)""" + utf8_contents = u""" + def setup_function(function): + mixed_encoding = u'São Paulo' + """.encode('utf-8') + p = testdir.makepyfile(utf8_contents) + assert u"mixed_encoding = u'São Paulo'".encode('utf-8') in p.read('rb') + + def test_inline_run_clean_modules(testdir): test_mod = testdir.makepyfile("def test_foo(): assert True") result = testdir.inline_run(str(test_mod))