Merge pull request #1079 from hpk42/issue1073

fix issue #1073 -- shortcut plugin hook lookup if the attrname is not prefixed with pytest_.
This commit is contained in:
Ronny Pfannschmidt 2015-09-28 16:15:42 +02:00
commit 22e1f4946e
4 changed files with 31 additions and 10 deletions

View File

@ -1,6 +1,11 @@
2.8.1.dev
---------
- fix issue #1073: avoid calling __getattr__ on potential plugin objects.
This fixes an incompatibility with pytest-django. Thanks Andreas Pelme,
Bruno Oliveira and Ronny Pfannschmidt for contributing and Holger Krekel
for the fix.
- Fix issue #704: handle versionconflict during plugin loading more
gracefully. Thanks Bruno Oliveira for the PR.

View File

@ -120,12 +120,6 @@ def _prepareconfig(args=None, plugins=None):
raise
def exclude_pytest_names(name):
return not name.startswith(name) or name == "pytest_plugins" or \
name.startswith("pytest_funcarg__")
class PytestPluginManager(PluginManager):
"""
Overwrites :py:class:`pluggy.PluginManager` to add pytest-specific
@ -171,8 +165,14 @@ class PytestPluginManager(PluginManager):
return self.add_hookspecs(module_or_class)
def parse_hookimpl_opts(self, plugin, name):
if exclude_pytest_names(name):
return None
# pytest hooks are always prefixed with pytest_
# so we avoid accessing possibly non-readable attributes
# (see issue #1073)
if not name.startswith("pytest_"):
return
# ignore some historic special names which can not be hooks anyway
if name == "pytest_plugins" or name.startswith("pytest_funcarg__"):
return
method = getattr(plugin, name)
opts = super(PytestPluginManager, self).parse_hookimpl_opts(plugin, name)

View File

@ -1918,14 +1918,14 @@ class FixtureManager:
autousenames = []
for name in dir(holderobj):
obj = getattr(holderobj, name, None)
if not callable(obj):
continue
# fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
# or are "@pytest.fixture" marked
marker = getfixturemarker(obj)
if marker is None:
if not name.startswith(self._argprefix):
continue
if not callable(obj):
continue
marker = defaultfuncargprefixmarker
name = name[len(self._argprefix):]
elif not isinstance(marker, FixtureFunctionMarker):

View File

@ -388,3 +388,19 @@ def test_search_conftest_up_to_inifile(testdir, confcutdir, passed, error):
if error:
match += '*%d error*' % error
result.stdout.fnmatch_lines(match)
def test_issue1073_conftest_special_objects(testdir):
testdir.makeconftest("""
class DontTouchMe:
def __getattr__(self, x):
raise Exception('cant touch me')
x = DontTouchMe()
""")
testdir.makepyfile("""
def test_some():
pass
""")
res = testdir.runpytest()
assert res.ret == 0