From e6f6015a57019a627248ff6572aa568f1c07c26d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 15 Apr 2020 23:43:34 +0300 Subject: [PATCH 1/4] bpo-40257: Improve help for the typing module * Show docstring for special forms. * Show docstring for special generic aliases. * Show documentation for __origin__ for generic aliases. --- Lib/pydoc.py | 7 +++++-- Lib/typing.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py index a89b8045709c27..f19e354f575ae8 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1672,8 +1672,11 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0, inspect.getdoc(object)): # If the passed object is a piece of data or an instance, # document its available methods instead of its value. - object = type(object) - desc += ' object' + if hasattr(object, '__origin__'): + object = object.__origin__ + else: + object = type(object) + desc += ' object' return title % desc + '\n\n' + renderer.document(object, name) def doc(thing, title='Python Library Documentation: %s', forceload=0, diff --git a/Lib/typing.py b/Lib/typing.py index 9cacaa840ca352..3eef70bbb06125 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -323,6 +323,14 @@ def __init__(self, name, doc): self._name = name self._doc = doc + @property + def __doc__(self): + return self._doc + + @__doc__.setter + def __doc__(self, value): + self._doc = value + def __eq__(self, other): if not isinstance(other, _SpecialForm): return NotImplemented @@ -672,6 +680,8 @@ def __init__(self, origin, params, *, inst=True, special=False, name=None): self.__slots__ = None # This is not documented. if not name: self.__module__ = origin.__module__ + if special: + self.__doc__ = f'A generic version of {origin.__module__}.{origin.__qualname__}' @_tp_cache def __getitem__(self, params): From b85e5c227a076526fabb75edf95c212d4889e4dc Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 18 Apr 2020 00:17:07 +0300 Subject: [PATCH 2/4] Remove the __doc__ setter in _SpecialForm. --- Lib/typing.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index 3eef70bbb06125..df3650001e78ed 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -327,10 +327,6 @@ def __init__(self, name, doc): def __doc__(self): return self._doc - @__doc__.setter - def __doc__(self, value): - self._doc = value - def __eq__(self, other): if not isinstance(other, _SpecialForm): return NotImplemented From fe96fea6d5e238c745de0cc92f6721d83923bc50 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 18 Apr 2020 00:18:14 +0300 Subject: [PATCH 3/4] Add a newline after the docstring of unclassified object. --- Lib/pydoc.py | 2 +- Lib/test/test_pydoc.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py index f19e354f575ae8..898cc44b295ee0 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1445,7 +1445,7 @@ def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=No if not doc: doc = getdoc(object) if doc: - line += '\n' + self.indent(str(doc)) + line += '\n' + self.indent(str(doc)) + '\n' return line class _PlainTextDoc(TextDoc): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 800913b425a258..6d358f4fe2fc3c 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -1255,7 +1255,8 @@ class X: X.attr.__doc__ = 'Custom descriptor' self.assertEqual(self._get_summary_lines(X.attr), """\ .Descr object> - Custom descriptor""") + Custom descriptor +""") X.attr.__name__ = 'foo' self.assertEqual(self._get_summary_lines(X.attr), """\ From d5b3e6d06fd1753e10088912a7bc23bafe396040 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 18 Apr 2020 10:55:59 +0300 Subject: [PATCH 4/4] Update docs. --- Doc/whatsnew/3.9.rst | 6 ++++++ .../next/Library/2020-04-18-10-52-15.bpo-40257.lv4WTq.rst | 4 ++++ 2 files changed, 10 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-04-18-10-52-15.bpo-40257.lv4WTq.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index aae8e5b0c97164..43a9fb625146cc 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -142,6 +142,12 @@ Other Language Changes grammar was much more restrictive. See :pep:`614` for details. (Contributed by Brandt Bucher in :issue:`39702`.) +* Improved help for the :mod:`typing` module. Docstrings are now shown for + all special forms and special generic aliases (like ``Union`` and ``List``). + Using :func:`help` with generic alias like ``List[int]`` will show the help + for the correspondent concrete type (``list`` in this case). + (Contributed by Serhiy Storchaka in :issue:`40257`.) + New Modules =========== diff --git a/Misc/NEWS.d/next/Library/2020-04-18-10-52-15.bpo-40257.lv4WTq.rst b/Misc/NEWS.d/next/Library/2020-04-18-10-52-15.bpo-40257.lv4WTq.rst new file mode 100644 index 00000000000000..6ed094add1f620 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-18-10-52-15.bpo-40257.lv4WTq.rst @@ -0,0 +1,4 @@ +Improved help for the :mod:`typing` module. Docstrings are now shown for all +special forms and special generic aliases (like ``Union`` and ``List``). +Using ``help()`` with generic alias like ``List[int]`` will show the help +for the correspondent concrete type (``list`` in this case).