-
-
Couldn't load subscription status.
- Fork 33.2k
gh-101552: Allow pydoc to display signatures in source format #124669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
f806791
4e319cf
38c4b42
c33c4cc
9c7b972
b14a719
33ef93d
afdf4fc
1549080
5831cc4
35ee105
c549c70
e448b82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -694,7 +694,7 @@ and its return annotation. To retrieve a :class:`!Signature` object, | |
| use the :func:`!signature` | ||
| function. | ||
|
|
||
| .. function:: signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False) | ||
| .. function:: signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False, annotation_format=Format.VALUE) | ||
|
|
||
| Return a :class:`Signature` object for the given *callable*: | ||
|
|
||
|
|
@@ -722,18 +722,20 @@ function. | |
| ``from __future__ import annotations`` was used), :func:`signature` will | ||
| attempt to automatically un-stringize the annotations using | ||
| :func:`annotationlib.get_annotations`. The | ||
| *globals*, *locals*, and *eval_str* parameters are passed | ||
| *globals*, *locals*, *eval_str*, and *annotation_format* parameters are passed | ||
|
||
| into :func:`!annotationlib.get_annotations` when resolving the | ||
| annotations; see the documentation for :func:`!annotationlib.get_annotations` | ||
| for instructions on how to use these parameters. | ||
| for instructions on how to use these parameters. For example, use | ||
| ``annotation_format=annotationlib.Format.STRING`` to return annotations in string | ||
| format. | ||
|
|
||
| Raises :exc:`ValueError` if no signature can be provided, and | ||
| :exc:`TypeError` if that type of object is not supported. Also, | ||
| if the annotations are stringized, and *eval_str* is not false, | ||
| the ``eval()`` call(s) to un-stringize the annotations in :func:`annotationlib.get_annotations` | ||
| could potentially raise any kind of exception. | ||
|
|
||
| A slash(/) in the signature of a function denotes that the parameters prior | ||
| A slash (/) in the signature of a function denotes that the parameters prior | ||
| to it are positional-only. For more info, see | ||
| :ref:`the FAQ entry on positional-only parameters <faq-positional-only-arguments>`. | ||
|
|
||
|
|
@@ -746,6 +748,9 @@ function. | |
| .. versionchanged:: 3.10 | ||
| The *globals*, *locals*, and *eval_str* parameters were added. | ||
|
|
||
| .. versionchanged:: 3.14 | ||
| The *annotation_format* parameter was added. | ||
|
|
||
| .. note:: | ||
|
|
||
| Some callables may not be introspectable in certain implementations of | ||
|
|
@@ -838,7 +843,7 @@ function. | |
| :class:`Signature` objects are also supported by the generic function | ||
| :func:`copy.replace`. | ||
|
|
||
| .. method:: format(*, max_width=None) | ||
| .. method:: format(*, max_width=None, unquote_annotations=False) | ||
|
||
|
|
||
| Create a string representation of the :class:`Signature` object. | ||
|
|
||
|
|
@@ -847,8 +852,17 @@ function. | |
| If the signature is longer than *max_width*, | ||
| all parameters will be on separate lines. | ||
|
|
||
| If *unquote_annotations* is True, :term:`annotations <annotation>` | ||
| in the signature are displayed without opening and closing quotation | ||
| marks. This is useful if the signature was created with the | ||
| :attr:`~annotationlib.Format.STRING` format or if | ||
| ``from __future__ import annotations`` was used. | ||
|
|
||
| .. versionadded:: 3.13 | ||
|
|
||
| .. versionchanged:: 3.14 | ||
| The *unquote_annotations* parameter was added. | ||
|
|
||
| .. classmethod:: Signature.from_callable(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False) | ||
|
|
||
| Return a :class:`Signature` (or its subclass) object for a given callable | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| def f(x: undefined): | ||
| pass |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| from annotationlib import Format, ForwardRef | ||
| import asyncio | ||
| import builtins | ||
| import collections | ||
|
|
@@ -22,7 +23,6 @@ | |
| import types | ||
| import tempfile | ||
| import textwrap | ||
| from typing import Unpack | ||
| import unicodedata | ||
| import unittest | ||
| import unittest.mock | ||
|
|
@@ -46,6 +46,7 @@ | |
| from test.test_inspect import inspect_fodder as mod | ||
| from test.test_inspect import inspect_fodder2 as mod2 | ||
| from test.test_inspect import inspect_stringized_annotations | ||
| from test.test_inspect import inspect_deferred_annotations | ||
|
|
||
|
|
||
| # Functions tested in this suite: | ||
|
|
@@ -4565,6 +4566,18 @@ def func( | |
| expected_multiline, | ||
| ) | ||
|
|
||
| def test_signature_format_unquote(self): | ||
| def func(x: 'int') -> 'str': ... | ||
|
|
||
| self.assertEqual( | ||
| inspect.signature(func).format(), | ||
| "(x: 'int') -> 'str'" | ||
| ) | ||
| self.assertEqual( | ||
| inspect.signature(func).format(unquote_annotations=True), | ||
| "(x: int) -> str" | ||
| ) | ||
|
|
||
| def test_signature_replace_parameters(self): | ||
| def test(a, b) -> 42: | ||
| pass | ||
|
|
@@ -4797,6 +4810,26 @@ def test_signature_eval_str(self): | |
| par('b', PORK, annotation=tuple), | ||
| ))) | ||
|
|
||
| def test_signature_annotation_format(self): | ||
| ida = inspect_deferred_annotations | ||
| sig = inspect.Signature | ||
| par = inspect.Parameter | ||
| PORK = inspect.Parameter.POSITIONAL_OR_KEYWORD | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🐷 |
||
| for signature_func in (inspect.signature, inspect.Signature.from_callable): | ||
| with self.subTest(signature_func=signature_func): | ||
| self.assertEqual( | ||
| signature_func(ida.f, annotation_format=Format.STRING), | ||
| sig([par("x", PORK, annotation="undefined")]) | ||
| ) | ||
| self.assertEqual( | ||
| signature_func(ida.f, annotation_format=Format.FORWARDREF), | ||
| sig([par("x", PORK, annotation=ForwardRef("undefined"))]) | ||
| ) | ||
| with self.assertRaisesRegex(NameError, "undefined"): | ||
| signature_func(ida.f, annotation_format=Format.VALUE) | ||
| with self.assertRaisesRegex(NameError, "undefined"): | ||
| signature_func(ida.f) | ||
|
|
||
| def test_signature_none_annotation(self): | ||
| class funclike: | ||
| # Has to be callable, and have correct | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Add a *format* parameter to :func:`inspect.signature`. Add an | ||
| *unquote_annotations* parameter to :meth:`inspect.Signature.format`. Use the | ||
JelleZijlstra marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| new functionality to improve the display of annotations in signatures in | ||
| :mod:`pydoc`. Patch by Jelle Zijlstra. | ||
Uh oh!
There was an error while loading. Please reload this page.