Skip to content

Commit

Permalink
Make FunctionDef.implicit_parameters return 1 for methods (#1531)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtylerwalls authored and Pierre-Sassoulas committed May 2, 2022
1 parent b28067e commit c4e11cb
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Release date: TBA

* Fix ``col_offset`` attribute for nodes involving ``with`` on ``PyPy``.

* Made ``FunctionDef.implicit_parameters`` return 1 for methods by making
``FunctionDef.is_bound`` return ``True``, as it does for class methods.

Closes PyCQA/pylint#6464

* Fixed a crash when ``_filter_stmts`` encounters an ``EmptyNode``.

Closes PyCQA/pylint#6438
Expand Down
5 changes: 4 additions & 1 deletion astroid/nodes/scoped_nodes/scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1587,6 +1587,9 @@ def blockstart_tolineno(self):
"""
return self.args.tolineno

def implicit_parameters(self) -> Literal[0, 1]:
return 1 if self.is_bound() else 0

def block_range(self, lineno):
"""Get a range from the given line number to where this node ends.
Expand Down Expand Up @@ -1648,7 +1651,7 @@ def is_bound(self):
False otherwise.
:rtype: bool
"""
return self.type == "classmethod"
return self.type in {"method", "classmethod"}

def is_abstract(self, pass_is_abstract=True, any_raise_is_abstract=False):
"""Check if the method is abstract.
Expand Down
18 changes: 17 additions & 1 deletion tests/unittest_brain_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

@pytest.mark.skipif(HAS_PYQT6 is None, reason="This test requires the PyQt6 library.")
class TestBrainQt:
AstroidManager.brain["extension_package_whitelist"] = {"PyQt6"}

@staticmethod
def test_value_of_lambda_instance_attrs_is_list():
"""Regression test for https://github.com/PyCQA/pylint/issues/6221
Expand All @@ -28,11 +30,25 @@ def test_value_of_lambda_instance_attrs_is_list():
from PyQt6 import QtPrintSupport as printsupport
printsupport.QPrintPreviewDialog.paintRequested #@
"""
AstroidManager.brain["extension_package_whitelist"] = {"PyQt6.QtPrintSupport"}
node = extract_node(src)
attribute_node = node.inferred()[0]
if attribute_node is Uninferable:
pytest.skip("PyQt6 C bindings may not be installed?")
assert isinstance(attribute_node, UnboundMethod)
# scoped_nodes.Lambda.instance_attrs is typed as Dict[str, List[NodeNG]]
assert isinstance(attribute_node.instance_attrs["connect"][0], FunctionDef)

@staticmethod
def test_implicit_parameters() -> None:
"""Regression test for https://github.com/PyCQA/pylint/issues/6464"""
src = """
from PyQt6.QtCore import QTimer
timer = QTimer()
timer.timeout.connect #@
"""
node = extract_node(src)
attribute_node = node.inferred()[0]
if attribute_node is Uninferable:
pytest.skip("PyQt6 C bindings may not be installed?")
assert isinstance(attribute_node, FunctionDef)
assert attribute_node.implicit_parameters() == 1
18 changes: 18 additions & 0 deletions tests/unittest_scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,24 @@ def test():
self.assertIsInstance(one, nodes.Const)
self.assertEqual(one.value, 1)

def test_func_is_bound(self) -> None:
data = """
class MyClass:
def bound(): #@
pass
"""
func = builder.extract_node(data)
self.assertIs(func.is_bound(), True)
self.assertEqual(func.implicit_parameters(), 1)

data2 = """
def not_bound(): #@
pass
"""
func2 = builder.extract_node(data2)
self.assertIs(func2.is_bound(), False)
self.assertEqual(func2.implicit_parameters(), 0)

def test_type_builtin_descriptor_subclasses(self) -> None:
astroid = builder.parse(
"""
Expand Down

0 comments on commit c4e11cb

Please sign in to comment.