Hello

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.


>> 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 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.


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

Reply via email to