3636from functools import reduce , wraps
3737from sys import intern
3838from typing import (
39- Any , Callable , ClassVar , Dict , Generic , Hashable , Iterable , List , Optional , Set ,
40- Tuple , TypeVar , Union )
39+ Any , Callable , ClassVar , Dict , Generic , Hashable , Iterable , List , Mapping ,
40+ Optional , Set , Tuple , Type , TypeVar , Union )
4141
4242
4343try :
@@ -2016,7 +2016,24 @@ def __exit__(self, exc_type, exc_val, exc_tb):
20162016 del self .stderr_backup
20172017
20182018
2019- def typedump (val , max_seq = 5 , special_handlers = None ):
2019+ def typedump (val : Any , max_seq : int = 5 ,
2020+ special_handlers : Optional [Mapping [Type , Callable ]] = None ,
2021+ fully_qualified_name : bool = True ) -> str :
2022+ """
2023+ Return a string representation of the type of *val*, recursing into
2024+ iterable objects.
2025+
2026+ :arg val: The object for which the type should be returned.
2027+ :arg max_seq: For iterable objects, the maximum number of elements to
2028+ include in the return string. Lower this value if you get a
2029+ :class:`RecursionError`.
2030+ :arg special_handlers: An optional mapping of specific types to special
2031+ handlers.
2032+ :arg fully_qualified_name: Return fully qualified names, that is,
2033+ include module names and use ``__qualname__`` instead of ``__name__``.
2034+
2035+ :returns: A string representation of the type of *val*.
2036+ """
20202037 if special_handlers is None :
20212038 special_handlers = {}
20222039
@@ -2027,10 +2044,26 @@ def typedump(val, max_seq=5, special_handlers=None):
20272044 else :
20282045 return hdlr (val )
20292046
2047+ def objname (obj : Any ) -> str :
2048+ if type (obj ).__module__ == "builtins" :
2049+ if fully_qualified_name :
2050+ return type (obj ).__qualname__
2051+ else :
2052+ return type (obj ).__name__
2053+
2054+ if fully_qualified_name :
2055+ return type (obj ).__module__ + "." + type (obj ).__qualname__
2056+ else :
2057+ return type (obj ).__name__
2058+
2059+ # Special handling for 'str' since it is also iterable
2060+ if isinstance (val , str ):
2061+ return "str"
2062+
20302063 try :
20312064 len (val )
20322065 except TypeError :
2033- return type (val ). __name__
2066+ return objname (val )
20342067 else :
20352068 if isinstance (val , dict ):
20362069 return "{%s}" % (
@@ -2040,17 +2073,16 @@ def typedump(val, max_seq=5, special_handlers=None):
20402073
20412074 try :
20422075 if len (val ) > max_seq :
2043- return "{}({},...)" .format (
2044- type (val ).__name__ ,
2045- "," .join (typedump (x , max_seq , special_handlers )
2046- for x in val [:max_seq ]))
2076+ t = "," .join (typedump (x , max_seq , special_handlers )
2077+ for x in val [:max_seq ])
2078+ return f"{ objname (val )} ({ t } ,...)"
20472079 else :
2048- return "{}({})" . format (
2049- type ( val ). __name__ ,
2050- "," . join ( typedump ( x , max_seq , special_handlers )
2051- for x in val ))
2080+ t = "," . join ( typedump ( x , max_seq , special_handlers )
2081+ for x in val )
2082+ return f" { objname ( val ) } ( { t } )"
2083+
20522084 except TypeError :
2053- return val . __class__ . __name__
2085+ return objname ( val )
20542086
20552087
20562088def invoke_editor (s , filename = "edit.txt" , descr = "the file" ):
0 commit comments