Do not emit type arguments twice

Fixes gh-7567
This commit is contained in:
Eric Wieser 2020-04-27 14:44:37 +01:00
parent 21ca43719a
commit 46372726de
2 changed files with 14 additions and 3 deletions

View File

@ -75,8 +75,13 @@ def _stringify_py37(annotation: Any) -> str:
qualname = stringify(annotation.__origin__) # ex. Union qualname = stringify(annotation.__origin__) # ex. Union
elif hasattr(annotation, '__qualname__'): elif hasattr(annotation, '__qualname__'):
qualname = '%s.%s' % (module, annotation.__qualname__) qualname = '%s.%s' % (module, annotation.__qualname__)
elif hasattr(annotation, '__origin__'):
# instantiated generic provided by a user
qualname = stringify(annotation.__origin__)
else: else:
qualname = repr(annotation) # we weren't able to extract the base type, appending arguments would
# only make them appear twice
return repr(annotation)
if getattr(annotation, '__args__', None): if getattr(annotation, '__args__', None):
if qualname == 'Union': if qualname == 'Union':
@ -91,7 +96,7 @@ def _stringify_py37(annotation: Any) -> str:
return '%s[[%s], %s]' % (qualname, args, returns) return '%s[[%s], %s]' % (qualname, args, returns)
elif str(annotation).startswith('typing.Annotated'): # for py39+ elif str(annotation).startswith('typing.Annotated'): # for py39+
return stringify(annotation.__args__[0]) return stringify(annotation.__args__[0])
elif annotation._special: elif getattr(annotation, '_special', False):
return qualname return qualname
else: else:
args = ', '.join(stringify(a) for a in annotation.__args__) args = ', '.join(stringify(a) for a in annotation.__args__)

View File

@ -10,7 +10,7 @@
import sys import sys
from numbers import Integral from numbers import Integral
from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional, Generic
import pytest import pytest
@ -24,6 +24,11 @@ class MyClass1:
class MyClass2(MyClass1): class MyClass2(MyClass1):
__qualname__ = '<MyClass2>' __qualname__ = '<MyClass2>'
T = TypeVar('T')
class MyList(List[T]):
pass
def test_stringify(): def test_stringify():
assert stringify(int) == "int" assert stringify(int) == "int"
@ -42,6 +47,7 @@ def test_stringify_type_hints_containers():
assert stringify(Tuple[str, str, str]) == "Tuple[str, str, str]" assert stringify(Tuple[str, str, str]) == "Tuple[str, str, str]"
assert stringify(Tuple[str, ...]) == "Tuple[str, ...]" assert stringify(Tuple[str, ...]) == "Tuple[str, ...]"
assert stringify(List[Dict[str, Tuple]]) == "List[Dict[str, Tuple]]" assert stringify(List[Dict[str, Tuple]]) == "List[Dict[str, Tuple]]"
assert stringify(MyList[Tuple[int, int]]) == "test_util_typing.MyList[Tuple[int, int]]"
@pytest.mark.skipif(sys.version_info < (3, 9), reason='python 3.9+ is required.') @pytest.mark.skipif(sys.version_info < (3, 9), reason='python 3.9+ is required.')