Hey Floris, all,
On Wed, Sep 29, 2010 at 00:12 +0100, Floris Bruynooghe wrote:
> As Holger pointed out the following test hangs py.test in my assertion
> clone, it triggers a bug in difflib:
>
> def test_hang_in_diff():
> x = "1\n" * 1000 + "abc" + "2\n" * 1000
> y = "1\n" * 1000 + "def" + "2\n" * 1000
> assert x == y
>
> It seems difflib can not deal with the 1000 identical trailing items.
>
> It fails with a TypeError somewhere very deep in a recursion or, when
> consuming the generator inside a list comprehension, just completely
> hangs. Also before failing it considers all the 2s as different too.
> Rather then debugging difflib (there are several possible bugs on
> bugs.python.org which might relate to this) I've come up with some
> code that does produce this instead:
>
> ______________________________ test_hang_in_diff
> _______________________________
> /tmp/sandbox/test_bugs.py:4: in test_hang_in_diff
> > assert x == y
> E assert '1\n1\n1\n1\n...n2\n2\n2\n2\n' ==
> '1\n1\n1\n1\n...n2\n2\n2\n2\n'
> E Skipping 1990 identical leading characters in diff
> E Skipping 1991 identical trailing characters in diff
> E 1
> E 1
> E 1
> E 1
> E 1
> E - abc2
> E + def2
> E 2
> E 2
> E 2
> E 2
looks good to me!
> Another solution is to use context_diff() which does not have this
> problem, but for some reason also considers all the trailing 2s to be
> different. Additionally context diff also doesn't provide the nice
> markers for differences inside a line which might be problematic as
> there's no guarantee there will be nice line endings in the input.
>
> In general I was already thinking of cutting off similar prefixes and
> suffixes before using ndiff, so this doesn't seem that bad to me. Do
> others think this is acceptable?
I find it acceptable. I guess we need to see how it works in RL projects.
Btw, I find it hard to guess how many people actually read this ML, despite
there being some >130 subscribers. But we'll get issue reports when things go
bad i guess :)
> This whole issue made me wonder if it should be possible to disable
> the pytest_assert_binrepr hook.
We could do a general "--assertmode=(choice)" with e.g.:
0: (no) don't do any assert reinterp (like --no-assert now)
1: (basic) do basic reinterpreation
2: (advanced) do basic reinterpretation + customizing hooks
and default to 2.
> It is probably sufficient to add an
> option which can be checked right at the start of the builtin
> pytest_assert_binrepr hook which will just return None or [] right
> away. But what is the best way to access the config setting from
> there? Is it fine to use py.test.config or should the setting be
> piggy-backed on some global again (e.g. change the current
> py.builtin.builtins.AssertionError._pytesthook into a ._pytestconfig)?
> Or maybe there's a more elegant solution for this that I'm unaware
> of?
I think there is an elegant solution. Instead of using "hook" in py/code/ we
use a generic "customize" function that is to be called. In
pytest_assertion.py's pytest_configure we write that function
such that it calls
pytest_assert_binrepr(config, ...)
hope that makes sense. If in doubt leave it to me and just use py.test.config.
I also want to introduce an "ini" style file for py.test, btw. hopefully
real soon now.
best,
holger
_______________________________________________
py-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/py-dev