From 6b405de35ec56d0d39a1f8f0d8f81f686949f211 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Thu, 10 Jul 2025 13:45:38 +0300 Subject: [PATCH] gh-111704: Add `stdtypes.rst` to doctests --- Doc/library/stdtypes.rst | 60 +++++++++++----------------------------- Lib/test/test_builtin.py | 13 +++++++-- 2 files changed, 27 insertions(+), 46 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 394c302fd354b9..5963d261a50ef7 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2545,51 +2545,39 @@ This type of string literal allows embedding arbitrary Python expressions within *replacement fields*, which are delimited by curly brackets (``{}``). These expressions are evaluated at runtime, similarly to :meth:`str.format`, and are converted into regular :class:`str` objects. -For example: - -.. doctest:: +For example:: >>> who = 'nobody' >>> nationality = 'Spanish' >>> f'{who.title()} expects the {nationality} Inquisition!' 'Nobody expects the Spanish Inquisition!' -It is also possible to use a multi line f-string: - -.. doctest:: +It is also possible to use a multi line f-string:: >>> f'''This is a string ... on two lines''' 'This is a string\non two lines' A single opening curly bracket, ``'{'``, marks a *replacement field* that -can contain any Python expression: - -.. doctest:: +can contain any Python expression:: >>> nationality = 'Spanish' >>> f'The {nationality} Inquisition!' 'The Spanish Inquisition!' -To include a literal ``{`` or ``}``, use a double bracket: - -.. doctest:: +To include a literal ``{`` or ``}``, use a double bracket:: >>> x = 42 >>> f'{{x}} is {x}' '{x} is 42' -Functions can also be used, and :ref:`format specifiers `: - -.. doctest:: +Functions can also be used, and :ref:`format specifiers `:: >>> from math import sqrt >>> f'√2 \N{ALMOST EQUAL TO} {sqrt(2):.5f}' '√2 ≈ 1.41421' -Any non-string expression is converted using :func:`str`, by default: - -.. doctest:: +Any non-string expression is converted using :func:`str`, by default:: >>> from fractions import Fraction >>> f'{Fraction(1, 3)}' @@ -2606,9 +2594,7 @@ Conversion Meaning ``!s`` :func:`str` ========== ============== -For example: - -.. doctest:: +For example:: >>> from fractions import Fraction >>> f'{Fraction(1, 3)!s}' @@ -2623,9 +2609,7 @@ While debugging it may be helpful to see both the expression and its value, by using the equals sign (``=``) after the expression. This preserves spaces within the brackets, and can be used with a converter. By default, the debugging operator uses the :func:`repr` (``!r``) conversion. -For example: - -.. doctest:: +For example:: >>> from fractions import Fraction >>> calculation = Fraction(1, 3) @@ -2642,9 +2626,7 @@ After the expression has been evaluated, and possibly converted to a string, the :meth:`!__format__` method of the result is called with the format specifier, or the empty string if no format specifier is given. The formatted result is then used as the final value for the replacement field. -For example: - -.. doctest:: +For example:: >>> from fractions import Fraction >>> f'{Fraction(1, 7):.6f}' @@ -2682,9 +2664,7 @@ This is also known as the string *formatting* or *interpolation* operator. Given ``format % values`` (where *format* is a string), ``%`` conversion specifications in *format* are replaced with zero or more elements of *values*. The effect is similar to using the :c:func:`sprintf` function in the C language. -For example: - -.. doctest:: +For example:: >>> print('%s has %d quote types.' % ('Python', 2)) Python has 2 quote types. @@ -4162,7 +4142,7 @@ copying. >>> v[-1] 103 >>> v[1:4] - + >>> bytes(v[1:4]) b'bce' @@ -5649,9 +5629,7 @@ The user-exposed type for the union object can be accessed from .. note:: The :meth:`!__or__` method for type objects was added to support the syntax ``X | Y``. If a metaclass implements :meth:`!__or__`, the Union may - override it: - - .. doctest:: + override it:: >>> class M(type): ... def __or__(self, other): @@ -5763,9 +5741,7 @@ attributes. However, since method attributes are actually stored on the underlying function object (:attr:`method.__func__`), setting method attributes on bound methods is disallowed. Attempting to set an attribute on a method results in an :exc:`AttributeError` being raised. In order to set a method -attribute, you need to explicitly set it on the underlying function object: - -.. doctest:: +attribute, you need to explicitly set it on the underlying function object:: >>> class C: ... def method(self): @@ -5775,7 +5751,7 @@ attribute, you need to explicitly set it on the underlying function object: >>> c.method.whoami = 'my name is method' # can't set on the method Traceback (most recent call last): File "", line 1, in - AttributeError: 'method' object has no attribute 'whoami' + AttributeError: 'method' object has no attribute 'whoami' and no __dict__ for setting new attributes >>> c.method.__func__.whoami = 'my name is method' >>> c.method.whoami 'my name is method' @@ -5946,9 +5922,7 @@ The limit is applied to the number of digit characters in the input or output string when a non-linear conversion algorithm would be involved. Underscores and the sign are not counted towards the limit. -When an operation would exceed the limit, a :exc:`ValueError` is raised: - -.. doctest:: +When an operation would exceed the limit, a :exc:`ValueError` is raised:: >>> import sys >>> sys.set_int_max_str_digits(4300) # Illustrative, this is the default. @@ -5973,9 +5947,7 @@ The default limit is 4300 digits as provided in The lowest limit that can be configured is 640 digits as provided in :data:`sys.int_info.str_digits_check_threshold `. -Verification: - -.. doctest:: +Verification:: >>> import sys >>> assert sys.int_info.default_max_str_digits == 4300, sys.int_info diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 8830641f0abdc7..775fb9225ad172 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2990,9 +2990,18 @@ def test_namespace_order(self): def load_tests(loader, tests, pattern): - from doctest import DocTestSuite + import doctest if sys.float_repr_style == 'short': - tests.addTest(DocTestSuite(builtins)) + tests.addTest(doctest.DocTestSuite(builtins)) + lib_tests = os.path.join(support.REPO_ROOT, 'Doc/library/stdtypes.rst') + if os.path.exists(lib_tests): + tests.addTests( + doctest.DocFileSuite( + lib_tests, + module_relative=False, + optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, + ), + ) return tests if __name__ == "__main__":