summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2020-03-26 10:05:56 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2020-03-26 10:05:56 +0100
commitf62be0a2d52b2ba01010cecc372fceb821528091 (patch)
treee15e33170159099b71f228c869db585d3b600a16
parent76fd7aa73cfbe650c97bf6828adb7e39490c3e99 (diff)
downloadastroid-git-f62be0a2d52b2ba01010cecc372fceb821528091.tar.gz
``BoundMethod.implicit_parameters`` returns a proper value for ``__new__``
Close PyCQA/pylint#2335
-rw-r--r--ChangeLog4
-rw-r--r--astroid/bases.py3
-rw-r--r--tests/unittest_inference.py21
3 files changed, 28 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 78af48d9..515fd656 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,10 @@ Release Date: TBA
Closes PyCQA/astroid#725
+* ``BoundMethod.implicit_parameters`` returns a proper value for ``__new__``
+
+ Close PyCQA/pylint#2335
+
* Allow slots added dynamically to a class to still be inferred
Close PyCQA/pylint#2334
diff --git a/astroid/bases.py b/astroid/bases.py
index ae66c7a3..a59cbd12 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -391,6 +391,9 @@ class BoundMethod(UnboundMethod):
self.bound = bound
def implicit_parameters(self):
+ if self.name == "__new__":
+ # __new__ acts as a classmethod but the class argument is not implicit.
+ return 0
return 1
def is_bound(self):
diff --git a/tests/unittest_inference.py b/tests/unittest_inference.py
index b2210a8d..21dc946d 100644
--- a/tests/unittest_inference.py
+++ b/tests/unittest_inference.py
@@ -5791,5 +5791,26 @@ def test_allow_retrieving_instance_attrs_and_special_attrs_for_functions():
assert len(attrs) == 2
+def test_implicit_parameters_bound_method():
+ code = """
+ class A(type):
+ @classmethod
+ def test(cls, first): return first
+ def __new__(cls, name, bases, dictionary):
+ return super().__new__(cls, name, bases, dictionary)
+
+ A.test #@
+ A.__new__ #@
+ """
+ test, dunder_new = extract_node(code)
+ test = next(test.infer())
+ assert isinstance(test, BoundMethod)
+ assert test.implicit_parameters() == 1
+
+ dunder_new = next(dunder_new.infer())
+ assert isinstance(dunder_new, BoundMethod)
+ assert dunder_new.implicit_parameters() == 0
+
+
if __name__ == "__main__":
unittest.main()