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 py-dev@codespeak.net http://codespeak.net/mailman/listinfo/py-dev