1 new commit in pytest:
https://bitbucket.org/hpk42/pytest/commits/a36faafd111e/
Changeset: a36faafd111e
User:hpk42
Date:2013-08-02 09:52:40
Summary: ref #322 cleanup all teardown calling to only happen when setup
succeeded.
don't use autouse fixtures for now because it would cause a proliferation
and overhead for the execution of every test. Rather introduce a
node.addfinalizer(fin) to attach a finalizer to the respective node
and call it from node.setup() functions if the setup phase succeeded
(i.e. there is no setup function or it finished successfully)
Affected #: 10 files
diff -r 44f1eaaf106f677b20f1c0fb6220fe198d9164ed -r
a36faafd111e3ef317b18f4fe86054bdfaaa4301 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,9 +2,10 @@
---
- fix issue322: tearDownClass is not run if setUpClass failed. Thanks
- Mathieu Agopian for fixing. The patch moves handling setUpClass
- into a new autofixture. (XXX impl-decide if rather adding addfinalizer()
- API to node's would have a similar effect)
+ Mathieu Agopian for the initial fix. Also make all of pytest/nose finalizer
+ mimick the same generic behaviour: if a setupX exists and fails,
+ don't run teardownX. This also introduces a new method "node.addfinalizer()"
+ helper which can only be called during the setup phase of a node.
- fix issue336: autouse fixture in plugins should work again.
diff -r 44f1eaaf106f677b20f1c0fb6220fe198d9164ed -r
a36faafd111e3ef317b18f4fe86054bdfaaa4301 _pytest/__init__.py
--- a/_pytest/__init__.py
+++ b/_pytest/__init__.py
@@ -1,2 +1,2 @@
#
-__version__ = '2.4.0.dev8'
+__version__ = '2.4.0.dev10'
diff -r 44f1eaaf106f677b20f1c0fb6220fe198d9164ed -r
a36faafd111e3ef317b18f4fe86054bdfaaa4301 _pytest/main.py
--- a/_pytest/main.py
+++ b/_pytest/main.py
@@ -41,7 +41,7 @@
help="run pytest in strict mode, warnings become errors.")
group = parser.getgroup("collect", "collection")
-group.addoption('--collectonly', '--collect-only', action="store_true",
+group.addoption('--collectonly', '--collect-only', action="store_true",
help="only collect tests, don't execute them."),
group.addoption('--pyargs', action="store_true",
help="try to interpret all arguments as python packages.")
@@ -326,6 +326,14 @@
def getplugins(self):
return self.config._getmatchingplugins(self.fspath)
+def addfinalizer(self, fin):
+""" register a function to be called when this node is finalized.
+
+This method can only be called when this node is active
+in a setup chain, for example during self.setup().
+"""
+self.session._setupstate.addfinalizer(fin, self)
+
def getparent(self, cls):
current = self
while current and not isinstance(current, cls):
diff -r 44f1eaaf106f677b20f1c0fb6220fe198d9164ed -r
a36faafd111e3ef317b18f4fe86054bdfaaa4301 _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -384,19 +384,19 @@
setup_module(self.obj)
else:
setup_module()
-
-def teardown(self):
-teardown_module = xunitsetup(self.obj, 'tearDownModule')
-if teardown_module is None:
-teardown_module = xunitsetup(self.obj, 'teardown_module')
-if teardown_module is not None:
+fin = getattr(self.obj, 'tearDownModule', None)
+if fin is None:
+fin = getattr(self.obj, 'teardown_module', None)
+if fin is not None:
#XXX: nose compat hack, move to nose plugin
# if it takes a positional arg, its probably a py.test style one
# so we pass the current module object
-if inspect.getargspec(teardown_module)[0]:
-teardown_module(self.obj)
+if inspect.getargspec(fin)[0]:
+finalizer = lambda: fin(self.obj)
else:
-teardown_module()
+finalizer = fin
+self.addfinalizer(finalizer)
+
class Class(PyCollector):
""" Collector for test methods. """
@@ -415,12 +415,11 @@
setup_class = getattr(setup_class, '__func__', setup_class)
setup_class(self.obj)
-def teardown(self):
-teardown_class = xunitsetup(self.obj, 'teardown_class')
-if teardown_class is not None:
-teardown_class = getattr(teardown_class, 'im_func', teardown_class)
-teardown_class = getattr(teardown_class, '__func__',
teardown_class)
-teardown_class(self.obj)
+fin_class = getattr(self.obj, 'teardown_class', None)
+if fin_class is not None:
+fin_class = getattr(fin_class, 'im_func', fin_class)
+fin_class = getattr(fin_class, '__func__', fin_class)
+self.addfinalizer(lambda: fin_class(self.obj))
class Instance(PyCollector):
def _getobj(self):
@@ -449,23 +448,17 @@
else:
obj = self.parent.obj