diff --git a/py/test/collect.py b/py/test/collect.py index dd745618a..8ce614b2e 100644 --- a/py/test/collect.py +++ b/py/test/collect.py @@ -20,6 +20,7 @@ The is a schematic example of a tree of collectors and test items:: """ import py from py.__.misc.warn import APIWARN +from py.__.test.outcome import Skipped def configproperty(name): def fget(self): @@ -81,11 +82,24 @@ class Node(object): def __getstate__(self): return (self.name, self.parent) def __setstate__(self, (name, parent)): - newnode = parent.join(name) - if newnode is None: - raise AssertionError(self, name, parent, parent.__dict__) - self.__dict__.update(newnode.__dict__) - #self.__init__(name=name, parent=parent) + try: + colitems = parent._memocollect() + except KeyboardInterrupt: + raise + except Exception: + # seems our parent can't collect us + # so let's be somewhat operable + self.name = name + self.parent = parent + self.config = parent.config + self._obj = "could not unpickle" + else: + for colitem in colitems: + if colitem.name == name: + # we are a copy that will not be returned + # by our parent + self.__dict__ = colitem.__dict__ + break def __repr__(self): if getattr(self.config.option, 'debug', False): @@ -368,11 +382,6 @@ class Collector(Node): warnoldcollect() return self.collect_by_name(name) - def multijoin(self, namelist): - """ DEPRECATED: return a list of child items matching the given namelist. """ - warnoldcollect() - return [self.join(name) for name in namelist] - class FSCollector(Collector): def __init__(self, fspath, parent=None, config=None): fspath = py.path.local(fspath) diff --git a/py/test/event.py b/py/test/event.py index 36dd30cec..3add3efcd 100644 --- a/py/test/event.py +++ b/py/test/event.py @@ -70,7 +70,15 @@ class ItemTestReport(BaseReport): def __init__(self, colitem, excinfo=None, when=None, outerr=None): self.colitem = colitem - self.keywords = colitem and colitem.readkeywords() + if colitem and when != "setup": + self.keywords = colitem.readkeywords() + else: + # if we fail during setup it might mean + # we are not able to access the underlying object + # this might e.g. happen if we are unpickled + # and our parent collector did not collect us + # (because it e.g. skipped for platform reasons) + self.keywords = {} if not excinfo: self.passed = True self.shortrepr = "." diff --git a/py/test/plugin/pytest_pytester.py b/py/test/plugin/pytest_pytester.py index c921547bf..ec6cc0587 100644 --- a/py/test/plugin/pytest_pytester.py +++ b/py/test/plugin/pytest_pytester.py @@ -234,10 +234,12 @@ class TmpTestdir: bindir = py.path.local(py.__file__).dirpath("bin") if py.std.sys.platform == "win32": script = bindir.join("win32", scriptname + ".cmd") + assert script.check() + return self.run(script, *args) else: script = bindir.join(scriptname) - assert script.check() - return self.run(py.std.sys.executable, script, *args) + assert script.check() + return self.run(py.std.sys.executable, script, *args) def runpytest(self, *args): p = py.path.local.make_numbered_dir(prefix="runpytest-", diff --git a/py/test/pycollect.py b/py/test/pycollect.py index 28b6d0177..25cebaeae 100644 --- a/py/test/pycollect.py +++ b/py/test/pycollect.py @@ -265,7 +265,7 @@ class FunctionMixin(PyobjMixin): teardown_func_or_meth(self.obj) def _prunetraceback(self, traceback): - if not self.config.option.fulltrace: + if hasattr(self, '_obj') and not self.config.option.fulltrace: code = py.code.Code(self.obj) path, firstlineno = code.path, code.firstlineno ntraceback = traceback.cut(path=path, firstlineno=firstlineno)