refactor: simplify bound method representation (#12492)
Co-authored-by: Sviatoslav Sydorenko <webknjaz@redhat.com> Co-authored-by: Farbod Ahmadian <farbod@datachef.com>
This commit is contained in:
parent
9947ec3ad1
commit
34e28295a7
1
AUTHORS
1
AUTHORS
|
@ -149,6 +149,7 @@ Evgeny Seliverstov
|
||||||
Fabian Sturm
|
Fabian Sturm
|
||||||
Fabien Zarifian
|
Fabien Zarifian
|
||||||
Fabio Zadrozny
|
Fabio Zadrozny
|
||||||
|
Farbod Ahmadian
|
||||||
faph
|
faph
|
||||||
Felix Hofstätter
|
Felix Hofstätter
|
||||||
Felix Nieuwenhuizen
|
Felix Nieuwenhuizen
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
The readability of assertion introspection of bound methods has been enhanced
|
||||||
|
-- by :user:`farbodahm`, :user:`webknjaz`, :user:`obestwalter`, :user:`flub`
|
||||||
|
and :user:`glyphack`.
|
||||||
|
|
||||||
|
Earlier, it was like:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
=================================== FAILURES ===================================
|
||||||
|
_____________________________________ test _____________________________________
|
||||||
|
|
||||||
|
def test():
|
||||||
|
> assert Help().fun() == 2
|
||||||
|
E assert 1 == 2
|
||||||
|
E + where 1 = <bound method Help.fun of <example.Help instance at 0x256a830>>()
|
||||||
|
E + where <bound method Help.fun of <example.Help instance at 0x256a830>> = <example.Help instance at 0x256a830>.fun
|
||||||
|
E + where <example.Help instance at 0x256a830> = Help()
|
||||||
|
|
||||||
|
example.py:7: AssertionError
|
||||||
|
=========================== 1 failed in 0.03 seconds ===========================
|
||||||
|
|
||||||
|
|
||||||
|
And now it's like:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
=================================== FAILURES ===================================
|
||||||
|
_____________________________________ test _____________________________________
|
||||||
|
|
||||||
|
def test():
|
||||||
|
> assert Help().fun() == 2
|
||||||
|
E assert 1 == 2
|
||||||
|
E + where 1 = fun()
|
||||||
|
E + where fun = <test_local.Help object at 0x1074be230>.fun
|
||||||
|
E + where <test_local.Help object at 0x1074be230> = Help()
|
||||||
|
|
||||||
|
test_local.py:13: AssertionError
|
||||||
|
=========================== 1 failed in 0.03 seconds ===========================
|
|
@ -60,7 +60,6 @@ class SafeRepr(reprlib.Repr):
|
||||||
s = ascii(x)
|
s = ascii(x)
|
||||||
else:
|
else:
|
||||||
s = super().repr(x)
|
s = super().repr(x)
|
||||||
|
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
raise
|
raise
|
||||||
except BaseException as exc:
|
except BaseException as exc:
|
||||||
|
|
|
@ -417,6 +417,10 @@ def _saferepr(obj: object) -> str:
|
||||||
sequences, especially '\n{' and '\n}' are likely to be present in
|
sequences, especially '\n{' and '\n}' are likely to be present in
|
||||||
JSON reprs.
|
JSON reprs.
|
||||||
"""
|
"""
|
||||||
|
if isinstance(obj, types.MethodType):
|
||||||
|
# for bound methods, skip redundant <bound method ...> information
|
||||||
|
return obj.__name__
|
||||||
|
|
||||||
maxsize = _get_maxsize_for_saferepr(util._config)
|
maxsize = _get_maxsize_for_saferepr(util._config)
|
||||||
return saferepr(obj, maxsize=maxsize).replace("\n", "\\n")
|
return saferepr(obj, maxsize=maxsize).replace("\n", "\\n")
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import marshal
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import py_compile
|
import py_compile
|
||||||
|
import re
|
||||||
import stat
|
import stat
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
@ -24,6 +25,7 @@ from _pytest._io.saferepr import DEFAULT_REPR_MAX_SIZE
|
||||||
from _pytest.assertion import util
|
from _pytest.assertion import util
|
||||||
from _pytest.assertion.rewrite import _get_assertion_exprs
|
from _pytest.assertion.rewrite import _get_assertion_exprs
|
||||||
from _pytest.assertion.rewrite import _get_maxsize_for_saferepr
|
from _pytest.assertion.rewrite import _get_maxsize_for_saferepr
|
||||||
|
from _pytest.assertion.rewrite import _saferepr
|
||||||
from _pytest.assertion.rewrite import AssertionRewritingHook
|
from _pytest.assertion.rewrite import AssertionRewritingHook
|
||||||
from _pytest.assertion.rewrite import get_cache_dir
|
from _pytest.assertion.rewrite import get_cache_dir
|
||||||
from _pytest.assertion.rewrite import PYC_TAIL
|
from _pytest.assertion.rewrite import PYC_TAIL
|
||||||
|
@ -2036,7 +2038,9 @@ class TestPyCacheDir:
|
||||||
assert test_foo_pyc.is_file()
|
assert test_foo_pyc.is_file()
|
||||||
|
|
||||||
# normal file: not touched by pytest, normal cache tag
|
# normal file: not touched by pytest, normal cache tag
|
||||||
bar_init_pyc = get_cache_dir(bar_init) / f"__init__.{sys.implementation.cache_tag}.pyc"
|
bar_init_pyc = (
|
||||||
|
get_cache_dir(bar_init) / f"__init__.{sys.implementation.cache_tag}.pyc"
|
||||||
|
)
|
||||||
assert bar_init_pyc.is_file()
|
assert bar_init_pyc.is_file()
|
||||||
|
|
||||||
|
|
||||||
|
@ -2103,3 +2107,26 @@ class TestIssue11140:
|
||||||
)
|
)
|
||||||
result = pytester.runpytest()
|
result = pytester.runpytest()
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestSafereprUnbounded:
|
||||||
|
class Help:
|
||||||
|
def bound_method(self): # pragma: no cover
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_saferepr_bound_method(self):
|
||||||
|
"""saferepr() of a bound method should show only the method name"""
|
||||||
|
assert _saferepr(self.Help().bound_method) == "bound_method"
|
||||||
|
|
||||||
|
def test_saferepr_unbounded(self):
|
||||||
|
"""saferepr() of an unbound method should still show the full information"""
|
||||||
|
obj = self.Help()
|
||||||
|
# using id() to fetch memory address fails on different platforms
|
||||||
|
pattern = re.compile(
|
||||||
|
rf"<{Path(__file__).stem}.{self.__class__.__name__}.Help object at 0x[0-9a-fA-F]*>",
|
||||||
|
)
|
||||||
|
assert pattern.match(_saferepr(obj))
|
||||||
|
assert (
|
||||||
|
_saferepr(self.Help)
|
||||||
|
== f"<class '{Path(__file__).stem}.{self.__class__.__name__}.Help'>"
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue