Repository: pylint-dev/astroid

Issue:
Unexpected error from pylint after upgrade to astroid 2.5.
### Steps to reproduce
astroid 2.5
pylint 2.6.0
elasticsearch 7.10.1
python 3.7.3
```
from elasticsearch import Elasticsearch
es = Elasticsearch(["test"])
es.indices.delete(index="test", ignore=[400, 404])
```
1.  run pylint

### Current behavior
line 3 >>> E1123: Unexpected keyword argument 'ignore' in method call (unexpected-keyword-arg)

### Expected behavior
astroid 2.4.2: no error from pylint



Discussion / hints:
I'm seeing similar 2.5-related issues with Enum subclasses. Particularly, `Enum.__members__.items()`. Pylint complains about `__members__` have not member `items` which is incorrect.
With pylint 2.6.2, and astroid 2.4.2, everything is fine. With astroid 2.5:

(note lazy_object_proxy 1.5.2 is present)

Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 582, in _build_master
    ws.require(__requires__)
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 899, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 790, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (lazy-object-proxy 0.0.0 (/usr/lib64/python3.9/site-packages), Requirement.parse('lazy_object_proxy>=1.4.0'), {'astroid'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/pylint-3", line 33, in <module>
    sys.exit(load_entry_point('pylint==2.6.2', 'console_scripts', 'pylint')())
  File "/usr/lib/python3.9/site-packages/pylint/__init__.py", line 19, in run_pylint
    from pylint.lint import Run as PylintRun
  File "/usr/lib/python3.9/site-packages/pylint/lint/__init__.py", line 75, in <module>
    from pylint.lint.check_parallel import check_parallel
  File "/usr/lib/python3.9/site-packages/pylint/lint/check_parallel.py", line 7, in <module>
    from pylint import reporters
  File "/usr/lib/python3.9/site-packages/pylint/reporters/__init__.py", line 24, in <module>
    from pylint import utils
  File "/usr/lib/python3.9/site-packages/pylint/utils/__init__.py", line 47, in <module>
    from pylint.utils.ast_walker import ASTWalker
  File "/usr/lib/python3.9/site-packages/pylint/utils/ast_walker.py", line 6, in <module>
    from astroid import nodes
  File "/usr/lib/python3.9/site-packages/astroid/__init__.py", line 66, in <module>
    from astroid.nodes import *
  File "/usr/lib/python3.9/site-packages/astroid/nodes.py", line 23, in <module>
    from astroid.node_classes import (
  File "/usr/lib/python3.9/site-packages/astroid/node_classes.py", line 44, in <module>
    from astroid import bases
  File "/usr/lib/python3.9/site-packages/astroid/bases.py", line 36, in <module>
    MANAGER = manager.AstroidManager()
  File "/usr/lib/python3.9/site-packages/astroid/util.py", line 27, in <lambda>
    lambda: importlib.import_module("." + module_name, "astroid")
  File "/usr/lib64/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/usr/lib/python3.9/site-packages/astroid/manager.py", line 29, in <module>
    from astroid.interpreter._import import spec
  File "/usr/lib/python3.9/site-packages/astroid/interpreter/_import/spec.py", line 29, in <module>
    from . import util
  File "/usr/lib/python3.9/site-packages/astroid/interpreter/_import/util.py", line 4, in <module>
    import pkg_resources
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 3257, in <module>
    def _initialize_master_working_set():
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 3240, in _call_aside
    f(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 3269, in _initialize_master_working_set
    working_set = WorkingSet._build_master()
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 584, in _build_master
    return cls._build_from_requirements(__requires__)
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 597, in _build_from_requirements
    dists = ws.resolve(reqs, Environment())
  File "/usr/lib/python3.9/site-packages/pkg_resources/__init__.py", line 785, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'lazy_object_proxy>=1.4.0' distribution was not found and is required by astroid

@drfunjohn thanks for your report.
@chiefnoah and @limburgher can you open separate issues with a clear reproducer?
Thanks in advance
Done, thanks! https://github.com/PyCQA/astroid/issues/897

@drfunjohn i identified the faulty commit (cc3bfc5dc94062a582b7b3226598f09d7ec7044e). I am looking for a patch.
Wow, thanks for quick response.
You are welcome but the patch seems tricky...



Fix (patch):
diff --git a/ChangeLog b/ChangeLog
index 2c454cb8df..519fa249f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,15 @@
 astroid's ChangeLog
 ===================
 
+What's New in astroid 2.5.1?
+============================
+Release Date: TBA
+
+* The ``context.path`` is reverted to a set because otherwise it leds to false positives 
+  for non `numpy` functions.
+
+  Closes #895 #899
+
 What's New in astroid 2.5?
 ============================
 Release Date: 2021-02-15
diff --git a/astroid/context.py b/astroid/context.py
index 27d1897f50..b667f8c2cd 100644
--- a/astroid/context.py
+++ b/astroid/context.py
@@ -30,10 +30,8 @@ class InferenceContext:
         "extra_context",
     )
 
-    maximum_path_visit = 3
-
     def __init__(self, path=None, inferred=None):
-        self.path = path or dict()
+        self.path = path or set()
         """
         :type: set(tuple(NodeNG, optional(str)))
 
@@ -90,10 +88,10 @@ def push(self, node):
         Allows one to see if the given node has already
         been looked at for this inference context"""
         name = self.lookupname
-        if self.path.get((node, name), 0) >= self.maximum_path_visit:
+        if (node, name) in self.path:
             return True
 
-        self.path[(node, name)] = self.path.setdefault((node, name), 0) + 1
+        self.path.add((node, name))
         return False
 
     def clone(self):
@@ -111,7 +109,7 @@ def clone(self):
 
     @contextlib.contextmanager
     def restore_path(self):
-        path = dict(self.path)
+        path = set(self.path)
         yield
         self.path = path
 


Test changes:
diff --git a/tests/unittest_brain_numpy_core_umath.py b/tests/unittest_brain_numpy_core_umath.py
index f384ea2539..593c9f89f9 100644
--- a/tests/unittest_brain_numpy_core_umath.py
+++ b/tests/unittest_brain_numpy_core_umath.py
@@ -226,9 +226,11 @@ def test_numpy_core_umath_functions_return_type(self):
             with self.subTest(typ=func_):
                 inferred_values = list(self._inferred_numpy_func_call(func_))
                 self.assertTrue(
-                    len(inferred_values) == 1,
+                    len(inferred_values) == 1
+                    or len(inferred_values) == 2
+                    and inferred_values[-1].pytype() is util.Uninferable,
                     msg="Too much inferred values ({}) for {:s}".format(
-                        inferred_values, func_
+                        inferred_values[-1].pytype(), func_
                     ),
                 )
                 self.assertTrue(
diff --git a/tests/unittest_inference.py b/tests/unittest_inference.py
index 55bbe9e348..edb755c188 100644
--- a/tests/unittest_inference.py
+++ b/tests/unittest_inference.py
@@ -1301,7 +1301,7 @@ def get_context_data(self, **kwargs):
         result = node.inferred()
         assert len(result) == 2
         assert isinstance(result[0], nodes.Dict)
-        assert isinstance(result[1], nodes.Dict)
+        assert result[1] is util.Uninferable
 
     def test_python25_no_relative_import(self):
         ast = resources.build_file("data/package/absimport.py")
@@ -3686,8 +3686,7 @@ def __getitem__(self, name):
         flow = AttributeDict()
         flow['app'] = AttributeDict()
         flow['app']['config'] = AttributeDict()
-        flow['app']['config']['doffing'] = AttributeDict()
-        flow['app']['config']['doffing']['thinkto'] = AttributeDict() #@
+        flow['app']['config']['doffing'] = AttributeDict() #@
         """
         )
         self.assertIsNone(helpers.safe_infer(ast_node.targets[0]))
diff --git a/tests/unittest_regrtest.py b/tests/unittest_regrtest.py
index eeedd35327..042c97f098 100644
--- a/tests/unittest_regrtest.py
+++ b/tests/unittest_regrtest.py
@@ -99,7 +99,7 @@ def test_numpy_crash(self):
         astroid = builder.string_build(data, __name__, __file__)
         callfunc = astroid.body[1].value.func
         inferred = callfunc.inferred()
-        self.assertEqual(len(inferred), 1)
+        self.assertEqual(len(inferred), 2)
 
     def test_nameconstant(self):
         # used to fail for Python 3.4