Hey Floris, On Fri, Oct 01, 2010 at 00:23 +0100, Floris Bruynooghe wrote: > On 29 September 2010 14:28, holger krekel <hol...@merlinux.eu> wrote: > > On Wed, Sep 29, 2010 at 00:12 +0100, Floris Bruynooghe wrote: > >> ______________________________ 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! > > I've committed a cleaned-up version of this now.
Great, thanks. It's now merged to py-trunk! > >> 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. > > Sounds like a good idea. Do you think there's place for a > advanced-no-builtin-plugin option in here, so that the builtin hook > will not run any code? Otherwise a bug in the builtin customisation > hook would completely stop this from being useful. I am not so afraid but we can do it. > > 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. > > Do you mean something like the attached diff does? In that case I'm > sort of tempted to remove the customise_assert() function I've added > there and just expose the DebugInterpreter so that you can modify the > attribute directly. I also considered the > customise_assert(binrepr_hook, config) signature for this, not sure > which would be best. I think i meant something different. Please have a look into this changeset which i just added: http://bitbucket.org/hpk42/py-trunk/changeset/64962794201b does this make sense to you? Also did a subsequent commit to rename to pytest_assertrepr_compare which now can get a config object so we can now introduce variations controled by config values. best, holger > > > Regards > Floris > > > -- > Debian GNU/Linux -- The Power of Freedom > www.debian.org | www.gnu.org | www.kernel.org > diff --git a/py/__init__.py b/py/__init__.py > --- a/py/__init__.py > +++ b/py/__init__.py > @@ -99,6 +99,7 @@ py.apipkg.initpkg(__name__, dict( > '_AssertionError' : '._code.assertion:AssertionError', > '_reinterpret_old' : '._code.assertion:reinterpret_old', > '_reinterpret' : '._code.assertion:reinterpret', > + 'customise_assert' : '._code._assertionnew:customise_assert', > }, > > # backports and additions of builtins > diff --git a/py/_code/_assertionnew.py b/py/_code/_assertionnew.py > --- a/py/_code/_assertionnew.py > +++ b/py/_code/_assertionnew.py > @@ -107,17 +107,21 @@ unary_map = { > } > > > +def customise_assert(config): > + """Customise the DebugInterpreter with pytest config""" > + DebugInterpreter.pytest_config = config > + > + > class DebugInterpreter(ast.NodeVisitor): > """Interpret AST nodes to gleam useful debugging information. > > The _pytesthook attribute is used to detect if the py.test > pytest_assertion plugin is loaded and if so call it's hooks. > """ > + pytest_config = None > > def __init__(self, frame): > self.frame = frame > - self._pytesthook = getattr(py.builtin.builtins.AssertionError, > - "_pytesthook") > > def generic_visit(self, node): > # Fallback when we don't have a special implementation. > @@ -183,9 +191,10 @@ class DebugInterpreter(ast.NodeVisitor): > if not result: > break > left_explanation, left_result = next_explanation, next_result > - if self._pytesthook: > - hook_result = self._pytesthook.pytest_assert_binrepr( > - op=op_symbol, left=left_result, right=next_result) > + if self.pytest_config: > + hook_result = self.pytest_config.hook.pytest_assert_binrepr( > + op=op_symbol, left=left_result, right=next_result, > + config=self.pytest_config) > if hook_result: > for new_expl in hook_result: > if new_expl: > diff --git a/py/_plugin/hookspec.py b/py/_plugin/hookspec.py > --- a/py/_plugin/hookspec.py > +++ b/py/_plugin/hookspec.py > @@ -127,7 +127,7 @@ def pytest_sessionfinish(session, exitst > # hooks for customising the assert methods > # ------------------------------------------------------------------------- > > -def pytest_assert_binrepr(op, left, right): > +def pytest_assert_binrepr(op, left, right, config): > """Customise explanation for binary operators > > Return None or an empty list for no custom explanation, otherwise > diff --git a/py/_plugin/pytest_assertion.py b/py/_plugin/pytest_assertion.py > --- a/py/_plugin/pytest_assertion.py > +++ b/py/_plugin/pytest_assertion.py > @@ -16,7 +16,7 @@ def pytest_configure(config): > warn_about_missing_assertion() > config._oldassertion = py.builtin.builtins.AssertionError > py.builtin.builtins.AssertionError = py.code._AssertionError > - py.builtin.builtins.AssertionError._pytesthook = config.hook > + py.code.customise_assert(config) > > def pytest_unconfigure(config): > if hasattr(config, '_oldassertion'): > _______________________________________________ > py-dev mailing list > py-dev@codespeak.net > http://codespeak.net/mailman/listinfo/py-dev -- _______________________________________________ py-dev mailing list py-dev@codespeak.net http://codespeak.net/mailman/listinfo/py-dev