diff options
-rw-r--r-- | _pytest/config.py | 71 | ||||
-rw-r--r-- | _pytest/core.py | 58 | ||||
-rw-r--r-- | _pytest/helpconfig.py | 4 | ||||
-rw-r--r-- | _pytest/main.py | 4 | ||||
-rw-r--r-- | _pytest/mark.py | 8 | ||||
-rw-r--r-- | _pytest/pytester.py | 4 | ||||
-rw-r--r-- | testing/test_core.py | 10 | ||||
-rw-r--r-- | testing/test_session.py | 5 |
8 files changed, 81 insertions, 83 deletions
diff --git a/_pytest/config.py b/_pytest/config.py index c4f488588..f52a635bc 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -2,20 +2,6 @@ import py import sys, os -import pytest - -def pytest_cmdline_parse(pluginmanager, args): - config = Config(pluginmanager) - config.parse(args) - return config - -def pytest_unconfigure(config): - while 1: - try: - fin = config._cleanup.pop() - except IndexError: - break - fin() class Parser: """ Parser for command line arguments and ini-file values. """ @@ -507,13 +493,46 @@ class Config(object): self._inicache = {} self._opt2dest = {} self._cleanup = [] + self.pluginmanager.register(self, "pytestconfig") + self._configured = False + + def pytest_plugin_registered(self, plugin): + call_plugin = self.pluginmanager.call_plugin + dic = call_plugin(plugin, "pytest_namespace", {}) or {} + if dic: + import pytest + setns(pytest, dic) + call_plugin(plugin, "pytest_addoption", {'parser': self._parser}) + if self._configured: + call_plugin(plugin, "pytest_configure", {'config': self}) + + def do_configure(self): + assert not self._configured + self._configured = True + self.hook.pytest_configure(config=self) + + def do_unconfigure(self): + assert self._configured + self._configured = False + self.hook.pytest_unconfigure(config=self) + self.pluginmanager.ensure_shutdown() + + def pytest_cmdline_parse(self, pluginmanager, args): + assert self == pluginmanager.config, (self, pluginmanager.config) + self.parse(args) + return self + + def pytest_unconfigure(config): + while config._cleanup: + fin = config._cleanup.pop() + fin() @classmethod def fromdictargs(cls, option_dict, args): """ constructor useable for subprocesses. """ from _pytest.core import get_plugin_manager pluginmanager = get_plugin_manager() - config = cls(pluginmanager) + config = pluginmanager.config # XXX slightly crude way to initialize capturing import _pytest.capture _pytest.capture.pytest_cmdline_parse(config.pluginmanager, args) @@ -572,11 +591,11 @@ class Config(object): self.pluginmanager.consider_setuptools_entrypoints() self.pluginmanager.consider_env() self._setinitialconftest(args) - self.pluginmanager.do_addoption(self._parser) if addopts: self.hook.pytest_cmdline_preparse(config=self, args=args) def _checkversion(self): + import pytest minver = self.inicfg.get('minversion', None) if minver: ver = minver.split(".") @@ -723,3 +742,23 @@ def getcfg(args, inibasenames): return iniconfig['pytest'] return {} + +def setns(obj, dic): + import pytest + for name, value in dic.items(): + if isinstance(value, dict): + mod = getattr(obj, name, None) + if mod is None: + modname = "pytest.%s" % name + mod = py.std.types.ModuleType(modname) + sys.modules[modname] = mod + mod.__all__ = [] + setattr(obj, name, mod) + obj.__all__.append(name) + setns(mod, value) + else: + setattr(obj, name, value) + obj.__all__.append(name) + #if obj != pytest: + # pytest.__all__.append(name) + setattr(pytest, name, value) diff --git a/_pytest/core.py b/_pytest/core.py index 6f87276bd..fae32228d 100644 --- a/_pytest/core.py +++ b/_pytest/core.py @@ -1,17 +1,17 @@ """ pytest PluginManager, basic initialization and tracing. -(c) Holger Krekel 2004-2010 """ import sys, os import inspect import py from _pytest import hookspec # the extension point definitions +from _pytest.config import Config assert py.__version__.split(".")[:2] >= ['1', '4'], ("installation problem: " "%s is too old, remove or upgrade 'py'" % (py.__version__)) default_plugins = ( - "config mark main terminal runner python pdb unittest capture skipping " + "mark main terminal runner python pdb unittest capture skipping " "tmpdir monkeypatch recwarn pastebin helpconfig nose assertion genscript " "junitxml resultlog doctest").split() @@ -91,6 +91,7 @@ class PluginManager(object): self.trace.root.setwriter(err.write) self.hook = HookRelay([hookspec], pm=self) self.register(self) + self.config = Config(self) # XXX unclear if the attr is needed if load: for spec in default_plugins: self.import_plugin(spec) @@ -100,7 +101,8 @@ class PluginManager(object): return name = name or getattr(plugin, '__name__', str(id(plugin))) if self.isregistered(plugin, name): - raise ValueError("Plugin already registered: %s=%s" %(name, plugin)) + raise ValueError("Plugin already registered: %s=%s\n%s" %( + name, plugin, self._name2plugin)) #self.trace("registering", name, plugin) self._name2plugin[name] = plugin self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self}) @@ -220,7 +222,6 @@ class PluginManager(object): if self.getplugin(modname) is not None: return try: - #self.trace("importing", modname) mod = importplugin(modname) except KeyboardInterrupt: raise @@ -247,59 +248,12 @@ class PluginManager(object): "trylast: mark a hook implementation function such that the " "plugin machinery will try to call it last/as late as possible.") - def pytest_plugin_registered(self, plugin): - import pytest - dic = self.call_plugin(plugin, "pytest_namespace", {}) or {} - if dic: - self._setns(pytest, 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 _setns(self, obj, dic): - import pytest - for name, value in dic.items(): - if isinstance(value, dict): - mod = getattr(obj, name, None) - if mod is None: - modname = "pytest.%s" % name - mod = py.std.types.ModuleType(modname) - sys.modules[modname] = mod - mod.__all__ = [] - setattr(obj, name, mod) - obj.__all__.append(name) - self._setns(mod, value) - else: - setattr(obj, name, value) - obj.__all__.append(name) - #if obj != pytest: - # pytest.__all__.append(name) - setattr(pytest, name, value) - def pytest_terminal_summary(self, terminalreporter): tw = terminalreporter._tw if terminalreporter.config.option.traceconfig: for hint in self._hints: tw.line("hint: %s" % hint) - def do_addoption(self, parser): - mname = "pytest_addoption" - methods = reversed(self.listattr(mname)) - MultiCall(methods, {'parser': parser}).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.ensure_shutdown() - def notify_exception(self, excinfo, option=None): if option and option.fulltrace: style = "long" @@ -350,6 +304,7 @@ def importplugin(importspec): name = importspec try: mod = "_pytest." + name + #print >>sys.stderr, "tryimport", mod __import__(mod) return sys.modules[mod] except ImportError: @@ -358,6 +313,7 @@ def importplugin(importspec): # raise pass # try: + #print >>sys.stderr, "tryimport", importspec __import__(importspec) except ImportError: raise ImportError(importspec) diff --git a/_pytest/helpconfig.py b/_pytest/helpconfig.py index 048863869..2be858f3b 100644 --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -54,9 +54,9 @@ def pytest_cmdline_main(config): sys.stderr.write(line + "\n") return 0 elif config.option.help: - config.pluginmanager.do_configure(config) + config.do_configure() showhelp(config) - config.pluginmanager.do_unconfigure(config) + config.do_unconfigure() return 0 def showhelp(config): diff --git a/_pytest/main.py b/_pytest/main.py index 680a99d3a..39c7dba3f 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -76,7 +76,7 @@ def wrap_session(config, doit): initstate = 0 try: try: - config.pluginmanager.do_configure(config) + config.do_configure() initstate = 1 config.hook.pytest_sessionstart(session=session) initstate = 2 @@ -105,7 +105,7 @@ def wrap_session(config, doit): session=session, exitstatus=session.exitstatus) if initstate >= 1: - config.pluginmanager.do_unconfigure(config) + config.do_unconfigure() config.pluginmanager.ensure_shutdown() return session.exitstatus diff --git a/_pytest/mark.py b/_pytest/mark.py index 9961f9d0e..59c72607e 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -1,5 +1,5 @@ """ generic mechanism for marking and selecting python functions. """ -import pytest, py +import py def pytest_namespace(): @@ -39,14 +39,14 @@ def pytest_addoption(parser): def pytest_cmdline_main(config): if config.option.markers: - config.pluginmanager.do_configure(config) + config.do_configure() tw = py.io.TerminalWriter() for line in config.getini("markers"): name, rest = line.split(":", 1) tw.write("@pytest.mark.%s:" % name, bold=True) tw.line(rest) tw.line() - config.pluginmanager.do_unconfigure(config) + config.do_unconfigure() return 0 pytest_cmdline_main.tryfirst = True @@ -129,6 +129,7 @@ def matchkeyword(colitem, keywordexpr): mapped_names = set() # Add the names of the current item and any parent items + import pytest for item in colitem.listchain(): if not isinstance(item, pytest.Instance): mapped_names.add(item.name) @@ -145,6 +146,7 @@ def matchkeyword(colitem, keywordexpr): def pytest_configure(config): + import pytest if config.option.strict: pytest.mark._config = config diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 322b11277..3d6ff2933 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -390,9 +390,9 @@ class TmpTestdir: def parseconfigure(self, *args): config = self.parseconfig(*args) - config.pluginmanager.do_configure(config) + config.do_configure() self.request.addfinalizer(lambda: - config.pluginmanager.do_unconfigure(config)) + config.do_unconfigure()) return config def getitem(self, source, funcname="test_func"): diff --git a/testing/test_core.py b/testing/test_core.py index 8a960228b..3948b4695 100644 --- a/testing/test_core.py +++ b/testing/test_core.py @@ -261,13 +261,13 @@ class TestBootstrapping: assert pm.getplugins() my2 = MyPlugin() pm.register(my2) - assert pm.getplugins()[1:] == [my, my2] + assert pm.getplugins()[2:] == [my, my2] assert pm.isregistered(my) assert pm.isregistered(my2) pm.unregister(my) assert not pm.isregistered(my) - assert pm.getplugins()[1:] == [my2] + assert pm.getplugins()[2:] == [my2] def test_listattr(self): plugins = PluginManager() @@ -319,7 +319,7 @@ class TestPytestPluginInteractions: def pytest_myhook(xyz): return xyz + 1 """) - config = testdir.Config(PluginManager(load=True)) + config = PluginManager(load=True).config config._conftest.importconftest(conf) print(config.pluginmanager.getplugins()) res = config.hook.pytest_myhook(xyz=10) @@ -383,13 +383,13 @@ class TestPytestPluginInteractions: config.pluginmanager.register(A()) assert len(l) == 0 - config.pluginmanager.do_configure(config=config) + config.do_configure() assert len(l) == 1 config.pluginmanager.register(A()) # leads to a configured() plugin assert len(l) == 2 assert l[0] != l[1] - config.pluginmanager.do_unconfigure(config=config) + config.do_unconfigure() config.pluginmanager.register(A()) assert len(l) == 2 diff --git a/testing/test_session.py b/testing/test_session.py index e8e67bde2..f206760cc 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -208,13 +208,14 @@ def test_plugin_specify(testdir): testdir.parseconfig("-p", "nqweotexistent") """) #pytest.raises(ImportError, - # "config.pluginmanager.do_configure(config)" + # "config.do_configure(config)" #) def test_plugin_already_exists(testdir): config = testdir.parseconfig("-p", "terminal") assert config.option.plugins == ['terminal'] - config.pluginmanager.do_configure(config) + config.do_configure() + config.do_unconfigure() def test_exclude(testdir): hellodir = testdir.mkdir("hello") |