]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149189: Revert "Modern defaults for `pprint` (#149190)" (#150249)
authorHugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Fri, 22 May 2026 20:22:03 +0000 (23:22 +0300)
committerGitHub <noreply@github.com>
Fri, 22 May 2026 20:22:03 +0000 (23:22 +0300)
14 files changed:
Doc/library/difflib.rst
Doc/library/pprint.rst
Doc/library/ssl.rst
Doc/library/unittest.mock.rst
Doc/tutorial/stdlib2.rst
Doc/whatsnew/3.15.rst
Lib/difflib.py
Lib/pprint.py
Lib/test/test_descrtut.py
Lib/test/test_pickle.py
Lib/test/test_pprint.py
Lib/test/test_stable_abi_ctypes.py
Lib/test/test_unittest/testmock/testhelpers.py
Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst [new file with mode: 0644]

index e5afa17441354181510358cc878230eab9f1f67e..8b812c173b595368a8d87392fb90c003958247c8 100644 (file)
@@ -728,18 +728,16 @@ Finally, we compare the two:
 
    >>> from pprint import pprint
    >>> pprint(result)
-   [
-       '    1. Beautiful is better than ugly.\n',
-       '-   2. Explicit is better than implicit.\n',
-       '-   3. Simple is better than complex.\n',
-       '+   3.   Simple is better than complex.\n',
-       '?     ++\n',
-       '-   4. Complex is better than complicated.\n',
-       '?            ^                     ---- ^\n',
-       '+   4. Complicated is better than complex.\n',
-       '?           ++++ ^                      ^\n',
-       '+   5. Flat is better than nested.\n',
-   ]
+   ['    1. Beautiful is better than ugly.\n',
+    '-   2. Explicit is better than implicit.\n',
+    '-   3. Simple is better than complex.\n',
+    '+   3.   Simple is better than complex.\n',
+    '?     ++\n',
+    '-   4. Complex is better than complicated.\n',
+    '?            ^                     ---- ^\n',
+    '+   4. Complicated is better than complex.\n',
+    '?           ++++ ^                      ^\n',
+    '+   5. Flat is better than nested.\n']
 
 As a single multi-line string it looks like this:
 
index d62ef1f4d1e6b17e98d5e2d1049921080180b312..4f043fbb3a46dff47bca303e2ff0861fd916026d 100644 (file)
@@ -17,7 +17,7 @@ objects which are not representable as Python literals.
 
 The formatted representation keeps objects on a single line if it can, and
 breaks them onto multiple lines if they don't fit within the allowed width,
-adjustable by the *width* parameter defaulting to 88 characters.
+adjustable by the *width* parameter defaulting to 80 characters.
 
 .. versionchanged:: 3.9
    Added support for pretty-printing :class:`types.SimpleNamespace`.
@@ -30,8 +30,9 @@ adjustable by the *width* parameter defaulting to 88 characters.
 Functions
 ---------
 
-.. function:: pp(object, stream=None, indent=4, width=88, depth=None, *, \
-                 compact=False, sort_dicts=False, underscore_numbers=False)
+.. function:: pp(object, stream=None, indent=1, width=80, depth=None, *, \
+                 compact=False, expand=False, sort_dicts=False, \
+                 underscore_numbers=False)
 
    Prints the formatted representation of *object*, followed by a newline.
    This function may be used in the interactive interpreter
@@ -66,11 +67,16 @@ Functions
    :param bool compact:
       Control the way long :term:`sequences <sequence>` are formatted.
       If ``False`` (the default),
+      each item of a sequence will be formatted on a separate line,
+      otherwise as many items as will fit within the *width*
+      will be formatted on each output line.
+      Incompatible with *expand*.
+
+   :param bool expand:
+      If ``True``,
       opening parentheses and brackets will be followed by a newline and the
       following content will be indented by one level, similar to
-      pretty-printed JSON.
-      If ``True``, as many items as will fit within the *width*
-      will be formatted on each output line.
+      pretty-printed JSON. Incompatible with *compact*.
 
    :param bool sort_dicts:
       If ``True``, dictionaries will be formatted with
@@ -85,25 +91,32 @@ Functions
    >>> import pprint
    >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
    >>> stuff.insert(0, stuff)
-   >>> pprint.pp(stuff, width=100)
-   [<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']
+   >>> pprint.pp(stuff)
+   [<Recursion on list with id=...>,
+    'spam',
+    'eggs',
+    'lumberjack',
+    'knights',
+    'ni']
 
    .. versionadded:: 3.8
 
 
-.. function:: pprint(object, stream=None, indent=4, width=88, depth=None, *, \
-                     compact=False, sort_dicts=True, underscore_numbers=False)
+.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
+                     compact=False, expand=False, sort_dicts=True, \
+                     underscore_numbers=False)
 
    Alias for :func:`~pprint.pp` with *sort_dicts* set to ``True`` by default,
    which would automatically sort the dictionaries' keys,
    you might want to use :func:`~pprint.pp` instead where it is ``False`` by default.
 
 
-.. function:: pformat(object, indent=4, width=88, depth=None, *, \
-                      compact=False, sort_dicts=True, underscore_numbers=False)
+.. function:: pformat(object, indent=1, width=80, depth=None, *, \
+                      compact=False, expand=False, sort_dicts=True, \
+                      underscore_numbers=False)
 
    Return the formatted representation of *object* as a string.  *indent*,
-   *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* are
+   *width*, *depth*, *compact*, *expand*, *sort_dicts* and *underscore_numbers* are
    passed to the :class:`PrettyPrinter` constructor as formatting parameters
    and their meanings are as described in the documentation above.
 
@@ -141,13 +154,13 @@ Functions
 
 .. _prettyprinter-objects:
 
-PrettyPrinter objects
+PrettyPrinter Objects
 ---------------------
 
 .. index:: single: ...; placeholder
 
-.. class:: PrettyPrinter(indent=4, width=88, depth=None, stream=None, *, \
-                         compact=False, sort_dicts=True, \
+.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
+                         compact=False, expand=False, sort_dicts=True, \
                          underscore_numbers=False)
 
    Construct a :class:`PrettyPrinter` instance.
@@ -158,23 +171,21 @@ PrettyPrinter objects
    >>> import pprint
    >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
    >>> stuff.insert(0, stuff[:])
-   >>> pp = pprint.PrettyPrinter()
+   >>> pp = pprint.PrettyPrinter(indent=4)
    >>> pp.pprint(stuff)
-   [
-       ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
+   [   ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
        'spam',
        'eggs',
        'lumberjack',
        'knights',
-       'ni',
-   ]
-   >>> pp = pprint.PrettyPrinter(indent=1, width=41, compact=True)
+       'ni']
+   >>> pp = pprint.PrettyPrinter(width=41, compact=True)
    >>> pp.pprint(stuff)
    [['spam', 'eggs', 'lumberjack',
      'knights', 'ni'],
     'spam', 'eggs', 'lumberjack', 'knights',
     'ni']
-   >>> pp = pprint.PrettyPrinter(width=41, indent=3)
+   >>> pp = pprint.PrettyPrinter(width=41, expand=True, indent=3)
    >>> pp.pprint(stuff)
    [
       [
@@ -210,11 +221,7 @@ PrettyPrinter objects
       No longer attempts to write to :data:`!sys.stdout` if it is ``None``.
 
    .. versionchanged:: 3.15
-      Changed default *indent* from 1 to 4
-      and default *width* from 80 to 88.
-      The default ``compact=False`` layout is now similar to
-      pretty-printed JSON, with opening parentheses and brackets
-      followed by a newline and the contents indented by one level.
+      Added the *expand* parameter.
 
 
 :class:`PrettyPrinter` instances have the following methods:
@@ -291,144 +298,219 @@ let's fetch information about a project from `PyPI <https://pypi.org>`_::
 In its basic form, :func:`~pprint.pp` shows the whole object::
 
    >>> pprint.pp(project_info)
-   {
-       'author': 'The Python Packaging Authority',
-       'author_email': 'pypa-dev@googlegroups.com',
-       'bugtrack_url': None,
-       'classifiers': [
-           'Development Status :: 3 - Alpha',
-           'Intended Audience :: Developers',
-           'License :: OSI Approved :: MIT License',
-           'Programming Language :: Python :: 2',
-           'Programming Language :: Python :: 2.6',
-           'Programming Language :: Python :: 2.7',
-           'Programming Language :: Python :: 3',
-           'Programming Language :: Python :: 3.2',
-           'Programming Language :: Python :: 3.3',
-           'Programming Language :: Python :: 3.4',
-           'Topic :: Software Development :: Build Tools',
-       ],
-       'description': 'A sample Python project\n'
-       '=======================\n'
-       '\n'
-       'This is the description file for the project.\n'
-       '\n'
-       'The file should use UTF-8 encoding and be written using ReStructured Text. It\n'
-       'will be used to generate the project webpage on PyPI, and should be written for\n'
-       'that purpose.\n'
-       '\n'
-       'Typical contents for this file would include an overview of the project, basic\n'
-       'usage examples, etc. Generally, including the project changelog in here is not\n'
-       'a good idea, although a simple "What\'s New" section for the most recent version\n'
-       'may be appropriate.',
-       'description_content_type': None,
-       'docs_url': None,
-       'download_url': 'UNKNOWN',
-       'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
-       'home_page': 'https://github.com/pypa/sampleproject',
-       'keywords': 'sample setuptools development',
-       'license': 'MIT',
-       'maintainer': None,
-       'maintainer_email': None,
-       'name': 'sampleproject',
-       'package_url': 'https://pypi.org/project/sampleproject/',
-       'platform': 'UNKNOWN',
-       'project_url': 'https://pypi.org/project/sampleproject/',
-       'project_urls': {'Download': 'UNKNOWN', 'Homepage': 'https://github.com/pypa/sampleproject'},
-       'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
-       'requires_dist': None,
-       'requires_python': None,
-       'summary': 'A sample Python project',
-       'version': '1.2.0',
-   }
+   {'author': 'The Python Packaging Authority',
+    'author_email': 'pypa-dev@googlegroups.com',
+    'bugtrack_url': None,
+    'classifiers': ['Development Status :: 3 - Alpha',
+                    'Intended Audience :: Developers',
+                    'License :: OSI Approved :: MIT License',
+                    'Programming Language :: Python :: 2',
+                    'Programming Language :: Python :: 2.6',
+                    'Programming Language :: Python :: 2.7',
+                    'Programming Language :: Python :: 3',
+                    'Programming Language :: Python :: 3.2',
+                    'Programming Language :: Python :: 3.3',
+                    'Programming Language :: Python :: 3.4',
+                    'Topic :: Software Development :: Build Tools'],
+    'description': 'A sample Python project\n'
+                   '=======================\n'
+                   '\n'
+                   'This is the description file for the project.\n'
+                   '\n'
+                   'The file should use UTF-8 encoding and be written using '
+                   'ReStructured Text. It\n'
+                   'will be used to generate the project webpage on PyPI, and '
+                   'should be written for\n'
+                   'that purpose.\n'
+                   '\n'
+                   'Typical contents for this file would include an overview of '
+                   'the project, basic\n'
+                   'usage examples, etc. Generally, including the project '
+                   'changelog in here is not\n'
+                   'a good idea, although a simple "What\'s New" section for the '
+                   'most recent version\n'
+                   'may be appropriate.',
+    'description_content_type': None,
+    'docs_url': None,
+    'download_url': 'UNKNOWN',
+    'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
+    'home_page': 'https://github.com/pypa/sampleproject',
+    'keywords': 'sample setuptools development',
+    'license': 'MIT',
+    'maintainer': None,
+    'maintainer_email': None,
+    'name': 'sampleproject',
+    'package_url': 'https://pypi.org/project/sampleproject/',
+    'platform': 'UNKNOWN',
+    'project_url': 'https://pypi.org/project/sampleproject/',
+    'project_urls': {'Download': 'UNKNOWN',
+                     'Homepage': 'https://github.com/pypa/sampleproject'},
+    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+    'requires_dist': None,
+    'requires_python': None,
+    'summary': 'A sample Python project',
+    'version': '1.2.0'}
 
 The result can be limited to a certain *depth* (ellipsis is used for deeper
 contents)::
 
    >>> pprint.pp(project_info, depth=1)
-   {
-       'author': 'The Python Packaging Authority',
-       'author_email': 'pypa-dev@googlegroups.com',
-       'bugtrack_url': None,
-       'classifiers': [...],
-       'description': 'A sample Python project\n'
-       '=======================\n'
-       '\n'
-       'This is the description file for the project.\n'
-       '\n'
-       'The file should use UTF-8 encoding and be written using ReStructured Text. It\n'
-       'will be used to generate the project webpage on PyPI, and should be written for\n'
-       'that purpose.\n'
-       '\n'
-       'Typical contents for this file would include an overview of the project, basic\n'
-       'usage examples, etc. Generally, including the project changelog in here is not\n'
-       'a good idea, although a simple "What\'s New" section for the most recent version\n'
-       'may be appropriate.',
-       'description_content_type': None,
-       'docs_url': None,
-       'download_url': 'UNKNOWN',
-       'downloads': {...},
-       'home_page': 'https://github.com/pypa/sampleproject',
-       'keywords': 'sample setuptools development',
-       'license': 'MIT',
-       'maintainer': None,
-       'maintainer_email': None,
-       'name': 'sampleproject',
-       'package_url': 'https://pypi.org/project/sampleproject/',
-       'platform': 'UNKNOWN',
-       'project_url': 'https://pypi.org/project/sampleproject/',
-       'project_urls': {...},
-       'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
-       'requires_dist': None,
-       'requires_python': None,
-       'summary': 'A sample Python project',
-       'version': '1.2.0',
-   }
+   {'author': 'The Python Packaging Authority',
+    'author_email': 'pypa-dev@googlegroups.com',
+    'bugtrack_url': None,
+    'classifiers': [...],
+    'description': 'A sample Python project\n'
+                   '=======================\n'
+                   '\n'
+                   'This is the description file for the project.\n'
+                   '\n'
+                   'The file should use UTF-8 encoding and be written using '
+                   'ReStructured Text. It\n'
+                   'will be used to generate the project webpage on PyPI, and '
+                   'should be written for\n'
+                   'that purpose.\n'
+                   '\n'
+                   'Typical contents for this file would include an overview of '
+                   'the project, basic\n'
+                   'usage examples, etc. Generally, including the project '
+                   'changelog in here is not\n'
+                   'a good idea, although a simple "What\'s New" section for the '
+                   'most recent version\n'
+                   'may be appropriate.',
+    'description_content_type': None,
+    'docs_url': None,
+    'download_url': 'UNKNOWN',
+    'downloads': {...},
+    'home_page': 'https://github.com/pypa/sampleproject',
+    'keywords': 'sample setuptools development',
+    'license': 'MIT',
+    'maintainer': None,
+    'maintainer_email': None,
+    'name': 'sampleproject',
+    'package_url': 'https://pypi.org/project/sampleproject/',
+    'platform': 'UNKNOWN',
+    'project_url': 'https://pypi.org/project/sampleproject/',
+    'project_urls': {...},
+    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+    'requires_dist': None,
+    'requires_python': None,
+    'summary': 'A sample Python project',
+    'version': '1.2.0'}
 
 Additionally, maximum character *width* can be suggested. If a long object
 cannot be split, the specified width will be exceeded::
 
    >>> pprint.pp(project_info, depth=1, width=60)
+   {'author': 'The Python Packaging Authority',
+    'author_email': 'pypa-dev@googlegroups.com',
+    'bugtrack_url': None,
+    'classifiers': [...],
+    'description': 'A sample Python project\n'
+                   '=======================\n'
+                   '\n'
+                   'This is the description file for the '
+                   'project.\n'
+                   '\n'
+                   'The file should use UTF-8 encoding and be '
+                   'written using ReStructured Text. It\n'
+                   'will be used to generate the project '
+                   'webpage on PyPI, and should be written '
+                   'for\n'
+                   'that purpose.\n'
+                   '\n'
+                   'Typical contents for this file would '
+                   'include an overview of the project, '
+                   'basic\n'
+                   'usage examples, etc. Generally, including '
+                   'the project changelog in here is not\n'
+                   'a good idea, although a simple "What\'s '
+                   'New" section for the most recent version\n'
+                   'may be appropriate.',
+    'description_content_type': None,
+    'docs_url': None,
+    'download_url': 'UNKNOWN',
+    'downloads': {...},
+    'home_page': 'https://github.com/pypa/sampleproject',
+    'keywords': 'sample setuptools development',
+    'license': 'MIT',
+    'maintainer': None,
+    'maintainer_email': None,
+    'name': 'sampleproject',
+    'package_url': 'https://pypi.org/project/sampleproject/',
+    'platform': 'UNKNOWN',
+    'project_url': 'https://pypi.org/project/sampleproject/',
+    'project_urls': {...},
+    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+    'requires_dist': None,
+    'requires_python': None,
+    'summary': 'A sample Python project',
+    'version': '1.2.0'}
+
+Lastly, we can format like pretty-printed JSON with the *expand* parameter.
+Best results are achieved with a higher *indent* value::
+
+   >>> pprint.pp(project_info, indent=4, expand=True)
    {
-       'author': 'The Python Packaging Authority',
-       'author_email': 'pypa-dev@googlegroups.com',
-       'bugtrack_url': None,
-       'classifiers': [...],
-       'description': 'A sample Python project\n'
-       '=======================\n'
-       '\n'
-       'This is the description file for the project.\n'
-       '\n'
-       'The file should use UTF-8 encoding and be written '
-       'using ReStructured Text. It\n'
-       'will be used to generate the project webpage on PyPI, '
-       'and should be written for\n'
-       'that purpose.\n'
-       '\n'
-       'Typical contents for this file would include an '
-       'overview of the project, basic\n'
-       'usage examples, etc. Generally, including the project '
-       'changelog in here is not\n'
-       'a good idea, although a simple "What\'s New" section '
-       'for the most recent version\n'
-       'may be appropriate.',
-       'description_content_type': None,
-       'docs_url': None,
-       'download_url': 'UNKNOWN',
-       'downloads': {...},
-       'home_page': 'https://github.com/pypa/sampleproject',
-       'keywords': 'sample setuptools development',
-       'license': 'MIT',
-       'maintainer': None,
-       'maintainer_email': None,
-       'name': 'sampleproject',
-       'package_url': 'https://pypi.org/project/sampleproject/',
-       'platform': 'UNKNOWN',
-       'project_url': 'https://pypi.org/project/sampleproject/',
-       'project_urls': {...},
-       'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
-       'requires_dist': None,
-       'requires_python': None,
-       'summary': 'A sample Python project',
-       'version': '1.2.0',
+      'author': 'The Python Packaging Authority',
+      'author_email': 'pypa-dev@googlegroups.com',
+      'bugtrack_url': None,
+      'classifiers': [
+         'Development Status :: 3 - Alpha',
+         'Intended Audience :: Developers',
+         'License :: OSI Approved :: MIT License',
+         'Programming Language :: Python :: 2',
+         'Programming Language :: Python :: 2.6',
+         'Programming Language :: Python :: 2.7',
+         'Programming Language :: Python :: 3',
+         'Programming Language :: Python :: 3.2',
+         'Programming Language :: Python :: 3.3',
+         'Programming Language :: Python :: 3.4',
+         'Topic :: Software Development :: Build Tools',
+      ],
+      'description': 'A sample Python project\n'
+      '=======================\n'
+      '\n'
+      'This is the description file for the project.\n'
+      '\n'
+      'The file should use UTF-8 encoding and be written using ReStructured '
+      'Text. It\n'
+      'will be used to generate the project webpage on PyPI, and should be '
+      'written for\n'
+      'that purpose.\n'
+      '\n'
+      'Typical contents for this file would include an overview of the project, '
+      'basic\n'
+      'usage examples, etc. Generally, including the project changelog in here '
+      'is not\n'
+      'a good idea, although a simple "What\'s New" section for the most recent '
+      'version\n'
+      'may be appropriate.',
+      'description_content_type': None,
+      'docs_url': None,
+      'download_url': 'UNKNOWN',
+      'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
+      'dynamic': None,
+      'home_page': 'https://github.com/pypa/sampleproject',
+      'keywords': 'sample setuptools development',
+      'license': 'MIT',
+      'license_expression': None,
+      'license_files': None,
+      'maintainer': None,
+      'maintainer_email': None,
+      'name': 'sampleproject',
+      'package_url': 'https://pypi.org/project/sampleproject/',
+      'platform': 'UNKNOWN',
+      'project_url': 'https://pypi.org/project/sampleproject/',
+      'project_urls': {
+         'Download': 'UNKNOWN',
+         'Homepage': 'https://github.com/pypa/sampleproject',
+      },
+      'provides_extra': None,
+      'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
+      'requires_dist': None,
+      'requires_python': None,
+      'summary': 'A sample Python project',
+      'version': '1.2.0',
+      'yanked': False,
+      'yanked_reason': None,
    }
index b180673f22973e2931c88d70ffaaa15b1f956e1c..c0f3757e583e95df9dba7c2fafa4ea87275ecd35 100644 (file)
@@ -2473,79 +2473,67 @@ Visual inspection shows that the certificate does identify the desired service
 (that is, the HTTPS host ``www.python.org``)::
 
    >>> pprint.pprint(cert)
-   {
-       'OCSP': ('http://ocsp.digicert.com',),
-       'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
-       'crlDistributionPoints': (
-           'http://crl3.digicert.com/sha2-ev-server-g1.crl',
-           'http://crl4.digicert.com/sha2-ev-server-g1.crl',
-       ),
-       'issuer': (
-           (('countryName', 'US'),),
-           (('organizationName', 'DigiCert Inc'),),
-           (('organizationalUnitName', 'www.digicert.com'),),
-           (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),),
-       ),
-       'notAfter': 'Sep  9 12:00:00 2016 GMT',
-       'notBefore': 'Sep  5 00:00:00 2014 GMT',
-       'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
-       'subject': (
-           (('businessCategory', 'Private Organization'),),
-           (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
-           (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
-           (('serialNumber', '3359300'),),
-           (('streetAddress', '16 Allen Rd'),),
-           (('postalCode', '03894-4801'),),
-           (('countryName', 'US'),),
-           (('stateOrProvinceName', 'NH'),),
-           (('localityName', 'Wolfeboro'),),
-           (('organizationName', 'Python Software Foundation'),),
-           (('commonName', 'www.python.org'),),
-       ),
-       'subjectAltName': (
-           ('DNS', 'www.python.org'),
-           ('DNS', 'python.org'),
-           ('DNS', 'pypi.org'),
-           ('DNS', 'docs.python.org'),
-           ('DNS', 'testpypi.org'),
-           ('DNS', 'bugs.python.org'),
-           ('DNS', 'wiki.python.org'),
-           ('DNS', 'hg.python.org'),
-           ('DNS', 'mail.python.org'),
-           ('DNS', 'packaging.python.org'),
-           ('DNS', 'pythonhosted.org'),
-           ('DNS', 'www.pythonhosted.org'),
-           ('DNS', 'test.pythonhosted.org'),
-           ('DNS', 'us.pycon.org'),
-           ('DNS', 'id.python.org'),
-       ),
-       'version': 3,
-   }
+   {'OCSP': ('http://ocsp.digicert.com',),
+    'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
+    'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl',
+                              'http://crl4.digicert.com/sha2-ev-server-g1.crl'),
+    'issuer': ((('countryName', 'US'),),
+               (('organizationName', 'DigiCert Inc'),),
+               (('organizationalUnitName', 'www.digicert.com'),),
+               (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)),
+    'notAfter': 'Sep  9 12:00:00 2016 GMT',
+    'notBefore': 'Sep  5 00:00:00 2014 GMT',
+    'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
+    'subject': ((('businessCategory', 'Private Organization'),),
+                (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
+                (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
+                (('serialNumber', '3359300'),),
+                (('streetAddress', '16 Allen Rd'),),
+                (('postalCode', '03894-4801'),),
+                (('countryName', 'US'),),
+                (('stateOrProvinceName', 'NH'),),
+                (('localityName', 'Wolfeboro'),),
+                (('organizationName', 'Python Software Foundation'),),
+                (('commonName', 'www.python.org'),)),
+    'subjectAltName': (('DNS', 'www.python.org'),
+                       ('DNS', 'python.org'),
+                       ('DNS', 'pypi.org'),
+                       ('DNS', 'docs.python.org'),
+                       ('DNS', 'testpypi.org'),
+                       ('DNS', 'bugs.python.org'),
+                       ('DNS', 'wiki.python.org'),
+                       ('DNS', 'hg.python.org'),
+                       ('DNS', 'mail.python.org'),
+                       ('DNS', 'packaging.python.org'),
+                       ('DNS', 'pythonhosted.org'),
+                       ('DNS', 'www.pythonhosted.org'),
+                       ('DNS', 'test.pythonhosted.org'),
+                       ('DNS', 'us.pycon.org'),
+                       ('DNS', 'id.python.org')),
+    'version': 3}
 
 Now the SSL channel is established and the certificate verified, you can
 proceed to talk with the server::
 
    >>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
    >>> pprint.pprint(conn.recv(1024).split(b"\r\n"))
-   [
-       b'HTTP/1.1 200 OK',
-       b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
-       b'Server: nginx',
-       b'Content-Type: text/html; charset=utf-8',
-       b'X-Frame-Options: SAMEORIGIN',
-       b'Content-Length: 45679',
-       b'Accept-Ranges: bytes',
-       b'Via: 1.1 varnish',
-       b'Age: 2188',
-       b'X-Served-By: cache-lcy1134-LCY',
-       b'X-Cache: HIT',
-       b'X-Cache-Hits: 11',
-       b'Vary: Cookie',
-       b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
-       b'Connection: close',
-       b'',
-       b'',
-   ]
+   [b'HTTP/1.1 200 OK',
+    b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
+    b'Server: nginx',
+    b'Content-Type: text/html; charset=utf-8',
+    b'X-Frame-Options: SAMEORIGIN',
+    b'Content-Length: 45679',
+    b'Accept-Ranges: bytes',
+    b'Via: 1.1 varnish',
+    b'Age: 2188',
+    b'X-Served-By: cache-lcy1134-LCY',
+    b'X-Cache: HIT',
+    b'X-Cache-Hits: 11',
+    b'Vary: Cookie',
+    b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
+    b'Connection: close',
+    b'',
+    b'']
 
 See the discussion of :ref:`ssl-security` below.
 
index 5b9f9eec93aa28dbd6ed4a7b0fc3787744e891d0..2ff1015af7a86e0060465f1c9efccbef77d2a607 100644 (file)
@@ -2347,12 +2347,10 @@ chained call:
     <MagicMock name='mock().method().other()()' id='...'>
     >>> kall = call(1).method(arg='foo').other('bar')(2.0)
     >>> kall.call_list()
-    [
-        call(1),
-        call().method(arg='foo'),
-        call().method().other('bar'),
-        call().method().other()(2.0),
-    ]
+    [call(1),
+     call().method(arg='foo'),
+     call().method().other('bar'),
+     call().method().other()(2.0)]
     >>> m.mock_calls == kall.call_list()
     True
 
index 0b0e934186c4b5e45e6ad4db7bf266606e55f180..cf3a44850b0b8f2af55dfc492424d93787d92a6f 100644 (file)
@@ -30,22 +30,11 @@ and indentation to more clearly reveal data structure::
    ...     'yellow'], 'blue']]]
    ...
    >>> pprint.pprint(t, width=30)
-   [
-       [
-           [
-               ['black', 'cyan'],
-               'white',
-               ['green', 'red'],
-           ],
-           [
-               [
-                   'magenta',
-                   'yellow',
-               ],
-               'blue',
-           ],
-       ],
-   ]
+   [[[['black', 'cyan'],
+      'white',
+      ['green', 'red']],
+     [['magenta', 'yellow'],
+      'blue']]]
 
 The :mod:`textwrap` module formats paragraphs of text to fit a given screen
 width::
index 0a7a87d81e53dcccd0eeabd42a0c5f78712a016a..8e6b1faa523f68e7f61385d25a865ad4b1392071 100644 (file)
@@ -1343,11 +1343,12 @@ pickletools
 pprint
 ------
 
-* :mod:`pprint` now uses modern defaults: ``indent=4, width=88``,
-  and the default ``compact=False`` output is now formatted similar to
-  pretty-printed :func:`json.dumps`.
+* Add an *expand* keyword argument for :func:`pprint.pprint`,
+  :func:`pprint.pformat`, :func:`pprint.pp`. If true, the output will be
+  formatted similar to pretty-printed :func:`json.dumps` when
+  *indent* is supplied.
   (Contributed by Stefan Todoran, Semyon Moroz and Hugo van Kemenade in
-  :gh:`112632` and :gh:`149189`.)
+  :gh:`112632`.)
 
 * Add t-string support to :mod:`pprint`.
   (Contributed by Loïc Simon and Hugo van Kemenade in :gh:`134551`.)
index 7a4ff15c34267b379e3548f0e27e74442c59289c..ae8b284b4d36474ed57819a9fbdf34a0374fc2bb 100644 (file)
@@ -559,17 +559,15 @@ class SequenceMatcher:
         >>> b[23:28] = []      # Make a deletion
         >>> b[30] += 'y'       # Make another replacement
         >>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes()))
-        [
-            [('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
-            [
-                ('equal', 16, 19, 17, 20),
-                ('replace', 19, 20, 20, 21),
-                ('equal', 20, 22, 21, 23),
-                ('delete', 22, 27, 23, 23),
-                ('equal', 27, 30, 23, 26),
-            ],
-            [('equal', 31, 34, 27, 30), ('replace', 34, 35, 30, 31), ('equal', 35, 38, 31, 34)],
-        ]
+        [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)],
+         [('equal', 16, 19, 17, 20),
+          ('replace', 19, 20, 20, 21),
+          ('equal', 20, 22, 21, 23),
+          ('delete', 22, 27, 23, 23),
+          ('equal', 27, 30, 23, 26)],
+         [('equal', 31, 34, 27, 30),
+          ('replace', 34, 35, 30, 31),
+          ('equal', 35, 38, 31, 34)]]
         """
 
         codes = self.get_opcodes()
@@ -786,18 +784,16 @@ class Differ:
 
     >>> from pprint import pprint as _pprint
     >>> _pprint(result)
-    [
-        '    1. Beautiful is better than ugly.\n',
-        '-   2. Explicit is better than implicit.\n',
-        '-   3. Simple is better than complex.\n',
-        '+   3.   Simple is better than complex.\n',
-        '?     ++\n',
-        '-   4. Complex is better than complicated.\n',
-        '?            ^                     ---- ^\n',
-        '+   4. Complicated is better than complex.\n',
-        '?           ++++ ^                      ^\n',
-        '+   5. Flat is better than nested.\n',
-    ]
+    ['    1. Beautiful is better than ugly.\n',
+     '-   2. Explicit is better than implicit.\n',
+     '-   3. Simple is better than complex.\n',
+     '+   3.   Simple is better than complex.\n',
+     '?     ++\n',
+     '-   4. Complex is better than complicated.\n',
+     '?            ^                     ---- ^\n',
+     '+   4. Complicated is better than complex.\n',
+     '?           ++++ ^                      ^\n',
+     '+   5. Flat is better than nested.\n']
 
     As a single multi-line string it looks like this:
 
index 1fd7e3ec95a073463c4a03d939441bbc97733c43..7355021998081dcda7bec837fbe6d39a50099631 100644 (file)
@@ -43,38 +43,23 @@ __all__ = ["pprint","pformat","isreadable","isrecursive","saferepr",
            "PrettyPrinter", "pp"]
 
 
-def pprint(
-    object,
-    stream=None,
-    indent=4,
-    width=88,
-    depth=None,
-    *,
-    compact=False,
-    sort_dicts=True,
-    underscore_numbers=False,
-):
+def pprint(object, stream=None, indent=1, width=80, depth=None, *,
+           compact=False, expand=False, sort_dicts=True,
+           underscore_numbers=False):
     """Pretty-print a Python object to a stream [default is sys.stdout]."""
     printer = PrettyPrinter(
         stream=stream, indent=indent, width=width, depth=depth,
-        compact=compact, sort_dicts=sort_dicts,
+        compact=compact, expand=expand, sort_dicts=sort_dicts,
         underscore_numbers=underscore_numbers)
     printer.pprint(object)
 
 
-def pformat(
-    object,
-    indent=4,
-    width=88,
-    depth=None,
-    *,
-    compact=False,
-    sort_dicts=True,
-    underscore_numbers=False,
-):
+def pformat(object, indent=1, width=80, depth=None, *,
+            compact=False, expand=False, sort_dicts=True,
+            underscore_numbers=False):
     """Format a Python object into a pretty-printed representation."""
     return PrettyPrinter(indent=indent, width=width, depth=depth,
-                         compact=compact, sort_dicts=sort_dicts,
+                         compact=compact, expand=expand, sort_dicts=sort_dicts,
                          underscore_numbers=underscore_numbers).pformat(object)
 
 
@@ -127,17 +112,9 @@ def _safe_tuple(t):
 
 
 class PrettyPrinter:
-    def __init__(
-        self,
-        indent=4,
-        width=88,
-        depth=None,
-        stream=None,
-        *,
-        compact=False,
-        sort_dicts=True,
-        underscore_numbers=False,
-    ):
+    def __init__(self, indent=1, width=80, depth=None, stream=None, *,
+                 compact=False, expand=False, sort_dicts=True,
+                 underscore_numbers=False):
         """Handle pretty printing operations onto a stream using a set of
         configured parameters.
 
@@ -156,6 +133,12 @@ class PrettyPrinter:
 
         compact
             If true, several items will be combined in one line.
+            Incompatible with expand mode.
+
+        expand
+            If true, the output will be formatted similar to
+            pretty-printed json.dumps() when ``indent`` is supplied.
+            Incompatible with compact mode.
 
         sort_dicts
             If true, dict keys are sorted.
@@ -172,6 +155,8 @@ class PrettyPrinter:
             raise ValueError('depth must be > 0')
         if not width:
             raise ValueError('width must be != 0')
+        if compact and expand:
+            raise ValueError('compact and expand are incompatible')
         self._depth = depth
         self._indent_per_level = indent
         self._width = width
@@ -180,6 +165,7 @@ class PrettyPrinter:
         else:
             self._stream = _sys.stdout
         self._compact = bool(compact)
+        self._expand = bool(expand)
         self._sort_dicts = sort_dicts
         self._underscore_numbers = underscore_numbers
 
@@ -232,36 +218,36 @@ class PrettyPrinter:
         stream.write(rep)
 
     def _format_block_start(self, start_str, indent):
-        if self._compact:
-            return start_str
-        return f"{start_str}\n{' ' * indent}"
+        if self._expand:
+            return f"{start_str}\n{' ' * indent}"
+        return start_str
 
     def _format_block_end(self, end_str, indent):
-        if self._compact:
-            return end_str
-        return f"\n{' ' * indent}{end_str}"
+        if self._expand:
+            return f"\n{' ' * indent}{end_str}"
+        return end_str
 
     def _child_indent(self, indent, prefix_len):
-        if self._compact:
-            return indent + prefix_len
-        return indent
+        if self._expand:
+            return indent
+        return indent + prefix_len
 
     def _write_indent_padding(self, write):
-        if self._compact:
-            if self._indent_per_level > 1:
-                write((self._indent_per_level - 1) * " ")
-        elif self._indent_per_level > 0:
-            write(self._indent_per_level * " ")
+        if self._expand:
+            if self._indent_per_level > 0:
+                write(self._indent_per_level * " ")
+        elif self._indent_per_level > 1:
+            write((self._indent_per_level - 1) * " ")
 
     def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
         # Lazy import to improve module import time
         from dataclasses import fields as dataclass_fields
 
         cls_name = object.__class__.__name__
-        if self._compact:
-            indent += len(cls_name) + 1
-        else:
+        if self._expand:
             indent += self._indent_per_level
+        else:
+            indent += len(cls_name) + 1
         items = [(f.name, getattr(object, f.name)) for f in dataclass_fields(object) if f.repr]
         stream.write(self._format_block_start(cls_name + '(', indent))
         self._format_namespace_items(items, stream, indent, allowance, context, level)
@@ -384,7 +370,7 @@ class PrettyPrinter:
 
     def _pprint_tuple(self, object, stream, indent, allowance, context, level):
         stream.write(self._format_block_start('(', indent))
-        if len(object) == 1 and self._compact:
+        if len(object) == 1 and not self._expand:
             endchar = ',)'
         else:
             endchar = ')'
@@ -405,7 +391,7 @@ class PrettyPrinter:
         else:
             stream.write(self._format_block_start(typ.__name__ + '({', indent))
             endchar = '})'
-            if self._compact:
+            if not self._expand:
                 indent += len(typ.__name__) + 1
         object = sorted(object, key=_safe_key)
         self._format_items(object, stream, indent, allowance + len(endchar),
@@ -423,10 +409,10 @@ class PrettyPrinter:
         chunks = []
         lines = object.splitlines(True)
         if level == 1:
-            if self._compact:
-                indent += 1
-            else:
+            if self._expand:
                 indent += self._indent_per_level
+            else:
+                indent += 1
             allowance += 1
         max_width1 = max_width = self._width - indent
         for i, line in enumerate(lines):
@@ -479,10 +465,10 @@ class PrettyPrinter:
             return
         parens = level == 1
         if parens:
-            if self._compact:
-                indent += 1
-            else:
+            if self._expand:
                 indent += self._indent_per_level
+            else:
+                indent += 1
             allowance += 1
             write(self._format_block_start('(', indent))
         delim = ''
@@ -499,11 +485,11 @@ class PrettyPrinter:
     def _pprint_bytearray(self, object, stream, indent, allowance, context, level):
         write = stream.write
         write(self._format_block_start('bytearray(', indent))
-        if self._compact:
-            recursive_indent = indent + 10
-        else:
+        if self._expand:
             write(' ' * self._indent_per_level)
             recursive_indent = indent + self._indent_per_level
+        else:
+            recursive_indent = indent + 10
         self._pprint_bytes(bytes(object), stream, recursive_indent,
                            allowance + 1, context, level + 1)
         write(self._format_block_end(')', indent))
@@ -531,10 +517,10 @@ class PrettyPrinter:
             cls_name = 'namespace'
         else:
             cls_name = object.__class__.__name__
-        if self._compact:
-            indent += len(cls_name) + 1
-        else:
+        if self._expand:
             indent += self._indent_per_level
+        else:
+            indent += len(cls_name) + 1
         items = object.__dict__.items()
         stream.write(self._format_block_start(cls_name + '(', indent))
         self._format_namespace_items(items, stream, indent, allowance, context,
@@ -564,7 +550,7 @@ class PrettyPrinter:
             )
             if not last:
                 write(delimnl)
-            elif not self._compact:
+            elif self._expand:
                 write(',')
 
     def _format_namespace_items(self, items, stream, indent, allowance, context, level):
@@ -590,7 +576,7 @@ class PrettyPrinter:
                 )
             if not last:
                 write(delimnl)
-            elif not self._compact:
+            elif self._expand:
                 write(',')
 
     def _format_items(self, items, stream, indent, allowance, context, level):
@@ -632,7 +618,7 @@ class PrettyPrinter:
             self._format(ent, stream, indent,
                          allowance if last else 1,
                          context, level)
-            if last and not self._compact:
+            if last and self._expand:
                 write(',')
 
     def _repr(self, object, context, level):
@@ -657,11 +643,11 @@ class PrettyPrinter:
             return
         rdf = self._repr(object.default_factory, context, level)
         cls = object.__class__
-        if self._compact:
+        if self._expand:
+            stream.write('%s(%s, ' % (cls.__name__, rdf))
+        else:
             indent += len(cls.__name__) + 1
             stream.write('%s(%s,\n%s' % (cls.__name__, rdf, ' ' * indent))
-        else:
-            stream.write('%s(%s, ' % (cls.__name__, rdf))
         self._pprint_dict(object, stream, indent, allowance + 1, context,
                           level)
         stream.write(')')
@@ -695,14 +681,14 @@ class PrettyPrinter:
         cls = object.__class__
         stream.write(self._format_block_start(cls.__name__ + '(',
                                               indent + self._indent_per_level))
-        if self._compact:
-            indent += len(cls.__name__) + 1
-        else:
+        if self._expand:
             indent += self._indent_per_level
+        else:
+            indent += len(cls.__name__) + 1
         for i, m in enumerate(object.maps):
             if i == len(object.maps) - 1:
                 self._format(m, stream, indent, allowance + 1, context, level)
-                if not self._compact:
+                if self._expand:
                     stream.write(',')
                 stream.write(self._format_block_end(')', indent - self._indent_per_level))
             else:
@@ -717,7 +703,7 @@ class PrettyPrinter:
             return
         cls = object.__class__
         stream.write(self._format_block_start(cls.__name__ + '([', indent))
-        if self._compact:
+        if not self._expand:
             indent += len(cls.__name__) + 1
         if object.maxlen is None:
             self._format_items(object, stream, indent, allowance + 2,
@@ -727,10 +713,10 @@ class PrettyPrinter:
             self._format_items(object, stream, indent, 2,
                                context, level)
             rml = self._repr(object.maxlen, context, level)
-            if self._compact:
-                stream.write('],\n%smaxlen=%s)' % (' ' * indent, rml))
-            else:
+            if self._expand:
                 stream.write('%s], maxlen=%s)' % ('\n' + ' ' * indent, rml))
+            else:
+                stream.write('],\n%smaxlen=%s)' % (' ' * indent, rml))
 
     _dispatch[_collections.deque.__repr__] = _pprint_deque
 
@@ -751,10 +737,10 @@ class PrettyPrinter:
 
     def _pprint_template(self, object, stream, indent, allowance, context, level):
         cls_name = object.__class__.__name__
-        if self._compact:
-            indent += len(cls_name) + 1
-        else:
+        if self._expand:
             indent += self._indent_per_level
+        else:
+            indent += len(cls_name) + 1
 
         items = (
             ("strings", object.strings),
@@ -770,20 +756,7 @@ class PrettyPrinter:
 
     def _pprint_interpolation(self, object, stream, indent, allowance, context, level):
         cls_name = object.__class__.__name__
-        if self._compact:
-            indent += len(cls_name)
-            items = (
-                object.value,
-                object.expression,
-                object.conversion,
-                object.format_spec,
-            )
-            stream.write(cls_name + "(")
-            self._format_items(
-                items, stream, indent, allowance, context, level
-            )
-            stream.write(")")
-        else:
+        if self._expand:
             indent += self._indent_per_level
             items = (
                 ("value", object.value),
@@ -798,6 +771,19 @@ class PrettyPrinter:
             stream.write(
                 self._format_block_end(")", indent - self._indent_per_level)
             )
+        else:
+            indent += len(cls_name)
+            items = (
+                object.value,
+                object.expression,
+                object.conversion,
+                object.format_spec,
+            )
+            stream.write(cls_name + "(")
+            self._format_items(
+                items, stream, indent, allowance, context, level
+            )
+            stream.write(")")
 
     t = t"{0}"
     _dispatch[type(t).__repr__] = _pprint_template
index 425fb85e93558d2593f860c5ff30ab84423bf0b0..828440a993a975d155c941332b63c9738411e494 100644 (file)
@@ -168,56 +168,54 @@ You can get the information from the list type:
 
     >>> import pprint
     >>> pprint.pprint(dir(list))    # like list.__dict__.keys(), but sorted
-    [
-        '__add__',
-        '__class__',
-        '__class_getitem__',
-        '__contains__',
-        '__delattr__',
-        '__delitem__',
-        '__dir__',
-        '__doc__',
-        '__eq__',
-        '__format__',
-        '__ge__',
-        '__getattribute__',
-        '__getitem__',
-        '__getstate__',
-        '__gt__',
-        '__hash__',
-        '__iadd__',
-        '__imul__',
-        '__init__',
-        '__init_subclass__',
-        '__iter__',
-        '__le__',
-        '__len__',
-        '__lt__',
-        '__mul__',
-        '__ne__',
-        '__new__',
-        '__reduce__',
-        '__reduce_ex__',
-        '__repr__',
-        '__reversed__',
-        '__rmul__',
-        '__setattr__',
-        '__setitem__',
-        '__sizeof__',
-        '__str__',
-        '__subclasshook__',
-        'append',
-        'clear',
-        'copy',
-        'count',
-        'extend',
-        'index',
-        'insert',
-        'pop',
-        'remove',
-        'reverse',
-        'sort',
-    ]
+    ['__add__',
+     '__class__',
+     '__class_getitem__',
+     '__contains__',
+     '__delattr__',
+     '__delitem__',
+     '__dir__',
+     '__doc__',
+     '__eq__',
+     '__format__',
+     '__ge__',
+     '__getattribute__',
+     '__getitem__',
+     '__getstate__',
+     '__gt__',
+     '__hash__',
+     '__iadd__',
+     '__imul__',
+     '__init__',
+     '__init_subclass__',
+     '__iter__',
+     '__le__',
+     '__len__',
+     '__lt__',
+     '__mul__',
+     '__ne__',
+     '__new__',
+     '__reduce__',
+     '__reduce_ex__',
+     '__repr__',
+     '__reversed__',
+     '__rmul__',
+     '__setattr__',
+     '__setitem__',
+     '__sizeof__',
+     '__str__',
+     '__subclasshook__',
+     'append',
+     'clear',
+     'copy',
+     'count',
+     'extend',
+     'index',
+     'insert',
+     'pop',
+     'remove',
+     'reverse',
+     'sort']
 
 The new introspection API gives more information than the old one:  in
 addition to the regular methods, it also shows the methods that are
index 55a3c654aa0a471a0c1c3d4ec331222a5dabcbb8..48375cf459ea0b15cd33dc613b09392984718fcf 100644 (file)
@@ -786,7 +786,11 @@ class CommandLineTest(unittest.TestCase):
             'b': ('character string', b'byte string'),
             'c': 'string'
         }
-        expect = "{'a': [1, 2.0, (3+4j)], 'b': ('character string', b'byte string'), 'c': 'string'}"
+        expect = '''
+            {'a': [1, 2.0, (3+4j)],
+             'b': ('character string', b'byte string'),
+             'c': 'string'}
+        '''
         self.set_pickle_data(data)
 
         with self.subTest(data=data):
index f439782f53e6fb9a8cad4c2a4824f38659fa9031..041c2072b9e253a9ace901508e6c8aa6e0ed8bd5 100644 (file)
@@ -3,7 +3,6 @@
 import collections
 import contextlib
 import dataclasses
-import functools
 import io
 import itertools
 import pprint
@@ -16,10 +15,6 @@ from collections.abc import ItemsView, KeysView, Mapping, MappingView, ValuesVie
 from test.support import cpython_only
 from test.support.import_helper import ensure_lazy_imports
 
-# Pin pre-3.15 width/indent for existing formatting tests.
-# compact=True keeps the legacy non-JSON-style container wrapping.
-_pformat = functools.partial(pprint.pformat, indent=1, width=80, compact=True)
-
 # list, tuple and dict subclasses that do or don't overwrite __repr__
 class list2(list):
     pass
@@ -169,6 +164,7 @@ class QueryTestCase(unittest.TestCase):
         self.assertRaises(ValueError, pprint.PrettyPrinter, depth=0)
         self.assertRaises(ValueError, pprint.PrettyPrinter, depth=-1)
         self.assertRaises(ValueError, pprint.PrettyPrinter, width=0)
+        self.assertRaises(ValueError, pprint.PrettyPrinter, compact=True, expand=True)
 
     def test_basic(self):
         # Verify .isrecursive() and .isreadable() w/o recursion
@@ -288,10 +284,10 @@ class QueryTestCase(unittest.TestCase):
                        True, False, None, ...,
                       ):
             native = repr(simple)
-            self.assertEqual(_pformat(simple), native)
-            self.assertEqual(_pformat(simple, width=1, indent=0)
+            self.assertEqual(pprint.pformat(simple), native)
+            self.assertEqual(pprint.pformat(simple, width=1, indent=0)
                              .replace('\n', ' '), native)
-            self.assertEqual(_pformat(simple, underscore_numbers=True), native)
+            self.assertEqual(pprint.pformat(simple, underscore_numbers=True), native)
             self.assertEqual(pprint.saferepr(simple), native)
 
     def test_container_repr_override_called(self):
@@ -322,8 +318,8 @@ class QueryTestCase(unittest.TestCase):
                     ):
             native = repr(cont)
             expected = '*' * len(native)
-            self.assertEqual(_pformat(cont), expected)
-            self.assertEqual(_pformat(cont, width=1, indent=0), expected)
+            self.assertEqual(pprint.pformat(cont), expected)
+            self.assertEqual(pprint.pformat(cont, width=1, indent=0), expected)
             self.assertEqual(pprint.saferepr(cont), expected)
 
     def test_basic_line_wrap(self):
@@ -344,7 +340,7 @@ class QueryTestCase(unittest.TestCase):
  'read_io_runtime_us': 0,
  'write_io_runtime_us': 43690}"""
         for type in [dict, dict2]:
-            self.assertEqual(_pformat(type(o)), exp)
+            self.assertEqual(pprint.pformat(type(o)), exp)
 
         exp = """\
 frozendict({'RPM_cal': 0,
@@ -354,7 +350,7 @@ frozendict({'RPM_cal': 0,
             'main_code_runtime_us': 0,
             'read_io_runtime_us': 0,
             'write_io_runtime_us': 43690})"""
-        self.assertEqual(_pformat(frozendict(o)), exp)
+        self.assertEqual(pprint.pformat(frozendict(o)), exp)
         exp = """\
 frozendict2({'RPM_cal': 0,
              'RPM_cal2': 48059,
@@ -363,79 +359,79 @@ frozendict2({'RPM_cal': 0,
              'main_code_runtime_us': 0,
              'read_io_runtime_us': 0,
              'write_io_runtime_us': 43690})"""
-        self.assertEqual(_pformat(frozendict2(o)), exp)
+        self.assertEqual(pprint.pformat(frozendict2(o)), exp)
 
         o = range(100)
         exp = 'dict_keys([%s])' % ',\n '.join(map(str, o))
         keys = dict.fromkeys(o).keys()
-        self.assertEqual(_pformat(keys, width=1), exp)
+        self.assertEqual(pprint.pformat(keys), exp)
         keys = frozendict.fromkeys(o).keys()
-        self.assertEqual(_pformat(keys, width=1), exp)
+        self.assertEqual(pprint.pformat(keys), exp)
 
         o = range(100)
         exp = 'dict_values([%s])' % ',\n '.join(map(str, o))
         values = {v: v for v in o}.values()
-        self.assertEqual(_pformat(values, width=1), exp)
+        self.assertEqual(pprint.pformat(values), exp)
         values = frozendict({v: v for v in o}).values()
-        self.assertEqual(_pformat(values, width=1), exp)
+        self.assertEqual(pprint.pformat(values), exp)
 
         o = range(100)
         exp = 'dict_items([%s])' % ',\n '.join("(%s, %s)" % (i, i) for i in o)
         items = {v: v for v in o}.items()
-        self.assertEqual(_pformat(items, width=11), exp)
+        self.assertEqual(pprint.pformat(items), exp)
         items = frozendict({v: v for v in o}).items()
-        self.assertEqual(_pformat(items, width=11), exp)
+        self.assertEqual(pprint.pformat(items), exp)
 
         o = range(100)
         exp = 'odict_keys([%s])' % ',\n '.join(map(str, o))
         keys = collections.OrderedDict.fromkeys(o).keys()
-        self.assertEqual(_pformat(keys, width=1), exp)
+        self.assertEqual(pprint.pformat(keys), exp)
 
         o = range(100)
         exp = 'odict_values([%s])' % ',\n '.join(map(str, o))
         values = collections.OrderedDict({v: v for v in o}).values()
-        self.assertEqual(_pformat(values, width=1), exp)
+        self.assertEqual(pprint.pformat(values), exp)
 
         o = range(100)
         exp = 'odict_items([%s])' % ',\n '.join("(%s, %s)" % (i, i) for i in o)
         items = collections.OrderedDict({v: v for v in o}).items()
-        self.assertEqual(_pformat(items, width=11), exp)
+        self.assertEqual(pprint.pformat(items), exp)
 
         o = range(100)
         exp = 'KeysView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
         keys_view = KeysView(dict.fromkeys(o))
-        self.assertEqual(_pformat(keys_view), exp)
+        self.assertEqual(pprint.pformat(keys_view), exp)
 
         o = range(100)
         exp = 'ItemsView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
         items_view = ItemsView(dict.fromkeys(o))
-        self.assertEqual(_pformat(items_view), exp)
+        self.assertEqual(pprint.pformat(items_view), exp)
 
         o = range(100)
         exp = 'MappingView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
         mapping_view = MappingView(dict.fromkeys(o))
-        self.assertEqual(_pformat(mapping_view), exp)
+        self.assertEqual(pprint.pformat(mapping_view), exp)
 
         o = range(100)
         exp = 'ValuesView({%s})' % (': None,\n '.join(map(str, o)) + ': None')
         values_view = ValuesView(dict.fromkeys(o))
-        self.assertEqual(_pformat(values_view), exp)
+        self.assertEqual(pprint.pformat(values_view), exp)
 
         o = range(100)
         exp = '[%s]' % ',\n '.join(map(str, o))
         for type in [list, list2]:
-            self.assertEqual(_pformat(type(o), width=1), exp)
+            self.assertEqual(pprint.pformat(type(o)), exp)
 
         o = tuple(range(100))
         exp = '(%s)' % ',\n '.join(map(str, o))
         for type in [tuple, tuple2]:
-            self.assertEqual(_pformat(type(o), width=1), exp)
+            self.assertEqual(pprint.pformat(type(o)), exp)
 
         # indent parameter
         o = range(100)
         exp = '[   %s]' % ',\n    '.join(map(str, o))
         for type in [list, list2]:
-            self.assertEqual(_pformat(type(o), indent=4, width=1), exp)
+            self.assertEqual(pprint.pformat(type(o), indent=4), exp)
 
     def test_nested_indentations(self):
         o1 = list(range(10))
@@ -444,13 +440,13 @@ frozendict2({'RPM_cal': 0,
         expected = """\
 [   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
     {'first': 1, 'second': 2, 'third': 3}]"""
-        self.assertEqual(pprint.pformat(o, indent=4, width=42, compact=True), expected)
+        self.assertEqual(pprint.pformat(o, indent=4, width=42), expected)
         expected = """\
 [   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
     {   'first': 1,
         'second': 2,
         'third': 3}]"""
-        self.assertEqual(pprint.pformat(o, indent=4, width=41, compact=True), expected)
+        self.assertEqual(pprint.pformat(o, indent=4, width=41), expected)
 
     def test_width(self):
         expected = """\
@@ -464,15 +460,17 @@ frozendict2({'RPM_cal': 0,
  [[[[[1, 2, 3],
      '1 2']]]]]"""
         o = eval(expected)
-        self.assertEqual(_pformat(o, width=15), expected)
-        self.assertEqual(_pformat(o, width=16), expected)
-        self.assertEqual(_pformat(o, width=25), expected)
-        self.assertEqual(_pformat(o, width=14), """\
-[[[[[[1, 2,
+        self.assertEqual(pprint.pformat(o, width=15), expected)
+        self.assertEqual(pprint.pformat(o, width=16), expected)
+        self.assertEqual(pprint.pformat(o, width=25), expected)
+        self.assertEqual(pprint.pformat(o, width=14), """\
+[[[[[[1,
+      2,
       3],
      '1 '
      '2']]]],
- {1: [1, 2,
+ {1: [1,
+      2,
       3],
   2: [12,
       34]},
@@ -482,14 +480,15 @@ frozendict2({'RPM_cal': 0,
   'ef',),
  set2({1,
        23}),
- [[[[[1, 2,
+ [[[[[1,
+      2,
       3],
      '1 '
      '2']]]]]""")
 
     def test_integer(self):
-        self.assertEqual(_pformat(1234567), '1234567')
-        self.assertEqual(_pformat(1234567, underscore_numbers=True), '1_234_567')
+        self.assertEqual(pprint.pformat(1234567), '1234567')
+        self.assertEqual(pprint.pformat(1234567, underscore_numbers=True), '1_234_567')
 
         class Temperature(int):
             def __new__(cls, celsius_degrees):
@@ -497,7 +496,7 @@ frozendict2({'RPM_cal': 0,
             def __repr__(self):
                 kelvin_degrees = self + 273.15
                 return f"{kelvin_degrees:.2f}°K"
-        self.assertEqual(_pformat(Temperature(1000)), '1273.15°K')
+        self.assertEqual(pprint.pformat(Temperature(1000)), '1273.15°K')
 
     def test_sorted_dict(self):
         # Starting in Python 2.5, pprint sorts dict displays by key regardless
@@ -505,8 +504,8 @@ frozendict2({'RPM_cal': 0,
         # Before the change, on 32-bit Windows pformat() gave order
         # 'a', 'c', 'b' here, so this test failed.
         d = {'a': 1, 'b': 1, 'c': 1}
-        self.assertEqual(_pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
-        self.assertEqual(_pformat([d, d]),
+        self.assertEqual(pprint.pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
+        self.assertEqual(pprint.pformat([d, d]),
             "[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 1, 'c': 1}]")
 
         # The next one is kind of goofy.  The sorted order depends on the
@@ -514,42 +513,63 @@ frozendict2({'RPM_cal': 0,
         # Python 2.5, this was in the test_same_as_repr() test.  It's worth
         # keeping around for now because it's one of few tests of pprint
         # against a crazy mix of types.
-        self.assertEqual(_pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
+        self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
             r"{5: [[]], 'xy\tab\n': (3,), (): {}}")
 
     def test_sort_dict(self):
         d = dict.fromkeys('cba')
-        self.assertEqual(_pformat(d, sort_dicts=False), "{'c': None, 'b': None, 'a': None}")
-        self.assertEqual(_pformat([d, d], sort_dicts=False),
+        self.assertEqual(pprint.pformat(d, sort_dicts=False), "{'c': None, 'b': None, 'a': None}")
+        self.assertEqual(pprint.pformat([d, d], sort_dicts=False),
             "[{'c': None, 'b': None, 'a': None}, {'c': None, 'b': None, 'a': None}]")
 
     def test_ordered_dict(self):
         d = collections.OrderedDict()
-        self.assertEqual(_pformat(d, width=1), 'OrderedDict()')
+        self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()')
         d = collections.OrderedDict([])
-        self.assertEqual(_pformat(d, width=1), 'OrderedDict()')
+        self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()')
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = collections.OrderedDict(zip(words, itertools.count()))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
-OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4),
-             ('over', 5), ('a', 6), ('lazy', 7), ('dog', 8)])""")
-        self.assertEqual(
-            _pformat(d.keys(), sort_dicts=False),
-            "odict_keys(['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'a', 'lazy', 'dog'])",
-        )
-        self.assertEqual(_pformat(d.items(), sort_dicts=False),
+OrderedDict([('the', 0),
+             ('quick', 1),
+             ('brown', 2),
+             ('fox', 3),
+             ('jumped', 4),
+             ('over', 5),
+             ('a', 6),
+             ('lazy', 7),
+             ('dog', 8)])""")
+        self.assertEqual(pprint.pformat(d.keys(), sort_dicts=False),
+"""\
+odict_keys(['the',
+ 'quick',
+ 'brown',
+ 'fox',
+ 'jumped',
+ 'over',
+ 'a',
+ 'lazy',
+ 'dog'])""")
+        self.assertEqual(pprint.pformat(d.items(), sort_dicts=False),
 """\
-odict_items([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5),
- ('a', 6), ('lazy', 7), ('dog', 8)])""")
-        self.assertEqual(_pformat(d.values(), sort_dicts=False),
+odict_items([('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)])""")
+        self.assertEqual(pprint.pformat(d.values(), sort_dicts=False),
                          "odict_values([0, 1, 2, 3, 4, 5, 6, 7, 8])")
 
     def test_mapping_proxy(self):
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = dict(zip(words, itertools.count()))
         m = types.MappingProxyType(d)
-        self.assertEqual(_pformat(m), """\
+        self.assertEqual(pprint.pformat(m), """\
 mappingproxy({'a': 6,
               'brown': 2,
               'dog': 8,
@@ -561,81 +581,49 @@ mappingproxy({'a': 6,
               'the': 0})""")
         d = collections.OrderedDict(zip(words, itertools.count()))
         m = types.MappingProxyType(d)
-        self.assertEqual(_pformat(m), """\
-mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
-                          ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+        self.assertEqual(pprint.pformat(m), """\
+mappingproxy(OrderedDict([('the', 0),
+                          ('quick', 1),
+                          ('brown', 2),
+                          ('fox', 3),
+                          ('jumped', 4),
+                          ('over', 5),
+                          ('a', 6),
+                          ('lazy', 7),
                           ('dog', 8)]))""")
 
     def test_dict_views(self):
         for dict_class in (dict, collections.OrderedDict, collections.Counter):
             empty = dict_class({})
             short = dict_class(dict(zip('edcba', 'edcba')))
-            lengths = {"empty": empty, "short": short}
+            long = dict_class(dict((chr(x), chr(x)) for x in range(90, 64, -1)))
+            lengths = {"empty": empty, "short": short, "long": long}
             prefix = "odict" if dict_class is collections.OrderedDict else "dict"
             for name, d in lengths.items():
                 with self.subTest(length=name, prefix=prefix):
+                    is_short = len(d) < 6
+                    joiner = ", " if is_short else ",\n "
                     k = d.keys()
                     v = d.values()
                     i = d.items()
-                    self.assertEqual(_pformat(k, sort_dicts=True),
+                    self.assertEqual(pprint.pformat(k, sort_dicts=True),
                                      prefix + "_keys([%s])" %
-                                     ", ".join(repr(key) for key in sorted(k)))
-                    self.assertEqual(_pformat(v, sort_dicts=True),
+                                     joiner.join(repr(key) for key in sorted(k)))
+                    self.assertEqual(pprint.pformat(v, sort_dicts=True),
                                      prefix + "_values([%s])" %
-                                     ", ".join(repr(val) for val in sorted(v)))
-                    self.assertEqual(_pformat(i, sort_dicts=True),
+                                     joiner.join(repr(val) for val in sorted(v)))
+                    self.assertEqual(pprint.pformat(i, sort_dicts=True),
                                      prefix + "_items([%s])" %
-                                     ", ".join(repr(item) for item in sorted(i)))
-                    self.assertEqual(_pformat(k, sort_dicts=False),
+                                     joiner.join(repr(item) for item in sorted(i)))
+                    self.assertEqual(pprint.pformat(k, sort_dicts=False),
                                      prefix + "_keys([%s])" %
-                                     ", ".join(repr(key) for key in k))
-                    self.assertEqual(_pformat(v, sort_dicts=False),
+                                     joiner.join(repr(key) for key in k))
+                    self.assertEqual(pprint.pformat(v, sort_dicts=False),
                                      prefix + "_values([%s])" %
-                                     ", ".join(repr(val) for val in v))
-                    self.assertEqual(_pformat(i, sort_dicts=False),
+                                     joiner.join(repr(val) for val in v))
+                    self.assertEqual(pprint.pformat(i, sort_dicts=False),
                                      prefix + "_items([%s])" %
-                                     ", ".join(repr(item) for item in i))
-
-        # Long case: views wrap with compact-mode packing.
-        long = dict((chr(x), chr(x)) for x in range(90, 64, -1))
-        sorted_keys = (
-            "['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',\n"
-            " 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']"
-        )
-        unsorted_keys = (
-            "['Z', 'Y', 'X', 'W', 'V', 'U', 'T', 'S', 'R', 'Q', 'P', 'O', 'N', 'M', 'L', 'K',\n"
-            " 'J', 'I', 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A']"
-        )
-        sorted_items = (
-            "[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ('E', 'E'), ('F', 'F'),\n"
-            " ('G', 'G'), ('H', 'H'), ('I', 'I'), ('J', 'J'), ('K', 'K'), ('L', 'L'),\n"
-            " ('M', 'M'), ('N', 'N'), ('O', 'O'), ('P', 'P'), ('Q', 'Q'), ('R', 'R'),\n"
-            " ('S', 'S'), ('T', 'T'), ('U', 'U'), ('V', 'V'), ('W', 'W'), ('X', 'X'),\n"
-            " ('Y', 'Y'), ('Z', 'Z')]"
-        )
-        unsorted_items = (
-            "[('Z', 'Z'), ('Y', 'Y'), ('X', 'X'), ('W', 'W'), ('V', 'V'), ('U', 'U'),\n"
-            " ('T', 'T'), ('S', 'S'), ('R', 'R'), ('Q', 'Q'), ('P', 'P'), ('O', 'O'),\n"
-            " ('N', 'N'), ('M', 'M'), ('L', 'L'), ('K', 'K'), ('J', 'J'), ('I', 'I'),\n"
-            " ('H', 'H'), ('G', 'G'), ('F', 'F'), ('E', 'E'), ('D', 'D'), ('C', 'C'),\n"
-            " ('B', 'B'), ('A', 'A')]"
-        )
-        for dict_class in (dict, collections.OrderedDict, collections.Counter):
-            d = dict_class(long)
-            prefix = "odict" if dict_class is collections.OrderedDict else "dict"
-            with self.subTest(length="long", prefix=prefix):
-                self.assertEqual(_pformat(d.keys(), sort_dicts=True),
-                                 f"{prefix}_keys({sorted_keys})")
-                self.assertEqual(_pformat(d.values(), sort_dicts=True),
-                                 f"{prefix}_values({sorted_keys})")
-                self.assertEqual(_pformat(d.items(), sort_dicts=True),
-                                 f"{prefix}_items({sorted_items})")
-                self.assertEqual(_pformat(d.keys(), sort_dicts=False),
-                                 f"{prefix}_keys({unsorted_keys})")
-                self.assertEqual(_pformat(d.values(), sort_dicts=False),
-                                 f"{prefix}_values({unsorted_keys})")
-                self.assertEqual(_pformat(d.items(), sort_dicts=False),
-                                 f"{prefix}_items({unsorted_items})")
+                                     joiner.join(repr(item) for item in i))
 
     def test_abc_views(self):
         empty = {}
@@ -653,55 +641,55 @@ mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
                 s = sorted(i)
                 joined_items = "({%s})" % joiner.join(["%r: %r" % (k, v) for (k, v) in i])
                 sorted_items = "({%s})" % joiner.join(["%r: %r" % (k, v) for (k, v) in s])
-                self.assertEqual(_pformat(KeysView(d), sort_dicts=True),
+                self.assertEqual(pprint.pformat(KeysView(d), sort_dicts=True),
                                  KeysView.__name__ + sorted_items)
-                self.assertEqual(_pformat(ItemsView(d), sort_dicts=True),
+                self.assertEqual(pprint.pformat(ItemsView(d), sort_dicts=True),
                                  ItemsView.__name__ + sorted_items)
-                self.assertEqual(_pformat(MappingView(d), sort_dicts=True),
+                self.assertEqual(pprint.pformat(MappingView(d), sort_dicts=True),
                                  MappingView.__name__ + sorted_items)
-                self.assertEqual(_pformat(MV(d), sort_dicts=True),
+                self.assertEqual(pprint.pformat(MV(d), sort_dicts=True),
                                  MV.__name__ + sorted_items)
-                self.assertEqual(_pformat(ValuesView(d), sort_dicts=True),
+                self.assertEqual(pprint.pformat(ValuesView(d), sort_dicts=True),
                                  ValuesView.__name__ + sorted_items)
-                self.assertEqual(_pformat(KeysView(d), sort_dicts=False),
+                self.assertEqual(pprint.pformat(KeysView(d), sort_dicts=False),
                                  KeysView.__name__ + joined_items)
-                self.assertEqual(_pformat(ItemsView(d), sort_dicts=False),
+                self.assertEqual(pprint.pformat(ItemsView(d), sort_dicts=False),
                                  ItemsView.__name__ + joined_items)
-                self.assertEqual(_pformat(MappingView(d), sort_dicts=False),
+                self.assertEqual(pprint.pformat(MappingView(d), sort_dicts=False),
                                  MappingView.__name__ + joined_items)
-                self.assertEqual(_pformat(MV(d), sort_dicts=False),
+                self.assertEqual(pprint.pformat(MV(d), sort_dicts=False),
                                  MV.__name__ + joined_items)
-                self.assertEqual(_pformat(ValuesView(d), sort_dicts=False),
+                self.assertEqual(pprint.pformat(ValuesView(d), sort_dicts=False),
                                  ValuesView.__name__ + joined_items)
 
     def test_nested_views(self):
         d = {1: MappingView({1: MappingView({1: MappingView({1: 2})})})}
         self.assertEqual(repr(d),
                          "{1: MappingView({1: MappingView({1: MappingView({1: 2})})})}")
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
                          "{1: MappingView({1: MappingView({1: MappingView({1: 2})})})}")
-        self.assertEqual(_pformat(d, depth=2),
+        self.assertEqual(pprint.pformat(d, depth=2),
                          "{1: MappingView({1: {...}})}")
         d = {}
         d1 = {1: d.values()}
         d2 = {1: d1.values()}
         d3 = {1: d2.values()}
-        self.assertEqual(_pformat(d3),
+        self.assertEqual(pprint.pformat(d3),
                          "{1: dict_values([dict_values([dict_values([])])])}")
-        self.assertEqual(_pformat(d3, depth=2),
+        self.assertEqual(pprint.pformat(d3, depth=2),
                          "{1: dict_values([{...}])}")
 
     def test_unorderable_items_views(self):
         """Check that views with unorderable items have stable sorting."""
         d = dict((((3+1j), 3), ((1+1j), (1+0j)), (1j, 0j), (500, None), (499, None)))
         iv = ItemsView(d)
-        self.assertEqual(_pformat(iv),
-                         _pformat(iv))
-        self.assertTrue(_pformat(iv).endswith(", 499: None, 500: None})"),
-                        _pformat(iv))
-        self.assertEqual(_pformat(d.items()),  # Won't be equal unless _safe_tuple
-                         _pformat(d.items()))  # is used in _safe_repr
-        self.assertTrue(_pformat(d.items()).endswith(", (499, None), (500, None)])"))
+        self.assertEqual(pprint.pformat(iv),
+                         pprint.pformat(iv))
+        self.assertTrue(pprint.pformat(iv).endswith(", 499: None, 500: None})"),
+                        pprint.pformat(iv))
+        self.assertEqual(pprint.pformat(d.items()),  # Won't be equal unless _safe_tuple
+                         pprint.pformat(d.items()))  # is used in _safe_repr
+        self.assertTrue(pprint.pformat(d.items()).endswith(", (499, None), (500, None)])"))
 
     def test_mapping_view_subclass_no_mapping(self):
         class BMV(MappingView):
@@ -710,7 +698,7 @@ mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
                 self.mapping = self._mapping
                 del self._mapping
 
-        self.assertRaises(AttributeError, _pformat, BMV({}))
+        self.assertRaises(AttributeError, pprint.pformat, BMV({}))
 
     def test_mapping_subclass_repr(self):
         """Test that mapping ABC views use their ._mapping's __repr__."""
@@ -734,10 +722,10 @@ mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
         self.assertEqual(repr(m), "MyMapping(['test', 1])")
         short_view_repr = "%s(MyMapping(['test', 1]))"
         self.assertEqual(repr(m.keys()), short_view_repr % "KeysView")
-        self.assertEqual(_pformat(m.items()), short_view_repr % "ItemsView")
-        self.assertEqual(_pformat(m.keys()), short_view_repr % "KeysView")
-        self.assertEqual(_pformat(MappingView(m)), short_view_repr % "MappingView")
-        self.assertEqual(_pformat(m.values()), short_view_repr % "ValuesView")
+        self.assertEqual(pprint.pformat(m.items()), short_view_repr % "ItemsView")
+        self.assertEqual(pprint.pformat(m.keys()), short_view_repr % "KeysView")
+        self.assertEqual(pprint.pformat(MappingView(m)), short_view_repr % "MappingView")
+        self.assertEqual(pprint.pformat(m.values()), short_view_repr % "ValuesView")
 
         alpha = "abcdefghijklmnopqrstuvwxyz"
         m = MyMapping(alpha)
@@ -745,19 +733,19 @@ mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
         long_view_repr = "%%s(MyMapping([%s]))" % alpha_repr
         self.assertEqual(repr(m), "MyMapping([%s])" % alpha_repr)
         self.assertEqual(repr(m.keys()), long_view_repr % "KeysView")
-        self.assertEqual(_pformat(m.items()), long_view_repr % "ItemsView")
-        self.assertEqual(_pformat(m.keys()), long_view_repr % "KeysView")
-        self.assertEqual(_pformat(MappingView(m)), long_view_repr % "MappingView")
-        self.assertEqual(_pformat(m.values()), long_view_repr % "ValuesView")
+        self.assertEqual(pprint.pformat(m.items()), long_view_repr % "ItemsView")
+        self.assertEqual(pprint.pformat(m.keys()), long_view_repr % "KeysView")
+        self.assertEqual(pprint.pformat(MappingView(m)), long_view_repr % "MappingView")
+        self.assertEqual(pprint.pformat(m.values()), long_view_repr % "ValuesView")
 
     def test_empty_simple_namespace(self):
         ns = types.SimpleNamespace()
-        formatted = _pformat(ns)
+        formatted = pprint.pformat(ns)
         self.assertEqual(formatted, "namespace()")
 
     def test_small_simple_namespace(self):
         ns = types.SimpleNamespace(a=1, b=2)
-        formatted = _pformat(ns)
+        formatted = pprint.pformat(ns)
         self.assertEqual(formatted, "namespace(a=1, b=2)")
 
     def test_simple_namespace(self):
@@ -772,7 +760,7 @@ mappingproxy(OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
             lazy=7,
             dog=8,
         )
-        formatted = pprint.pformat(ns, width=60, indent=4, compact=True)
+        formatted = pprint.pformat(ns, width=60, indent=4)
         self.assertEqual(formatted, """\
 namespace(the=0,
           quick=1,
@@ -797,7 +785,7 @@ namespace(the=0,
             lazy=7,
             dog=8,
         )
-        formatted = _pformat(ns, width=60)
+        formatted = pprint.pformat(ns, width=60)
         self.assertEqual(formatted, """\
 AdvancedNamespace(the=0,
                   quick=1,
@@ -811,17 +799,17 @@ AdvancedNamespace(the=0,
 
     def test_empty_dataclass(self):
         dc = dataclasses.make_dataclass("MyDataclass", ())()
-        formatted = _pformat(dc)
+        formatted = pprint.pformat(dc)
         self.assertEqual(formatted, "MyDataclass()")
 
     def test_small_dataclass(self):
         dc = dataclass1("text", 123)
-        formatted = _pformat(dc)
+        formatted = pprint.pformat(dc)
         self.assertEqual(formatted, "dataclass1(field1='text', field2=123, field3=False)")
 
     def test_larger_dataclass(self):
         dc = dataclass1("some fairly long text", int(1e10), True)
-        formatted = pprint.pformat([dc, dc], width=60, indent=4, compact=True)
+        formatted = pprint.pformat([dc, dc], width=60, indent=4)
         self.assertEqual(formatted, """\
 [   dataclass1(field1='some fairly long text',
                field2=10000000000,
@@ -832,12 +820,12 @@ AdvancedNamespace(the=0,
 
     def test_dataclass_with_repr(self):
         dc = dataclass2()
-        formatted = _pformat(dc, width=20)
+        formatted = pprint.pformat(dc, width=20)
         self.assertEqual(formatted, "custom repr that doesn't fit within pprint width")
 
     def test_dataclass_no_repr(self):
         dc = dataclass3()
-        formatted = _pformat(dc, width=10)
+        formatted = pprint.pformat(dc, width=10)
         self.assertRegex(
             formatted,
             fr"<{re.escape(__name__)}.dataclass3 object at \w+>",
@@ -846,7 +834,7 @@ AdvancedNamespace(the=0,
     def test_recursive_dataclass(self):
         dc = dataclass4(None)
         dc.a = dc
-        formatted = _pformat(dc, width=10)
+        formatted = pprint.pformat(dc, width=10)
         self.assertEqual(formatted, """\
 dataclass4(a=...,
            b=1)""")
@@ -856,7 +844,7 @@ dataclass4(a=...,
         dc6 = dataclass6(None)
         dc5.a = dc6
         dc6.c = dc5
-        formatted = _pformat(dc5, width=10)
+        formatted = pprint.pformat(dc5, width=10)
         self.assertEqual(formatted, """\
 dataclass5(a=dataclass6(c=...,
                         d=1),
@@ -870,7 +858,7 @@ dataclass5(a=dataclass6(c=...,
 {'names with spaces': 'should be presented using repr()',
  others.should.not.be: like.this}"""
 
-        dotted_printer = DottedPrettyPrinter(indent=1, compact=True)
+        dotted_printer = DottedPrettyPrinter()
         self.assertEqual(dotted_printer.pformat(o), exp)
 
         # length(repr(obj)) < width
@@ -882,29 +870,47 @@ dataclass5(a=dataclass6(c=...,
         self.assertEqual(dotted_printer.pformat(o2), exp2)
 
     def test_set_reprs(self):
-        self.assertEqual(_pformat(set()), 'set()')
-        self.assertEqual(_pformat(set(range(3))), '{0, 1, 2}')
-        self.assertEqual(_pformat(set(range(7)), width=20), '''\
-{0, 1, 2, 3, 4, 5,
+        self.assertEqual(pprint.pformat(set()), 'set()')
+        self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}')
+        self.assertEqual(pprint.pformat(set(range(7)), width=20), '''\
+{0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
  6}''')
-        self.assertEqual(_pformat(set2(range(7)), width=20), '''\
-set2({0, 1, 2, 3, 4,
-      5, 6})''')
-        self.assertEqual(_pformat(set3(range(7)), width=20),
+        self.assertEqual(pprint.pformat(set2(range(7)), width=20), '''\
+set2({0,
+      1,
+      2,
+      3,
+      4,
+      5,
+      6})''')
+        self.assertEqual(pprint.pformat(set3(range(7)), width=20),
                          'set3({0, 1, 2, 3, 4, 5, 6})')
 
-        self.assertEqual(_pformat(frozenset()), 'frozenset()')
-        self.assertEqual(_pformat(frozenset(range(3))),
+        self.assertEqual(pprint.pformat(frozenset()), 'frozenset()')
+        self.assertEqual(pprint.pformat(frozenset(range(3))),
                          'frozenset({0, 1, 2})')
-        self.assertEqual(_pformat(frozenset(range(7)), width=20), '''\
-frozenset({0, 1, 2,
-           3, 4, 5,
+        self.assertEqual(pprint.pformat(frozenset(range(7)), width=20), '''\
+frozenset({0,
+           1,
+           2,
+           3,
+           4,
+           5,
            6})''')
-        self.assertEqual(_pformat(frozenset2(range(7)), width=20), '''\
-frozenset2({0, 1, 2,
-            3, 4, 5,
+        self.assertEqual(pprint.pformat(frozenset2(range(7)), width=20), '''\
+frozenset2({0,
+            1,
+            2,
+            3,
+            4,
+            5,
             6})''')
-        self.assertEqual(_pformat(frozenset3(range(7)), width=20),
+        self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20),
                          'frozenset3({0, 1, 2, 3, 4, 5, 6})')
 
     def test_set_of_sets_reprs(self):
@@ -936,21 +942,21 @@ frozenset2({0, 1, 2,
         fs0 = frozenset()
         fs1 = frozenset(('abc', 'xyz'))
         data = frozenset((fs0, fs1))
-        self.assertEqual(_pformat(data),
+        self.assertEqual(pprint.pformat(data),
                          'frozenset({%r, %r})' % (fs0, fs1))
-        self.assertEqual(_pformat(data), repr(data))
+        self.assertEqual(pprint.pformat(data), repr(data))
 
         fs2 = frozenset(('one', 'two'))
         data = {fs2: frozenset((fs0, fs1))}
-        self.assertEqual(_pformat(data),
+        self.assertEqual(pprint.pformat(data),
                          "{%r: frozenset({%r, %r})}" % (fs2, fs0, fs1))
-        self.assertEqual(_pformat(data), repr(data))
+        self.assertEqual(pprint.pformat(data), repr(data))
 
         # Single-line, unordered:
         fs1 = frozenset(("xyz", "qwerty"))
         fs2 = frozenset(("abcd", "spam"))
         fs = frozenset((fs1, fs2))
-        self.assertEqual(_pformat(fs), repr(fs))
+        self.assertEqual(pprint.pformat(fs), repr(fs))
 
         # Multiline, unordered:
         def check(res, invariants):
@@ -960,7 +966,7 @@ frozenset2({0, 1, 2,
         fs1 = frozenset(('regular string', 'other string'))
         fs2 = frozenset(('third string', 'one more string'))
         check(
-            _pformat(frozenset((fs1, fs2))),
+            pprint.pformat(frozenset((fs1, fs2))),
             [
                 """
                 frozenset({%r,
@@ -975,7 +981,7 @@ frozenset2({0, 1, 2,
 
         # Everything is multiline, unordered:
         check(
-            _pformat(
+            pprint.pformat(
                 frozenset((
                     frozenset((
                         "xyz very-very long string",
@@ -1022,16 +1028,16 @@ frozenset2({0, 1, 2,
         nested_tuple = (1, (2, (3, (4, (5, 6)))))
         nested_dict = {1: {2: {3: {4: {5: {6: 6}}}}}}
         nested_list = [1, [2, [3, [4, [5, [6, []]]]]]]
-        self.assertEqual(_pformat(nested_tuple), repr(nested_tuple))
-        self.assertEqual(_pformat(nested_dict), repr(nested_dict))
-        self.assertEqual(_pformat(nested_list), repr(nested_list))
+        self.assertEqual(pprint.pformat(nested_tuple), repr(nested_tuple))
+        self.assertEqual(pprint.pformat(nested_dict), repr(nested_dict))
+        self.assertEqual(pprint.pformat(nested_list), repr(nested_list))
 
         lv1_tuple = '(1, (...))'
         lv1_dict = '{1: {...}}'
         lv1_list = '[1, [...]]'
-        self.assertEqual(_pformat(nested_tuple, depth=1), lv1_tuple)
-        self.assertEqual(_pformat(nested_dict, depth=1), lv1_dict)
-        self.assertEqual(_pformat(nested_list, depth=1), lv1_list)
+        self.assertEqual(pprint.pformat(nested_tuple, depth=1), lv1_tuple)
+        self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict)
+        self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list)
 
     def test_sort_unorderable_values(self):
         # Issue 3976:  sorted pprints fail for unorderable values.
@@ -1041,24 +1047,24 @@ frozenset2({0, 1, 2,
         skeys = sorted(keys, key=id)
         clean = lambda s: s.replace(' ', '').replace('\n','')
 
-        self.assertEqual(clean(_pformat(set(keys))),
+        self.assertEqual(clean(pprint.pformat(set(keys))),
             '{' + ','.join(map(repr, skeys)) + '}')
-        self.assertEqual(clean(_pformat(frozenset(keys))),
+        self.assertEqual(clean(pprint.pformat(frozenset(keys))),
             'frozenset({' + ','.join(map(repr, skeys)) + '})')
-        self.assertEqual(clean(_pformat(dict.fromkeys(keys))),
+        self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))),
             '{' + ','.join('%r:None' % k for k in skeys) + '}')
-        self.assertEqual(clean(_pformat(dict.fromkeys(keys).keys())),
+        self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys).keys())),
             'dict_keys([' + ','.join('%r' % k for k in skeys) + '])')
-        self.assertEqual(clean(_pformat(dict.fromkeys(keys).items())),
+        self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys).items())),
             'dict_items([' + ','.join('(%r,None)' % k for k in skeys) + '])')
 
         # Issue 10017: TypeError on user-defined types as dict keys.
-        self.assertEqual(_pformat({Unorderable: 0, 1: 0}),
+        self.assertEqual(pprint.pformat({Unorderable: 0, 1: 0}),
                          '{1: 0, ' + repr(Unorderable) +': 0}')
 
         # Issue 14998: TypeError on tuples with NoneTypes as dict keys.
         keys = [(1,), (None,)]
-        self.assertEqual(_pformat(dict.fromkeys(keys, 0)),
+        self.assertEqual(pprint.pformat(dict.fromkeys(keys, 0)),
                          '{%r: 0, %r: 0}' % tuple(sorted(keys, key=id)))
 
     def test_sort_orderable_and_unorderable_values(self):
@@ -1071,24 +1077,24 @@ frozenset2({0, 1, 2,
         self.assertEqual(sorted([b, a]), [a, b])
         self.assertEqual(sorted([a, b]), [a, b])
         # set
-        self.assertEqual(_pformat(set([b, a]), width=1),
+        self.assertEqual(pprint.pformat(set([b, a]), width=1),
                          '{%r,\n %r}' % (a, b))
-        self.assertEqual(_pformat(set([a, b]), width=1),
+        self.assertEqual(pprint.pformat(set([a, b]), width=1),
                          '{%r,\n %r}' % (a, b))
         # dict
-        self.assertEqual(_pformat(dict.fromkeys([b, a]), width=1),
+        self.assertEqual(pprint.pformat(dict.fromkeys([b, a]), width=1),
                          '{%r: None,\n %r: None}' % (a, b))
-        self.assertEqual(_pformat(dict.fromkeys([a, b]), width=1),
+        self.assertEqual(pprint.pformat(dict.fromkeys([a, b]), width=1),
                          '{%r: None,\n %r: None}' % (a, b))
 
     def test_str_wrap(self):
         # pprint tries to wrap strings intelligently
         fox = 'the quick brown fox jumped over a lazy dog'
-        self.assertEqual(_pformat(fox, width=19), """\
+        self.assertEqual(pprint.pformat(fox, width=19), """\
 ('the quick brown '
  'fox jumped over '
  'a lazy dog')""")
-        self.assertEqual(_pformat({'a': 1, 'b': fox, 'c': 2},
+        self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2},
                                         width=25), """\
 {'a': 1,
  'b': 'the quick brown '
@@ -1101,28 +1107,28 @@ frozenset2({0, 1, 2,
         # - non-ASCII is allowed
         # - an apostrophe doesn't disrupt the pprint
         special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo"
-        self.assertEqual(_pformat(special, width=68), repr(special))
-        self.assertEqual(_pformat(special, width=31), """\
+        self.assertEqual(pprint.pformat(special, width=68), repr(special))
+        self.assertEqual(pprint.pformat(special, width=31), """\
 ('Portons dix bons "whiskys"\\n'
  "à l'avocat goujat\\t qui "
  'fumait au zoo')""")
-        self.assertEqual(_pformat(special, width=20), """\
+        self.assertEqual(pprint.pformat(special, width=20), """\
 ('Portons dix bons '
  '"whiskys"\\n'
  "à l'avocat "
  'goujat\\t qui '
  'fumait au zoo')""")
-        self.assertEqual(_pformat([[[[[special]]]]], width=35), """\
+        self.assertEqual(pprint.pformat([[[[[special]]]]], width=35), """\
 [[[[['Portons dix bons "whiskys"\\n'
      "à l'avocat goujat\\t qui "
      'fumait au zoo']]]]]""")
-        self.assertEqual(_pformat([[[[[special]]]]], width=25), """\
+        self.assertEqual(pprint.pformat([[[[[special]]]]], width=25), """\
 [[[[['Portons dix bons '
      '"whiskys"\\n'
      "à l'avocat "
      'goujat\\t qui '
      'fumait au zoo']]]]]""")
-        self.assertEqual(_pformat([[[[[special]]]]], width=23), """\
+        self.assertEqual(pprint.pformat([[[[[special]]]]], width=23), """\
 [[[[['Portons dix '
      'bons "whiskys"\\n'
      "à l'avocat "
@@ -1131,14 +1137,14 @@ frozenset2({0, 1, 2,
      'zoo']]]]]""")
         # An unwrappable string is formatted as its repr
         unwrappable = "x" * 100
-        self.assertEqual(_pformat(unwrappable, width=80), repr(unwrappable))
-        self.assertEqual(_pformat(''), "''")
+        self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable))
+        self.assertEqual(pprint.pformat(''), "''")
         # Check that the pprint is a usable repr
         special *= 10
         for width in range(3, 40):
-            formatted = _pformat(special, width=width)
+            formatted = pprint.pformat(special, width=width)
             self.assertEqual(eval(formatted), special)
-            formatted = _pformat([special] * 2, width=width)
+            formatted = pprint.pformat([special] * 2, width=width)
             self.assertEqual(eval(formatted), [special] * 2)
 
     def test_compact(self):
@@ -1151,7 +1157,7 @@ frozenset2({0, 1, 2,
   14, 15],
  [], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3],
  [0, 1, 2, 3, 4]]"""
-        self.assertEqual(_pformat(o, width=47, compact=True), expected)
+        self.assertEqual(pprint.pformat(o, width=47, compact=True), expected)
 
     def test_compact_width(self):
         levels = 20
@@ -1160,117 +1166,117 @@ frozenset2({0, 1, 2,
         for i in range(levels - 1):
             o = [o]
         for w in range(levels * 2 + 1, levels + 3 * number - 1):
-            lines = _pformat(o, width=w, compact=True).splitlines()
+            lines = pprint.pformat(o, width=w, compact=True).splitlines()
             maxwidth = max(map(len, lines))
             self.assertLessEqual(maxwidth, w)
             self.assertGreater(maxwidth, w - 3)
 
     def test_bytes_wrap(self):
-        self.assertEqual(_pformat(b'', width=1), "b''")
-        self.assertEqual(_pformat(b'abcd', width=1), "b'abcd'")
+        self.assertEqual(pprint.pformat(b'', width=1), "b''")
+        self.assertEqual(pprint.pformat(b'abcd', width=1), "b'abcd'")
         letters = b'abcdefghijklmnopqrstuvwxyz'
-        self.assertEqual(_pformat(letters, width=29), repr(letters))
-        self.assertEqual(_pformat(letters, width=19), """\
+        self.assertEqual(pprint.pformat(letters, width=29), repr(letters))
+        self.assertEqual(pprint.pformat(letters, width=19), """\
 (b'abcdefghijkl'
  b'mnopqrstuvwxyz')""")
-        self.assertEqual(_pformat(letters, width=18), """\
+        self.assertEqual(pprint.pformat(letters, width=18), """\
 (b'abcdefghijkl'
  b'mnopqrstuvwx'
  b'yz')""")
-        self.assertEqual(_pformat(letters, width=16), """\
+        self.assertEqual(pprint.pformat(letters, width=16), """\
 (b'abcdefghijkl'
  b'mnopqrstuvwx'
  b'yz')""")
         special = bytes(range(16))
-        self.assertEqual(_pformat(special, width=61), repr(special))
-        self.assertEqual(_pformat(special, width=48), """\
+        self.assertEqual(pprint.pformat(special, width=61), repr(special))
+        self.assertEqual(pprint.pformat(special, width=48), """\
 (b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
  b'\\x0c\\r\\x0e\\x0f')""")
-        self.assertEqual(_pformat(special, width=32), """\
+        self.assertEqual(pprint.pformat(special, width=32), """\
 (b'\\x00\\x01\\x02\\x03'
  b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
  b'\\x0c\\r\\x0e\\x0f')""")
-        self.assertEqual(_pformat(special, width=1), """\
+        self.assertEqual(pprint.pformat(special, width=1), """\
 (b'\\x00\\x01\\x02\\x03'
  b'\\x04\\x05\\x06\\x07'
  b'\\x08\\t\\n\\x0b'
  b'\\x0c\\r\\x0e\\x0f')""")
-        self.assertEqual(_pformat({'a': 1, 'b': letters, 'c': 2},
+        self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
                                         width=21), """\
 {'a': 1,
  'b': b'abcdefghijkl'
       b'mnopqrstuvwx'
       b'yz',
  'c': 2}""")
-        self.assertEqual(_pformat({'a': 1, 'b': letters, 'c': 2},
+        self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
                                         width=20), """\
 {'a': 1,
  'b': b'abcdefgh'
       b'ijklmnop'
       b'qrstuvwxyz',
  'c': 2}""")
-        self.assertEqual(_pformat([[[[[[letters]]]]]], width=25), """\
+        self.assertEqual(pprint.pformat([[[[[[letters]]]]]], width=25), """\
 [[[[[[b'abcdefghijklmnop'
       b'qrstuvwxyz']]]]]]""")
-        self.assertEqual(_pformat([[[[[[special]]]]]], width=41), """\
+        self.assertEqual(pprint.pformat([[[[[[special]]]]]], width=41), """\
 [[[[[[b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
       b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f']]]]]]""")
         # Check that the pprint is a usable repr
         for width in range(1, 64):
-            formatted = _pformat(special, width=width)
+            formatted = pprint.pformat(special, width=width)
             self.assertEqual(eval(formatted), special)
-            formatted = _pformat([special] * 2, width=width)
+            formatted = pprint.pformat([special] * 2, width=width)
             self.assertEqual(eval(formatted), [special] * 2)
 
     def test_bytearray_wrap(self):
-        self.assertEqual(_pformat(bytearray(), width=1), "bytearray(b'')")
+        self.assertEqual(pprint.pformat(bytearray(), width=1), "bytearray(b'')")
         letters = bytearray(b'abcdefghijklmnopqrstuvwxyz')
-        self.assertEqual(_pformat(letters, width=40), repr(letters))
-        self.assertEqual(_pformat(letters, width=28), """\
+        self.assertEqual(pprint.pformat(letters, width=40), repr(letters))
+        self.assertEqual(pprint.pformat(letters, width=28), """\
 bytearray(b'abcdefghijkl'
           b'mnopqrstuvwxyz')""")
-        self.assertEqual(_pformat(letters, width=27), """\
+        self.assertEqual(pprint.pformat(letters, width=27), """\
 bytearray(b'abcdefghijkl'
           b'mnopqrstuvwx'
           b'yz')""")
-        self.assertEqual(_pformat(letters, width=25), """\
+        self.assertEqual(pprint.pformat(letters, width=25), """\
 bytearray(b'abcdefghijkl'
           b'mnopqrstuvwx'
           b'yz')""")
         special = bytearray(range(16))
-        self.assertEqual(_pformat(special, width=72), repr(special))
-        self.assertEqual(_pformat(special, width=57), """\
+        self.assertEqual(pprint.pformat(special, width=72), repr(special))
+        self.assertEqual(pprint.pformat(special, width=57), """\
 bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
           b'\\x0c\\r\\x0e\\x0f')""")
-        self.assertEqual(_pformat(special, width=41), """\
+        self.assertEqual(pprint.pformat(special, width=41), """\
 bytearray(b'\\x00\\x01\\x02\\x03'
           b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
           b'\\x0c\\r\\x0e\\x0f')""")
-        self.assertEqual(_pformat(special, width=1), """\
+        self.assertEqual(pprint.pformat(special, width=1), """\
 bytearray(b'\\x00\\x01\\x02\\x03'
           b'\\x04\\x05\\x06\\x07'
           b'\\x08\\t\\n\\x0b'
           b'\\x0c\\r\\x0e\\x0f')""")
-        self.assertEqual(_pformat({'a': 1, 'b': letters, 'c': 2},
+        self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
                                         width=31), """\
 {'a': 1,
  'b': bytearray(b'abcdefghijkl'
                 b'mnopqrstuvwx'
                 b'yz'),
  'c': 2}""")
-        self.assertEqual(_pformat([[[[[letters]]]]], width=37), """\
+        self.assertEqual(pprint.pformat([[[[[letters]]]]], width=37), """\
 [[[[[bytearray(b'abcdefghijklmnop'
                b'qrstuvwxyz')]]]]]""")
-        self.assertEqual(_pformat([[[[[special]]]]], width=50), """\
+        self.assertEqual(pprint.pformat([[[[[special]]]]], width=50), """\
 [[[[[bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
                b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f')]]]]]""")
 
     def test_default_dict(self):
         d = collections.defaultdict(int)
-        self.assertEqual(_pformat(d, width=1), "defaultdict(<class 'int'>, {})")
+        self.assertEqual(pprint.pformat(d, width=1), "defaultdict(<class 'int'>, {})")
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = collections.defaultdict(int, zip(words, itertools.count()))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
 defaultdict(<class 'int'>,
             {'a': 6,
@@ -1285,15 +1291,15 @@ defaultdict(<class 'int'>,
 
     def test_counter(self):
         d = collections.Counter()
-        self.assertEqual(_pformat(d, width=1), "Counter()")
+        self.assertEqual(pprint.pformat(d, width=1), "Counter()")
         d = collections.Counter('senselessness')
-        self.assertEqual(_pformat(d, width=40),
+        self.assertEqual(pprint.pformat(d, width=40),
 """\
 Counter({'s': 6,
          'e': 4,
          'n': 2,
          'l': 1})""")
-        self.assertEqual(_pformat(d, indent=2, width=1),
+        self.assertEqual(pprint.pformat(d, indent=2, width=1),
 """\
 Counter({ 's': 6,
           'e': 4,
@@ -1302,11 +1308,11 @@ Counter({ 's': 6,
 
     def test_chainmap(self):
         d = collections.ChainMap()
-        self.assertEqual(_pformat(d, width=1), "ChainMap({})")
+        self.assertEqual(pprint.pformat(d, width=1), "ChainMap({})")
         words = 'the quick brown fox jumped over a lazy dog'.split()
         items = list(zip(words, itertools.count()))
         d = collections.ChainMap(dict(items))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
 ChainMap({'a': 6,
           'brown': 2,
@@ -1318,7 +1324,7 @@ ChainMap({'a': 6,
           'quick': 1,
           'the': 0})""")
         d = collections.ChainMap(dict(items), collections.OrderedDict(items))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
 ChainMap({'a': 6,
           'brown': 2,
@@ -1329,10 +1335,16 @@ ChainMap({'a': 6,
           'over': 5,
           'quick': 1,
           'the': 0},
-         OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
-                      ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+         OrderedDict([('the', 0),
+                      ('quick', 1),
+                      ('brown', 2),
+                      ('fox', 3),
+                      ('jumped', 4),
+                      ('over', 5),
+                      ('a', 6),
+                      ('lazy', 7),
                       ('dog', 8)]))""")
-        self.assertEqual(_pformat(d.keys()),
+        self.assertEqual(pprint.pformat(d.keys()),
 """\
 KeysView(ChainMap({'a': 6,
           'brown': 2,
@@ -1343,10 +1355,16 @@ KeysView(ChainMap({'a': 6,
           'over': 5,
           'quick': 1,
           'the': 0},
-         OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
-                      ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+         OrderedDict([('the', 0),
+                      ('quick', 1),
+                      ('brown', 2),
+                      ('fox', 3),
+                      ('jumped', 4),
+                      ('over', 5),
+                      ('a', 6),
+                      ('lazy', 7),
                       ('dog', 8)])))""")
-        self.assertEqual(_pformat(d.items()),
+        self.assertEqual(pprint.pformat(d.items()),
  """\
 ItemsView(ChainMap({'a': 6,
           'brown': 2,
@@ -1357,10 +1375,16 @@ ItemsView(ChainMap({'a': 6,
           'over': 5,
           'quick': 1,
           'the': 0},
-         OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
-                      ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+         OrderedDict([('the', 0),
+                      ('quick', 1),
+                      ('brown', 2),
+                      ('fox', 3),
+                      ('jumped', 4),
+                      ('over', 5),
+                      ('a', 6),
+                      ('lazy', 7),
                       ('dog', 8)])))""")
-        self.assertEqual(_pformat(d.values()),
+        self.assertEqual(pprint.pformat(d.values()),
  """\
 ValuesView(ChainMap({'a': 6,
           'brown': 2,
@@ -1371,34 +1395,52 @@ ValuesView(ChainMap({'a': 6,
           'over': 5,
           'quick': 1,
           'the': 0},
-         OrderedDict([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3),
-                      ('jumped', 4), ('over', 5), ('a', 6), ('lazy', 7),
+         OrderedDict([('the', 0),
+                      ('quick', 1),
+                      ('brown', 2),
+                      ('fox', 3),
+                      ('jumped', 4),
+                      ('over', 5),
+                      ('a', 6),
+                      ('lazy', 7),
                       ('dog', 8)])))""")
 
     def test_deque(self):
         d = collections.deque()
-        self.assertEqual(_pformat(d, width=1), "deque([])")
+        self.assertEqual(pprint.pformat(d, width=1), "deque([])")
         d = collections.deque(maxlen=7)
-        self.assertEqual(_pformat(d, width=1), "deque([], maxlen=7)")
+        self.assertEqual(pprint.pformat(d, width=1), "deque([], maxlen=7)")
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = collections.deque(zip(words, itertools.count()))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
-deque([('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4),
-       ('over', 5), ('a', 6), ('lazy', 7), ('dog', 8)])""")
+deque([('the', 0),
+       ('quick', 1),
+       ('brown', 2),
+       ('fox', 3),
+       ('jumped', 4),
+       ('over', 5),
+       ('a', 6),
+       ('lazy', 7),
+       ('dog', 8)])""")
         d = collections.deque(zip(words, itertools.count()), maxlen=7)
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
-deque([('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5), ('a', 6),
-       ('lazy', 7), ('dog', 8)],
+deque([('brown', 2),
+       ('fox', 3),
+       ('jumped', 4),
+       ('over', 5),
+       ('a', 6),
+       ('lazy', 7),
+       ('dog', 8)],
       maxlen=7)""")
 
     def test_user_dict(self):
         d = collections.UserDict()
-        self.assertEqual(_pformat(d, width=1), "{}")
+        self.assertEqual(pprint.pformat(d, width=1), "{}")
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = collections.UserDict(zip(words, itertools.count()))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
 {'a': 6,
  'brown': 2,
@@ -1409,7 +1451,7 @@ deque([('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5), ('a', 6),
  'over': 5,
  'quick': 1,
  'the': 0}""")
-        self.assertEqual(_pformat(d.keys()), """\
+        self.assertEqual(pprint.pformat(d.keys()), """\
 KeysView({'a': 6,
  'brown': 2,
  'dog': 8,
@@ -1419,7 +1461,7 @@ KeysView({'a': 6,
  'over': 5,
  'quick': 1,
  'the': 0})""")
-        self.assertEqual(_pformat(d.items()), """\
+        self.assertEqual(pprint.pformat(d.items()), """\
 ItemsView({'a': 6,
  'brown': 2,
  'dog': 8,
@@ -1429,7 +1471,7 @@ ItemsView({'a': 6,
  'over': 5,
  'quick': 1,
  'the': 0})""")
-        self.assertEqual(_pformat(d.values()), """\
+        self.assertEqual(pprint.pformat(d.values()), """\
 ValuesView({'a': 6,
  'brown': 2,
  'dog': 8,
@@ -1442,24 +1484,31 @@ ValuesView({'a': 6,
 
     def test_user_list(self):
         d = collections.UserList()
-        self.assertEqual(_pformat(d, width=1), "[]")
+        self.assertEqual(pprint.pformat(d, width=1), "[]")
         words = 'the quick brown fox jumped over a lazy dog'.split()
         d = collections.UserList(zip(words, itertools.count()))
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
-[('the', 0), ('quick', 1), ('brown', 2), ('fox', 3), ('jumped', 4), ('over', 5),
- ('a', 6), ('lazy', 7), ('dog', 8)]""")
+[('the', 0),
+ ('quick', 1),
+ ('brown', 2),
+ ('fox', 3),
+ ('jumped', 4),
+ ('over', 5),
+ ('a', 6),
+ ('lazy', 7),
+ ('dog', 8)]""")
 
     def test_user_string(self):
         d = collections.UserString('')
-        self.assertEqual(_pformat(d, width=1), "''")
+        self.assertEqual(pprint.pformat(d, width=1), "''")
         d = collections.UserString('the quick brown fox jumped over a lazy dog')
-        self.assertEqual(_pformat(d, width=20),
+        self.assertEqual(pprint.pformat(d, width=20),
 """\
 ('the quick brown '
  'fox jumped over '
  'a lazy dog')""")
-        self.assertEqual(_pformat({1: d}, width=20),
+        self.assertEqual(pprint.pformat({1: d}, width=20),
 """\
 {1: 'the quick '
     'brown fox '
@@ -1468,22 +1517,22 @@ ValuesView({'a': 6,
 
     def test_template(self):
         d = t""
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
                          "Template(strings=('',), interpolations=())")
-        self.assertEqual(_pformat(d), repr(d))
-        self.assertEqual(_pformat(d, width=1),
+        self.assertEqual(pprint.pformat(d), repr(d))
+        self.assertEqual(pprint.pformat(d, width=1),
 """\
 Template(strings=('',),
          interpolations=())""")
         name = "World"
         d = t"Hello {name}"
-        self.assertEqual(_pformat(d),
+        self.assertEqual(pprint.pformat(d),
 """\
 Template(strings=('Hello ', ''),
          interpolations=(Interpolation('World', 'name', None, ''),))""")
         ver = {3.13: False, 3.14: True}
         d = t"Hello { {"name": "Python", "version": ver}!s:z}!"
-        self.assertEqual(_pformat(d, width=1),
+        self.assertEqual(pprint.pformat(d, width=1),
 """\
 Template(strings=('Hello ',
                   '!'),
@@ -1501,13 +1550,13 @@ Template(strings=('Hello ',
     def test_expand_template(self):
         d = t""
         self.assertEqual(
-            pprint.pformat(d),
+            pprint.pformat(d, expand=True),
             "Template(strings=('',), interpolations=())",
         )
         name = "World"
         d = t"Hello {name}"
         self.assertEqual(
-            pprint.pformat(d, width=40, indent=4),
+            pprint.pformat(d, width=40, indent=4, expand=True),
             """\
 Template(
     strings=('Hello ', ''),
@@ -1524,7 +1573,7 @@ Template(
         ver = {3.13: False, 3.14: True}
         d = t"Hello { {"name": "Python", "version": ver}!s:z}!"
         self.assertEqual(
-            pprint.pformat(d, width=40, indent=4),
+            pprint.pformat(d, width=40, indent=4, expand=True),
             """\
 Template(
     strings=('Hello ', '!'),
@@ -1565,7 +1614,8 @@ Template(
             corge=7,
             garply=(1, 2, 3, 4),
         )
-        self.assertEqual(pprint.pformat(dummy_dataclass, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_dataclass, width=40, indent=4,
+                                        expand=True),
 """\
 DummyDataclass(
     foo='foo',
@@ -1585,7 +1635,8 @@ DummyDataclass(
             "quux": ["foo", "bar", "baz"],
             "corge": 7,
         }
-        self.assertEqual(pprint.pformat(dummy_dict, width=40, indent=4, sort_dicts=False),
+        self.assertEqual(pprint.pformat(dummy_dict, width=40, indent=4,
+                                        expand=True, sort_dicts=False),
 """\
 {
     'foo': 'bar',
@@ -1603,7 +1654,8 @@ DummyDataclass(
                 ("baz", 123),
             ]
         )
-        self.assertEqual(pprint.pformat(dummy_ordered_dict, width=20, indent=4),
+        self.assertEqual(pprint.pformat(dummy_ordered_dict, width=20, indent=4,
+                                        expand=True),
 """\
 OrderedDict([
     ('foo', 1),
@@ -1618,7 +1670,8 @@ OrderedDict([
             "baz",
             "qux",
         ]
-        self.assertEqual(pprint.pformat(dummy_list, width=20, indent=4),
+        self.assertEqual(pprint.pformat(dummy_list, width=20, indent=4,
+                                        expand=True),
 """\
 [
     'foo',
@@ -1636,7 +1689,8 @@ OrderedDict([
             5,
             6,
         )
-        self.assertEqual(pprint.pformat(dummy_tuple, width=20, indent=4),
+        self.assertEqual(pprint.pformat(dummy_tuple, width=20, indent=4,
+                                        expand=True),
 """\
 (
     'foo',
@@ -1649,7 +1703,7 @@ OrderedDict([
 
     def test_expand_single_element_tuple(self):
         self.assertEqual(
-            pprint.pformat((1,), width=1, indent=4),
+            pprint.pformat((1,), width=1, indent=4, expand=True),
             """\
 (
     1,
@@ -1663,7 +1717,8 @@ OrderedDict([
             "qux",
             (1, 2, 3),
         }
-        self.assertEqual(pprint.pformat(dummy_set, width=20, indent=4),
+        self.assertEqual(pprint.pformat(dummy_set, width=20, indent=4,
+                                        expand=True),
 """\
 {
     'bar',
@@ -1686,7 +1741,8 @@ OrderedDict([
                 frozenset(dummy_set),
             }
         )
-        self.assertEqual(pprint.pformat(dummy_frozenset, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_frozenset, width=40, indent=4,
+                                        expand=True),
 """\
 frozenset({
     frozenset({(1, 2, 3)}),
@@ -1701,7 +1757,7 @@ frozenset({
             {"foo": "bar", "baz": 123, "qux": [1, 2]}
         )
         self.assertEqual(
-            pprint.pformat(dummy_frozendict, width=20, indent=4),
+            pprint.pformat(dummy_frozendict, width=20, indent=4, expand=True),
             """\
 frozendict({
     'baz': 123,
@@ -1712,7 +1768,8 @@ frozendict({
 
     def test_expand_bytes(self):
         dummy_bytes = b"Hello world! foo bar baz 123 456 789"
-        self.assertEqual(pprint.pformat(dummy_bytes, width=20, indent=4),
+        self.assertEqual(pprint.pformat(dummy_bytes, width=20, indent=4,
+                                        expand=True),
 """\
 (
     b'Hello world!'
@@ -1723,7 +1780,8 @@ frozendict({
     def test_expand_bytearray(self):
         dummy_bytes = b"Hello world! foo bar baz 123 456 789"
         dummy_byte_array = bytearray(dummy_bytes)
-        self.assertEqual(pprint.pformat(dummy_byte_array, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_byte_array, width=40, indent=4,
+                                        expand=True),
 """\
 bytearray(
     b'Hello world! foo bar baz 123 456'
@@ -1739,7 +1797,8 @@ bytearray(
             "corge": 7,
         }
         dummy_mappingproxy = types.MappingProxyType(dummy_dict)
-        self.assertEqual(pprint.pformat(dummy_mappingproxy, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_mappingproxy, width=40, indent=4,
+                                        expand=True),
 """\
 mappingproxy({
     'baz': 123,
@@ -1760,7 +1819,8 @@ mappingproxy({
             ),
         )
 
-        self.assertEqual(pprint.pformat(dummy_namespace, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_namespace, width=40, indent=4,
+                                        expand=True),
 """\
 namespace(
     foo='bar',
@@ -1778,7 +1838,8 @@ namespace(
         dummy_defaultdict["foo"].append("baz")
         dummy_defaultdict["foo"].append("qux")
         dummy_defaultdict["bar"] = {"foo": "bar", "baz": None}
-        self.assertEqual(pprint.pformat(dummy_defaultdict, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_defaultdict, width=40, indent=4,
+                                        expand=True),
 """\
 defaultdict(<class 'list'>, {
     'bar': {'baz': None, 'foo': 'bar'},
@@ -1795,7 +1856,8 @@ Counter({
     'd': 2,
     'e': 1,
 })"""
-        self.assertEqual(pprint.pformat(dummy_counter, width=40, indent=4), expected)
+        self.assertEqual(pprint.pformat(dummy_counter, width=40, indent=4,
+                                        expand=True), expected)
 
         expected2 = """\
 Counter({
@@ -1805,7 +1867,8 @@ Counter({
   'd': 2,
   'e': 1,
 })"""
-        self.assertEqual(pprint.pformat(dummy_counter, width=20, indent=2), expected2)
+        self.assertEqual(pprint.pformat(dummy_counter, width=20, indent=2,
+                                        expand=True), expected2)
 
     def test_expand_chainmap(self):
         dummy_dict = {
@@ -1821,7 +1884,8 @@ Counter({
             {"corge": dummy_dict},
         )
         dummy_chainmap.maps.append({"garply": "waldo"})
-        self.assertEqual(pprint.pformat(dummy_chainmap, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_chainmap, width=40, indent=4,
+                                        expand=True),
 """\
 ChainMap(
     {'foo': 'bar'},
@@ -1863,7 +1927,8 @@ ChainMap(
         dummy_deque.append(dummy_dict)
         dummy_deque.extend(dummy_list)
         dummy_deque.appendleft(dummy_set)
-        self.assertEqual(pprint.pformat(dummy_deque, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_deque, width=40, indent=4,
+                                        expand=True),
 """\
 deque([
     {(1, 2, 3)},
@@ -1894,7 +1959,8 @@ deque([
                                         "corge": 7 })
         dummy_userdict.access_count = 5
 
-        self.assertEqual(pprint.pformat(dummy_userdict, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_userdict, width=40, indent=4,
+                                        expand=True),
 """\
 {
     'baz': 123,
@@ -1914,7 +1980,8 @@ deque([
         dummy_userlist = DummyUserList(["first", 2, {"key": "value"},
                                        [4, 5, 6]])
 
-        self.assertEqual(pprint.pformat(dummy_userlist, width=40, indent=4),
+        self.assertEqual(pprint.pformat(dummy_userlist, width=40, indent=4,
+                                        expand=True),
 """\
 [
     'first',
@@ -1926,7 +1993,7 @@ deque([
     def test_expand_dict_keys(self):
         d = {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}
         self.assertEqual(
-            pprint.pformat(d.keys(), width=20, indent=4),
+            pprint.pformat(d.keys(), width=20, indent=4, expand=True),
             """\
 dict_keys([
     'bar',
@@ -1940,7 +2007,7 @@ dict_keys([
     def test_expand_dict_values(self):
         d = {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}
         self.assertEqual(
-            pprint.pformat(d.values(), width=20, indent=4),
+            pprint.pformat(d.values(), width=20, indent=4, expand=True),
             """\
 dict_values([
     1,
@@ -1954,7 +2021,7 @@ dict_values([
     def test_expand_dict_items(self):
         d = {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}
         self.assertEqual(
-            pprint.pformat(d.items(), width=20, indent=4),
+            pprint.pformat(d.items(), width=20, indent=4, expand=True),
             """\
 dict_items([
     ('bar', 2),
@@ -1968,7 +2035,7 @@ dict_items([
     def test_expand_str(self):
         s = "The quick brown fox jumped over the lazy dog " * 3
         self.assertEqual(
-            pprint.pformat(s, width=40, indent=4),
+            pprint.pformat(s, width=40, indent=4, expand=True),
             """\
 (
     'The quick brown fox jumped over '
index ac5c4296c663d07581947e0abd27c09042cc45ea..09ee2d53f98f585a8b65455094c03360ecd0a0a5 100644 (file)
@@ -1032,19 +1032,15 @@ if feature_macros['USE_STACKCHECK']:
         'PyOS_CheckStack',
     )
 
-EXPECTED_FEATURE_MACROS = set([
-    'HAVE_FORK',
-    'MS_WINDOWS',
-    'PY_HAVE_THREAD_NATIVE_ID',
-    'Py_REF_DEBUG',
-    'Py_TRACE_REFS',
-    'USE_STACKCHECK',
-])
-WINDOWS_FEATURE_MACROS = {
-    'HAVE_FORK': False,
-    'MS_WINDOWS': True,
-    'PY_HAVE_THREAD_NATIVE_ID': True,
-    'Py_REF_DEBUG': 'maybe',
-    'Py_TRACE_REFS': 'maybe',
-    'USE_STACKCHECK': 'maybe',
-}
+EXPECTED_FEATURE_MACROS = set(['HAVE_FORK',
+ 'MS_WINDOWS',
+ 'PY_HAVE_THREAD_NATIVE_ID',
+ 'Py_REF_DEBUG',
+ 'Py_TRACE_REFS',
+ 'USE_STACKCHECK'])
+WINDOWS_FEATURE_MACROS = {'HAVE_FORK': False,
+ 'MS_WINDOWS': True,
+ 'PY_HAVE_THREAD_NATIVE_ID': True,
+ 'Py_REF_DEBUG': 'maybe',
+ 'Py_TRACE_REFS': 'maybe',
+ 'USE_STACKCHECK': 'maybe'}
index f8643552011f4e877144abfe744f1ca0f32c8fd0..0e82c723ec3eaa2495f7ee929eed8a20b4f75a42 100644 (file)
@@ -1162,7 +1162,9 @@ class TestCallList(unittest.TestCase):
         mock.foo.bar().baz('fish', cat='dog')
 
         expected = (
-            "[call(1, 2), call.foo(a=3), call.foo.bar(),"
+            "[call(1, 2),\n"
+            " call.foo(a=3),\n"
+            " call.foo.bar(),\n"
             " call.foo.bar().baz('fish', cat='dog')]"
         )
         self.assertEqual(str(mock.mock_calls), expected)
diff --git a/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst b/Misc/NEWS.d/next/Library/2026-05-18-17-17-20.gh-issue-149189.a8IooK.rst
new file mode 100644 (file)
index 0000000..bad027f
--- /dev/null
@@ -0,0 +1 @@
+Revert the changes to :mod:`pprint` defaults. Patch by Hugo van Kemenade.