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