merge config, pluginmanager, main into one file

--HG--
branch : trunk
This commit is contained in:
holger krekel 2010-10-12 12:54:32 +02:00
parent 6efc6dcb62
commit 6631447161
14 changed files with 415 additions and 444 deletions

View File

@ -232,7 +232,7 @@ initialisation, command line and configuration hooks
generic "runtest" hooks
------------------------------
Almost runtest related hooks receive a :py:class:`pytest.collect.Item` object.
All all runtest related hooks receive a :py:class:`pytest.collect.Item` object.
.. autofunction:: pytest_runtest_protocol
.. autofunction:: pytest_runtest_setup
@ -340,13 +340,13 @@ name. Given a filesystem ``fspath`` it is constructed as follows:
Reference of important objects involved in hooks
===========================================================
.. autoclass:: pytest._config.Config
.. autoclass:: pytest._core.Config
:members:
.. autoclass:: pytest.collect.Item
.. autoclass:: pytest.plugin.session.Item
:inherited-members:
.. autoclass:: pytest.collect.Node
.. autoclass:: pytest.plugin.session.Node
:members:
.. autoclass:: pytest.plugin.runner.CallInfo

View File

@ -1,14 +1,17 @@
"""
py.test / pytest API for unit and functional testing with Python.
see http://pytest.org for documentation and details
(c) Holger Krekel and others, 2004-2010
"""
__version__ = "2.0.0dev0"
__all__ = ['collect', 'cmdline', 'config']
__all__ = ['config', 'cmdline']
import pytest._config
config = pytest._config.Config()
from pytest import main as cmdline
from pytest import _core as cmdline
from pytest._core import Config
config = Config()
def __main__():
raise SystemExit(cmdline.main())

View File

@ -1,6 +1,25 @@
import py, os
from pytest.pluginmanager import PluginManager
import optparse
import py
import sys, os
default_plugins = (
"session terminal python runner pdb capture mark skipping tmpdir monkeypatch "
"recwarn pastebin unittest helpconfig nose assertion genscript "
"junitxml doctest keyword").split()
def main(args=None):
import sys
if args is None:
args = sys.argv[1:]
config = py.test.config
config.parse(args)
try:
exitstatus = config.hook.pytest_cmdline_main(config=config)
except config.Error:
e = sys.exc_info()[1]
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
exitstatus = 3
py.test.config = config.__class__()
return exitstatus
class Parser:
""" Parser for command line arguments. """
@ -47,7 +66,7 @@ class Parser:
for group in groups:
if group.options:
desc = group.description or group.name
optgroup = optparse.OptionGroup(optparser, desc)
optgroup = py.std.optparse.OptionGroup(optparser, desc)
optgroup.add_options(group.options)
optparser.add_option_group(optgroup)
return optparser.parse_args([str(x) for x in args])
@ -68,11 +87,11 @@ class OptionGroup:
def addoption(self, *optnames, **attrs):
""" add an option to this group. """
option = optparse.Option(*optnames, **attrs)
option = py.std.optparse.Option(*optnames, **attrs)
self._addoption_instance(option, shortupper=False)
def _addoption(self, *optnames, **attrs):
option = optparse.Option(*optnames, **attrs)
option = py.std.optparse.Option(*optnames, **attrs)
self._addoption_instance(option, shortupper=True)
def _addoption_instance(self, option, shortupper=False):
@ -85,10 +104,10 @@ class OptionGroup:
self.options.append(option)
class MyOptionParser(optparse.OptionParser):
class MyOptionParser(py.std.optparse.OptionParser):
def __init__(self, parser):
self._parser = parser
optparse.OptionParser.__init__(self, usage=parser._usage)
py.std.optparse.OptionParser.__init__(self, usage=parser._usage)
def format_epilog(self, formatter):
hints = self._parser.hints
if hints:
@ -96,6 +115,7 @@ class MyOptionParser(optparse.OptionParser):
s = "\n" + s + "\n"
return s
return ""
class Conftest(object):
""" the single place for accessing values and interacting
towards conftest modules from py.test objects.
@ -386,15 +406,368 @@ class Config(object):
except AttributeError:
return self._conftest.rget(name, path)
#
# helpers
#
class PluginManager(object):
def __init__(self):
from pytest import hookspec
self.registry = Registry()
self._name2plugin = {}
self._hints = []
self.hook = HookRelay([hookspec], registry=self.registry)
self.register(self)
for spec in default_plugins:
self.import_plugin(spec)
def onpytestaccess():
# it's enough to have our containing module loaded as
# it initializes a per-process config instance
# which loads default plugins which add to py.test.*
pass
def _getpluginname(self, plugin, name):
if name is None:
if hasattr(plugin, '__name__'):
name = plugin.__name__.split(".")[-1]
else:
name = id(plugin)
return name
def register(self, plugin, name=None, prepend=False):
assert not self.isregistered(plugin), plugin
assert not self.registry.isregistered(plugin), plugin
name = self._getpluginname(plugin, name)
if name in self._name2plugin:
return False
self._name2plugin[name] = plugin
self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self})
self.hook.pytest_plugin_registered(manager=self, plugin=plugin)
self.registry.register(plugin, prepend=prepend)
return True
def unregister(self, plugin):
self.hook.pytest_plugin_unregistered(plugin=plugin)
self.registry.unregister(plugin)
for name, value in list(self._name2plugin.items()):
if value == plugin:
del self._name2plugin[name]
def isregistered(self, plugin, name=None):
if self._getpluginname(plugin, name) in self._name2plugin:
return True
for val in self._name2plugin.values():
if plugin == val:
return True
def addhooks(self, spec):
self.hook._addhooks(spec, prefix="pytest_")
def getplugins(self):
return list(self.registry)
def skipifmissing(self, name):
if not self.hasplugin(name):
py.test.skip("plugin %r is missing" % name)
def hasplugin(self, name):
try:
self.getplugin(name)
except KeyError:
return False
else:
return True
def getplugin(self, name):
try:
return self._name2plugin[name]
except KeyError:
impname = canonical_importname(name)
return self._name2plugin[impname]
# API for bootstrapping
#
def _envlist(self, varname):
val = py.std.os.environ.get(varname, None)
if val is not None:
return val.split(',')
return ()
def consider_env(self):
for spec in self._envlist("PYTEST_PLUGINS"):
self.import_plugin(spec)
def consider_setuptools_entrypoints(self):
try:
from pkg_resources import iter_entry_points
except ImportError:
return # XXX issue a warning
for ep in iter_entry_points('pytest11'):
name = canonical_importname(ep.name)
if name in self._name2plugin:
continue
plugin = ep.load()
self.register(plugin, name=name)
def consider_preparse(self, args):
for opt1,opt2 in zip(args, args[1:]):
if opt1 == "-p":
self.import_plugin(opt2)
def consider_conftest(self, conftestmodule):
cls = getattr(conftestmodule, 'ConftestPlugin', None)
if cls is not None:
raise ValueError("%r: 'ConftestPlugins' only existed till 1.0.0b1, "
"were removed in 1.0.0b2" % (cls,))
if self.register(conftestmodule, name=conftestmodule.__file__):
self.consider_module(conftestmodule)
def consider_module(self, mod):
attr = getattr(mod, "pytest_plugins", ())
if attr:
if not isinstance(attr, (list, tuple)):
attr = (attr,)
for spec in attr:
self.import_plugin(spec)
def import_plugin(self, spec):
assert isinstance(spec, str)
modname = canonical_importname(spec)
if modname in self._name2plugin:
return
try:
mod = importplugin(modname)
except KeyboardInterrupt:
raise
except py.test.skip.Exception:
e = py.std.sys.exc_info()[1]
self._hints.append("skipped plugin %r: %s" %((modname, e.msg)))
else:
self.register(mod, modname)
self.consider_module(mod)
def pytest_terminal_summary(self, terminalreporter):
tw = terminalreporter._tw
if terminalreporter.config.option.traceconfig:
for hint in self._hints:
tw.line("hint: %s" % hint)
#
#
# API for interacting with registered and instantiated plugin objects
#
#
def listattr(self, attrname, plugins=None):
return self.registry.listattr(attrname, plugins=plugins)
def notify_exception(self, excinfo=None):
if excinfo is None:
excinfo = py.code.ExceptionInfo()
excrepr = excinfo.getrepr(funcargs=True, showlocals=True)
res = self.hook.pytest_internalerror(excrepr=excrepr)
if not py.builtin.any(res):
for line in str(excrepr).split("\n"):
sys.stderr.write("INTERNALERROR> %s\n" %line)
sys.stderr.flush()
def do_addoption(self, parser):
mname = "pytest_addoption"
methods = self.registry.listattr(mname, reverse=True)
mc = MultiCall(methods, {'parser': parser})
mc.execute()
def _setns(self, obj, dic):
for name, value in dic.items():
if isinstance(value, dict):
mod = getattr(obj, name, None)
if mod is None:
mod = py.std.types.ModuleType(name)
sys.modules['pytest.%s' % name] = mod
sys.modules['py.test.%s' % name] = mod
mod.__all__ = []
setattr(obj, name, mod)
self._setns(mod, value)
else:
#print "setting", name, value, "on", obj
setattr(obj, name, value)
obj.__all__.append(name)
def pytest_plugin_registered(self, plugin):
dic = self.call_plugin(plugin, "pytest_namespace", {}) or {}
if dic:
self._setns(py.test, dic)
if hasattr(self, '_config'):
self.call_plugin(plugin, "pytest_addoption",
{'parser': self._config._parser})
self.call_plugin(plugin, "pytest_configure",
{'config': self._config})
def call_plugin(self, plugin, methname, kwargs):
return MultiCall(
methods=self.listattr(methname, plugins=[plugin]),
kwargs=kwargs, firstresult=True).execute()
def do_configure(self, config):
assert not hasattr(self, '_config')
self._config = config
config.hook.pytest_configure(config=self._config)
def do_unconfigure(self, config):
config = self._config
del self._config
config.hook.pytest_unconfigure(config=config)
config.pluginmanager.unregister(self)
def canonical_importname(name):
name = name.lower()
modprefix = "pytest_"
if not name.startswith(modprefix):
name = modprefix + name
return name
def importplugin(importspec):
#print "importing", importspec
try:
return __import__(importspec)
except ImportError:
e = py.std.sys.exc_info()[1]
if str(e).find(importspec) == -1:
raise
name = importspec
try:
if name.startswith("pytest_"):
name = importspec[7:]
return __import__("pytest.plugin.%s" %(name), None, None, '__doc__')
except ImportError:
e = py.std.sys.exc_info()[1]
if str(e).find(name) == -1:
raise
# show the original exception, not the failing internal one
return __import__(importspec)
class MultiCall:
""" execute a call into multiple python functions/methods. """
def __init__(self, methods, kwargs, firstresult=False):
self.methods = methods[:]
self.kwargs = kwargs.copy()
self.kwargs['__multicall__'] = self
self.results = []
self.firstresult = firstresult
def __repr__(self):
status = "%d results, %d meths" % (len(self.results), len(self.methods))
return "<MultiCall %s, kwargs=%r>" %(status, self.kwargs)
def execute(self):
while self.methods:
method = self.methods.pop()
kwargs = self.getkwargs(method)
res = method(**kwargs)
if res is not None:
self.results.append(res)
if self.firstresult:
return res
if not self.firstresult:
return self.results
def getkwargs(self, method):
kwargs = {}
for argname in varnames(method):
try:
kwargs[argname] = self.kwargs[argname]
except KeyError:
pass # might be optional param
return kwargs
def varnames(func):
import inspect
if not inspect.isfunction(func) and not inspect.ismethod(func):
func = getattr(func, '__call__', func)
ismethod = inspect.ismethod(func)
rawcode = py.code.getrawcode(func)
try:
return rawcode.co_varnames[ismethod:]
except AttributeError:
return ()
class Registry:
"""
Manage Plugins: register/unregister call calls to plugins.
"""
def __init__(self, plugins=None):
if plugins is None:
plugins = []
self._plugins = plugins
def register(self, plugin, prepend=False):
assert not isinstance(plugin, str)
assert not plugin in self._plugins
if not prepend:
self._plugins.append(plugin)
else:
self._plugins.insert(0, plugin)
def unregister(self, plugin):
self._plugins.remove(plugin)
def isregistered(self, plugin):
return plugin in self._plugins
def __iter__(self):
return iter(self._plugins)
def listattr(self, attrname, plugins=None, reverse=False):
l = []
if plugins is None:
plugins = self._plugins
for plugin in plugins:
try:
l.append(getattr(plugin, attrname))
except AttributeError:
continue
if reverse:
l.reverse()
return l
class HookRelay:
def __init__(self, hookspecs, registry, prefix="pytest_"):
if not isinstance(hookspecs, list):
hookspecs = [hookspecs]
self._hookspecs = []
self._registry = registry
for hookspec in hookspecs:
self._addhooks(hookspec, prefix)
def _addhooks(self, hookspecs, prefix):
self._hookspecs.append(hookspecs)
added = False
for name, method in vars(hookspecs).items():
if name.startswith(prefix):
if not method.__doc__:
raise ValueError("docstring required for hook %r, in %r"
% (method, hookspecs))
firstresult = getattr(method, 'firstresult', False)
hc = HookCaller(self, name, firstresult=firstresult)
setattr(self, name, hc)
added = True
#print ("setting new hook", name)
if not added:
raise ValueError("did not find new %r hooks in %r" %(
prefix, hookspecs,))
def _performcall(self, name, multicall):
return multicall.execute()
class HookCaller:
def __init__(self, hookrelay, name, firstresult):
self.hookrelay = hookrelay
self.name = name
self.firstresult = firstresult
def __repr__(self):
return "<HookCaller %r>" %(self.name,)
def __call__(self, **kwargs):
methods = self.hookrelay._registry.listattr(self.name)
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
return self.hookrelay._performcall(self.name, mc)
def pcall(self, plugins, **kwargs):
methods = self.hookrelay._registry.listattr(self.name, plugins=plugins)
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
return self.hookrelay._performcall(self.name, mc)

View File

@ -1,6 +1,4 @@
"""
hook specifications for py.test plugins
"""
""" hook specifications for pytest plugins, invoked from _core.py and builtin plugins. """
# -------------------------------------------------------------------------
# Initialization

View File

@ -1,18 +0,0 @@
__all__ = []
import py, pytest
def main(args=None):
import sys
if args is None:
args = sys.argv[1:]
config = py.test.config
config.parse(args)
try:
exitstatus = config.hook.pytest_cmdline_main(config=config)
except config.Error:
e = sys.exc_info()[1]
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
exitstatus = 3
py.test.config = config.__class__()
return exitstatus

View File

@ -1,6 +1,6 @@
import py
from pytest.pluginmanager import HookRelay
from pytest._core import HookRelay
def pytest_funcarg___pytest(request):
return PytestArg(request)

View File

@ -8,7 +8,7 @@ import re
import inspect
import time
from fnmatch import fnmatch
from pytest._config import Config as pytestConfig
from pytest._core import Config as pytestConfig
from pytest.plugin.session import Collection
from py.builtin import print_
@ -222,7 +222,6 @@ class TmpTestdir:
""" this is used from tests that want to re-invoke parse(). """
if not args:
args = [self.tmpdir]
from pytest import _config
oldconfig = py.test.config
try:
c = py.test.config = pytestConfig()

View File

@ -1,381 +0,0 @@
"""
managing loading and interacting with pytest plugins.
"""
import py
import sys
default_plugins = (
"session terminal python runner pdb capture mark skipping tmpdir monkeypatch "
"recwarn pastebin unittest helpconfig nose assertion genscript "
"junitxml doctest keyword").split()
def check_old_use(mod, modname):
clsname = modname[len('pytest_'):].capitalize() + "Plugin"
assert not hasattr(mod, clsname), (mod, clsname)
class PluginManager(object):
def __init__(self):
from pytest import hookspec
self.registry = Registry()
self._name2plugin = {}
self._hints = []
self.hook = HookRelay([hookspec], registry=self.registry)
self.register(self)
for spec in default_plugins:
self.import_plugin(spec)
def _getpluginname(self, plugin, name):
if name is None:
if hasattr(plugin, '__name__'):
name = plugin.__name__.split(".")[-1]
else:
name = id(plugin)
return name
def register(self, plugin, name=None, prepend=False):
assert not self.isregistered(plugin), plugin
assert not self.registry.isregistered(plugin), plugin
name = self._getpluginname(plugin, name)
if name in self._name2plugin:
return False
self._name2plugin[name] = plugin
self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self})
self.hook.pytest_plugin_registered(manager=self, plugin=plugin)
self.registry.register(plugin, prepend=prepend)
return True
def unregister(self, plugin):
self.hook.pytest_plugin_unregistered(plugin=plugin)
self.registry.unregister(plugin)
for name, value in list(self._name2plugin.items()):
if value == plugin:
del self._name2plugin[name]
def isregistered(self, plugin, name=None):
if self._getpluginname(plugin, name) in self._name2plugin:
return True
for val in self._name2plugin.values():
if plugin == val:
return True
def addhooks(self, spec):
self.hook._addhooks(spec, prefix="pytest_")
def getplugins(self):
return list(self.registry)
def skipifmissing(self, name):
if not self.hasplugin(name):
py.test.skip("plugin %r is missing" % name)
def hasplugin(self, name):
try:
self.getplugin(name)
except KeyError:
return False
else:
return True
def getplugin(self, name):
try:
return self._name2plugin[name]
except KeyError:
impname = canonical_importname(name)
return self._name2plugin[impname]
# API for bootstrapping
#
def _envlist(self, varname):
val = py.std.os.environ.get(varname, None)
if val is not None:
return val.split(',')
return ()
def consider_env(self):
for spec in self._envlist("PYTEST_PLUGINS"):
self.import_plugin(spec)
def consider_setuptools_entrypoints(self):
try:
from pkg_resources import iter_entry_points
except ImportError:
return # XXX issue a warning
for ep in iter_entry_points('pytest11'):
name = canonical_importname(ep.name)
if name in self._name2plugin:
continue
plugin = ep.load()
self.register(plugin, name=name)
def consider_preparse(self, args):
for opt1,opt2 in zip(args, args[1:]):
if opt1 == "-p":
self.import_plugin(opt2)
def consider_conftest(self, conftestmodule):
cls = getattr(conftestmodule, 'ConftestPlugin', None)
if cls is not None:
raise ValueError("%r: 'ConftestPlugins' only existed till 1.0.0b1, "
"were removed in 1.0.0b2" % (cls,))
if self.register(conftestmodule, name=conftestmodule.__file__):
self.consider_module(conftestmodule)
def consider_module(self, mod):
attr = getattr(mod, "pytest_plugins", ())
if attr:
if not isinstance(attr, (list, tuple)):
attr = (attr,)
for spec in attr:
self.import_plugin(spec)
def import_plugin(self, spec):
assert isinstance(spec, str)
modname = canonical_importname(spec)
if modname in self._name2plugin:
return
try:
mod = importplugin(modname)
except KeyboardInterrupt:
raise
except py.test.skip.Exception:
e = py.std.sys.exc_info()[1]
self._hints.append("skipped plugin %r: %s" %((modname, e.msg)))
else:
check_old_use(mod, modname)
self.register(mod, modname)
self.consider_module(mod)
def pytest_terminal_summary(self, terminalreporter):
tw = terminalreporter._tw
if terminalreporter.config.option.traceconfig:
for hint in self._hints:
tw.line("hint: %s" % hint)
#
#
# API for interacting with registered and instantiated plugin objects
#
#
def listattr(self, attrname, plugins=None):
return self.registry.listattr(attrname, plugins=plugins)
def notify_exception(self, excinfo=None):
if excinfo is None:
excinfo = py.code.ExceptionInfo()
excrepr = excinfo.getrepr(funcargs=True, showlocals=True)
res = self.hook.pytest_internalerror(excrepr=excrepr)
if not py.builtin.any(res):
for line in str(excrepr).split("\n"):
sys.stderr.write("INTERNALERROR> %s\n" %line)
sys.stderr.flush()
def do_addoption(self, parser):
mname = "pytest_addoption"
methods = self.registry.listattr(mname, reverse=True)
mc = MultiCall(methods, {'parser': parser})
mc.execute()
def _setns(self, obj, dic):
for name, value in dic.items():
if isinstance(value, dict):
mod = getattr(obj, name, None)
if mod is None:
mod = py.std.types.ModuleType(name)
sys.modules['pytest.%s' % name] = mod
sys.modules['py.test.%s' % name] = mod
mod.__all__ = []
setattr(obj, name, mod)
self._setns(mod, value)
else:
#print "setting", name, value, "on", obj
setattr(obj, name, value)
obj.__all__.append(name)
def pytest_plugin_registered(self, plugin):
dic = self.call_plugin(plugin, "pytest_namespace", {}) or {}
if dic:
self._setns(py.test, dic)
if hasattr(self, '_config'):
self.call_plugin(plugin, "pytest_addoption",
{'parser': self._config._parser})
self.call_plugin(plugin, "pytest_configure",
{'config': self._config})
def call_plugin(self, plugin, methname, kwargs):
return MultiCall(
methods=self.listattr(methname, plugins=[plugin]),
kwargs=kwargs, firstresult=True).execute()
def do_configure(self, config):
assert not hasattr(self, '_config')
self._config = config
config.hook.pytest_configure(config=self._config)
def do_unconfigure(self, config):
config = self._config
del self._config
config.hook.pytest_unconfigure(config=config)
config.pluginmanager.unregister(self)
def canonical_importname(name):
name = name.lower()
modprefix = "pytest_"
if not name.startswith(modprefix):
name = modprefix + name
return name
def importplugin(importspec):
#print "importing", importspec
try:
return __import__(importspec)
except ImportError:
e = py.std.sys.exc_info()[1]
if str(e).find(importspec) == -1:
raise
name = importspec
try:
if name.startswith("pytest_"):
name = importspec[7:]
return __import__("pytest.plugin.%s" %(name), None, None, '__doc__')
except ImportError:
e = py.std.sys.exc_info()[1]
if str(e).find(name) == -1:
raise
# show the original exception, not the failing internal one
return __import__(importspec)
class MultiCall:
""" execute a call into multiple python functions/methods. """
def __init__(self, methods, kwargs, firstresult=False):
self.methods = methods[:]
self.kwargs = kwargs.copy()
self.kwargs['__multicall__'] = self
self.results = []
self.firstresult = firstresult
def __repr__(self):
status = "%d results, %d meths" % (len(self.results), len(self.methods))
return "<MultiCall %s, kwargs=%r>" %(status, self.kwargs)
def execute(self):
while self.methods:
method = self.methods.pop()
kwargs = self.getkwargs(method)
res = method(**kwargs)
if res is not None:
self.results.append(res)
if self.firstresult:
return res
if not self.firstresult:
return self.results
def getkwargs(self, method):
kwargs = {}
for argname in varnames(method):
try:
kwargs[argname] = self.kwargs[argname]
except KeyError:
pass # might be optional param
return kwargs
def varnames(func):
import inspect
if not inspect.isfunction(func) and not inspect.ismethod(func):
func = getattr(func, '__call__', func)
ismethod = inspect.ismethod(func)
rawcode = py.code.getrawcode(func)
try:
return rawcode.co_varnames[ismethod:]
except AttributeError:
return ()
class Registry:
"""
Manage Plugins: register/unregister call calls to plugins.
"""
def __init__(self, plugins=None):
if plugins is None:
plugins = []
self._plugins = plugins
def register(self, plugin, prepend=False):
assert not isinstance(plugin, str)
assert not plugin in self._plugins
if not prepend:
self._plugins.append(plugin)
else:
self._plugins.insert(0, plugin)
def unregister(self, plugin):
self._plugins.remove(plugin)
def isregistered(self, plugin):
return plugin in self._plugins
def __iter__(self):
return iter(self._plugins)
def listattr(self, attrname, plugins=None, reverse=False):
l = []
if plugins is None:
plugins = self._plugins
for plugin in plugins:
try:
l.append(getattr(plugin, attrname))
except AttributeError:
continue
if reverse:
l.reverse()
return l
class HookRelay:
def __init__(self, hookspecs, registry, prefix="pytest_"):
if not isinstance(hookspecs, list):
hookspecs = [hookspecs]
self._hookspecs = []
self._registry = registry
for hookspec in hookspecs:
self._addhooks(hookspec, prefix)
def _addhooks(self, hookspecs, prefix):
self._hookspecs.append(hookspecs)
added = False
for name, method in vars(hookspecs).items():
if name.startswith(prefix):
if not method.__doc__:
raise ValueError("docstring required for hook %r, in %r"
% (method, hookspecs))
firstresult = getattr(method, 'firstresult', False)
hc = HookCaller(self, name, firstresult=firstresult)
setattr(self, name, hc)
added = True
#print ("setting new hook", name)
if not added:
raise ValueError("did not find new %r hooks in %r" %(
prefix, hookspecs,))
def _performcall(self, name, multicall):
return multicall.execute()
class HookCaller:
def __init__(self, hookrelay, name, firstresult):
self.hookrelay = hookrelay
self.name = name
self.firstresult = firstresult
def __repr__(self):
return "<HookCaller %r>" %(self.name,)
def __call__(self, **kwargs):
methods = self.hookrelay._registry.listattr(self.name)
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
return self.hookrelay._performcall(self.name, mc)
def pcall(self, plugins, **kwargs):
methods = self.hookrelay._registry.listattr(self.name, plugins=plugins)
mc = MultiCall(methods, kwargs, firstresult=self.firstresult)
return self.hookrelay._performcall(self.name, mc)

View File

@ -3,7 +3,7 @@ import py
pytest_plugins = "pytester"
import pytest.plugin
plugindir = py.path.local(pytest.plugin.__file__).dirpath()
from pytest.pluginmanager import default_plugins
from pytest._core import default_plugins
def pytest_collect_file(path, parent):
if path.basename.startswith("pytest_") and path.ext == ".py":

View File

@ -1,7 +1,7 @@
import py
import os, sys
from pytest.plugin._pytest import HookRecorder
from pytest.pluginmanager import Registry
from pytest._core import Registry
def test_hookrecorder_basic():
rec = HookRecorder(Registry())
@ -29,7 +29,7 @@ def test_hookrecorder_basic_no_args_hook():
def test_functional(testdir, linecomp):
reprec = testdir.inline_runsource("""
import py
from pytest.pluginmanager import HookRelay, Registry
from pytest._core import HookRelay, Registry
pytest_plugins="_pytest"
def test_func(_pytest):
class ApiClass:

View File

@ -2,7 +2,7 @@ import py
import os
from pytest.plugin.resultlog import generic_path, ResultLog, \
pytest_configure, pytest_unconfigure
from pytest.collect import Node, Item, FSCollector
from pytest.plugin.session import Node, Item, FSCollector
def test_generic_path(testdir):
from pytest.plugin.session import Collection

View File

@ -1,5 +1,5 @@
import py
from pytest._config import Conftest
from pytest._core import Conftest
def pytest_generate_tests(metafunc):
if "basedir" in metafunc.funcargnames:

View File

@ -1,5 +1,5 @@
import py
from pytest import _config as parseopt
from pytest import main as parseopt
class TestParser:
def test_init(self, capsys):
@ -42,7 +42,7 @@ class TestParser:
group = parseopt.OptionGroup("hello")
group.addoption("--option1", action="store_true")
assert len(group.options) == 1
assert isinstance(group.options[0], parseopt.optparse.Option)
assert isinstance(group.options[0], py.std.optparse.Option)
def test_group_shortopt_lowercase(self):
parser = parseopt.Parser()

View File

@ -1,6 +1,6 @@
import py, os
from pytest.pluginmanager import PluginManager, canonical_importname
from pytest.pluginmanager import Registry, MultiCall, HookRelay, varnames
from pytest._core import PluginManager, canonical_importname
from pytest._core import Registry, MultiCall, HookRelay, varnames
class TestBootstrapping:
@ -232,7 +232,6 @@ class TestBootstrapping:
class TestPytestPluginInteractions:
def test_addhooks_conftestplugin(self, testdir):
from pytest._config import Config
newhooks = testdir.makepyfile(newhooks="""
def pytest_myhook(xyz):
"new hook"
@ -245,7 +244,7 @@ class TestPytestPluginInteractions:
def pytest_myhook(xyz):
return xyz + 1
""")
config = Config()
config = testdir.Config()
config._conftest.importconftest(conf)
print(config.pluginmanager.getplugins())
res = config.hook.pytest_myhook(xyz=10)
@ -283,12 +282,11 @@ class TestPytestPluginInteractions:
])
def test_do_option_conftestplugin(self, testdir):
from pytest._config import Config
p = testdir.makepyfile("""
def pytest_addoption(parser):
parser.addoption('--test123', action="store_true")
""")
config = Config()
config = testdir.Config()
config._conftest.importconftest(p)
print(config.pluginmanager.getplugins())
config.parse([])
@ -321,8 +319,7 @@ class TestPytestPluginInteractions:
])
def test_do_option_postinitialize(self, testdir):
from pytest._config import Config
config = Config()
config = testdir.Config()
config.parse([])
config.pluginmanager.do_configure(config=config)
assert not hasattr(config.option, 'test123')