From 00c0d62c9b137a343a157bfc2afadd78ac9af981 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 10 Oct 2013 11:40:31 -0400 Subject: [PATCH 1/4] Adding test capturing #366 where an error occurs when package resources are loaded from the test package. --- testing/test_assertrewrite.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index f4b35dc00..935682a85 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -493,3 +493,34 @@ def test_rewritten(): raise e monkeypatch.setattr(b, "open", open) assert not _write_pyc(state, [1], source_path, pycpath) + + def test_resources_provider_for_loader(self, testdir): + """ + Attempts to load resources from a package should succeed normally, + even when the AssertionRewriteHook is used to load the modules. + + See #366 for details. + """ + pytest.importorskip("pkg_resources") + + testdir.mkpydir('testpkg') + contents = { + 'testpkg/test_pkg': """ + import pkg_resources + + import pytest + from _pytest.assertion.rewrite import AssertionRewritingHook + + def test_load_resource(): + assert isinstance(__loader__, AssertionRewritingHook) + res = pkg_resources.resource_string(__name__, 'resource.txt') + assert res == 'Load me please.' + """, + } + testdir.makepyfile(**contents) + testdir.maketxtfile(**{'testpkg/resource': "Load me please."}) + + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + '* 1 passed*', + ]) From a4c17dfb19b1c1bfe1e380da72b1364f31cfd7a9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 10 Oct 2013 11:56:12 -0400 Subject: [PATCH 2/4] Register the AssertionRewritingHook loader with pkg_resources; fixes #366. --- _pytest/assertion/rewrite.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index f79698ae4..1f05fc51c 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -41,6 +41,7 @@ class AssertionRewritingHook(object): def __init__(self): self.session = None self.modules = {} + self._register_with_pkg_resources() def set_session(self, session): self.fnpats = session.config.getini("python_files") @@ -169,6 +170,23 @@ class AssertionRewritingHook(object): tp = desc[2] return tp == imp.PKG_DIRECTORY + @classmethod + def _register_with_pkg_resources(cls): + """ + Ensure package resources can be loaded from this loader. + """ + try: + pkg_resources = __import__('pkg_resources') + # access an attribute in case a deferred importer is present + pkg_resources.__name__ + except ImportError: + return + + # Since pytest tests are always located in the file system, the + # DefaultProvider is appropriate. + pkg_resources.register_loader_type(cls, pkg_resources.DefaultProvider) + + def _write_pyc(state, co, source_path, pyc): # Technically, we don't have to have the same pyc format as # (C)Python, since these "pycs" should never be seen by builtin From ee5b836e2777118d0ff6dd2adbf605c3bbf8a464 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 10 Oct 2013 17:39:37 -0400 Subject: [PATCH 3/4] Implement suggestions by HPK --- _pytest/assertion/rewrite.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 1f05fc51c..a61ba9651 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -173,10 +173,11 @@ class AssertionRewritingHook(object): @classmethod def _register_with_pkg_resources(cls): """ - Ensure package resources can be loaded from this loader. + Ensure package resources can be loaded from this loader. May be called + multiple times, as the operation is idempotent. """ try: - pkg_resources = __import__('pkg_resources') + import pkg_resources # access an attribute in case a deferred importer is present pkg_resources.__name__ except ImportError: From 2697b63bcde216f0f88c1d98e493b819d629a301 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 10 Oct 2013 18:01:56 -0400 Subject: [PATCH 4/4] Fix bytes/string mismatch in test on Python 3 --- testing/test_assertrewrite.py | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 935682a85..9348a99f0 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -514,6 +514,7 @@ def test_rewritten(): def test_load_resource(): assert isinstance(__loader__, AssertionRewritingHook) res = pkg_resources.resource_string(__name__, 'resource.txt') + res = res.decode('ascii') assert res == 'Load me please.' """, }