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

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

83 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 msg = "unsupported operand type(s) for {}: {!r} and {!r}" 

108 return msg.format(self.op, self.left_type.name, self.right_type.name) 

109 

110 

111def _instancecheck(cls, other) -> bool: 

112 wrapped = cls.__wrapped__ 

113 other_cls = other.__class__ 

114 is_instance_of = wrapped is other_cls or issubclass(other_cls, wrapped) 

115 warnings.warn( 

116 "%r is deprecated and slated for removal in astroid " 

117 "2.0, use %r instead" % (cls.__class__.__name__, wrapped.__name__), 

118 PendingDeprecationWarning, 

119 stacklevel=2, 

120 ) 

121 return is_instance_of 

122 

123 

124def check_warnings_filter() -> bool: 

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

126 

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

128 """ 

129 return any( 

130 issubclass(DeprecationWarning, filter[2]) 

131 and filter[0] != "ignore" 

132 and filter[3] != "__main__" 

133 for filter in warnings.filters 

134 ) 

135 

136 

137def safe_infer( 

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

139 context: InferenceContext | None = None, 

140) -> InferenceResult | None: 

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

142 

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

144 one node has been inferred). 

145 """ 

146 if isinstance(node, UninferableBase): 

147 return node 

148 try: 

149 inferit = node.infer(context=context) 

150 value = next(inferit) 

151 except (InferenceError, StopIteration): 

152 return None 

153 try: 

154 next(inferit) 

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

156 except InferenceError: 

157 return None # there is some kind of ambiguity 

158 except StopIteration: 

159 return value