make pytest_plugin_registered a historic hook
--HG-- branch : more_plugin
This commit is contained in:
parent
e7a2e53108
commit
4e116ed503
|
@ -122,8 +122,8 @@ class PytestPluginManager(PluginManager):
|
|||
if ret:
|
||||
if not conftest:
|
||||
self._globalplugins.append(plugin)
|
||||
self.hook.pytest_plugin_registered(plugin=plugin,
|
||||
manager=self)
|
||||
self.hook.pytest_plugin_registered.call_historic(
|
||||
kwargs=dict(plugin=plugin, manager=self))
|
||||
return ret
|
||||
|
||||
def unregister(self, plugin):
|
||||
|
@ -707,8 +707,8 @@ class Config(object):
|
|||
def do_setns(dic):
|
||||
import pytest
|
||||
setns(pytest, dic)
|
||||
self.hook.pytest_namespace.call_historic({}, proc=do_setns)
|
||||
self.hook.pytest_addoption.call_historic(dict(parser=self._parser))
|
||||
self.hook.pytest_namespace.call_historic(do_setns, {})
|
||||
self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))
|
||||
|
||||
def add_cleanup(self, func):
|
||||
""" Add a function to be called when the config object gets out of
|
||||
|
@ -718,7 +718,7 @@ class Config(object):
|
|||
def _do_configure(self):
|
||||
assert not self._configured
|
||||
self._configured = True
|
||||
self.hook.pytest_configure.call_historic(dict(config=self))
|
||||
self.hook.pytest_configure.call_historic(kwargs=dict(config=self))
|
||||
|
||||
def _ensure_unconfigure(self):
|
||||
if self._configured:
|
||||
|
@ -840,7 +840,8 @@ class Config(object):
|
|||
assert not hasattr(self, 'args'), (
|
||||
"can only parse cmdline args at most once per Config object")
|
||||
self._origargs = args
|
||||
self.hook.pytest_addhooks.call_historic(dict(pluginmanager=self.pluginmanager))
|
||||
self.hook.pytest_addhooks.call_historic(
|
||||
kwargs=dict(pluginmanager=self.pluginmanager))
|
||||
self._preparse(args)
|
||||
# XXX deprecated hook:
|
||||
self.hook.pytest_cmdline_preparse(config=self, args=args)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
PluginManager, basic initialization and tracing.
|
||||
"""
|
||||
import sys
|
||||
import inspect
|
||||
from inspect import isfunction, ismethod, isclass, formatargspec, getargspec
|
||||
import py
|
||||
|
||||
py3 = sys.version_info > (3,0)
|
||||
|
@ -267,7 +267,6 @@ class PluginManager(object):
|
|||
def addhooks(self, module_or_class):
|
||||
""" add new hook definitions from the given module_or_class using
|
||||
the prefix/excludefunc with which the PluginManager was initialized. """
|
||||
isclass = int(inspect.isclass(module_or_class))
|
||||
names = []
|
||||
for name in dir(module_or_class):
|
||||
if name.startswith(self._prefix):
|
||||
|
@ -394,17 +393,17 @@ def varnames(func, startindex=None):
|
|||
return cache["_varnames"]
|
||||
except KeyError:
|
||||
pass
|
||||
if inspect.isclass(func):
|
||||
if isclass(func):
|
||||
try:
|
||||
func = func.__init__
|
||||
except AttributeError:
|
||||
return ()
|
||||
startindex = 1
|
||||
else:
|
||||
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
||||
if not isfunction(func) and not ismethod(func):
|
||||
func = getattr(func, '__call__', func)
|
||||
if startindex is None:
|
||||
startindex = int(inspect.ismethod(func))
|
||||
startindex = int(ismethod(func))
|
||||
|
||||
rawcode = py.code.getrawcode(func)
|
||||
try:
|
||||
|
@ -461,10 +460,9 @@ class HookCaller(object):
|
|||
assert not self.has_spec()
|
||||
self._specmodule_or_class = specmodule_or_class
|
||||
specfunc = getattr(specmodule_or_class, self.name)
|
||||
self.argnames = ["__multicall__"] + list(varnames(
|
||||
specfunc, startindex=inspect.isclass(specmodule_or_class)
|
||||
))
|
||||
assert "self" not in self.argnames # sanity check
|
||||
argnames = varnames(specfunc, startindex=isclass(specmodule_or_class))
|
||||
assert "self" not in argnames # sanity check
|
||||
self.argnames = ["__multicall__"] + list(argnames)
|
||||
self.firstresult = getattr(specfunc, 'firstresult', False)
|
||||
if hasattr(specfunc, "historic"):
|
||||
self._call_history = []
|
||||
|
@ -512,27 +510,26 @@ class HookCaller(object):
|
|||
assert not self.is_historic()
|
||||
return self._docall(self._nonwrappers + self._wrappers, kwargs)
|
||||
|
||||
def callextra(self, methods, **kwargs):
|
||||
def call_extra(self, methods, kwargs):
|
||||
assert not self.is_historic()
|
||||
hc = self.clone()
|
||||
for method in methods:
|
||||
hc.add_method(method)
|
||||
return hc(**kwargs)
|
||||
|
||||
def _docall(self, methods, kwargs):
|
||||
return MultiCall(methods, kwargs, firstresult=self.firstresult).execute()
|
||||
|
||||
def call_historic(self, kwargs, proc=None):
|
||||
self._call_history.append((kwargs, proc))
|
||||
def call_historic(self, proc=None, kwargs=None):
|
||||
self._call_history.append((kwargs or {}, proc))
|
||||
self._docall(self._nonwrappers + self._wrappers, kwargs)
|
||||
|
||||
def _apply_history(self, method):
|
||||
if self.is_historic():
|
||||
for kwargs, proc in self._call_history:
|
||||
args = [kwargs[argname] for argname in varnames(method)]
|
||||
res = method(*args)
|
||||
if proc is not None:
|
||||
proc(res)
|
||||
res = self._docall([method], kwargs)
|
||||
if res and proc is not None:
|
||||
proc(res[0])
|
||||
|
||||
def _docall(self, methods, kwargs):
|
||||
return MultiCall(methods, kwargs, firstresult=self.firstresult).execute()
|
||||
|
||||
|
||||
class PluginValidationError(Exception):
|
||||
|
@ -542,5 +539,5 @@ class PluginValidationError(Exception):
|
|||
def formatdef(func):
|
||||
return "%s%s" % (
|
||||
func.__name__,
|
||||
inspect.formatargspec(*inspect.getargspec(func))
|
||||
formatargspec(*getargspec(func))
|
||||
)
|
||||
|
|
|
@ -19,6 +19,11 @@ def pytest_namespace():
|
|||
time.
|
||||
"""
|
||||
|
||||
@hookspec_opts(historic=True)
|
||||
def pytest_plugin_registered(plugin, manager):
|
||||
""" a new pytest plugin got registered. """
|
||||
|
||||
|
||||
@hookspec_opts(historic=True)
|
||||
def pytest_addoption(parser):
|
||||
"""register argparse-style options and ini-style config values.
|
||||
|
@ -259,9 +264,6 @@ def pytest_doctest_prepare_content(content):
|
|||
# error handling and internal debugging hooks
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def pytest_plugin_registered(plugin, manager):
|
||||
""" a new pytest plugin got registered. """
|
||||
|
||||
def pytest_internalerror(excrepr, excinfo):
|
||||
""" called for internal errors. """
|
||||
|
||||
|
|
|
@ -381,7 +381,8 @@ class PyCollector(PyobjMixin, pytest.Collector):
|
|||
if hasattr(cls, "pytest_generate_tests"):
|
||||
methods.append(cls().pytest_generate_tests)
|
||||
if methods:
|
||||
self.ihook.pytest_generate_tests.callextra(methods, metafunc=metafunc)
|
||||
self.ihook.pytest_generate_tests.call_extra(methods,
|
||||
dict(metafunc=metafunc))
|
||||
else:
|
||||
self.ihook.pytest_generate_tests(metafunc=metafunc)
|
||||
|
||||
|
@ -1623,7 +1624,6 @@ class FixtureManager:
|
|||
self.session = session
|
||||
self.config = session.config
|
||||
self._arg2fixturedefs = {}
|
||||
self._seenplugins = set()
|
||||
self._holderobjseen = set()
|
||||
self._arg2finish = {}
|
||||
self._nodeid_and_autousenames = [("", self.config.getini("usefixtures"))]
|
||||
|
@ -1648,11 +1648,7 @@ class FixtureManager:
|
|||
node)
|
||||
return FuncFixtureInfo(argnames, names_closure, arg2fixturedefs)
|
||||
|
||||
### XXX this hook should be called for historic events like pytest_configure
|
||||
### so that we don't have to do the below pytest_configure hook
|
||||
def pytest_plugin_registered(self, plugin):
|
||||
if plugin in self._seenplugins:
|
||||
return
|
||||
nodeid = None
|
||||
try:
|
||||
p = py.path.local(plugin.__file__)
|
||||
|
@ -1667,13 +1663,6 @@ class FixtureManager:
|
|||
if p.sep != "/":
|
||||
nodeid = nodeid.replace(p.sep, "/")
|
||||
self.parsefactories(plugin, nodeid)
|
||||
self._seenplugins.add(plugin)
|
||||
|
||||
@pytest.hookimpl_opts(tryfirst=True)
|
||||
def pytest_configure(self, config):
|
||||
plugins = config.pluginmanager.getplugins()
|
||||
for plugin in plugins:
|
||||
self.pytest_plugin_registered(plugin)
|
||||
|
||||
def _getautousenames(self, nodeid):
|
||||
""" return a tuple of fixture names to be used. """
|
||||
|
|
|
@ -111,7 +111,7 @@ class TestPluginManager:
|
|||
l.append(arg*10)
|
||||
pm.register(Plugin2())
|
||||
assert l == [1, 10]
|
||||
pm.hook.he_method1.call_historic(dict(arg=12))
|
||||
pm.hook.he_method1.call_historic(kwargs=dict(arg=12))
|
||||
assert l == [1, 10, 120, 12]
|
||||
|
||||
def test_with_result_memorized(self, pm):
|
||||
|
@ -122,7 +122,7 @@ class TestPluginManager:
|
|||
pm.addhooks(Hooks)
|
||||
|
||||
he_method1 = pm.hook.he_method1
|
||||
he_method1.call_historic(proc=lambda res: l.append(res), kwargs=dict(arg=1))
|
||||
he_method1.call_historic(lambda res: l.append(res), dict(arg=1))
|
||||
l = []
|
||||
class Plugin:
|
||||
def he_method1(self, arg):
|
||||
|
@ -140,7 +140,7 @@ class TestPluginManager:
|
|||
def he_method1(arg):
|
||||
return arg * 10
|
||||
|
||||
l = pm.hook.he_method1.callextra([he_method1], arg=1)
|
||||
l = pm.hook.he_method1.call_extra([he_method1], dict(arg=1))
|
||||
assert l == [10]
|
||||
|
||||
|
||||
|
@ -323,7 +323,8 @@ class TestPytestPluginInteractions:
|
|||
""")
|
||||
config = get_plugin_manager().config
|
||||
pm = config.pluginmanager
|
||||
pm.hook.pytest_addhooks.call_historic(dict(pluginmanager=config.pluginmanager))
|
||||
pm.hook.pytest_addhooks.call_historic(
|
||||
kwargs=dict(pluginmanager=config.pluginmanager))
|
||||
config.pluginmanager._importconftest(conf)
|
||||
#print(config.pluginmanager.getplugins())
|
||||
res = config.hook.pytest_myhook(xyz=10)
|
||||
|
@ -399,10 +400,10 @@ class TestPytestPluginInteractions:
|
|||
pytestpm = get_plugin_manager() # fully initialized with plugins
|
||||
saveindent = []
|
||||
class api1:
|
||||
def pytest_plugin_registered(self, plugin):
|
||||
def pytest_plugin_registered(self):
|
||||
saveindent.append(pytestpm.trace.root.indent)
|
||||
class api2:
|
||||
def pytest_plugin_registered(self, plugin):
|
||||
def pytest_plugin_registered(self):
|
||||
saveindent.append(pytestpm.trace.root.indent)
|
||||
raise ValueError()
|
||||
l = []
|
||||
|
@ -412,7 +413,7 @@ class TestPytestPluginInteractions:
|
|||
p = api1()
|
||||
pytestpm.register(p)
|
||||
assert pytestpm.trace.root.indent == indent
|
||||
assert len(l) == 2
|
||||
assert len(l) >= 2
|
||||
assert 'pytest_plugin_registered' in l[0]
|
||||
assert 'finish' in l[1]
|
||||
|
||||
|
|
Loading…
Reference in New Issue