--- a/monkeytype/stubs.py
+++ b/monkeytype/stubs.py
@@ -342,7 +342,8 @@ class RenderAnnotation(GenericTypeRewrit
return rendered[len(tilde_prefix):] if rendered.startswith(tilde_prefix) else rendered
def make_builtin_tuple(self, elements: Iterable[str]) -> str:
- return ', '.join(elements) if elements else '()'
+ res = ", ".join(elements)
+ return res if res else "()"
def make_container_type(self, container_type: str, elements: str) -> str:
return f'{container_type}[{elements}]'
@@ -568,7 +569,9 @@ class ReplaceTypedDictsWithStubs(TypeRew
args = getattr(container, '__args__', None)
if args is None:
return container
- elif args == ((),): # special case of empty tuple `Tuple[()]`
+ elif args == ((),) or (
+ container.__qualname__ == "Tuple" and args == ()
+ ): # special case of empty tuple `Tuple[()]`
elems: Tuple[Any, ...] = ()
else:
# Avoid adding a suffix for the first one so that
--- a/monkeytype/encoding.py
+++ b/monkeytype/encoding.py
@@ -85,6 +85,9 @@ def type_to_dict(typ: type) -> TypeDict:
'qualname': qualname,
}
elem_types = getattr(typ, '__args__', None)
+ # in Python 3.11, for Tuple[()] elem_types will be ()
+ if qualname == "Tuple" and elem_types == ():
+ d["elem_types"] = []
if elem_types and is_generic(typ):
# empty typing.Tuple is weird; the spec says it should be Tuple[()],
# which results in __args__ of `((),)`