From 397f51b8a4759e9fed29ec0d94201c40dbb1bb45 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 3 Nov 2023 11:18:34 +0300 Subject: [PATCH 1/6] gh-111681: Fix doctests in `typing.rst` and run it in CI --- Doc/library/typing.rst | 5 ++--- Lib/test/test_typing.py | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index bdff2bb776d844..30f74fec34fbc2 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1954,7 +1954,7 @@ without the dedicated syntax, as documented below. .. doctest:: - >>> from typing import ParamSpec + >>> from typing import ParamSpec, get_origin >>> P = ParamSpec("P") >>> get_origin(P.args) is P True @@ -3065,8 +3065,7 @@ Introspection helpers >>> class P(Protocol): ... def a(self) -> str: ... ... b: int - >>> get_protocol_members(P) - frozenset({'a', 'b'}) + >>> assert get_protocol_members(P) == frozenset({'a', 'b'}) Raise :exc:`TypeError` for arguments that are not Protocols. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 7f60bf4bbc1e75..03e3b934a73a72 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -9,8 +9,9 @@ import pickle import re import sys -import warnings -from unittest import TestCase, main, skipUnless, skip +import os +import doctest +from unittest import TestCase, main, skip from unittest.mock import patch from copy import copy, deepcopy @@ -45,7 +46,7 @@ import weakref import types -from test.support import import_helper, captured_stderr, cpython_only +from test.support import captured_stderr, cpython_only, REPO_ROOT from test import mod_generics_cache from test import _typed_dict_helper @@ -9465,5 +9466,15 @@ def test_is_not_instance_of_iterable(self): self.assertNotIsInstance(type_to_test, collections.abc.Iterable) +def load_tests(loader, tests, pattern): + tests.addTests(doctest.DocFileSuite( + os.path.join(REPO_ROOT, 'Doc/library/typing.rst'), + module_relative=False, + # Some tests in `typing.rst` pretend to be executed in `__main__`: + globs={'__name__': '__main__'}, + )) + return tests + + if __name__ == '__main__': main() From cd22a8774dd3e4fc4516a48d58cf6274a96714a8 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 3 Nov 2023 11:55:11 +0300 Subject: [PATCH 2/6] Test if Sphinx can catch obvious errors --- Doc/library/typing.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 30f74fec34fbc2..c1dd7a8a99bda8 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -648,6 +648,9 @@ to this is that a list of types can be used to substitute a :class:`ParamSpec`:: >>> Z[int, [dict, float]] __main__.Z[int, [dict, float]] + >>> 1 + 2 + 4 + Classes generic over a :class:`ParamSpec` can also be created using explicit inheritance from :class:`Generic`. In this case, ``**`` is not used:: From a4c7b5fb3723248227e7c205b0e80d6047ce970a Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 3 Nov 2023 09:44:40 +0000 Subject: [PATCH 3/6] Update typing.rst --- Doc/library/typing.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index c1dd7a8a99bda8..b9c092493426bf 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -641,7 +641,9 @@ User-defined generics for parameter expressions are also supported via parameter specification variables in the form ``[**P]``. The behavior is consistent with type variables' described above as parameter specification variables are treated by the typing module as a specialized type variable. The one exception -to this is that a list of types can be used to substitute a :class:`ParamSpec`:: +to this is that a list of types can be used to substitute a :class:`ParamSpec`: + +.. doctest:: >>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec ... From 9461271601820b9eda05ddcc49c68ea42127c649 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 3 Nov 2023 14:28:40 +0300 Subject: [PATCH 4/6] Only keep small changes --- Doc/library/typing.rst | 8 ++------ Lib/test/test_typing.py | 14 +------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index b9c092493426bf..af04e2007a173c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -643,16 +643,11 @@ with type variables' described above as parameter specification variables are treated by the typing module as a specialized type variable. The one exception to this is that a list of types can be used to substitute a :class:`ParamSpec`: -.. doctest:: - >>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec ... >>> Z[int, [dict, float]] __main__.Z[int, [dict, float]] - >>> 1 + 2 - 4 - Classes generic over a :class:`ParamSpec` can also be created using explicit inheritance from :class:`Generic`. In this case, ``**`` is not used:: @@ -3070,7 +3065,8 @@ Introspection helpers >>> class P(Protocol): ... def a(self) -> str: ... ... b: int - >>> assert get_protocol_members(P) == frozenset({'a', 'b'}) + >>> get_protocol_members(P) == frozenset({'a', 'b'}) + True Raise :exc:`TypeError` for arguments that are not Protocols. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 03e3b934a73a72..9dd637b974769c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -9,8 +9,6 @@ import pickle import re import sys -import os -import doctest from unittest import TestCase, main, skip from unittest.mock import patch from copy import copy, deepcopy @@ -46,7 +44,7 @@ import weakref import types -from test.support import captured_stderr, cpython_only, REPO_ROOT +from test.support import captured_stderr, cpython_only from test import mod_generics_cache from test import _typed_dict_helper @@ -9466,15 +9464,5 @@ def test_is_not_instance_of_iterable(self): self.assertNotIsInstance(type_to_test, collections.abc.Iterable) -def load_tests(loader, tests, pattern): - tests.addTests(doctest.DocFileSuite( - os.path.join(REPO_ROOT, 'Doc/library/typing.rst'), - module_relative=False, - # Some tests in `typing.rst` pretend to be executed in `__main__`: - globs={'__name__': '__main__'}, - )) - return tests - - if __name__ == '__main__': main() From d7eae8be13e90ae0654b2a46ded488d9e8f5511c Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 3 Nov 2023 14:29:42 +0300 Subject: [PATCH 5/6] Typo --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index af04e2007a173c..538a0bbaa899e1 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -641,7 +641,7 @@ User-defined generics for parameter expressions are also supported via parameter specification variables in the form ``[**P]``. The behavior is consistent with type variables' described above as parameter specification variables are treated by the typing module as a specialized type variable. The one exception -to this is that a list of types can be used to substitute a :class:`ParamSpec`: +to this is that a list of types can be used to substitute a :class:`ParamSpec`:: >>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec ... From c84f3008c8a5bac692e46c171effeba19dc45ee2 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 3 Nov 2023 11:35:29 +0000 Subject: [PATCH 6/6] add `.. doctest::` to the failing one to prevent regressions --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 538a0bbaa899e1..f82f53514a71dc 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3059,7 +3059,7 @@ Introspection helpers Return the set of members defined in a :class:`Protocol`. - :: + .. doctest:: >>> from typing import Protocol, get_protocol_members >>> class P(Protocol):