Coverage for /pythoncovmergedfiles/medio/medio/src/pydantic/pydantic/_internal/_repr.py: 31%
62 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-27 07:38 +0000
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-27 07:38 +0000
1"""
2Tools to provide pretty/human-readable display of objects.
3"""
4from __future__ import annotations as _annotations
6import types
7import typing
8from typing import Any
10import typing_extensions
12from . import _typing_extra
14if typing.TYPE_CHECKING:
15 ReprArgs: typing_extensions.TypeAlias = 'typing.Iterable[tuple[str | None, Any]]'
16 RichReprResult: typing_extensions.TypeAlias = (
17 'typing.Iterable[Any | tuple[Any] | tuple[str, Any] | tuple[str, Any, Any]]'
18 )
21class PlainRepr(str):
22 """
23 String class where repr doesn't include quotes. Useful with Representation when you want to return a string
24 representation of something that is valid (or pseudo-valid) python.
25 """
27 def __repr__(self) -> str:
28 return str(self)
31class Representation:
32 # Mixin to provide `__str__`, `__repr__`, and `__pretty__` and `__rich_repr__` methods.
33 # `__pretty__` is used by [devtools](https://python-devtools.helpmanual.io/).
34 # `__rich_repr__` is used by [rich](https://rich.readthedocs.io/en/stable/pretty.html).
35 # (this is not a docstring to avoid adding a docstring to classes which inherit from Representation)
37 # we don't want to use a type annotation here as it can break get_type_hints
38 __slots__ = tuple() # type: typing.Collection[str]
40 def __repr_args__(self) -> ReprArgs:
41 """
42 Returns the attributes to show in __str__, __repr__, and __pretty__ this is generally overridden.
44 Can either return:
45 * name - value pairs, e.g.: `[('foo_name', 'foo'), ('bar_name', ['b', 'a', 'r'])]`
46 * or, just values, e.g.: `[(None, 'foo'), (None, ['b', 'a', 'r'])]`
47 """
48 attrs_names = self.__slots__
49 if not attrs_names and hasattr(self, '__dict__'):
50 attrs_names = self.__dict__.keys()
51 attrs = ((s, getattr(self, s)) for s in attrs_names)
52 return [(a, v) for a, v in attrs if v is not None]
54 def __repr_name__(self) -> str:
55 """
56 Name of the instance's class, used in __repr__.
57 """
58 return self.__class__.__name__
60 def __repr_str__(self, join_str: str) -> str:
61 return join_str.join(repr(v) if a is None else f'{a}={v!r}' for a, v in self.__repr_args__())
63 def __pretty__(self, fmt: typing.Callable[[Any], Any], **kwargs: Any) -> typing.Generator[Any, None, None]:
64 """
65 Used by devtools (https://python-devtools.helpmanual.io/) to provide a human-readable representations of objects
66 """
67 yield self.__repr_name__() + '('
68 yield 1
69 for name, value in self.__repr_args__():
70 if name is not None:
71 yield name + '='
72 yield fmt(value)
73 yield ','
74 yield 0
75 yield -1
76 yield ')'
78 def __str__(self) -> str:
79 return self.__repr_str__(' ')
81 def __repr__(self) -> str:
82 return f'{self.__repr_name__()}({self.__repr_str__(", ")})'
84 def __rich_repr__(self) -> RichReprResult:
85 """Get fields for Rich library"""
86 for name, field_repr in self.__repr_args__():
87 if name is None:
88 yield field_repr
89 else:
90 yield name, field_repr
93def display_as_type(obj: Any) -> str:
94 """
95 Pretty representation of a type, should be as close as possible to the original type definition string.
97 Takes some logic from `typing._type_repr`.
98 """
99 if isinstance(obj, types.FunctionType):
100 return obj.__name__
101 elif obj is ...:
102 return '...'
103 elif isinstance(obj, Representation):
104 return repr(obj)
106 if not isinstance(obj, (_typing_extra.typing_base, _typing_extra.WithArgsTypes, type)):
107 obj = obj.__class__
109 if _typing_extra.origin_is_union(typing_extensions.get_origin(obj)):
110 args = ', '.join(map(display_as_type, typing_extensions.get_args(obj)))
111 return f'Union[{args}]'
112 elif isinstance(obj, _typing_extra.WithArgsTypes):
113 args = ', '.join(map(display_as_type, typing_extensions.get_args(obj)))
114 return f'{obj.__qualname__}[{args}]'
115 elif isinstance(obj, type):
116 return obj.__qualname__
117 else:
118 return repr(obj).replace('typing.', '').replace('typing_extensions.', '')