Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/astroid/util.py: 66%

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

77 statements  

1# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html 

2# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE 

3# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt 

4 

5 

6from __future__ import annotations 

7 

8import warnings 

9from typing import TYPE_CHECKING, Any, Final, Literal 

10 

11from astroid.exceptions import InferenceError 

12 

13if TYPE_CHECKING: 

14 from astroid import bases, nodes 

15 from astroid.context import InferenceContext 

16 from astroid.typing import InferenceResult 

17 

18 

19class UninferableBase: 

20 """Special inference object, which is returned when inference fails. 

21 

22 This is meant to be used as a singleton. Use astroid.util.Uninferable to access it. 

23 """ 

24 

25 def __repr__(self) -> Literal["Uninferable"]: 

26 return "Uninferable" 

27 

28 __str__ = __repr__ 

29 

30 def __getattribute__(self, name: str) -> Any: 

31 if name == "next": 

32 raise AttributeError("next method should not be called") 

33 if name.startswith("__") and name.endswith("__"): 

34 return object.__getattribute__(self, name) 

35 if name == "accept": 

36 return object.__getattribute__(self, name) 

37 return self 

38 

39 def __call__(self, *args: Any, **kwargs: Any) -> UninferableBase: 

40 return self 

41 

42 def __bool__(self) -> Literal[False]: 

43 return False 

44 

45 __nonzero__ = __bool__ 

46 

47 def accept(self, visitor): 

48 return visitor.visit_uninferable(self) 

49 

50 

51Uninferable: Final = UninferableBase() 

52 

53 

54class BadOperationMessage: 

55 """Object which describes a TypeError occurred somewhere in the inference chain. 

56 

57 This is not an exception, but a container object which holds the types and 

58 the error which occurred. 

59 """ 

60 

61 

62class BadUnaryOperationMessage(BadOperationMessage): 

63 """Object which describes operational failures on UnaryOps.""" 

64 

65 def __init__(self, operand, op, error): 

66 self.operand = operand 

67 self.op = op 

68 self.error = error 

69 

70 @property 

71 def _object_type_helper(self): 

72 from astroid import helpers # pylint: disable=import-outside-toplevel 

73 

74 return helpers.object_type 

75 

76 def _object_type(self, obj): 

77 objtype = self._object_type_helper(obj) 

78 if isinstance(objtype, UninferableBase): 

79 return None 

80 

81 return objtype 

82 

83 def __str__(self) -> str: 

84 if hasattr(self.operand, "name"): 

85 operand_type = self.operand.name 

86 else: 

87 object_type = self._object_type(self.operand) 

88 if hasattr(object_type, "name"): 

89 operand_type = object_type.name 

90 else: 

91 # Just fallback to as_string 

92 operand_type = object_type.as_string() 

93 

94 msg = "bad operand type for unary {}: {}" 

95 return msg.format(self.op, operand_type) 

96 

97 

98class BadBinaryOperationMessage(BadOperationMessage): 

99 """Object which describes type errors for BinOps.""" 

100 

101 def __init__(self, left_type, op, right_type): 

102 self.left_type = left_type 

103 self.right_type = right_type 

104 self.op = op 

105 

106 def __str__(self) -> str: 

107 return ( 

108 f"unsupported operand type(s) for {self.op}: {self.left_type.name!r} " 

109 f"and {self.right_type.name!r}" 

110 ) 

111 

112 

113def check_warnings_filter() -> bool: 

114 """Return True if any other than the default DeprecationWarning filter is enabled. 

115 

116 https://docs.python.org/3/library/warnings.html#default-warning-filter 

117 """ 

118 return any( 

119 issubclass(DeprecationWarning, filter[2]) 

120 and filter[0] != "ignore" 

121 and filter[3] != "__main__" 

122 for filter in warnings.filters 

123 ) 

124 

125 

126def safe_infer( 

127 node: nodes.NodeNG | bases.Proxy | UninferableBase, 

128 context: InferenceContext | None = None, 

129) -> InferenceResult | None: 

130 """Return the inferred value for the given node. 

131 

132 Return None if inference failed or if there is some ambiguity (more than 

133 one node has been inferred). 

134 """ 

135 if isinstance(node, UninferableBase): 

136 return node 

137 try: 

138 inferit = node.infer(context=context) 

139 value = next(inferit) 

140 except (InferenceError, StopIteration): 

141 return None 

142 try: 

143 next(inferit) 

144 return None # None if there is ambiguity on the inferred node 

145 except InferenceError: 

146 return None # there is some kind of ambiguity 

147 except StopIteration: 

148 return value