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 :
@@ -2018,7 +2018,24 @@ def __exit__(self, exc_type, exc_val, exc_tb):
20182018 del self .stderr_backup
20192019
20202020
2021- def typedump (val , max_seq = 5 , special_handlers = None ):
2021+ def typedump (val : Any , max_seq : int = 5 ,
2022+ special_handlers : Optional [Mapping [Type , Callable ]] = None ,
2023+ fully_qualified_name : bool = True ) -> str :
2024+ """
2025+ Return a string representation of the type of *val*, recursing into
2026+ iterable objects.
2027+
2028+ :arg val: The object for which the type should be returned.
2029+ :arg max_seq: For iterable objects, the maximum number of elements to
2030+ include in the return string. Lower this value if you get a
2031+ :class:`RecursionError`.
2032+ :arg special_handlers: An optional mapping of specific types to special
2033+ handlers.
2034+ :arg fully_qualified_name: Return fully qualified names, that is,
2035+ include module names and use ``__qualname__`` instead of ``__name__``.
2036+
2037+ :returns: A string representation of the type of *val*.
2038+ """
20222039 if special_handlers is None :
20232040 special_handlers = {}
20242041
@@ -2029,10 +2046,26 @@ def typedump(val, max_seq=5, special_handlers=None):
20292046 else :
20302047 return hdlr (val )
20312048
2049+ def objname (obj : Any ) -> str :
2050+ if type (obj ).__module__ == "builtins" :
2051+ if fully_qualified_name :
2052+ return type (obj ).__qualname__
2053+ else :
2054+ return type (obj ).__name__
2055+
2056+ if fully_qualified_name :
2057+ return type (obj ).__module__ + "." + type (obj ).__qualname__
2058+ else :
2059+ return type (obj ).__name__
2060+
2061+ # Special handling for 'str' since it is also iterable
2062+ if isinstance (val , str ):
2063+ return "str"
2064+
20322065 try :
20332066 len (val )
20342067 except TypeError :
2035- return type (val ). __name__
2068+ return objname (val )
20362069 else :
20372070 if isinstance (val , dict ):
20382071 return "{%s}" % (
@@ -2042,17 +2075,16 @@ def typedump(val, max_seq=5, special_handlers=None):
20422075
20432076 try :
20442077 if len (val ) > max_seq :
2045- return "{}({},...)" .format (
2046- type (val ).__name__ ,
2047- "," .join (typedump (x , max_seq , special_handlers )
2048- for x in val [:max_seq ]))
2078+ t = "," .join (typedump (x , max_seq , special_handlers )
2079+ for x in val [:max_seq ])
2080+ return f"{ objname (val )} ({ t } ,...)"
20492081 else :
2050- return "{}({})" . format (
2051- type ( val ). __name__ ,
2052- "," . join ( typedump ( x , max_seq , special_handlers )
2053- for x in val ))
2082+ t = "," . join ( typedump ( x , max_seq , special_handlers )
2083+ for x in val )
2084+ return f" { objname ( val ) } ( { t } )"
2085+
20542086 except TypeError :
2055- return val . __class__ . __name__
2087+ return objname ( val )
20562088
20572089
20582090def invoke_editor (s , filename = "edit.txt" , descr = "the file" ):
0 commit comments