summaryrefslogtreecommitdiff
path: root/_pytest
diff options
context:
space:
mode:
authorholger krekel <holger@merlinux.eu>2013-09-30 13:14:14 +0200
committerholger krekel <holger@merlinux.eu>2013-09-30 13:14:14 +0200
commitd946299b0a3e42e447c92b6074f196077b9b7a91 (patch)
tree087a4fd36d5f83654316eaff8b1820612884014b /_pytest
parent694c6fd0e7f4270b43fb14d3a31d8b4d828bb11f (diff)
downloadpytest-d946299b0a3e42e447c92b6074f196077b9b7a91.tar.gz
shift pytest_configure/unconfigure/addoption/namespace hook calling to config object.
The _pytest.config module itself is no longer a plugin but the actual config instance is plugin-registered as ``pytestconfig``. This allows to put most pytest specific logic to _pytest.config instead of in the core pluginmanager.
Diffstat (limited to '_pytest')
-rw-r--r--_pytest/config.py71
-rw-r--r--_pytest/core.py58
-rw-r--r--_pytest/helpconfig.py4
-rw-r--r--_pytest/main.py4
-rw-r--r--_pytest/mark.py8
-rw-r--r--_pytest/pytester.py4
6 files changed, 73 insertions, 76 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"):