Skip to content

Commit

Permalink
Merge branch 'master' into fix-classdef-keywords
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre-Sassoulas authored Mar 7, 2021
2 parents 2b2ad87 + 45aac90 commit feaa011
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 77 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Release Date: TBA

* Iterate over ``Keywords`` when using ``ClassDef.get_children``

* Detects `import numpy` as a valid `numpy` import.

Closes PyCQA/pylint#3974


What's New in astroid 2.5.1?
============================
Expand Down
5 changes: 4 additions & 1 deletion astroid/brain/brain_numpy_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ def _is_a_numpy_module(node: astroid.node_classes.Name) -> bool:
x for x in node.lookup(module_nickname)[1] if isinstance(x, astroid.Import)
]
for target in potential_import_target:
if ("numpy", module_nickname) in target.names:
if ("numpy", module_nickname) in target.names or (
"numpy",
None,
) in target.names:
return True
return False

Expand Down
183 changes: 107 additions & 76 deletions tests/unittest_brain_numpy_core_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class BrainNumpyCoreMultiarrayTest(unittest.TestCase):
("is_busday", "['2011-07-01', '2011-07-02', '2011-07-18']"),
("lexsort", "(('toto', 'tutu'), ('riri', 'fifi'))"),
("packbits", "np.array([1, 2])"),
("ravel_multi_index", "np.array([[1, 2], [2, 1]])", "(3, 4)"),
("unpackbits", "np.array([[1], [2], [3]], dtype=np.uint8)"),
("vdot", "[1, 2]", "[1, 2]"),
("where", "[True, False]", "[1, 2]", "[2, 1]"),
Expand Down Expand Up @@ -77,105 +76,137 @@ def _inferred_numpy_func_call(self, func_name, *func_args):
)
return node.infer()

def _inferred_numpy_no_alias_func_call(self, func_name, *func_args):
node = builder.extract_node(
"""
import numpy
func = numpy.{:s}
func({:s})
""".format(
func_name, ",".join(func_args)
)
)
return node.infer()

def test_numpy_function_calls_inferred_as_ndarray(self):
"""
Test that calls to numpy functions are inferred as numpy.ndarray
"""
for func_ in self.numpy_functions_returning_array:
with self.subTest(typ=func_):
inferred_values = list(self._inferred_numpy_func_call(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == ".ndarray",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)
for infer_wrapper in (
self._inferred_numpy_func_call,
self._inferred_numpy_no_alias_func_call,
):
for func_ in self.numpy_functions_returning_array:
with self.subTest(typ=func_):
inferred_values = list(infer_wrapper(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == ".ndarray",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)

def test_numpy_function_calls_inferred_as_bool(self):
"""
Test that calls to numpy functions are inferred as bool
"""
for func_ in self.numpy_functions_returning_bool:
with self.subTest(typ=func_):
inferred_values = list(self._inferred_numpy_func_call(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "builtins.bool",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)
for infer_wrapper in (
self._inferred_numpy_func_call,
self._inferred_numpy_no_alias_func_call,
):
for func_ in self.numpy_functions_returning_bool:
with self.subTest(typ=func_):
inferred_values = list(infer_wrapper(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "builtins.bool",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)

def test_numpy_function_calls_inferred_as_dtype(self):
"""
Test that calls to numpy functions are inferred as numpy.dtype
"""
for func_ in self.numpy_functions_returning_dtype:
with self.subTest(typ=func_):
inferred_values = list(self._inferred_numpy_func_call(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "numpy.dtype",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)
for infer_wrapper in (
self._inferred_numpy_func_call,
self._inferred_numpy_no_alias_func_call,
):
for func_ in self.numpy_functions_returning_dtype:
with self.subTest(typ=func_):
inferred_values = list(infer_wrapper(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "numpy.dtype",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)

def test_numpy_function_calls_inferred_as_none(self):
"""
Test that calls to numpy functions are inferred as None
"""
for func_ in self.numpy_functions_returning_none:
with self.subTest(typ=func_):
inferred_values = list(self._inferred_numpy_func_call(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "builtins.NoneType",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)
for infer_wrapper in (
self._inferred_numpy_func_call,
self._inferred_numpy_no_alias_func_call,
):
for func_ in self.numpy_functions_returning_none:
with self.subTest(typ=func_):
inferred_values = list(infer_wrapper(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "builtins.NoneType",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)

def test_numpy_function_calls_inferred_as_tuple(self):
"""
Test that calls to numpy functions are inferred as tuple
"""
for func_ in self.numpy_functions_returning_tuple:
with self.subTest(typ=func_):
inferred_values = list(self._inferred_numpy_func_call(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "builtins.tuple",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)
for infer_wrapper in (
self._inferred_numpy_func_call,
self._inferred_numpy_no_alias_func_call,
):
for func_ in self.numpy_functions_returning_tuple:
with self.subTest(typ=func_):
inferred_values = list(infer_wrapper(*func_))
self.assertTrue(
len(inferred_values) == 1,
msg="Too much inferred values ({}) for {:s}".format(
inferred_values, func_[0]
),
)
self.assertTrue(
inferred_values[-1].pytype() == "builtins.tuple",
msg="Illicit type for {:s} ({})".format(
func_[0], inferred_values[-1].pytype()
),
)


if __name__ == "__main__":
Expand Down

0 comments on commit feaa011

Please sign in to comment.