• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1:mod:`!reprlib` --- Alternate :func:`repr` implementation
2=========================================================
3
4.. module:: reprlib
5   :synopsis: Alternate repr() implementation with size limits.
6
7.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
8
9**Source code:** :source:`Lib/reprlib.py`
10
11--------------
12
13The :mod:`!reprlib` module provides a means for producing object representations
14with limits on the size of the resulting strings. This is used in the Python
15debugger and may be useful in other contexts as well.
16
17This module provides a class, an instance, and a function:
18
19
20.. class:: Repr(*, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, \
21                maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, \
22                maxother=30, fillvalue="...", indent=None)
23
24   Class which provides formatting services useful in implementing functions
25   similar to the built-in :func:`repr`; size limits for  different object types
26   are added to avoid the generation of representations which are excessively long.
27
28   The keyword arguments of the constructor can be used as a shortcut to set the
29   attributes of the :class:`Repr` instance. Which means that the following
30   initialization::
31
32      aRepr = reprlib.Repr(maxlevel=3)
33
34   Is equivalent to::
35
36      aRepr = reprlib.Repr()
37      aRepr.maxlevel = 3
38
39   See section `Repr Objects`_ for more information about :class:`Repr`
40   attributes.
41
42   .. versionchanged:: 3.12
43      Allow attributes to be set via keyword arguments.
44
45
46.. data:: aRepr
47
48   This is an instance of :class:`Repr` which is used to provide the
49   :func:`.repr` function described below.  Changing the attributes of this
50   object will affect the size limits used by :func:`.repr` and the Python
51   debugger.
52
53
54.. function:: repr(obj)
55
56   This is the :meth:`~Repr.repr` method of ``aRepr``.  It returns a string
57   similar to that returned by the built-in function of the same name, but with
58   limits on most sizes.
59
60In addition to size-limiting tools, the module also provides a decorator for
61detecting recursive calls to :meth:`~object.__repr__` and substituting a
62placeholder string instead.
63
64
65.. index:: single: ...; placeholder
66
67.. decorator:: recursive_repr(fillvalue="...")
68
69   Decorator for :meth:`~object.__repr__` methods to detect recursive calls within the
70   same thread.  If a recursive call is made, the *fillvalue* is returned,
71   otherwise, the usual :meth:`!__repr__` call is made.  For example:
72
73   .. doctest::
74
75      >>> from reprlib import recursive_repr
76      >>> class MyList(list):
77      ...     @recursive_repr()
78      ...     def __repr__(self):
79      ...         return '<' + '|'.join(map(repr, self)) + '>'
80      ...
81      >>> m = MyList('abc')
82      >>> m.append(m)
83      >>> m.append('x')
84      >>> print(m)
85      <'a'|'b'|'c'|...|'x'>
86
87   .. versionadded:: 3.2
88
89
90.. _repr-objects:
91
92Repr Objects
93------------
94
95:class:`Repr` instances provide several attributes which can be used to provide
96size limits for the representations of different object types,  and methods
97which format specific object types.
98
99
100.. attribute:: Repr.fillvalue
101
102   This string is displayed for recursive references. It defaults to
103   ``...``.
104
105   .. versionadded:: 3.11
106
107
108.. attribute:: Repr.maxlevel
109
110   Depth limit on the creation of recursive representations.  The default is ``6``.
111
112
113.. attribute:: Repr.maxdict
114               Repr.maxlist
115               Repr.maxtuple
116               Repr.maxset
117               Repr.maxfrozenset
118               Repr.maxdeque
119               Repr.maxarray
120
121   Limits on the number of entries represented for the named object type.  The
122   default is ``4`` for :attr:`maxdict`, ``5`` for :attr:`maxarray`, and  ``6`` for
123   the others.
124
125
126.. attribute:: Repr.maxlong
127
128   Maximum number of characters in the representation for an integer.  Digits
129   are dropped from the middle.  The default is ``40``.
130
131
132.. attribute:: Repr.maxstring
133
134   Limit on the number of characters in the representation of the string.  Note
135   that the "normal" representation of the string is used as the character source:
136   if escape sequences are needed in the representation, these may be mangled when
137   the representation is shortened.  The default is ``30``.
138
139
140.. attribute:: Repr.maxother
141
142   This limit is used to control the size of object types for which no specific
143   formatting method is available on the :class:`Repr` object. It is applied in a
144   similar manner as :attr:`maxstring`.  The default is ``20``.
145
146
147.. attribute:: Repr.indent
148
149   If this attribute is set to ``None`` (the default), the output is formatted
150   with no line breaks or indentation, like the standard :func:`repr`.
151   For example:
152
153   .. doctest:: indent
154
155      >>> example = [
156      ...     1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']
157      >>> import reprlib
158      >>> aRepr = reprlib.Repr()
159      >>> print(aRepr.repr(example))
160      [1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']
161
162   If :attr:`~Repr.indent` is set to a string, each recursion level
163   is placed on its own line, indented by that string:
164
165   .. doctest:: indent
166
167      >>> aRepr.indent = '-->'
168      >>> print(aRepr.repr(example))
169      [
170      -->1,
171      -->'spam',
172      -->{
173      -->-->'a': 2,
174      -->-->'b': 'spam eggs',
175      -->-->'c': {
176      -->-->-->3: 4.5,
177      -->-->-->6: [],
178      -->-->},
179      -->},
180      -->'ham',
181      ]
182
183   Setting :attr:`~Repr.indent` to a positive integer value behaves as if it
184   was set to a string with that number of spaces:
185
186   .. doctest:: indent
187
188      >>> aRepr.indent = 4
189      >>> print(aRepr.repr(example))
190      [
191          1,
192          'spam',
193          {
194              'a': 2,
195              'b': 'spam eggs',
196              'c': {
197                  3: 4.5,
198                  6: [],
199              },
200          },
201          'ham',
202      ]
203
204   .. versionadded:: 3.12
205
206
207.. method:: Repr.repr(obj)
208
209   The equivalent to the built-in :func:`repr` that uses the formatting imposed by
210   the instance.
211
212
213.. method:: Repr.repr1(obj, level)
214
215   Recursive implementation used by :meth:`.repr`.  This uses the type of *obj* to
216   determine which formatting method to call, passing it *obj* and *level*.  The
217   type-specific methods should call :meth:`repr1` to perform recursive formatting,
218   with ``level - 1`` for the value of *level* in the recursive  call.
219
220
221.. method:: Repr.repr_TYPE(obj, level)
222   :noindex:
223
224   Formatting methods for specific types are implemented as methods with a name
225   based on the type name.  In the method name, **TYPE** is replaced by
226   ``'_'.join(type(obj).__name__.split())``. Dispatch to these methods is
227   handled by :meth:`repr1`. Type-specific methods which need to recursively
228   format a value should call ``self.repr1(subobj, level - 1)``.
229
230
231.. _subclassing-reprs:
232
233Subclassing Repr Objects
234------------------------
235
236The use of dynamic dispatching by :meth:`Repr.repr1` allows subclasses of
237:class:`Repr` to add support for additional built-in object types or to modify
238the handling of types already supported. This example shows how special support
239for file objects could be added:
240
241.. testcode::
242
243   import reprlib
244   import sys
245
246   class MyRepr(reprlib.Repr):
247
248       def repr_TextIOWrapper(self, obj, level):
249           if obj.name in {'<stdin>', '<stdout>', '<stderr>'}:
250               return obj.name
251           return repr(obj)
252
253   aRepr = MyRepr()
254   print(aRepr.repr(sys.stdin))         # prints '<stdin>'
255
256.. testoutput::
257
258   <stdin>
259