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
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
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
6from __future__ import annotations
8import warnings
9from typing import TYPE_CHECKING, Any, Final, Literal
11from astroid.exceptions import InferenceError
13if TYPE_CHECKING:
14 from astroid import bases, nodes
15 from astroid.context import InferenceContext
16 from astroid.typing import InferenceResult
19class UninferableBase:
20 """Special inference object, which is returned when inference fails.
22 This is meant to be used as a singleton. Use astroid.util.Uninferable to access it.
23 """
25 def __repr__(self) -> Literal["Uninferable"]:
26 return "Uninferable"
28 __str__ = __repr__
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
39 def __call__(self, *args: Any, **kwargs: Any) -> UninferableBase:
40 return self
42 def __bool__(self) -> Literal[False]:
43 return False
45 __nonzero__ = __bool__
47 def accept(self, visitor):
48 return visitor.visit_uninferable(self)
51Uninferable: Final = UninferableBase()
54class BadOperationMessage:
55 """Object which describes a TypeError occurred somewhere in the inference chain.
57 This is not an exception, but a container object which holds the types and
58 the error which occurred.
59 """
62class BadUnaryOperationMessage(BadOperationMessage):
63 """Object which describes operational failures on UnaryOps."""
65 def __init__(self, operand, op, error):
66 self.operand = operand
67 self.op = op
68 self.error = error
70 @property
71 def _object_type_helper(self):
72 from astroid import helpers # pylint: disable=import-outside-toplevel
74 return helpers.object_type
76 def _object_type(self, obj):
77 objtype = self._object_type_helper(obj)
78 if isinstance(objtype, UninferableBase):
79 return None
81 return objtype
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()
94 msg = "bad operand type for unary {}: {}"
95 return msg.format(self.op, operand_type)
98class BadBinaryOperationMessage(BadOperationMessage):
99 """Object which describes type errors for BinOps."""
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
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)
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
124def check_warnings_filter() -> bool:
125 """Return True if any other than the default DeprecationWarning filter is enabled.
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 )
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.
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