On Wed, Dec 23, 2009 at 01:36:33PM +0100, Fabio Tranchitella wrote:
I think we should provide a zope.testing package which does not emit deprecation warnings while running the testrunner on other packages, otherwise there is no way to really understand why the package you are working on is using a deprecated API.
+1
I propose the patch attached to this message to zope.testing.
It tries to avoid importing zope.testing.doctest unless it is really needed. In this way, developers can see the DeprecationWarning with the path of *their* code, and fix it, instead of receiving the DeprecationWarning because the testrunner imports zope.testing.doctest itself.
Before applying the patch, running the tests on another package produced this output:
----------------------------------------------------------------------- .../zope/testing/testrunner/debug.py:23: DeprecationWarning: zope.testing.doctest is deprecated in favour of the Python standard library doctest module from zope.testing import doctest Running zope.testing.testrunner.layer.UnitTests tests: ... -----------------------------------------------------------------------
After applying my patch, I get this:
----------------------------------------------------------------------- .../zope/interface/tests/test_adapter.py:405: DeprecationWarning: zope.testing.doctest is deprecated in favour of the Python standard library doctest module from zope.testing import doctest Running zope.testing.testrunner.layer.UnitTests tests: ... -----------------------------------------------------------------------
Comments?
Let's look at it:
Thanks, Fabio
Index: src/zope/testing/testrunner/formatter.py =================================================================== --- src/zope/testing/testrunner/formatter.py (revisione 106999) +++ src/zope/testing/testrunner/formatter.py (copia locale) @@ -19,10 +19,9 @@ import sys import re import traceback +import warnings
-from zope.testing import doctest
- doctest_template = """ File "%s", line %s, in %s
@@ -328,6 +327,9 @@ def format_traceback(self, exc_info): """Format the traceback.""" v = exc_info[1] + warnings.simplefilter('ignore') + from zope.testing import doctest + warnings.filters.pop()
I'm not thrilled. Can we 'import doctest' from the stdlib, and hope that these isinstance checks work fine? Specifically, can we make it so that zope.testing.doctest's exceptions _inherit_ from stdlib's doctest exceptions? Otherwise people who convert to stdlib's doctest to avoid deprecation warnings will lose all the nice doctest formatting and post-mortem debugging bits they're accustomed to.
if isinstance(v, doctest.DocTestFailureException): tb = v.args[0] elif isinstance(v, doctest.DocTestFailure): @@ -560,6 +562,9 @@ print print self.colorize('error', msg) v = exc_info[1] + warnings.simplefilter('ignore'); + from zope.testing import doctest + warnings.filters.pop() if isinstance(v, doctest.DocTestFailureException): self.print_doctest_failure(v.args[0]) elif isinstance(v, doctest.DocTestFailure): Index: src/zope/testing/testrunner/doctest.py =================================================================== --- src/zope/testing/testrunner/doctest.py (revisione 106999) +++ src/zope/testing/testrunner/doctest.py (copia locale) @@ -17,10 +17,11 @@ """
import sys -from zope.testing import doctest import zope.testing.testrunner.feature
+from zope.testing import doctest
+
Doesn't seem like much of a change ;) Suggest importing stdlib here as well.
class DocTest(zope.testing.testrunner.feature.Feature):
active = True Index: src/zope/testing/testrunner/runner.py =================================================================== --- src/zope/testing/testrunner/runner.py (revisione 106999) +++ src/zope/testing/testrunner/runner.py (copia locale) @@ -34,7 +34,6 @@ from zope.testing.testrunner.refcount import TrackRefs from zope.testing.testrunner.options import get_options import zope.testing.testrunner.coverage -import zope.testing.testrunner.doctest import zope.testing.testrunner.logsupport import zope.testing.testrunner.selftest import zope.testing.testrunner.profiling @@ -177,7 +176,10 @@ self.features.append(zope.testing.testrunner.selftest.SelfTest(self)) self.features.append(zope.testing.testrunner.logsupport.Logging(self)) self.features.append(zope.testing.testrunner.coverage.Coverage(self)) - self.features.append(zope.testing.testrunner.doctest.DocTest(self)) + if options.ndiff or options.udiff or options.cdiff or \ + options.report_only_first_failure is not None: + from zope.testing.testrunner.doctest import DocTest + self.features.append(DocTest(self))
A *strong* -1 for this bit.
self.features.append(zope.testing.testrunner.profiling.Profiling(self)) if is_jython: # Jython GC support is not yet implemented Index: src/zope/testing/testrunner/debug.py =================================================================== --- src/zope/testing/testrunner/debug.py (revisione 106999) +++ src/zope/testing/testrunner/debug.py (copia locale) @@ -20,12 +20,12 @@ import sys import pdb
-from zope.testing import doctest import zope.testing.testrunner.interfaces
def post_mortem(exc_info): err = exc_info[1] + from zope.testing import doctest
Same here: I'd like to use stdlib's doctest.
if isinstance(err, (doctest.UnexpectedException, doctest.DocTestFailure)):
if isinstance(err, doctest.UnexpectedException):
Cheers! Marius Gedminas -- http://pov.lt/ -- Zope 3 consulting and development