From 925661eb800aed09c1bb17f93c700235aa646ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 28 Aug 2023 23:01:45 +0200 Subject: [PATCH 01/18] =?UTF-8?q?=E2=9C=A8=20Add=20doc=20and=20DocInfo=20f?= =?UTF-8?q?rom=20PEP=20727:=20https://peps.python.org/pep-0727/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/typing_extensions.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index b0b1bceb..15b6dff4 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -60,6 +60,8 @@ 'clear_overloads', 'dataclass_transform', 'deprecated', + 'doc', + 'DocInfo', 'get_overloads', 'final', 'get_args', @@ -2809,6 +2811,43 @@ def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]: return frozenset(tp.__protocol_attrs__) return frozenset(_get_protocol_attrs(tp)) +if hasattr(typing, "doc"): + doc = typing.doc + DocInfo = typing.DocInfo +else: + class DocInfo: + """Container for documentation information as returned by ``doc()``. + + It is expected this class wouldn't be manually created but instead returned + by ``doc()`` inside of type annotations using ``Annotated``. + + The ``documentation`` attribute contains the documentation string passed + to ``doc()``. + """ + def __init__(self, documentation: str): + self.documentation = documentation + def __repr__(self) -> str: + return f"DocInfo({self.documentation})" + + def doc(documentation: str) -> DocInfo: + """Define the documentation of a type annotation using ``Annotated``, to be + used in class attributes, function and method parameters, return values, + and variables. + + The value should be a string literal to allow static tools like editors + to use it. + + This complements docstrings. + + It returns a class ``DocInfo`` instance containing the documentation value in + the ``documentation`` attribute. + + Example:: + + >>> from typing_extensions import doc, Annotated + >>> def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: ... + """ + return DocInfo(documentation) # Aliases for items that have always been in typing. # Explicitly assign these (rather than using `from typing import *` at the top), From bc80a6109081ce4d5476214860da157afb3632f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 28 Aug 2023 23:06:35 +0200 Subject: [PATCH 02/18] =?UTF-8?q?=E2=9C=85=20Add=20test=20for=20doc=20and?= =?UTF-8?q?=20DocInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test_typing_extensions.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index e741d699..68e438f0 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -38,6 +38,7 @@ from typing_extensions import clear_overloads, get_overloads, overload from typing_extensions import NamedTuple from typing_extensions import override, deprecated, Buffer, TypeAliasType, TypeVar, get_protocol_members, is_protocol +from typing_extensions import doc, DocInfo from _typed_dict_test_helper import Foo, FooGeneric, VeryAnnotated # Flags used to mark tests that only apply after a specific @@ -5895,5 +5896,16 @@ class MyAlias(TypeAliasType): pass +class DocTests(BaseTestCase): + def test_annotation(self): + + def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: pass + + hints = get_type_hints(hi, include_extras=True) + doc_info = hints["to"].__metadata__[0] + self.assertEqual(doc_info.documentation, "Who to say hi to") + self.assertIsInstance(doc_info, DocInfo) + + if __name__ == '__main__': main() From 0e8f113878534cdb6c5e95c838ee76b32c5ee9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 28 Aug 2023 23:17:58 +0200 Subject: [PATCH 03/18] =?UTF-8?q?=F0=9F=8E=A8=20Format=20extra=20whitespac?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test_typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 68e438f0..33c2cc15 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5898,7 +5898,7 @@ class MyAlias(TypeAliasType): class DocTests(BaseTestCase): def test_annotation(self): - + def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: pass hints = get_type_hints(hi, include_extras=True) From 9a39422193cb63b9ec26fb038d11d0c6fac71205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 29 Aug 2023 10:55:59 +0200 Subject: [PATCH 04/18] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20flake8=20error=20in?= =?UTF-8?q?=20source?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/typing_extensions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 15b6dff4..f7f88867 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2826,6 +2826,7 @@ class DocInfo: """ def __init__(self, documentation: str): self.documentation = documentation + def __repr__(self) -> str: return f"DocInfo({self.documentation})" From 14e9926f5cbd37bf208569c1c311d7fa63b0bfd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 29 Aug 2023 22:47:31 +0200 Subject: [PATCH 05/18] =?UTF-8?q?=F0=9F=8E=A8=20Tweak=20repr=20of=20DocInf?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index f7f88867..41d794a6 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2828,7 +2828,7 @@ def __init__(self, documentation: str): self.documentation = documentation def __repr__(self) -> str: - return f"DocInfo({self.documentation})" + return f"DocInfo({self.documentation!r})" def doc(documentation: str) -> DocInfo: """Define the documentation of a type annotation using ``Annotated``, to be From cb3dd38cae7e83159da12995ab56a84ccc2dcec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 29 Aug 2023 22:47:49 +0200 Subject: [PATCH 06/18] =?UTF-8?q?=E2=9C=85=20Add=20test=20for=20repr=20of?= =?UTF-8?q?=20DocInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test_typing_extensions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 33c2cc15..105f9bec 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5905,6 +5905,10 @@ def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: pass doc_info = hints["to"].__metadata__[0] self.assertEqual(doc_info.documentation, "Who to say hi to") self.assertIsInstance(doc_info, DocInfo) + + def test_repr(self): + doc_info = doc("Who to say hi to") + self.assertEqual(repr(doc_info), "DocInfo('Who to say hi to')") if __name__ == '__main__': From dc9b83792bc11ca42a07121e8850b85eed0f8d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 30 Aug 2023 01:36:13 +0200 Subject: [PATCH 07/18] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20format=20in=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test_typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 105f9bec..e9a43b80 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5905,7 +5905,7 @@ def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: pass doc_info = hints["to"].__metadata__[0] self.assertEqual(doc_info.documentation, "Who to say hi to") self.assertIsInstance(doc_info, DocInfo) - + def test_repr(self): doc_info = doc("Who to say hi to") self.assertEqual(repr(doc_info), "DocInfo('Who to say hi to')") From 7508ae551ccd3ac06efe3274a1fde40a798364a6 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 29 Aug 2023 18:13:58 -0700 Subject: [PATCH 08/18] Documentation, changelog, more tests --- CHANGELOG.md | 2 ++ doc/index.rst | 46 +++++++++++++++++++++++++++++++++++ src/test_typing_extensions.py | 20 +++++++++++++++ src/typing_extensions.py | 16 ++++++++++-- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd98764..126d12e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Release 4.8.0 (???) +- Add `typing_extensions.doc`, as proposed by PEP 727. Patch by + Sebastián Ramírez. - Drop support for Python 3.7 (including PyPy-3.7). Patch by Alex Waygood. - Fix bug where `get_original_bases()` would return incorrect results when called on a concrete subclass of a generic class. Patch by Alex Waygood diff --git a/doc/index.rst b/doc/index.rst index 7e68e270..1eb857d6 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -616,6 +616,29 @@ Functions .. versionadded:: 4.2.0 +.. function:: doc(documentation) + + Define the documentation of a type annotation using :data:`Annotated`, to be + used in class attributes, function and method parameters, return values, + and variables. + + The value should be a string literal to allow static tools like editors + to use it. + + This complements docstrings. + + It returns a :class:`DocInfo` instance containing the documentation value in + the ``documentation`` attribute. + + Example:: + + >>> from typing_extensions import doc, Annotated + >>> def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: ... + + .. versionadded:: 4.8.0 + + See :pep:`727`. + .. function:: get_args(tp) See :py:func:`typing.get_args`. In ``typing`` since 3.8. @@ -721,6 +744,29 @@ Functions .. versionadded:: 4.1.0 + +Helper classes +~~~~~~~~~~~~~~ + +.. class:: DocInfo(documentation) + + Container for documentation information as returned by :func:`doc`. + + It is expected this class wouldn't be manually created but instead returned + by :func:`doc` inside of type annotations using :data:`Annotated`. + + The ``documentation`` attribute contains the documentation string passed + to :func:`doc`. + + .. versionadded:: 4.8.0 + + See :pep:`727`. + + .. attribute:: documentation + + The documentation string passed to :func:`doc`. + + Pure aliases ~~~~~~~~~~~~ diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index e9a43b80..ce38d442 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5910,6 +5910,26 @@ def test_repr(self): doc_info = doc("Who to say hi to") self.assertEqual(repr(doc_info), "DocInfo('Who to say hi to')") + def test_hashability(self): + doc_info = doc("Who to say hi to") + self.assertIsInstance(hash(doc_info), int) + self.assertNotEqual(hash(doc_info), hash(doc("Who not to say hi to"))) + + def test_equality(self): + doc_info = doc("Who to say hi to") + # Equal to itself + self.assertEqual(doc_info, doc_info) + # Equal to another instance with the same string + self.assertEqual(doc_info, doc("Who to say hi to")) + # Not equial to another instance with a different string + self.assertNotEqual(doc_info, doc("Who not to say hi to")) + + def test_pickle(self): + doc_info = doc("Who to say hi to") + for proto in range(pickle.HIGHEST_PROTOCOL): + pickled = pickle.dumps(doc_info, protocol=proto) + self.assertEqual(doc_info, pickle.loads(pickled)) + if __name__ == '__main__': main() diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 41d794a6..3f827199 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2811,8 +2811,8 @@ def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]: return frozenset(tp.__protocol_attrs__) return frozenset(_get_protocol_attrs(tp)) -if hasattr(typing, "doc"): - doc = typing.doc + +if hasattr(typing, "DocInfo"): DocInfo = typing.DocInfo else: class DocInfo: @@ -2830,6 +2830,18 @@ def __init__(self, documentation: str): def __repr__(self) -> str: return f"DocInfo({self.documentation!r})" + def __hash__(self) -> int: + return hash(self.documentation) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DocInfo): + return NotImplemented + return self.documentation == other.documentation + + +if hasattr(typing, "doc"): + doc = typing.doc +else: def doc(documentation: str) -> DocInfo: """Define the documentation of a type annotation using ``Annotated``, to be used in class attributes, function and method parameters, return values, From 3e53acda5c3a5e2a7bad101ba2e3d946ab0426a7 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 29 Aug 2023 18:15:45 -0700 Subject: [PATCH 09/18] Update src/typing_extensions.py --- src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index 3f827199..c9649d96 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2824,7 +2824,7 @@ class DocInfo: The ``documentation`` attribute contains the documentation string passed to ``doc()``. """ - def __init__(self, documentation: str): + def __init__(self, documentation: str) -> None: self.documentation = documentation def __repr__(self) -> str: From 852e3760391dcdd0bc2eb40a60aa45dd59140afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 13:43:07 +0200 Subject: [PATCH 10/18] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20to=20simp?= =?UTF-8?q?lify=20it,=20make=20it=20only=20a=20Doc=20class,=20nothing=20el?= =?UTF-8?q?se?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/typing_extensions.py | 54 ++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index c9649d96..f9ec4116 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -60,8 +60,7 @@ 'clear_overloads', 'dataclass_transform', 'deprecated', - 'doc', - 'DocInfo', + 'Doc', 'get_overloads', 'final', 'get_args', @@ -2812,19 +2811,27 @@ def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]: return frozenset(_get_protocol_attrs(tp)) -if hasattr(typing, "DocInfo"): - DocInfo = typing.DocInfo +if hasattr(typing, "Doc"): + Doc = typing.Doc else: - class DocInfo: - """Container for documentation information as returned by ``doc()``. + class Doc: + """Define the documentation of a type annotation using ``Annotated``, to be + used in class attributes, function and method parameters, return values, + and variables. + + The value should be a positional-only string literal to allow static tools + like editors and documentation generators to use it. + + This complements docstrings. - It is expected this class wouldn't be manually created but instead returned - by ``doc()`` inside of type annotations using ``Annotated``. + The string value passed is available in the attribute ``documentation``. - The ``documentation`` attribute contains the documentation string passed - to ``doc()``. + Example:: + + >>> from typing_extensions import Annotated, Doc + >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ... """ - def __init__(self, documentation: str) -> None: + def __init__(self, /, documentation: str) -> None: self.documentation = documentation def __repr__(self) -> str: @@ -2834,34 +2841,11 @@ def __hash__(self) -> int: return hash(self.documentation) def __eq__(self, other: object) -> bool: - if not isinstance(other, DocInfo): + if not isinstance(other, Doc): return NotImplemented return self.documentation == other.documentation -if hasattr(typing, "doc"): - doc = typing.doc -else: - def doc(documentation: str) -> DocInfo: - """Define the documentation of a type annotation using ``Annotated``, to be - used in class attributes, function and method parameters, return values, - and variables. - - The value should be a string literal to allow static tools like editors - to use it. - - This complements docstrings. - - It returns a class ``DocInfo`` instance containing the documentation value in - the ``documentation`` attribute. - - Example:: - - >>> from typing_extensions import doc, Annotated - >>> def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: ... - """ - return DocInfo(documentation) - # Aliases for items that have always been in typing. # Explicitly assign these (rather than using `from typing import *` at the top), # so that we get a CI error if one of these is deleted from typing.py From c0780b9257f8e898a97eadf13a3bc30575f25de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 13:43:44 +0200 Subject: [PATCH 11/18] =?UTF-8?q?=E2=9C=85=20Update=20tests=20for=20Doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test_typing_extensions.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index ce38d442..d136132d 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -38,7 +38,7 @@ from typing_extensions import clear_overloads, get_overloads, overload from typing_extensions import NamedTuple from typing_extensions import override, deprecated, Buffer, TypeAliasType, TypeVar, get_protocol_members, is_protocol -from typing_extensions import doc, DocInfo +from typing_extensions import Doc from _typed_dict_test_helper import Foo, FooGeneric, VeryAnnotated # Flags used to mark tests that only apply after a specific @@ -5899,33 +5899,33 @@ class MyAlias(TypeAliasType): class DocTests(BaseTestCase): def test_annotation(self): - def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: pass + def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: pass hints = get_type_hints(hi, include_extras=True) doc_info = hints["to"].__metadata__[0] self.assertEqual(doc_info.documentation, "Who to say hi to") - self.assertIsInstance(doc_info, DocInfo) + self.assertIsInstance(doc_info, Doc) def test_repr(self): - doc_info = doc("Who to say hi to") + doc_info = Doc("Who to say hi to") self.assertEqual(repr(doc_info), "DocInfo('Who to say hi to')") def test_hashability(self): - doc_info = doc("Who to say hi to") + doc_info = Doc("Who to say hi to") self.assertIsInstance(hash(doc_info), int) - self.assertNotEqual(hash(doc_info), hash(doc("Who not to say hi to"))) + self.assertNotEqual(hash(doc_info), hash(Doc("Who not to say hi to"))) def test_equality(self): - doc_info = doc("Who to say hi to") + doc_info = Doc("Who to say hi to") # Equal to itself self.assertEqual(doc_info, doc_info) # Equal to another instance with the same string - self.assertEqual(doc_info, doc("Who to say hi to")) - # Not equial to another instance with a different string - self.assertNotEqual(doc_info, doc("Who not to say hi to")) + self.assertEqual(doc_info, Doc("Who to say hi to")) + # Not equal to another instance with a different string + self.assertNotEqual(doc_info, Doc("Who not to say hi to")) def test_pickle(self): - doc_info = doc("Who to say hi to") + doc_info = Doc("Who to say hi to") for proto in range(pickle.HIGHEST_PROTOCOL): pickled = pickle.dumps(doc_info, protocol=proto) self.assertEqual(doc_info, pickle.loads(pickled)) From 0b1aeda12e40ea5eac1515e24b11e1afcc77103b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 13:52:45 +0200 Subject: [PATCH 12/18] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Update=20repr=20of?= =?UTF-8?q?=20Doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index f9ec4116..d4b1238b 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2835,7 +2835,7 @@ def __init__(self, /, documentation: str) -> None: self.documentation = documentation def __repr__(self) -> str: - return f"DocInfo({self.documentation!r})" + return f"Doc({self.documentation!r})" def __hash__(self) -> int: return hash(self.documentation) From 3dc5df24cc8a9457d1efdc8473bea0f1ae749c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 13:53:03 +0200 Subject: [PATCH 13/18] =?UTF-8?q?=E2=9C=85=20Update=20tests=20of=20repr=20?= =?UTF-8?q?of=20Doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test_typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index d136132d..d8197821 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5908,7 +5908,7 @@ def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: pass def test_repr(self): doc_info = Doc("Who to say hi to") - self.assertEqual(repr(doc_info), "DocInfo('Who to say hi to')") + self.assertEqual(repr(doc_info), "Doc('Who to say hi to')") def test_hashability(self): doc_info = Doc("Who to say hi to") From 5a30bcb1ccb408d565df4a36933dd43d20edb4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 14:01:11 +0200 Subject: [PATCH 14/18] =?UTF-8?q?=F0=9F=93=9D=20Update=20the=20docs,=20rem?= =?UTF-8?q?ove=20doc()=20and=20rename=20DocInfo=20to=20Doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/index.rst | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index 1eb857d6..cdda520d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -616,29 +616,6 @@ Functions .. versionadded:: 4.2.0 -.. function:: doc(documentation) - - Define the documentation of a type annotation using :data:`Annotated`, to be - used in class attributes, function and method parameters, return values, - and variables. - - The value should be a string literal to allow static tools like editors - to use it. - - This complements docstrings. - - It returns a :class:`DocInfo` instance containing the documentation value in - the ``documentation`` attribute. - - Example:: - - >>> from typing_extensions import doc, Annotated - >>> def hi(to: Annotated[str, doc("Who to say hi to")]) -> None: ... - - .. versionadded:: 4.8.0 - - See :pep:`727`. - .. function:: get_args(tp) See :py:func:`typing.get_args`. In ``typing`` since 3.8. @@ -748,15 +725,23 @@ Functions Helper classes ~~~~~~~~~~~~~~ -.. class:: DocInfo(documentation) +.. class:: Doc(/, documentation) + + Define the documentation of a type annotation using :data:`Annotated`, to be + used in class attributes, function and method parameters, return values, + and variables. + + The value should be a positional-only string literal to allow static tools + like editors and documentation generators to use it. - Container for documentation information as returned by :func:`doc`. + This complements docstrings. + + The string value passed is available in the attribute ``documentation``. - It is expected this class wouldn't be manually created but instead returned - by :func:`doc` inside of type annotations using :data:`Annotated`. + Example:: - The ``documentation`` attribute contains the documentation string passed - to :func:`doc`. + >>> from typing_extensions import Annotated, Doc + >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ... .. versionadded:: 4.8.0 @@ -764,7 +749,7 @@ Helper classes .. attribute:: documentation - The documentation string passed to :func:`doc`. + The documentation string passed to :class:`Doc`. Pure aliases From d1db8e3c8a6e17b0eeca1a692d82b66fd5cbc974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 14:02:17 +0200 Subject: [PATCH 15/18] Update CHANGELOG.md Co-authored-by: Alex Waygood --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 126d12e3..a60b250c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Release 4.8.0 (???) -- Add `typing_extensions.doc`, as proposed by PEP 727. Patch by +- Add `typing_extensions.Doc`, as proposed by PEP 727. Patch by Sebastián Ramírez. - Drop support for Python 3.7 (including PyPy-3.7). Patch by Alex Waygood. - Fix bug where `get_original_bases()` would return incorrect results when From 6df13cde1f03b1422135e9081e7e42e3037cabe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 14:06:21 +0200 Subject: [PATCH 16/18] Update src/typing_extensions.py Co-authored-by: Alex Waygood --- src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing_extensions.py b/src/typing_extensions.py index d4b1238b..2b4e887e 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2831,7 +2831,7 @@ class Doc: >>> from typing_extensions import Annotated, Doc >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ... """ - def __init__(self, /, documentation: str) -> None: + def __init__(self, documentation: str, /) -> None: self.documentation = documentation def __repr__(self) -> str: From 5f18c2d2e68e02c3ad13d54fc0d930ece91d8cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 14:06:45 +0200 Subject: [PATCH 17/18] =?UTF-8?q?=F0=9F=93=9D=20Update/fix=20syntax=20for?= =?UTF-8?q?=20positional-only=20marker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.rst b/doc/index.rst index cdda520d..8660596d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -725,7 +725,7 @@ Functions Helper classes ~~~~~~~~~~~~~~ -.. class:: Doc(/, documentation) +.. class:: Doc(documentation, /) Define the documentation of a type annotation using :data:`Annotated`, to be used in class attributes, function and method parameters, return values, From b09655b518d654154b18e543eae681494d39707b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 31 Aug 2023 17:19:09 +0200 Subject: [PATCH 18/18] =?UTF-8?q?=F0=9F=93=9D=20Rename=20section=20to=20An?= =?UTF-8?q?notation=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index 8660596d..c5812979 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -722,8 +722,8 @@ Functions .. versionadded:: 4.1.0 -Helper classes -~~~~~~~~~~~~~~ +Annotation metadata +~~~~~~~~~~~~~~~~~~~ .. class:: Doc(documentation, /)