[py-dev] controlling assertions and difflib
holger krekel
holger at merlinux.eu
Sat Oct 2 19:33:43 CEST 2010
Hey Floris,
On Fri, Oct 01, 2010 at 00:23 +0100, Floris Bruynooghe wrote:
> On 29 September 2010 14:28, holger krekel <holger at 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 at codespeak.net
> http://codespeak.net/mailman/listinfo/py-dev
--
More information about the Pytest-dev
mailing list