Blob Blame History Raw
--- 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 `((),)`