"reprlib" --- もう一つの "repr()" の実装
****************************************

**ソースコード:** Lib/reprlib.py

======================================================================

"reprlib" モジュールは、結果の文字列のサイズに対する制限付きでオブジェ
クト表現を生成するための手段を提供します。これは Python デバッガの中で
使用されており、他の文脈でも同様に役に立つかもしれません。

このモジュールはクラスとインスタンス、それに関数を提供します:

class reprlib.Repr(*, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, maxother=30, fillvalue='...', indent=None)

   組み込み関数 "repr()" に似た関数を実装するために役に立つフォーマッ
   ト用サービスを提供します。 過度に長い表現を作り出さないようにするた
   めの大きさの制限をオブジェクト型ごとに設定できます。

   The keyword arguments of the constructor can be used as a shortcut
   to set the attributes of the "Repr" instance. Which means that the
   following initialization:

      aRepr = reprlib.Repr(maxlevel=3)

   は、次のコードと等しいです:

      aRepr = reprlib.Repr()
      aRepr.maxlevel = 3

   See section Repr Objects for more information about "Repr"
   attributes.

   バージョン 3.12 で変更: Allow attributes to be set via keyword
   arguments.

reprlib.aRepr

   これは下で説明される "repr()" 関数を提供するために使われる "Repr"
   のインスタンスです。このオブジェクトの属性を変更すると、 "repr()"
   と Python デバッガが使うサイズ制限に影響します。

reprlib.repr(obj)

   これは "aRepr" の "repr()" メソッドです。同じ名前の組み込み関数が返
   す文字列と似ていますが、最大サイズに制限のある文字列を返します。

In addition to size-limiting tools, the module also provides a
decorator for detecting recursive calls to "__repr__()" and
substituting a placeholder string instead.

@reprlib.recursive_repr(fillvalue='...')

   Decorator for "__repr__()" methods to detect recursive calls within
   the same thread.  If a recursive call is made, the *fillvalue* is
   returned, otherwise, the usual "__repr__()" call is made.  For
   example:

      >>> from reprlib import recursive_repr
      >>> class MyList(list):
      ...     @recursive_repr()
      ...     def __repr__(self):
      ...         return '<' + '|'.join(map(repr, self)) + '>'
      ...
      >>> m = MyList('abc')
      >>> m.append(m)
      >>> m.append('x')
      >>> print(m)
      <'a'|'b'|'c'|...|'x'>

   Added in version 3.2.


Reprオブジェクト
================

"Repr" インスタンスはオブジェクト型毎に表現する文字列のサイズを制限す
るために使えるいくつかの属性と、特定のオブジェクト型をフォーマットする
メソッドを提供します。

Repr.fillvalue

   This string is displayed for recursive references. It defaults to
   "...".

   Added in version 3.11.

Repr.maxlevel

   再帰的な表現を作る場合の深さ制限。デフォルトは "6" です。

Repr.maxdict
Repr.maxlist
Repr.maxtuple
Repr.maxset
Repr.maxfrozenset
Repr.maxdeque
Repr.maxarray

   指定されたオブジェクト型に対するエントリ表現の数についての制限。
   "maxdict" に対するデフォルトは "4" で、 "maxarray" は "5" 、その他
   に対しては "6" です。

Repr.maxlong

   整数の表現のおける文字数の最大値。中央の数字が抜け落ちます。デフォ
   ルトは "40" です。

Repr.maxstring

   文字列の表現における文字数の制限。文字列の"通常の"表現は文字の「元
   」として使われることに注意してください。表現にエスケープシーケンス
   が必要とされる場合、表現が短縮されるときにこれらのエスケープシーケ
   ンスの形式は崩れます。デフォルトは "30" です。

Repr.maxother

   この制限は "Repr" オブジェクトに利用できる特定のフォーマットメソッ
   ドがないオブジェクト型のサイズをコントロールするために使われます。
   "maxstring" と同じようなやり方で適用されます。デフォルトは "20" で
   す。

Repr.indent

   If this attribute is set to "None" (the default), the output is
   formatted with no line breaks or indentation, like the standard
   "repr()". For example:

      >>> example = [
      ...     1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']
      >>> import reprlib
      >>> aRepr = reprlib.Repr()
      >>> print(aRepr.repr(example))
      [1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']

   If "indent" is set to a string, each recursion level is placed on
   its own line, indented by that string:

      >>> aRepr.indent = '-->'
      >>> print(aRepr.repr(example))
      [
      -->1,
      -->'spam',
      -->{
      -->-->'a': 2,
      -->-->'b': 'spam eggs',
      -->-->'c': {
      -->-->-->3: 4.5,
      -->-->-->6: [],
      -->-->},
      -->},
      -->'ham',
      ]

   Setting "indent" to a positive integer value behaves as if it was
   set to a string with that number of spaces:

      >>> aRepr.indent = 4
      >>> print(aRepr.repr(example))
      [
          1,
          'spam',
          {
              'a': 2,
              'b': 'spam eggs',
              'c': {
                  3: 4.5,
                  6: [],
              },
          },
          'ham',
      ]

   Added in version 3.12.

Repr.repr(obj)

   このインスタンスで設定されたフォーマットを使う、組み込み "repr()"
   と等価なもの。

Repr.repr1(obj, level)

   "repr()" が使う再帰的な実装。 *obj* の型を使ってどのフォーマットメ
   ソッドを呼び出すかを決定し、それに *obj* と *level* を渡します。 再
   帰呼び出しにおいて *level* の値に対して "level - 1" を与える再帰的
   なフォーマットを実行するために、型に固有のメソッドは "repr1()" を呼
   び出します。

Repr.repr_TYPE(obj, level)

   型名に基づく名前をもつメソッドとして、特定の型に対するフォーマット
   メソッドは実装されます。メソッド名では、 **TYPE** は
   "'_'.join(type(obj).__name__.split())" に置き換えられます。これらの
   メソッドへのディスパッチは "repr1()" によって処理されます。再帰的に
   値をフォーマットする必要がある型固有のメソッドは、
   "self.repr1(subobj, level - 1)" を呼び出します。


Reprオブジェクトをサブクラス化する
==================================

The use of dynamic dispatching by "Repr.repr1()" allows subclasses of
"Repr" to add support for additional built-in object types or to
modify the handling of types already supported. This example shows how
special support for file objects could be added:

   import reprlib
   import sys

   class MyRepr(reprlib.Repr):

       def repr_TextIOWrapper(self, obj, level):
           if obj.name in {'<stdin>', '<stdout>', '<stderr>'}:
               return obj.name
           return repr(obj)

   aRepr = MyRepr()
   print(aRepr.repr(sys.stdin))         # prints '<stdin>'

   <stdin>
