Skip to content

Commit

Permalink
create NodeNG.inferred_best() and replace inferred()[0]
Browse files Browse the repository at this point in the history
  • Loading branch information
ostr00000 committed Mar 24, 2023
1 parent 598e4c3 commit 0ee6bcf
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 58 deletions.
15 changes: 15 additions & 0 deletions astroid/nodes/node_ng.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,21 @@ def inferred(self):
"""
return list(self.infer())

def inferred_best(self) -> InferenceResult:
"""Return single inferred value, possibly avoid Uninferable.
Try to return value of type other than :class:`UninferableBase`.
It is still possible to return :class:`UninferableBase`
if there is no other choice.
:returns: The best inferred value.
:rtype: InferenceResult
"""
return sorted(
self.infer(),
key=lambda inf: isinstance(inf, util.UninferableBase)
)[0]

def instantiate_class(self):
"""Instantiate an instance of the defined class.
Expand Down
2 changes: 1 addition & 1 deletion tests/brain/numpy/test_core_einsumfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test_function_parameters() -> None:
numpy.einsum #@
"""
)
actual_args = instance.inferred()[0].args
actual_args = instance.inferred_best().args

assert actual_args.vararg == "operands"
assert [arg.name for arg in actual_args.kwonlyargs] == ["out", "optimize"]
Expand Down
2 changes: 1 addition & 1 deletion tests/brain/numpy/test_core_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ def test_function_parameters(method: str, expected_args: list[str]) -> None:
numpy.{method} #@
"""
)
actual_args = instance.inferred()[0].args.args
actual_args = instance.inferred_best().args.args
assert [arg.name for arg in actual_args] == expected_args
4 changes: 2 additions & 2 deletions tests/brain/numpy/test_core_numerictypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def test_generic_types_are_subscriptables(self):
np.{type_}[int]
"""
node = builder.extract_node(src)
cls_node = node.inferred()[0]
cls_node = node.inferred_best()
self.assertIsInstance(cls_node, nodes.ClassDef)
self.assertEqual(cls_node.name, type_)

Expand Down Expand Up @@ -407,5 +407,5 @@ def test_numpy_object_uninferable(self):
np.number[int]
"""
node = builder.extract_node(src)
cls_node = node.inferred()[0]
cls_node = node.inferred_best()
self.assertIs(cls_node, Uninferable)
2 changes: 1 addition & 1 deletion tests/brain/numpy/test_ma.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TestBrainNumpyMa:

def _assert_maskedarray(self, code):
node = builder.extract_node(code)
cls_node = node.inferred()[0]
cls_node = node.inferred_best()
assert cls_node.pytype() == "numpy.ma.core.MaskedArray"

@pytest.mark.parametrize("alias_import", [True, False])
Expand Down
2 changes: 1 addition & 1 deletion tests/brain/numpy/test_ndarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,6 @@ def test_numpy_ndarray_class_support_type_indexing(self):
np.ndarray[int]
"""
node = builder.extract_node(src)
cls_node = node.inferred()[0]
cls_node = node.inferred_best()
self.assertIsInstance(cls_node, nodes.ClassDef)
self.assertEqual(cls_node.name, "ndarray")
4 changes: 2 additions & 2 deletions tests/brain/test_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def test_type_subscript(self):
a: type[int] = int
"""
)
val_inf = src.annotation.value.inferred()[0]
val_inf = src.annotation.value.inferred_best()
self.assertIsInstance(val_inf, astroid.ClassDef)
self.assertEqual(val_inf.name, "type")
meth_inf = val_inf.getattr("__class_getitem__")[0]
Expand All @@ -163,7 +163,7 @@ def test_invalid_type_subscript(self):
a: str[int] = "abc"
"""
)
val_inf = src.annotation.value.inferred()[0]
val_inf = src.annotation.value.inferred_best()
self.assertIsInstance(val_inf, astroid.ClassDef)
self.assertEqual(val_inf.name, "str")
with self.assertRaises(AttributeInferenceError):
Expand Down
8 changes: 4 additions & 4 deletions tests/brain/test_ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def test_ctypes_redefined_types_members(c_type, builtin_type, type_code):
"""
node = extract_node(src)
assert isinstance(node, nodes.NodeNG)
node_inf = node.inferred()[0]
node_inf = node.inferred_best()
assert node_inf.pytype() == f"builtins.{builtin_type}"

src = f"""
Expand All @@ -77,7 +77,7 @@ def test_ctypes_redefined_types_members(c_type, builtin_type, type_code):
"""
node = extract_node(src)
assert isinstance(node, nodes.NodeNG)
node_inf = node.inferred()[0]
node_inf = node.inferred_best()
assert isinstance(node_inf, nodes.Const)
assert node_inf.value == type_code

Expand All @@ -95,7 +95,7 @@ def test_cdata_member_access() -> None:
"""
node = extract_node(src)
assert isinstance(node, nodes.NodeNG)
node_inf = node.inferred()[0]
node_inf = node.inferred_best()
assert node_inf.display_type() == "Class"
assert node_inf.qname() == "_ctypes._SimpleCData._objects"

Expand All @@ -111,6 +111,6 @@ def test_other_ctypes_member_untouched() -> None:
"""
node = extract_node(src)
assert isinstance(node, nodes.NodeNG)
node_inf = node.inferred()[0]
node_inf = node.inferred_best()
assert isinstance(node_inf, nodes.Const)
assert node_inf.value == 6
2 changes: 1 addition & 1 deletion tests/brain/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ def pear(self):

# Test that both of the successfully inferred `Name` & `Attribute`
# nodes refer to the user-defined Enum class.
for inferred in (attribute_nodes[0].inferred()[0], name_nodes[0].inferred()[0]):
for inferred in (attribute_nodes[0].inferred_best(), name_nodes[0].inferred_best()):
assert isinstance(inferred, astroid.Instance)
assert inferred.name == "Enum"
assert inferred.qname() == "module_with_class_named_enum.Enum"
Expand Down
6 changes: 3 additions & 3 deletions tests/brain/test_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_value_of_lambda_instance_attrs_is_list():
printsupport.QPrintPreviewDialog.paintRequested #@
"""
node = extract_node(src)
attribute_node = node.inferred()[0]
attribute_node = node.inferred_best()
if attribute_node is Uninferable:
pytest.skip("PyQt6 C bindings may not be installed?")
assert isinstance(attribute_node, UnboundMethod)
Expand All @@ -47,7 +47,7 @@ def test_implicit_parameters() -> None:
timer.timeout.connect #@
"""
node = extract_node(src)
attribute_node = node.inferred()[0]
attribute_node = node.inferred_best()
if attribute_node is Uninferable:
pytest.skip("PyQt6 C bindings may not be installed?")
assert isinstance(attribute_node, FunctionDef)
Expand All @@ -65,7 +65,7 @@ def test_slot_disconnect_no_args() -> None:
timer.timeout.disconnect #@
"""
node = extract_node(src)
attribute_node = node.inferred()[0]
attribute_node = node.inferred_best()
if attribute_node is Uninferable:
pytest.skip("PyQt6 C bindings may not be installed?")
assert isinstance(attribute_node, FunctionDef)
Expand Down
2 changes: 1 addition & 1 deletion tests/brain/test_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_enum(enum_name):

# Check the extracted node
assert isinstance(node, nodes.NodeNG)
node_inf = node.inferred()[0]
node_inf = node.inferred_best()
assert isinstance(node_inf, nodes.ClassDef)
assert node_inf.display_type() == "Class"
assert node_inf.is_subtype_of("enum.IntEnum")
Expand Down
Loading

0 comments on commit 0ee6bcf

Please sign in to comment.