pylint
pylint copied to clipboard
Pylint doesn't complain on Protocol callback argument-type / return-type mismatch
Bug description
from typing import Protocol
class Handler(Protocol):
def __call__(self, value: int, name: str) -> int:
pass
def invalid_func_arg_type_mismatch(value: str, name: str) -> int:
return value * 2
def invalid_func_return_type_mismatch(value: int, name: str) -> str:
return value * 2
class AsyncHandler(Protocol):
async def __call__(self, value: int, name: str) -> int:
pass
async def invalid_async_func_arg_type_mismatch(value: str, name: str) -> int:
return value * 2
async def invalid_async_func_return_type_mismatch(value: int, name: str) -> str:
return value * 2
# None of the following lines triggers a pylint issue regarding
# mismatch of the return-type or argument-type from the defined Protocol.
# My IntelliJ IDE complains on all 4 lines, because either an argument-type
# or the return-type of the function will not match the `Protocol` I try to assign
# to.
# Expected type 'Handler', got '(value: str, name: str) -> int' instead
my_handler_a: Handler = invalid_func_arg_type_mismatch
# Expected type 'Handler', got '(value: int, name: str) -> str' instead
my_handler_b: Handler = invalid_func_return_type_mismatch
# Expected type 'AsyncHandler', got '(value: str, name: str) -> Coroutine[Any, Any, int]' instead
my_handler_c: AsyncHandler = invalid_async_func_arg_type_mismatch
# Expected type 'AsyncHandler', got '(value: int, name: str) -> Coroutine[Any, Any, str]' instead
my_handler_d: AsyncHandler = invalid_async_func_return_type_mismatch
Configuration
Command used
pylint scratch.py
Pylint output
************* Module src.tests.scratch
src/tests/scratch.py:1:0: C0114: Missing module docstring (missing-module-docstring)
src/tests/scratch.py:4:0: C0115: Missing class docstring (missing-class-docstring)
src/tests/scratch.py:4:0: R0903: Too few public methods (1/2) (too-few-public-methods)
src/tests/scratch.py:9:0: C0116: Missing function or method docstring (missing-function-docstring)
src/tests/scratch.py:9:47: W0613: Unused argument 'name' (unused-argument)
src/tests/scratch.py:13:0: C0116: Missing function or method docstring (missing-function-docstring)
src/tests/scratch.py:13:50: W0613: Unused argument 'name' (unused-argument)
src/tests/scratch.py:17:0: C0115: Missing class docstring (missing-class-docstring)
src/tests/scratch.py:17:0: R0903: Too few public methods (1/2) (too-few-public-methods)
src/tests/scratch.py:22:0: C0116: Missing function or method docstring (missing-function-docstring)
src/tests/scratch.py:22:59: W0613: Unused argument 'name' (unused-argument)
src/tests/scratch.py:26:0: C0116: Missing function or method docstring (missing-function-docstring)
src/tests/scratch.py:26:62: W0613: Unused argument 'name' (unused-argument)
------------------------------------------------------------------
Your code has been rated at 3.16/10 (previous run: 3.16/10, +0.00)
Expected behavior
Assignment with mismatched types should result in output of pylint complaining about the mismatch with the given Protocol.
Pylint version
pylint 3.3.4
astroid 3.3.8
Python 3.12.9 (main, Feb 4 2025, 14:38:38) [Clang 16.0.0 (clang-1600.0.26.6)]
OS / Environment
MacOS, 15.3.1 (24D70), Apple M1 Pro
Additional dependencies
Thank you for bringing this up. This would be a new check/message, as I don't think pylint currently checks for such cases. A type checker like mypy should be able to pick up these type mismatches.