@@ -1157,64 +1157,99 @@ def convert(
11571157 )
11581158
11591159
1160- def convert_type (ty : t .Any | None , default : t .Any | None = None ) -> ParamType [t .Any ]:
1160+ def _guess_type (
1161+ ty : type [t .Any ] | ParamType [t .Any ] | None ,
1162+ default : t .Any | None ,
1163+ ) -> type [t .Any ] | tuple [type [t .Any ], ...] | ParamType [t .Any ] | None :
1164+ """Infer a type from *ty* or *default*.
1165+
1166+ Returns *ty* unchanged when it is not ``None``. Otherwise inspects
1167+ *default* to produce a ``type``, a ``tuple`` of types (for tuple
1168+ defaults), or ``None``.
1169+ """
1170+ if ty is not None :
1171+ return ty
1172+
1173+ if default is None :
1174+ return None
1175+
1176+ if not isinstance (default , (tuple , list )):
1177+ return type (default )
1178+
1179+ # If the default is empty, return None so convert_type falls
1180+ # through to STRING.
1181+ if not default :
1182+ return None
1183+
1184+ item = default [0 ]
1185+
1186+ # A sequence of iterables needs to detect the inner types.
1187+ # Can't call convert_type recursively because that would
1188+ # incorrectly unwind the tuple to a single type.
1189+ if isinstance (item , (tuple , list )):
1190+ return tuple (map (type , item ))
1191+
1192+ return type (item )
1193+
1194+
1195+ @t .overload
1196+ def convert_type (ty : None , default : None = None ) -> StringParamType : ...
1197+
1198+
1199+ @t .overload
1200+ def convert_type (
1201+ ty : type [t .Any ] | ParamType [t .Any ], default : t .Any | None = None
1202+ ) -> ParamType [t .Any ]: ...
1203+
1204+
1205+ @t .overload
1206+ def convert_type (
1207+ ty : t .Any | None , default : t .Any | None = None
1208+ ) -> ParamType [t .Any ]: ...
1209+
1210+
1211+ def convert_type (
1212+ ty : t .Any | None = None , default : t .Any | None = None
1213+ ) -> ParamType [t .Any ]:
11611214 """Find the most appropriate :class:`ParamType` for the given Python
11621215 type. If the type isn't provided, it can be inferred from a default
11631216 value.
11641217 """
1165- guessed_type = False
1166-
1167- if ty is None and default is not None :
1168- if isinstance (default , (tuple , list )):
1169- # If the default is empty, ty will remain None and will
1170- # return STRING.
1171- if default :
1172- item = default [0 ]
1173-
1174- # A tuple of tuples needs to detect the inner types.
1175- # Can't call convert recursively because that would
1176- # incorrectly unwind the tuple to a single type.
1177- if isinstance (item , (tuple , list )):
1178- ty = tuple (map (type , item ))
1179- else :
1180- ty = type (item )
1181- else :
1182- ty = type (default )
1218+ guessed = _guess_type (ty , default )
1219+ is_guessed = guessed is not ty
11831220
1184- guessed_type = True
1221+ if isinstance (guessed , tuple ):
1222+ return Tuple (guessed )
11851223
1186- if isinstance (ty , tuple ):
1187- return Tuple (ty )
1188-
1189- if isinstance (ty , ParamType ):
1190- return ty
1224+ if isinstance (guessed , ParamType ):
1225+ return guessed
11911226
1192- if ty is str or ty is None :
1227+ if guessed is str or guessed is None :
11931228 return STRING
11941229
1195- if ty is int :
1230+ if guessed is int :
11961231 return INT
11971232
1198- if ty is float :
1233+ if guessed is float :
11991234 return FLOAT
12001235
1201- if ty is bool :
1236+ if guessed is bool :
12021237 return BOOL
12031238
1204- if guessed_type :
1239+ if is_guessed :
12051240 return STRING
12061241
12071242 if __debug__ :
12081243 try :
1209- if issubclass (ty , ParamType ):
1244+ if issubclass (guessed , ParamType ):
12101245 raise AssertionError (
1211- f"Attempted to use an uninstantiated parameter type ({ ty } )."
1246+ f"Attempted to use an uninstantiated parameter type ({ guessed } )."
12121247 )
12131248 except TypeError :
1214- # ty is an instance (correct), so issubclass fails.
1249+ # guessed is an instance (correct), so issubclass fails.
12151250 pass
12161251
1217- return FuncParamType (ty )
1252+ return FuncParamType (guessed )
12181253
12191254
12201255#: A dummy parameter type that just does nothing. From a user's
0 commit comments