From 46a7ea7adabf5ff306a936c080ce52052acaf96d Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 18 Nov 2020 22:29:03 +0900 Subject: [PATCH] Add NewType support to typing.stringify() and restify() --- sphinx/util/typing.py | 9 +++++++++ tests/test_util_typing.py | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index 18649433b..9d9355414 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -88,10 +88,14 @@ def is_system_TypeVar(typ: Any) -> bool: def restify(cls: Optional["Type"]) -> str: """Convert python class to a reST reference.""" + from sphinx.util import inspect # lazy loading + if cls is None or cls is NoneType: return ':obj:`None`' elif cls is Ellipsis: return '...' + elif inspect.isNewType(cls): + return ':class:`%s`' % cls.__name__ elif cls.__module__ in ('__builtin__', 'builtins'): return ':class:`%s`' % cls.__name__ else: @@ -277,6 +281,8 @@ def _restify_py36(cls: Optional["Type"]) -> str: def stringify(annotation: Any) -> str: """Stringify type annotation object.""" + from sphinx.util import inspect # lazy loading + if isinstance(annotation, str): if annotation.startswith("'") and annotation.endswith("'"): # might be a double Forward-ref'ed type. Go unquoting. @@ -285,6 +291,9 @@ def stringify(annotation: Any) -> str: return annotation elif isinstance(annotation, TypeVar): return annotation.__name__ + elif inspect.isNewType(annotation): + # Could not get the module where it defiend + 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 c81cdaba2..882c652cc 100644 --- a/tests/test_util_typing.py +++ b/tests/test_util_typing.py @@ -10,7 +10,8 @@ import sys from numbers import Integral -from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, TypeVar, Union +from typing import (Any, Callable, Dict, Generator, List, NewType, Optional, Tuple, TypeVar, + Union) import pytest @@ -26,6 +27,7 @@ class MyClass2(MyClass1): T = TypeVar('T') +MyInt = NewType('MyInt', int) class MyList(List[T]): @@ -92,6 +94,7 @@ 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:`List`\\ [:obj:`tests.test_util_typing.T`]" + assert restify(MyInt) == ":class:`MyInt`" def test_restify_type_hints_custom_class(): @@ -179,6 +182,7 @@ def test_stringify_type_hints_typevars(): assert stringify(T_co) == "T_co" assert stringify(T_contra) == "T_contra" assert stringify(List[T]) == "List[T]" + assert stringify(MyInt) == "MyInt" def test_stringify_type_hints_custom_class():