summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2021-09-05 18:28:27 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2021-09-05 18:28:27 +0900
commitc5b35efce353a3e1670185704bcd1453b9da3533 (patch)
treea71efcd702772f10232829471fa7a92cc243241c
parent336605b8e4b14c5da9f4d872fb730dc6894edb77 (diff)
downloadsphinx-git-c5b35efce353a3e1670185704bcd1453b9da3533.tar.gz
Close #9560: autodoc: Allow to refer NewType with modname in py310+
Before 3.10, an instance of NewType has incorrect module name. But it was fixed on 3.10. This starts to use the module info if the interpreter is 3.10+.
-rw-r--r--CHANGES2
-rw-r--r--sphinx/util/typing.py14
-rw-r--r--tests/test_util_typing.py11
3 files changed, 22 insertions, 5 deletions
diff --git a/CHANGES b/CHANGES
index 5c75a1d62..79a7a87bb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,8 @@ Features added
* #9445: autodoc: Support class properties
* #9479: autodoc: Emit a warning if target is a mocked object
+* #9560: autodoc: Allow to refer NewType instances with module name in Python
+ 3.10 or above
* #9447: html theme: Expose the version of Sphinx in the form of tuple as a
template variable ``sphinx_version_tuple``
* #9445: py domain: ``:py:property:`` directive supports ``:classmethod:``
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py
index cf4318cda..004fb4a71 100644
--- a/sphinx/util/typing.py
+++ b/sphinx/util/typing.py
@@ -116,7 +116,12 @@ def restify(cls: Optional[Type]) -> str:
elif cls in INVALID_BUILTIN_CLASSES:
return ':class:`%s`' % INVALID_BUILTIN_CLASSES[cls]
elif inspect.isNewType(cls):
- return ':class:`%s`' % cls.__name__
+ if sys.version_info > (3, 10):
+ # newtypes have correct module info since Python 3.10+
+ print(cls, type(cls), dir(cls))
+ return ':class:`%s.%s`' % (cls.__module__, cls.__name__)
+ else:
+ return ':class:`%s`' % cls.__name__
elif UnionType and isinstance(cls, UnionType):
if len(cls.__args__) > 1 and None in cls.__args__:
args = ' | '.join(restify(a) for a in cls.__args__ if a)
@@ -307,8 +312,11 @@ def stringify(annotation: Any) -> str:
else:
return '.'.join([annotation.__module__, annotation.__name__])
elif inspect.isNewType(annotation):
- # Could not get the module where it defined
- return annotation.__name__
+ if sys.version_info > (3, 10):
+ # newtypes have correct module info since Python 3.10+
+ return '%s.%s' % (annotation.__module__, annotation.__name__)
+ else:
+ return annotation.__name__
elif not annotation:
return repr(annotation)
elif annotation is NoneType:
diff --git a/tests/test_util_typing.py b/tests/test_util_typing.py
index 9cb1d61ef..bbee68f82 100644
--- a/tests/test_util_typing.py
+++ b/tests/test_util_typing.py
@@ -113,7 +113,11 @@ def test_restify_type_hints_typevars():
assert restify(T_co) == ":obj:`tests.test_util_typing.T_co`"
assert restify(T_contra) == ":obj:`tests.test_util_typing.T_contra`"
assert restify(List[T]) == ":class:`~typing.List`\\ [:obj:`tests.test_util_typing.T`]"
- assert restify(MyInt) == ":class:`MyInt`"
+
+ if sys.version_info >= (3, 10):
+ assert restify(MyInt) == ":class:`tests.test_util_typing.MyInt`"
+ else:
+ assert restify(MyInt) == ":class:`MyInt`"
def test_restify_type_hints_custom_class():
@@ -250,7 +254,10 @@ def test_stringify_type_hints_typevars():
assert stringify(T_contra) == "tests.test_util_typing.T_contra"
assert stringify(List[T]) == "List[tests.test_util_typing.T]"
- assert stringify(MyInt) == "MyInt"
+ if sys.version_info >= (3, 10):
+ assert stringify(MyInt) == "tests.test_util_typing.MyInt"
+ else:
+ assert stringify(MyInt) == "MyInt"
def test_stringify_type_hints_custom_class():