zope.testing fails miserably on unicode

Bug #561568 reported by Adam Groszer
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Zope 3
Won't Fix
Undecided
Unassigned
zope.testing
Invalid
Undecided
Unassigned

Bug Description

Some doctest output can esily become unicode.

  Running:
.../browser/README.txt/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py:1596: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if got == want:
/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py:1616: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if got == want:
/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py:1625: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if got == want:

Error in test .../browser/README.txt
Traceback (most recent call last):
  File "/usr/local/lib/python2.5/unittest.py", line 260, in run
    testMethod()
  File "/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py", line 2327, in runTest
    test, out=write, clear_globs=False)
  File "/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py", line 1497, in run
    return self.__run(test, compileflags, out)
  File "/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py", line 1376, in __run
    if check(example.want, got, self.optionflags):
  File "/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py", line 1631, in check_output
    if _ellipsis_match(want, got):
  File "/home/adi/.buildout/eggs/zope.testing-3.7.5-py2.5.egg/zope/testing/doctest.py", line 308, in _ellipsis_match
    if got.startswith(w):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 5690: ordinal not in range(128)

Tres Seaver (tseaver)
Changed in zope3:
status: New → Won't Fix
Revision history for this message
Tres Seaver (tseaver) wrote :

Can you please provide a sample doctest fragment which provokes the bug? We have some tests in place on the trunkwhich attempt to verify that the behavior is correct.

Changed in zope.testing:
status: New → Incomplete
Revision history for this message
Adam Groszer (agroszer) wrote :

Seems like this was fixed somewhere between 3.7.5 and trunk.
My test is in r110975. It passes. Newest release also passes with our app.

Changed in zope.testing:
status: Incomplete → Fix Released
Revision history for this message
Adam Groszer (agroszer) wrote :

Still fails with zope.testing 3.9.4.
Cause is a simple
>>> print browser.contents
it has some utf-8 encoded non-ascii strings. Need to investigate further.

Changed in zope.testing:
status: Fix Released → Incomplete
Adam Groszer (agroszer)
tags: added: bugday20100424
Revision history for this message
Adam Groszer (agroszer) wrote :

Add
# -*- coding: UTF-8 -*-
to the top of the doctest... kabooom, until that got and want will be str, after that got is str want is unicode therefore forcing a conversion at OutputChecker::check_output

Revision history for this message
Alberto Berti (azazell) wrote :

.. -*- mode: rst; coding: utf-8 -*-

A sample failing test
=====================

:Test-Layer: functional

Let's first check what's the default encoding:

   >>> import sys
   >>> sys.getdefaultencoding()
   'ascii'

then make all the test machinery fail on UnicodeDecodeError:

   >>> print u'Kabòòm'
   Kabòòm

Revision history for this message
Alberto Berti (azazell) wrote :

The problem is that in DocTestRunner.__run() does check_output without type checking the two compared members (the example output that could be an unicode fragment like in the example above, and the output of the running doctest, which is _always_ a string because _SpoofOut.write(value) encodes value to 'utf8' if value is an unicode).

Later then in check_output there is the chance that an unicode example fragment is compared to a string.

The string should instead be decoded to unicode before comparison:

This is the traceback of the error:

Error in test /home/azazel/wip/airpim/apsignup/apsignup/src/airpim/signup/a1.txt
Traceback (most recent call last):
  File "/usr/lib/python2.6/unittest.py", line 279, in run
    testMethod()
  File "/home/azazel/wip/airpim/apsignup/apsignup/eggs/zope.testing-3.8.7-py2.6.egg/zope/testing/doctest.py", line 2330, in runTest
    test, out=write, clear_globs=False)
  File "/home/azazel/wip/airpim/apsignup/apsignup/eggs/zope.testing-3.8.7-py2.6.egg/zope/testing/doctest.py", line 1502, in run
    return self.__run(test, compileflags, out)
  File "/home/azazel/wip/airpim/apsignup/apsignup/eggs/zope.testing-3.8.7-py2.6.egg/zope/testing/doctest.py", line 1414, in __run
    self.report_failure(out, test, example, got)
  File "/home/azazel/wip/airpim/apsignup/apsignup/eggs/zope.testing-3.8.7-py2.6.egg/zope/testing/doctest.py", line 1280, in report_failure
    self._checker.output_difference(example, got, self.optionflags))
  File "/home/azazel/wip/airpim/apsignup/apsignup/eggs/zope.testing-3.8.7-py2.6.egg/zope/testing/doctest.py", line 1701, in output_difference
    return 'Differences (%s):\n' % kind + _indent(''.join(diff))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128)

Revision history for this message
Marius Gedminas (mgedmin) wrote :

We've deprecated zope.testing.doctest and are gently redirecting everyone to use stdlib's doctest.

Revision history for this message
Colin Watson (cjwatson) wrote :

The zope.testing project on Launchpad has been archived at the request of the Zope developers (see https://answers.launchpad.net/launchpad/+question/683589 and https://answers.launchpad.net/launchpad/+question/685285). If this bug is still relevant, please refile it at https://github.com/zopefoundation/zope.testing.

Changed in zope.testing:
status: Incomplete → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.