| | |
| | """This module defines the :class:`NiceRepr` mixin class, which defines a |
| | ``__repr__`` and ``__str__`` method that only depend on a custom ``__nice__`` |
| | method, which you must define. This means you only have to overload one |
| | function instead of two. Furthermore, if the object defines a ``__len__`` |
| | method, then the ``__nice__`` method defaults to something sensible, otherwise |
| | it is treated as abstract and raises ``NotImplementedError``. |
| | |
| | To use simply have your object inherit from :class:`NiceRepr` |
| | (multi-inheritance should be ok). |
| | |
| | This code was copied from the ubelt library: https://github.com/Erotemic/ubelt |
| | |
| | Example: |
| | >>> # Objects that define __nice__ have a default __str__ and __repr__ |
| | >>> class Student(NiceRepr): |
| | ... def __init__(self, name): |
| | ... self.name = name |
| | ... def __nice__(self): |
| | ... return self.name |
| | >>> s1 = Student('Alice') |
| | >>> s2 = Student('Bob') |
| | >>> print(f's1 = {s1}') |
| | >>> print(f's2 = {s2}') |
| | s1 = <Student(Alice)> |
| | s2 = <Student(Bob)> |
| | |
| | Example: |
| | >>> # Objects that define __len__ have a default __nice__ |
| | >>> class Group(NiceRepr): |
| | ... def __init__(self, data): |
| | ... self.data = data |
| | ... def __len__(self): |
| | ... return len(self.data) |
| | >>> g = Group([1, 2, 3]) |
| | >>> print(f'g = {g}') |
| | g = <Group(3)> |
| | """ |
| | import warnings |
| |
|
| |
|
| | class NiceRepr: |
| | """Inherit from this class and define ``__nice__`` to "nicely" print your |
| | objects. |
| | |
| | Defines ``__str__`` and ``__repr__`` in terms of ``__nice__`` function |
| | Classes that inherit from :class:`NiceRepr` should redefine ``__nice__``. |
| | If the inheriting class has a ``__len__``, method then the default |
| | ``__nice__`` method will return its length. |
| | |
| | Example: |
| | >>> class Foo(NiceRepr): |
| | ... def __nice__(self): |
| | ... return 'info' |
| | >>> foo = Foo() |
| | >>> assert str(foo) == '<Foo(info)>' |
| | >>> assert repr(foo).startswith('<Foo(info) at ') |
| | |
| | Example: |
| | >>> class Bar(NiceRepr): |
| | ... pass |
| | >>> bar = Bar() |
| | >>> import pytest |
| | >>> with pytest.warns(None) as record: |
| | >>> assert 'object at' in str(bar) |
| | >>> assert 'object at' in repr(bar) |
| | |
| | Example: |
| | >>> class Baz(NiceRepr): |
| | ... def __len__(self): |
| | ... return 5 |
| | >>> baz = Baz() |
| | >>> assert str(baz) == '<Baz(5)>' |
| | """ |
| |
|
| | def __nice__(self): |
| | """str: a "nice" summary string describing this module""" |
| | if hasattr(self, '__len__'): |
| | |
| | |
| | return str(len(self)) |
| | else: |
| | |
| | raise NotImplementedError( |
| | f'Define the __nice__ method for {self.__class__!r}') |
| |
|
| | def __repr__(self): |
| | """str: the string of the module""" |
| | try: |
| | nice = self.__nice__() |
| | classname = self.__class__.__name__ |
| | return f'<{classname}({nice}) at {hex(id(self))}>' |
| | except NotImplementedError as ex: |
| | warnings.warn(str(ex), category=RuntimeWarning) |
| | return object.__repr__(self) |
| |
|
| | def __str__(self): |
| | """str: the string of the module""" |
| | try: |
| | classname = self.__class__.__name__ |
| | nice = self.__nice__() |
| | return f'<{classname}({nice})>' |
| | except NotImplementedError as ex: |
| | warnings.warn(str(ex), category=RuntimeWarning) |
| | return object.__repr__(self) |
| |
|