Skip to content

Commit

Permalink
Handle built-in __init__ call with bad args.
Browse files Browse the repository at this point in the history
  • Loading branch information
jzohrab committed Jan 17, 2025
1 parent a08d9b4 commit b495cd4
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 24 deletions.
52 changes: 36 additions & 16 deletions pylint/checkers/typecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -1455,13 +1455,13 @@ def visit_call(self, node: nodes.Call) -> None:
"""

def _dp(s, val=None):
if "Attribute.__init__ l.13" not in str(node):
# print("Not in init")
return
if val is None:
print(f" {s}", flush=True)
else:
print(f" {s}: {val}", flush=True)
return
## if "Attribute.__init__" not in str(node):
## return
## if val is None:
## print(f" {s}", flush=True)
## else:
## print(f" {s}: {val}", flush=True)

_dp("-" * 25)
_dp("visit call, node", node)
Expand All @@ -1477,24 +1477,44 @@ def _dp(s, val=None):

_dp("Data dump for __init__ call")
call_site = astroid.arguments.CallSite.from_call(node)
num_positional_args = len(call_site.positional_arguments)
_dp("call_site", call_site)
# _dp("call_site args", call_site.arguments)
# _dp("call site positional args:", call_site.positional_arguments)
# _dp("call site keyword args:", call_site.keyword_arguments)
# _dp("call site invalid args", call_site.has_invalid_arguments())
# _dp("call site inv keywords", call_site.has_invalid_keywords())
_dp("node args", node.args)
_dp("node frame", node.frame())
_dp("isinst", isinstance(node.frame(), nodes.ClassDef))
_dp("funcdef", isinstance(called, nodes.FunctionDef))
# _dp("isinst", isinstance(node.frame(), nodes.ClassDef))
# _dp("funcdef", isinstance(called, nodes.FunctionDef))
_dp("called", called)
_dp("bound method init in called", "BoundMethod __init__ of builtins.object" in str(called))
_dp("called.args", called.args)
_dp("frame body", node.frame().body)
_dp("called in frame body", called in node.frame().body)
_dp("npa", num_positional_args)
_dp("dec names", called.decoratornames())
# _dp("called in frame body", called in node.frame().body)
# _dp("dec names", called.decoratornames())

def _call_site_has_args(cs):
"True if any args passed."
has_args = (
False
or len(cs.positional_arguments) > 0
or len(cs.keyword_arguments.items()) > 0
or cs.starargs is not None
or cs.kwargs is not None
)
return has_args

if called.args.args is None:
_dp("called.args.args is None")
_dp("called.name", called.name)
if called.name == "isinstance":
# Verify whether second argument of isinstance is a valid type
self._check_isinstance_args(node, callable_name)
# Built-in functions have no argument information.
_dp("Returning now")
# Check built-in __init__ ... a user-defined __init__ function
# is handled elsewhere.
if "BoundMethod __init__ of builtins.object" in str(called):
if _call_site_has_args(call_site):
self.add_message("too-many-function-args", node=node, args=("__init__",))
return

if len(called.argnames()) != len(set(called.argnames())):
Expand Down
12 changes: 4 additions & 8 deletions tests/test_self.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,21 +343,17 @@ def test_wrong_import_position_when_others_disabled(self) -> None:

def test_super_init_with_non_self_argument(self) -> None:
module1 = join(HERE, "regrtest_data", "super_init_with_non_self_argument.py")
args = [module1]
args = [module1, "-rn", "-sn"]
out = StringIO()
self._run_pylint(args, out=out)
actual_output = self._clean_paths(out.getvalue().strip())

expected_output = textwrap.dedent(
expected = textwrap.dedent(
f"""
************* Module super_init_with_non_self_argument
{module1}:11:0: blah
{module1}:13:8: E1121: Too many positional arguments for __init__ call (too-many-function-args)
"""
)
assert (
"Your code has been rated at 10.00/10" not in actual_output
), "bad code should fail."
assert self._clean_paths(expected_output.strip()) == actual_output.strip()
assert self._clean_paths(expected.strip()) == actual_output.strip()

def test_progress_reporting(self) -> None:
module1 = join(HERE, "regrtest_data", "import_something.py")
Expand Down

0 comments on commit b495cd4

Please sign in to comment.