Skip to content
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

Close #9560: autodoc: Allow to refer NewType with modname in py310+ #9611

Merged
merged 1 commit into from Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -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:``
Expand Down
14 changes: 11 additions & 3 deletions sphinx/util/typing.py
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
11 changes: 9 additions & 2 deletions tests/test_util_typing.py
Expand Up @@ -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():
Expand Down Expand Up @@ -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():
Expand Down