greatly refine deprecaction warnings and use new "recwarn" plugin for it.
--HG-- branch : trunk
This commit is contained in:
parent
671684be5c
commit
3245b0c1af
|
@ -26,3 +26,15 @@ def test_stacklevel():
|
||||||
lno = test_stacklevel.func_code.co_firstlineno + 6
|
lno = test_stacklevel.func_code.co_firstlineno + 6
|
||||||
warning = str(err)
|
warning = str(err)
|
||||||
assert warning.find(":%s" % lno) != -1
|
assert warning.find(":%s" % lno) != -1
|
||||||
|
|
||||||
|
def test_function():
|
||||||
|
capture = py.io.StdCapture()
|
||||||
|
py.log._apiwarn("x.y.z", "something", function=test_function)
|
||||||
|
out, err = capture.reset()
|
||||||
|
print "out", out
|
||||||
|
print "err", err
|
||||||
|
assert err.find("x.y.z") != -1
|
||||||
|
lno = test_function.func_code.co_firstlineno
|
||||||
|
exp = "%s:%s" % (mypath, lno)
|
||||||
|
assert err.find(exp) != -1
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,17 @@ class Warning(py.std.exceptions.DeprecationWarning):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.msg
|
return self.msg
|
||||||
|
|
||||||
def _apiwarn(startversion, msg, stacklevel=1):
|
def _apiwarn(startversion, msg, stacklevel=1, function=None):
|
||||||
# below is mostly COPIED from python2.4/warnings.py's def warn()
|
# below is mostly COPIED from python2.4/warnings.py's def warn()
|
||||||
# Get context information
|
# Get context information
|
||||||
msg = "%s (since version %s)" %(msg, startversion)
|
msg = "%s (since version %s)" %(msg, startversion)
|
||||||
warn(msg, stacklevel=stacklevel+1)
|
warn(msg, stacklevel=stacklevel+1, function=function)
|
||||||
|
|
||||||
def warn(msg, stacklevel=1):
|
def warn(msg, stacklevel=1, function=None):
|
||||||
|
if function is not None:
|
||||||
|
filename = py.std.inspect.getfile(function)
|
||||||
|
lineno = function.func_code.co_firstlineno
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
caller = sys._getframe(stacklevel)
|
caller = sys._getframe(stacklevel)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
|
@ -347,7 +347,7 @@ class Collector(Node):
|
||||||
setattr(self, attrname, True)
|
setattr(self, attrname, True)
|
||||||
method = getattr(self.__class__, 'run', None)
|
method = getattr(self.__class__, 'run', None)
|
||||||
if method is not None and method != Collector.run:
|
if method is not None and method != Collector.run:
|
||||||
warnoldcollect()
|
warnoldcollect(function=method)
|
||||||
names = self.run()
|
names = self.run()
|
||||||
return filter(None, [self.join(name) for name in names])
|
return filter(None, [self.join(name) for name in names])
|
||||||
|
|
||||||
|
@ -356,14 +356,12 @@ class Collector(Node):
|
||||||
You can return an empty list. Callers of this method
|
You can return an empty list. Callers of this method
|
||||||
must take care to catch exceptions properly.
|
must take care to catch exceptions properly.
|
||||||
"""
|
"""
|
||||||
warnoldcollect()
|
|
||||||
return [colitem.name for colitem in self._memocollect()]
|
return [colitem.name for colitem in self._memocollect()]
|
||||||
|
|
||||||
def join(self, name):
|
def join(self, name):
|
||||||
""" DEPRECATED: return a child collector or item for the given name.
|
""" DEPRECATED: return a child collector or item for the given name.
|
||||||
If the return value is None there is no such child.
|
If the return value is None there is no such child.
|
||||||
"""
|
"""
|
||||||
warnoldcollect()
|
|
||||||
return self.collect_by_name(name)
|
return self.collect_by_name(name)
|
||||||
|
|
||||||
class FSCollector(Collector):
|
class FSCollector(Collector):
|
||||||
|
@ -451,20 +449,21 @@ class Item(Node):
|
||||||
""" a basic test item. """
|
""" a basic test item. """
|
||||||
def _deprecated_testexecution(self):
|
def _deprecated_testexecution(self):
|
||||||
if self.__class__.run != Item.run:
|
if self.__class__.run != Item.run:
|
||||||
warnoldtestrun()
|
warnoldtestrun(function=self.run)
|
||||||
self.run()
|
self.run()
|
||||||
return True
|
return True
|
||||||
elif self.__class__.execute != Item.execute:
|
elif self.__class__.execute != Item.execute:
|
||||||
warnoldtestrun()
|
warnoldtestrun(function=self.execute)
|
||||||
self.execute(self.obj, *self._args)
|
self.execute(self.obj, *self._args)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
warnoldtestrun()
|
""" deprecated, here because subclasses might call it. """
|
||||||
return self.execute(self.obj, *self._args)
|
return self.execute(self.obj, *self._args)
|
||||||
|
|
||||||
def execute(self, obj, *args):
|
def execute(self, obj, *args):
|
||||||
warnoldtestrun()
|
""" deprecated, here because subclasses might call it. """
|
||||||
|
warnoldtestrun(function=self.execute)
|
||||||
return obj(*args)
|
return obj(*args)
|
||||||
|
|
||||||
def repr_metainfo(self):
|
def repr_metainfo(self):
|
||||||
|
@ -477,14 +476,14 @@ class Item(Node):
|
||||||
def runtest(self):
|
def runtest(self):
|
||||||
""" execute this test item."""
|
""" execute this test item."""
|
||||||
|
|
||||||
def warnoldcollect():
|
def warnoldcollect(function=None):
|
||||||
py.log._apiwarn("1.0",
|
py.log._apiwarn("1.0",
|
||||||
"implement collector.collect() instead of "
|
"implement collector.collect() instead of "
|
||||||
"collector.run() and collector.join()",
|
"collector.run() and collector.join()",
|
||||||
stacklevel=2)
|
stacklevel=2, function=function)
|
||||||
|
|
||||||
def warnoldtestrun():
|
def warnoldtestrun(function=None):
|
||||||
py.log._apiwarn("1.0",
|
py.log._apiwarn("1.0",
|
||||||
"implement item.runtest() instead of "
|
"implement item.runtest() instead of "
|
||||||
"item.run() and item.execute()",
|
"item.run() and item.execute()",
|
||||||
stacklevel=2)
|
stacklevel=2, function=function)
|
||||||
|
|
|
@ -44,6 +44,7 @@ class WarningsRecorder:
|
||||||
for i, w in py.builtin.enumerate(self.list):
|
for i, w in py.builtin.enumerate(self.list):
|
||||||
if issubclass(w.category, cls):
|
if issubclass(w.category, cls):
|
||||||
return self.list.pop(i)
|
return self.list.pop(i)
|
||||||
|
__tracebackhide__ = True
|
||||||
assert 0, "%r not found in %r" %(cls, self.list)
|
assert 0, "%r not found in %r" %(cls, self.list)
|
||||||
|
|
||||||
#def resetregistry(self):
|
#def resetregistry(self):
|
||||||
|
@ -51,7 +52,7 @@ class WarningsRecorder:
|
||||||
# warnings.onceregistry.clear()
|
# warnings.onceregistry.clear()
|
||||||
# warnings.__warningregistry__.clear()
|
# warnings.__warningregistry__.clear()
|
||||||
|
|
||||||
def reset(self):
|
def clear(self):
|
||||||
self.list[:] = []
|
self.list[:] = []
|
||||||
|
|
||||||
def finalize(self):
|
def finalize(self):
|
||||||
|
@ -69,7 +70,7 @@ def test_WarningRecorder():
|
||||||
warn = rec.pop()
|
warn = rec.pop()
|
||||||
assert str(warn.message) == "hello"
|
assert str(warn.message) == "hello"
|
||||||
l = rec.list
|
l = rec.list
|
||||||
rec.reset()
|
rec.clear()
|
||||||
assert len(rec.list) == 0
|
assert len(rec.list) == 0
|
||||||
assert l is rec.list
|
assert l is rec.list
|
||||||
py.test.raises(AssertionError, "rec.pop()")
|
py.test.raises(AssertionError, "rec.pop()")
|
||||||
|
|
|
@ -131,13 +131,6 @@ class TestCollectFS:
|
||||||
names = [x.name for x in col.collect()]
|
names = [x.name for x in col.collect()]
|
||||||
assert names == ["dir1", "dir2", "test_one.py", "test_two.py", "x"]
|
assert names == ["dir1", "dir2", "test_one.py", "test_two.py", "x"]
|
||||||
|
|
||||||
def test_collector_deprecated_run_method(self, testdir, recwarn):
|
|
||||||
modcol = testdir.getmodulecol("pass")
|
|
||||||
res1 = modcol.run()
|
|
||||||
recwarn.pop(DeprecationWarning)
|
|
||||||
res2 = modcol.collect()
|
|
||||||
assert res1 == [x.name for x in res2]
|
|
||||||
|
|
||||||
class TestCollectPluginHooks:
|
class TestCollectPluginHooks:
|
||||||
def test_pytest_collect_file(self, testdir):
|
def test_pytest_collect_file(self, testdir):
|
||||||
tmpdir = testdir.tmpdir
|
tmpdir = testdir.tmpdir
|
||||||
|
|
|
@ -2,15 +2,8 @@
|
||||||
import py
|
import py
|
||||||
|
|
||||||
class TestCollectDeprecated:
|
class TestCollectDeprecated:
|
||||||
def test_directory_run_join_warnings(self, testdir):
|
|
||||||
p = testdir.makepyfile(test_one="")
|
|
||||||
config = testdir.parseconfig(p)
|
|
||||||
dirnode = config.getfsnode(p.dirpath())
|
|
||||||
py.test.deprecated_call(dirnode.run)
|
|
||||||
# XXX for directories we still have join()
|
|
||||||
#py.test.deprecated_call(dirnode.join, 'test_one')
|
|
||||||
|
|
||||||
def test_collect_with_deprecated_run_and_join(self, testdir):
|
def test_collect_with_deprecated_run_and_join(self, testdir, recwarn):
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
@ -52,23 +45,31 @@ class TestCollectDeprecated:
|
||||||
""")
|
""")
|
||||||
config = testdir.parseconfig()
|
config = testdir.parseconfig()
|
||||||
dirnode = config.getfsnode(p.dirpath())
|
dirnode = config.getfsnode(p.dirpath())
|
||||||
colitems = py.test.deprecated_call(dirnode.collect)
|
colitems = dirnode.collect()
|
||||||
|
w = recwarn.pop(DeprecationWarning)
|
||||||
|
assert w.filename.find("conftest.py") != -1
|
||||||
|
#recwarn.resetregistry()
|
||||||
|
#assert 0, (w.message, w.filename, w.lineno)
|
||||||
assert len(colitems) == 1
|
assert len(colitems) == 1
|
||||||
modcol = colitems[0]
|
modcol = colitems[0]
|
||||||
assert modcol.name == "somefile.py"
|
assert modcol.name == "somefile.py"
|
||||||
colitems = py.test.deprecated_call(modcol.collect)
|
colitems = modcol.collect()
|
||||||
|
recwarn.pop(DeprecationWarning)
|
||||||
assert len(colitems) == 2
|
assert len(colitems) == 2
|
||||||
assert colitems[0].name == 'check'
|
assert colitems[0].name == 'check'
|
||||||
assert colitems[1].name == 'Cls'
|
assert colitems[1].name == 'Cls'
|
||||||
clscol = colitems[1]
|
clscol = colitems[1]
|
||||||
colitems = py.test.deprecated_call(clscol.collect)
|
|
||||||
|
colitems = clscol.collect()
|
||||||
|
recwarn.pop(DeprecationWarning)
|
||||||
assert len(colitems) == 1
|
assert len(colitems) == 1
|
||||||
icol = colitems[0]
|
icol = colitems[0]
|
||||||
colitems = py.test.deprecated_call(icol.collect)
|
colitems = icol.collect()
|
||||||
|
recwarn.pop(DeprecationWarning)
|
||||||
assert len(colitems) == 1
|
assert len(colitems) == 1
|
||||||
assert colitems[0].name == 'check2'
|
assert colitems[0].name == 'check2'
|
||||||
|
|
||||||
def test_collect_with_deprecated_join_but_no_run(self, testdir):
|
def test_collect_with_deprecated_join_but_no_run(self, testdir, recwarn):
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
@ -87,42 +88,57 @@ class TestCollectDeprecated:
|
||||||
def check_one(): pass
|
def check_one(): pass
|
||||||
class SomeClass: pass
|
class SomeClass: pass
|
||||||
""")
|
""")
|
||||||
colitems = py.test.deprecated_call(col.collect)
|
colitems = col.collect()
|
||||||
|
recwarn.pop(DeprecationWarning)
|
||||||
assert len(colitems) == 1
|
assert len(colitems) == 1
|
||||||
funcitem = colitems[0]
|
funcitem = colitems[0]
|
||||||
assert funcitem.name == "check_one"
|
assert funcitem.name == "check_one"
|
||||||
|
|
||||||
def test_function_custom_run(self, testdir):
|
def test_function_custom_run(self, testdir, recwarn):
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
import py
|
import py
|
||||||
class MyFunction(py.test.collect.Function):
|
class Function(py.test.collect.Function):
|
||||||
def run(self):
|
def run(self):
|
||||||
pass
|
pass
|
||||||
Function=MyFunction
|
|
||||||
""")
|
""")
|
||||||
modcol = testdir.getmodulecol("def test_func(): pass")
|
modcol = testdir.getmodulecol("def test_func(): pass")
|
||||||
funcitem = modcol.collect()[0]
|
funcitem = modcol.collect()[0]
|
||||||
assert funcitem.name == 'test_func'
|
assert funcitem.name == 'test_func'
|
||||||
py.test.deprecated_call(funcitem.runtest)
|
recwarn.clear()
|
||||||
|
funcitem.runtest()
|
||||||
|
recwarn.pop(DeprecationWarning)
|
||||||
|
|
||||||
def test_function_custom_execute(self, testdir):
|
def test_function_custom_execute(self, testdir, recwarn):
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
import py
|
import py
|
||||||
|
|
||||||
class MyFunction(py.test.collect.Function):
|
class MyFunction(py.test.collect.Function):
|
||||||
def execute(self, obj, *args):
|
def execute(self, obj, *args):
|
||||||
pass
|
pass
|
||||||
Function=MyFunction
|
Function=MyFunction
|
||||||
""")
|
""")
|
||||||
modcol = testdir.getmodulecol("def test_func(): pass")
|
modcol = testdir.getmodulecol("def test_func2(): pass")
|
||||||
funcitem = modcol.collect()[0]
|
funcitem = modcol.collect()[0]
|
||||||
assert funcitem.name == 'test_func'
|
assert funcitem.name == 'test_func2'
|
||||||
py.test.deprecated_call(funcitem.runtest)
|
funcitem._deprecated_testexecution()
|
||||||
|
w = recwarn.pop(DeprecationWarning)
|
||||||
|
assert w.filename.find("conftest.py") != -1
|
||||||
|
|
||||||
def test_function_deprecated_run_execute(self, testdir):
|
def test_function_deprecated_run_execute(self, testdir, recwarn):
|
||||||
modcol = testdir.getmodulecol("def test_some(): pass")
|
testdir.makepyfile(conftest="""
|
||||||
|
import py
|
||||||
|
|
||||||
|
class Function(py.test.collect.Function):
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
modcol = testdir.getmodulecol("def test_some2(): pass")
|
||||||
funcitem = modcol.collect()[0]
|
funcitem = modcol.collect()[0]
|
||||||
py.test.deprecated_call(funcitem.run)
|
|
||||||
py.test.deprecated_call(funcitem.execute, funcitem.obj)
|
recwarn.clear()
|
||||||
|
funcitem._deprecated_testexecution()
|
||||||
|
recwarn.pop(DeprecationWarning)
|
||||||
|
|
||||||
def test_function_deprecated_run_recursive(self, testdir):
|
def test_function_deprecated_run_recursive(self, testdir):
|
||||||
testdir.makepyfile(conftest="""
|
testdir.makepyfile(conftest="""
|
||||||
|
|
Loading…
Reference in New Issue