Skip to content

Commit 7f4b21f

Browse files
committed
Declare function mutators with inline comment
This is accomplised by defining an "error" called decorator-preserves-signature which, when disabled via a comment on a decorator definition, will disable function argument checks on calls to functions that have that decorator. We use an error to do this in order to consume the inline comment state via the linter.file_state._supression_mapping
1 parent d064010 commit 7f4b21f

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ build-stamp
2727
.pytest_cache/
2828
.mypy_cache/
2929
.benchmarks/
30+
venv

pylint/checkers/typecheck.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,11 @@ def _missing_member_hint(
381381
"Used when a slice step is 0 and the object doesn't implement "
382382
"a custom __getitem__ method.",
383383
),
384+
"E1145": (
385+
"",
386+
"decorator-preserves-signature",
387+
"Ignore invalid argument errors on calls to this function",
388+
),
384389
"W1113": (
385390
"Keyword argument before variable positional arguments list "
386391
"in the definition of %s function",
@@ -1454,10 +1459,18 @@ def visit_call(self, node: nodes.Call) -> None:
14541459
return
14551460

14561461
# Has the function signature changed in ways we cannot reliably detect?
1457-
if hasattr(called, "decorators") and decorated_with(
1458-
called, self.linter.config.signature_mutators
1459-
):
1460-
return
1462+
if getattr(called, "decorators", None):
1463+
if decorated_with(called, self.linter.config.signature_mutators):
1464+
return
1465+
1466+
called_decorator: astroid.NodeNG
1467+
for called_decorator in filter(
1468+
None, map(safe_infer, called.decorators.nodes)
1469+
):
1470+
if not self.linter.file_state._module_msgs_state.get("E1145", {}).get(
1471+
called_decorator.lineno, True
1472+
):
1473+
return
14611474

14621475
num_positional_args = len(call_site.positional_arguments)
14631476
keyword_args = list(call_site.keyword_arguments.keys())

tests/functional/a/arguments.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,17 @@ def wrapper(*args, do_something=True, **kwargs):
240240
return wrapper
241241

242242

243+
def yet_another_mutation_decorator(fun): # pylint: disable=decorator-preserves-signature
244+
"""Yet another decorator that changes a function's signature"""
245+
def wrapper(*args, do_something=True, **kwargs):
246+
if do_something:
247+
return fun(*args, **kwargs)
248+
249+
return None
250+
251+
return wrapper
252+
253+
243254
@mutation_decorator
244255
def mutated_function(arg):
245256
return arg
@@ -250,11 +261,17 @@ def mutated(arg):
250261
return arg
251262

252263

264+
@yet_another_mutation_decorator
265+
def another_mutated_function(arg):
266+
return arg
267+
268+
253269
mutated_function(do_something=False)
254270
mutated_function()
255271

256272
mutated(do_something=True)
257273

274+
another_mutated_function(do_something=False)
258275

259276
def func(one, two, three):
260277
return one + two + three

0 commit comments

Comments
 (0)