Merge lp:~gz/testtools/unicode_tracebacks_501166 into lp:~testtools-committers/testtools/trunk
| Status: | Superseded | ||||
|---|---|---|---|---|---|
| Proposed branch: | lp:~gz/testtools/unicode_tracebacks_501166 | ||||
| Merge into: | lp:~testtools-committers/testtools/trunk | ||||
| Diff against target: |
1010 lines (+763/-25) (has conflicts) 11 files modified
testtools/__init__.py (+1/-1) testtools/compat.py (+186/-15) testtools/content.py (+3/-3) testtools/run.py (+2/-2) testtools/testcase.py (+1/-1) testtools/testresult/real.py (+30/-1) testtools/tests/__init__.py (+2/-0) testtools/tests/test_compat.py (+239/-0) testtools/tests/test_content.py (+1/-1) testtools/tests/test_testresult.py (+285/-1) testtools/testsuite.py (+13/-0) Text conflict in testtools/testresult/real.py |
||||
| To merge this branch: | bzr merge lp:~gz/testtools/unicode_tracebacks_501166 | ||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Robert Collins | 2010-05-26 | Needs Fixing on 2010-05-31 | |
| testtools developers | preliminary | 2010-05-26 | Pending |
|
Review via email:
|
|||
This proposal has been superseded by a proposal from 2010-06-18.
Description of the Change
Proposed just to get this on the radar and solicit some early feedback. Needs a fair bit more work (and testing, I haven't looked at Python 3 yet) before it could be merged. Am happy to be told to move around code, rewrite tests, whatever.
As described in the bug, testtools on Python 2 currently falls over if any part of a traceback is not ascii. 90% of the problem is just the stringification of exception instances, but to be properly robust against funny inputs other elements of the traceback need to be correctly decoded as well.
The aim of the branch is to swap out the TestResult traceback formatting code on Python 2 only, and make it behave pretty much as Python 3 already does. I did have some additional changes with added improvements to the presentation, but have removed most of them for the moment.
Problem code is scattered across unittest, traceback and lineache which leaves a choice of three unpalatable options:
* Duplicating a lot of code from the standard library to change a few lines
* Invasive monkey patching of core modules
* Crazy and not terribly succinct hackery
I have avoided monkey patching, but much of the added code is not very nice.
Brief overview of the diff:
<testtools/
Make sure unicode route is used (needing to create a dummy TestResult instance here feels like an abstraction leak)
<testtools/run.py>
Make stub runner use unicode route
<testtools/
On Python implementations where str is bytes make traceback formatting use a unicode returning alternative to the standard traceback functions, and a couple of other changes to stay on unicode route
<testtools/
Substantive changes here. The various new functions essentially only matter for Python 2 so seemed next to _u and _b might be the right place.
* unicode_
* _detect_encoding and _get_source_
* _get_exception_
* _format_exc_info - overall traceback and exception formatting as unicode.
<testtools/
Add new test module to suite.
<testtools/
End-to-end testing of encoding handling and formatting. Rather ad-hoc setup at the moment, but the intention in the test cases themselves is about right.
<testtools/
Unit testing of added functions in utils that don't depend too much on the environment. Currently just the decoding of lines from Python source files. The other functions could be tested here, but because the type and how it is handled throughout the package matters, they all need to be tested as a whole anyway.
| Martin Packman (gz) wrote : | # |
> I think
>
> 38 - result = TextTestResult(
> 39 + result = TextTestResult(
> 40 result.
>
> Needs a comment (such as 'the testtools TextTestResult outputs unicode, and
> sys.stdout is usually a bytestream not an encoded stream'). Writing this makes
> me think 'why doesn't TextTestResult take care of this for users of the API ?
I think this is a weakness with the Runner code really, it's rather light on useful logic, and half the module is under `if __name__ == '__main__':` so none of it's reusable. And there's still bug 501174 too.
> I don't really like testtools.utils; I'd consider putting stuff in small
> dedicated modules rather than a catchall; not mandatory - what do you think?
> E.g. we could move _u and _b to testtools.
Well, these are mostly compatibility hacks rather than useful tools, and a bunch of them should never run on some versions of Python. A better name than 'utils' would be good.
> + if sys.version_info > (3, 0) or sys.platform == "cli":
> This is repeated; helper function time.
I'm still not sure on the best spelling of this check, it might be more readable as `if str is unicode:` but I need to check all of these conditionals actually do the right thing with Python 3 and the 2to3 conversion script.
> + # Python 3 and IronPython strings are unicode, use parent class
> method
> Perhaps "traceback strings are unicode, ..."
Well, as in the str type is unicode, but yeah, this cares about what the traceback module returns.
> The deep magic is a little mind bending at first encounter, perhaps a couple
> of hints in there to aid understanding in new readers. Also, if it was a
> helper you wouldn't need the manual del, which is otherwise pretty opaque.
It's unfortunately not the kind of thing that's reusable, so a helper may not help much. The good news is if we do change the stack stripping logic we'll be ripping this out anyway.
Perhaps just copying the function straight from unittest would be less painful anyway. One of the things I thought might need checking is what is okay to copy things into the MIT-licensed testtools from unittest and the rest of the Python standard library. Writing this sort of patch means the code is inevitably some sort of derivative, even without verbatim copying of functions.
> The _run helper you have suggests the api for testtools.run isn't powerful
> enough/easy enough yet. Please consider improving that rather than
> reimplementing (even though its tiny code-wise, principle applies here)
Yep. Was trying to avoid rolling that issue into this one though, as it felt more rewrite to me than fix.
> _run_external_case wants to be two things:
> - create a module returning info on it with a cleanup method
> - use that info to run the test
Yeah, wants teasing out into a couple of smaller, more logical helpers.
> whats different between rmtempdir and shutil.
Nothing useful currently, I wrote it because I thought I'd have to work around a problem with unicode on byte based filesystems (as per posix) and bytes on unicode based f...
| Robert Collins (lifeless) wrote : | # |
briefly, and I know I'm missing bits.
grab me on IRC for the matcher
yes, split utils into the iter and the encoding stuff
For the rest, do what you think makes the most sense ;)
-Rob
- 67. By Martin Packman on 2010-06-04
-
PEP 8 style fixes raised in review
- 68. By Martin Packman on 2010-06-11
-
Fix a bunch of boneheaded errors in TestNonAsciiResults
- 69. By Martin Packman on 2010-06-11
-
Merge trunk to pick up fixes for IronPython and Python 3
- 70. By Martin Packman on 2010-06-14
-
Changes to make tests work on Python 3, and a short term hack to make output robust
- 71. By Martin Packman on 2010-06-14
-
Make final problem test for Python 3 run rather than skip
- 72. By Martin Packman on 2010-06-14
-
Rearrange some TestNonAsciiResults helpers
- 73. By Martin Packman on 2010-06-14
-
Use flag in utils to record whether the str type is unicode rather than checking version and platform in multiple places
- 74. By Martin Packman on 2010-06-14
-
Work around a couple of quirks in non-mainstream Python implementations
- 75. By Martin Packman on 2010-06-15
-
Revert work around for IronPython coding declaration as it breaks Python 2
- 76. By Martin Packman on 2010-06-15
-
Poke encoding specific code in TestNonAsciiResults some more
- 77. By Martin Packman on 2010-06-15
-
Fix test_traceback_
rechecks_ encoding which got broken when adding Python 3 support - 78. By Martin Packman on 2010-06-15
-
Found `ascii` function in Python 3 which saves some reimplementation
- 79. By Martin Packman on 2010-06-15
-
Unbreak test_non_
ascii_dirname from IronPython returning filesystem encoding as None - 80. By Martin Packman on 2010-06-15
-
Revert no longer needed cosmetic changes to test_content
- 81. By Martin Packman on 2010-06-15
-
Sanitise unicode_
output_ stream a bit and add some tests, needs more work - 82. By Martin Packman on 2010-06-18
-
Make Jython skip unicode filesystem tests correctly again
- 83. By Martin Packman on 2010-06-18
-
Fix and test a bug with encoding of SyntaxError lines
- 84. By Martin Packman on 2010-06-18
-
Move most of utils module to compat and put iterate_tests in testsuite module
- 85. By Martin Packman on 2010-06-20
-
Trivial issues seen when scanning the diff for review
- 86. By Martin Packman on 2010-06-20
-
getlocale can return None if no locale is set, default to ascii
- 87. By Martin Packman on 2010-06-20
-
Allow detect encoding tests to work when a Python implementation may object to compiling them
- 88. By Martin Packman on 2010-06-20
-
Allow for mangling in shift_jis test if the exception encoding is incompatible
- 89. By Martin Packman on 2010-06-20
-
Document in tests the problems caused by CPython patch for issue #1031213
- 90. By Martin Packman on 2010-06-22
-
Avoid problem introduced with fix to Python bug #1031213 by ignoring the SyntaxError line and rereading the file instead
- 91. By Martin Packman on 2010-06-22
-
Change a test from using iso-8859-7 to iso-8859-5 which doesn't happen to have the test character on the same codepoint as iso-8859-1
- 92. By Martin Packman on 2010-06-22
-
Don't encode output as UTF-8 for TestNonAsciiResults
- 93. By Martin Packman on 2010-06-22
-
Make StringException
.__str_ _ return UTF-8 rather than ascii/replace to prepare for merge - 94. By Martin Packman on 2010-06-22
-
Merge trunk to resolve conflict in _StringException stringifying methods
- 95. By Martin Packman on 2010-06-22
-
Add NEWS for unicode tracebacks on Python 2
- 96. By Martin Packman on 2010-06-22
-
Unbreak test_assertion_
text_shift_ jis for Pythons with a unicode str type - 97. By Martin Packman on 2010-06-22
-
Move Python 2 _StringException argument type check to __init__ from stringify methods

Thank you very much for doing this! I appreciate its early days, so I'll simply brain dump what I see and we can filter it in future passes.
I think
38 - result = TextTestResult( sys.stdout) unicode_ output_ stream( sys.stdout) ) startTestRun( )
39 + result = TextTestResult(
40 result.
Needs a comment (such as 'the testtools TextTestResult outputs unicode, and sys.stdout is usually a bytestream not an encoded stream'). Writing this makes me think 'why doesn't TextTestResult take care of this for users of the API ?
I don't really like testtools.utils; I'd consider putting stuff in small dedicated modules rather than a catchall; not mandatory - what do you think? E.g. we could move _u and _b to testtools. sequencetypes. Or something.
+ if sys.version_info > (3, 0) or sys.platform == "cli":
This is repeated; helper function time.
+ # Python 3 and IronPython strings are unicode, use parent class method
Perhaps "traceback strings are unicode, ..."
The deep magic is a little mind bending at first encounter, perhaps a couple of hints in there to aid understanding in new readers. Also, if it was a helper you wouldn't need the manual del, which is otherwise pretty opaque.
Minor nit: PEP8 got changed strangely; please don't use leading empty lines in docstrings. ults(TestCase) : ults(TestCase) :
+class TestNonAsciiRes
+ """
+ Test all kinds of tracebacks are cleanly interpreted as unicode
+
->
+class TestNonAsciiRes
+ """Test all kinds of tracebacks are cleanly interpreted as unicode
The _run helper you have suggests the api for testtools.run isn't powerful enough/easy enough yet. Please consider improving that rather than reimplementing (even though its tiny code-wise, principle applies here)
_run_external_case wants to be two things:
- create a module returning info on it with a cleanup method
- use that info to run the test
whats different between rmtempdir and shutil. rmtree( ignore_ errors= True) ?
rather than using a list of sample texts, consider subclasses that set _sample_text - this is closer to using multiply_tests, and gives cleaner info about things that go wrong as well as simpler test code (no loops needed). Or you could even just use testscenarios and multiply_tests.
I agree about better fidelity on the testing; consider an RE Matcher, or something along those lines.
Please file a bug about this - it seems unrelated to unicode:
# GZ 2010-05-25: Seems this breaks testtools internals.
Rather than assertIn, the DocTestMatches might be closer fidelity, or make an RE or similar one.
Only one line of VWS here please (PEP8 :P)
397 +import traceback
398 +
399 +
400 +import testtools
TestGetSourceEn coding would benefit from being able to create a module as per the split up run helper suggested above.
And to come back to utils - it really likes like we want an encodings or stringencodings or something module. If thats all that is in utils at the moment, just rename utils; otherwise put your new stuff in a different file. Or whatever feels right.
This looks pretty good; I'd be happy to land it with the above things done - its nearly *there*.
Thanks again,
Rob