From b238845d0f4935f805521b09073211e50251f0dc Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 7 May 2020 13:14:58 -0700 Subject: [PATCH] Fix _is_setup_py for files encoded differently than locale --- changelog/7180.bugfix.rst | 1 + src/_pytest/doctest.py | 10 +++++----- testing/test_doctest.py | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 changelog/7180.bugfix.rst diff --git a/changelog/7180.bugfix.rst b/changelog/7180.bugfix.rst new file mode 100644 index 0000000000..d2dd55e9b8 --- /dev/null +++ b/changelog/7180.bugfix.rst @@ -0,0 +1 @@ +Fix ``_is_setup_py`` for files encoded differently than locale. diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index 0210847781..e1dd9691cc 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -108,20 +108,20 @@ def pytest_unconfigure(): RUNNER_CLASS = None -def pytest_collect_file(path, parent): +def pytest_collect_file(path: py.path.local, parent): config = parent.config if path.ext == ".py": - if config.option.doctestmodules and not _is_setup_py(config, path, parent): + if config.option.doctestmodules and not _is_setup_py(path): return DoctestModule.from_parent(parent, fspath=path) elif _is_doctest(config, path, parent): return DoctestTextfile.from_parent(parent, fspath=path) -def _is_setup_py(config, path, parent): +def _is_setup_py(path: py.path.local) -> bool: if path.basename != "setup.py": return False - contents = path.read() - return "setuptools" in contents or "distutils" in contents + contents = path.read_binary() + return b"setuptools" in contents or b"distutils" in contents def _is_doctest(config, path, parent): diff --git a/testing/test_doctest.py b/testing/test_doctest.py index c9defec5d5..39afb4e989 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -5,6 +5,7 @@ from _pytest.compat import MODULE_NOT_FOUND_ERROR from _pytest.doctest import _get_checker from _pytest.doctest import _is_mocked +from _pytest.doctest import _is_setup_py from _pytest.doctest import _patch_unwrap_mock_aware from _pytest.doctest import DoctestItem from _pytest.doctest import DoctestModule @@ -1487,3 +1488,27 @@ def test_warning_on_unwrap_of_broken_object(stop): with pytest.raises(KeyError): inspect.unwrap(bad_instance, stop=stop) assert inspect.unwrap.__module__ == "inspect" + + +def test_is_setup_py_not_named_setup_py(tmpdir): + not_setup_py = tmpdir.join("not_setup.py") + not_setup_py.write('from setuptools import setup; setup(name="foo")') + assert not _is_setup_py(not_setup_py) + + +@pytest.mark.parametrize("mod", ("setuptools", "distutils.core")) +def test_is_setup_py_is_a_setup_py(tmpdir, mod): + setup_py = tmpdir.join("setup.py") + setup_py.write('from {} import setup; setup(name="foo")'.format(mod)) + assert _is_setup_py(setup_py) + + +@pytest.mark.parametrize("mod", ("setuptools", "distutils.core")) +def test_is_setup_py_different_encoding(tmpdir, mod): + setup_py = tmpdir.join("setup.py") + contents = ( + "# -*- coding: cp1252 -*-\n" + 'from {} import setup; setup(name="foo", description="€")\n'.format(mod) + ) + setup_py.write_binary(contents.encode("cp1252")) + assert _is_setup_py(setup_py)