Source code for xdoctest.utils.util_mixins

"""
Port of NiceRepr from ubelt.util_mixins
"""

from __future__ import annotations
import warnings


[docs] class NiceRepr: """ Defines `__str__` and `__repr__` in terms of `__nice__` function Classes that inherit `NiceRepr` must define `__nice__` Example: >>> class Foo(NiceRepr): ... pass >>> class Bar(NiceRepr): ... def __nice__(self): ... return 'info' >>> foo = Foo() >>> bar = Bar() >>> assert str(bar) == '<Bar(info)>' >>> assert repr(bar).startswith('<Bar(info) at ') >>> assert 'object at' in str(foo) >>> assert 'object at' in repr(foo) """ def __nice__(self) -> str: """ Returns: str """ if hasattr(self, '__len__'): # It is a common pattern for objects to use __len__ in __nice__ # As a convenience we define a default __nice__ for these objects # return str(len(self)) # hasattr doesn't narrow to Sized for ty, so call __len__ directly return str(self.__len__()) # type: ignore else: # In all other cases force the subclass to overload __nice__ raise NotImplementedError( 'Define the __nice__ method for {!r}'.format(self.__class__) ) def __repr__(self) -> str: """ Returns: str """ try: nice = self.__nice__() classname = self.__class__.__name__ return '<{0}({1}) at {2}>'.format(classname, nice, hex(id(self))) except Exception as ex: warnings.warn(str(ex), category=RuntimeWarning) return object.__repr__(self) def __str__(self) -> str: """ Returns: str """ try: classname = self.__class__.__name__ nice = self.__nice__() return '<{0}({1})>'.format(classname, nice) except Exception as ex: warnings.warn(str(ex), category=RuntimeWarning) return object.__repr__(self)