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:
commit
22e1f4946e
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue