Skip to content

Commit a32250c

Browse files
authored
Fix false negatives when isinstance is provided too many or too few arguments (#9868)
- add too-many-function-args call - include handling for too-few-function-args
1 parent cb6db06 commit a32250c

File tree

14 files changed

+58
-7
lines changed

14 files changed

+58
-7
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
isinstance("foo") # [too-few-function-args]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
As of 2024-08-13, #9847, ```too-few-function-args``` is only implemented for the
2+
```isinstance``` built-in function.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
isinstance("foo", str)

doc/user_guide/checkers/features.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,8 @@ Typecheck checker Messages
12411241
:invalid-slice-step (E1144): *Slice step cannot be 0*
12421242
Used when a slice step is 0 and the object doesn't implement a custom
12431243
__getitem__ method.
1244+
:too-few-function-args (E1145): *Too few positional arguments for %s call*
1245+
Used when a function or method call has fewer arguments than expected.
12441246
:too-many-function-args (E1121): *Too many positional arguments for %s call*
12451247
Used when a function call passes too many positional arguments.
12461248
:unexpected-keyword-arg (E1123): *Unexpected keyword argument %r in %s call*

doc/user_guide/messages/messages_overview.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ All messages in the error category:
155155
error/star-needs-assignment-target
156156
error/syntax-error
157157
error/too-few-format-args
158+
error/too-few-function-args
158159
error/too-many-format-args
159160
error/too-many-function-args
160161
error/too-many-star-expressions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fix a false negative when `isinstance` has too many arguments.
2+
Change now emits a `too-many-function-args` output with behavior similar to other
3+
`too-many-function-args` calls.
4+
5+
Closes #9847
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Add `too-few-function-args` for when fewer arguments than expected are provided for a
2+
function or method call.
3+
As of this PR, `too-few-function-args` only applies to the built-in function `isinstance`.
4+
5+
Closes #9847

pylint/checkers/typecheck.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ def _missing_member_hint(
377377
"Used when a slice step is 0 and the object doesn't implement "
378378
"a custom __getitem__ method.",
379379
),
380+
"E1145": (
381+
"Too few positional arguments for %s call",
382+
"too-few-function-args",
383+
"Used when a function or method call has fewer arguments than expected.",
384+
),
380385
"W1113": (
381386
"Keyword argument before variable positional arguments list "
382387
"in the definition of %s function",
@@ -1419,9 +1424,22 @@ def _check_argument_order(
14191424
if calling_parg_names != called_param_names[: len(calling_parg_names)]:
14201425
self.add_message("arguments-out-of-order", node=node, args=())
14211426

1422-
def _check_isinstance_args(self, node: nodes.Call) -> None:
1423-
if len(node.args) != 2:
1424-
# isinstance called with wrong number of args
1427+
def _check_isinstance_args(self, node: nodes.Call, callable_name: str) -> None:
1428+
if len(node.args) > 2:
1429+
# for when isinstance called with too many args
1430+
self.add_message(
1431+
"too-many-function-args",
1432+
node=node,
1433+
args=(callable_name,),
1434+
confidence=HIGH,
1435+
)
1436+
elif len(node.args) < 2:
1437+
self.add_message(
1438+
"too-few-function-args",
1439+
node=node,
1440+
args=(callable_name,),
1441+
confidence=HIGH,
1442+
)
14251443
return
14261444

14271445
second_arg = node.args[1]
@@ -1451,7 +1469,7 @@ def visit_call(self, node: nodes.Call) -> None:
14511469
if called.args.args is None:
14521470
if called.name == "isinstance":
14531471
# Verify whether second argument of isinstance is a valid type
1454-
self._check_isinstance_args(node)
1472+
self._check_isinstance_args(node, callable_name)
14551473
# Built-in functions have no argument information.
14561474
return
14571475

@@ -1554,7 +1572,9 @@ def visit_call(self, node: nodes.Call) -> None:
15541572
elif not overload_function:
15551573
# Too many positional arguments.
15561574
self.add_message(
1557-
"too-many-function-args", node=node, args=(callable_name,)
1575+
"too-many-function-args",
1576+
node=node,
1577+
args=(callable_name,),
15581578
)
15591579
break
15601580

tests/functional/c/consider/consider_merging_isinstance.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ def isinstances():
2323
result = isinstance(var[10], str) or isinstance(var[10], int) and var[8] * 14 or isinstance(var[10], float) and var[5] * 14.4 or isinstance(var[10], list) # [consider-merging-isinstance]
2424
result = isinstance(var[11], int) or isinstance(var[11], int) or isinstance(var[11], float) # [consider-merging-isinstance]
2525

26-
result = isinstance(var[20])
27-
result = isinstance()
26+
result = isinstance(var[20]) # [too-few-function-args]
27+
result = isinstance() # [too-few-function-args]
2828

2929
# Combination merged and not merged
3030
result = isinstance(var[12], (int, float)) or isinstance(var[12], list) # [consider-merging-isinstance]

tests/functional/c/consider/consider_merging_isinstance.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ consider-merging-isinstance:19:13:19:73:isinstances:Consider merging these isins
44
consider-merging-isinstance:22:13:22:127:isinstances:Consider merging these isinstance calls to isinstance(var[6], (float, int)):UNDEFINED
55
consider-merging-isinstance:23:13:23:158:isinstances:Consider merging these isinstance calls to isinstance(var[10], (list, str)):UNDEFINED
66
consider-merging-isinstance:24:13:24:95:isinstances:Consider merging these isinstance calls to isinstance(var[11], (float, int)):UNDEFINED
7+
too-few-function-args:26:13:26:32:isinstances:Too few positional arguments for function call:HIGH
8+
too-few-function-args:27:13:27:25:isinstances:Too few positional arguments for function call:HIGH
79
consider-merging-isinstance:30:13:30:75:isinstances:Consider merging these isinstance calls to isinstance(var[12], (float, int, list)):UNDEFINED

0 commit comments

Comments
 (0)