Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/setuptools/_vendor/typeguard/_utils.py: 38%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

97 statements  

1from __future__ import annotations 

2 

3import inspect 

4import sys 

5from importlib import import_module 

6from inspect import currentframe 

7from types import CodeType, FrameType, FunctionType 

8from typing import TYPE_CHECKING, Any, Callable, ForwardRef, Union, cast, final 

9from weakref import WeakValueDictionary 

10 

11if TYPE_CHECKING: 

12 from ._memo import TypeCheckMemo 

13 

14if sys.version_info >= (3, 13): 

15 from typing import get_args, get_origin 

16 

17 def evaluate_forwardref(forwardref: ForwardRef, memo: TypeCheckMemo) -> Any: 

18 return forwardref._evaluate( 

19 memo.globals, memo.locals, type_params=(), recursive_guard=frozenset() 

20 ) 

21 

22elif sys.version_info >= (3, 10): 

23 from typing import get_args, get_origin 

24 

25 def evaluate_forwardref(forwardref: ForwardRef, memo: TypeCheckMemo) -> Any: 

26 return forwardref._evaluate( 

27 memo.globals, memo.locals, recursive_guard=frozenset() 

28 ) 

29 

30else: 

31 from typing_extensions import get_args, get_origin 

32 

33 evaluate_extra_args: tuple[frozenset[Any], ...] = ( 

34 (frozenset(),) if sys.version_info >= (3, 9) else () 

35 ) 

36 

37 def evaluate_forwardref(forwardref: ForwardRef, memo: TypeCheckMemo) -> Any: 

38 from ._union_transformer import compile_type_hint, type_substitutions 

39 

40 if not forwardref.__forward_evaluated__: 

41 forwardref.__forward_code__ = compile_type_hint(forwardref.__forward_arg__) 

42 

43 try: 

44 return forwardref._evaluate(memo.globals, memo.locals, *evaluate_extra_args) 

45 except NameError: 

46 if sys.version_info < (3, 10): 

47 # Try again, with the type substitutions (list -> List etc.) in place 

48 new_globals = memo.globals.copy() 

49 new_globals.setdefault("Union", Union) 

50 if sys.version_info < (3, 9): 

51 new_globals.update(type_substitutions) 

52 

53 return forwardref._evaluate( 

54 new_globals, memo.locals or new_globals, *evaluate_extra_args 

55 ) 

56 

57 raise 

58 

59 

60_functions_map: WeakValueDictionary[CodeType, FunctionType] = WeakValueDictionary() 

61 

62 

63def get_type_name(type_: Any) -> str: 

64 name: str 

65 for attrname in "__name__", "_name", "__forward_arg__": 

66 candidate = getattr(type_, attrname, None) 

67 if isinstance(candidate, str): 

68 name = candidate 

69 break 

70 else: 

71 origin = get_origin(type_) 

72 candidate = getattr(origin, "_name", None) 

73 if candidate is None: 

74 candidate = type_.__class__.__name__.strip("_") 

75 

76 if isinstance(candidate, str): 

77 name = candidate 

78 else: 

79 return "(unknown)" 

80 

81 args = get_args(type_) 

82 if args: 

83 if name == "Literal": 

84 formatted_args = ", ".join(repr(arg) for arg in args) 

85 else: 

86 formatted_args = ", ".join(get_type_name(arg) for arg in args) 

87 

88 name += f"[{formatted_args}]" 

89 

90 module = getattr(type_, "__module__", None) 

91 if module and module not in (None, "typing", "typing_extensions", "builtins"): 

92 name = module + "." + name 

93 

94 return name 

95 

96 

97def qualified_name(obj: Any, *, add_class_prefix: bool = False) -> str: 

98 """ 

99 Return the qualified name (e.g. package.module.Type) for the given object. 

100 

101 Builtins and types from the :mod:`typing` package get special treatment by having 

102 the module name stripped from the generated name. 

103 

104 """ 

105 if obj is None: 

106 return "None" 

107 elif inspect.isclass(obj): 

108 prefix = "class " if add_class_prefix else "" 

109 type_ = obj 

110 else: 

111 prefix = "" 

112 type_ = type(obj) 

113 

114 module = type_.__module__ 

115 qualname = type_.__qualname__ 

116 name = qualname if module in ("typing", "builtins") else f"{module}.{qualname}" 

117 return prefix + name 

118 

119 

120def function_name(func: Callable[..., Any]) -> str: 

121 """ 

122 Return the qualified name of the given function. 

123 

124 Builtins and types from the :mod:`typing` package get special treatment by having 

125 the module name stripped from the generated name. 

126 

127 """ 

128 # For partial functions and objects with __call__ defined, __qualname__ does not 

129 # exist 

130 module = getattr(func, "__module__", "") 

131 qualname = (module + ".") if module not in ("builtins", "") else "" 

132 return qualname + getattr(func, "__qualname__", repr(func)) 

133 

134 

135def resolve_reference(reference: str) -> Any: 

136 modulename, varname = reference.partition(":")[::2] 

137 if not modulename or not varname: 

138 raise ValueError(f"{reference!r} is not a module:varname reference") 

139 

140 obj = import_module(modulename) 

141 for attr in varname.split("."): 

142 obj = getattr(obj, attr) 

143 

144 return obj 

145 

146 

147def is_method_of(obj: object, cls: type) -> bool: 

148 return ( 

149 inspect.isfunction(obj) 

150 and obj.__module__ == cls.__module__ 

151 and obj.__qualname__.startswith(cls.__qualname__ + ".") 

152 ) 

153 

154 

155def get_stacklevel() -> int: 

156 level = 1 

157 frame = cast(FrameType, currentframe()).f_back 

158 while frame and frame.f_globals.get("__name__", "").startswith("typeguard."): 

159 level += 1 

160 frame = frame.f_back 

161 

162 return level 

163 

164 

165@final 

166class Unset: 

167 __slots__ = () 

168 

169 def __repr__(self) -> str: 

170 return "<unset>" 

171 

172 

173unset = Unset()