diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 99d5c48c92d7..9dbd3b7572c1 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -936,7 +936,7 @@ def do_func_def( lineno = n.lineno args = self.transform_args(n.args, lineno, no_type_check=no_type_check) - if special_function_elide_names(n.name): + if self.options.pos_only_special_methods and special_function_elide_names(n.name): for arg in args: arg.pos_only = True diff --git a/mypy/options.py b/mypy/options.py index ad4b26cca095..bc592eebdb3e 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -400,6 +400,9 @@ def __init__(self) -> None: # Export line-level, limited, fine-grained dependency information in cache data # (undocumented feature). self.export_ref_info = False + # Treat special methods as being implicitly positional-only. + # Set to False when running stubtest. + self.pos_only_special_methods = True self.disable_bytearray_promotion = False self.disable_memoryview_promotion = False diff --git a/mypy/stubtest.py b/mypy/stubtest.py index ee15fed81b4b..0a6932ada553 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1060,7 +1060,6 @@ def _verify_signature( and not stub_arg.variable.name.startswith("__") and stub_arg.variable.name.strip("_") != "self" and stub_arg.variable.name.strip("_") != "cls" - and not is_dunder(function_name, exclude_special=True) # noisy for dunder methods ): yield ( f'stub parameter "{stub_arg.variable.name}" should be positional-only ' @@ -2235,6 +2234,7 @@ def test_stubs(args: _Arguments, use_builtins_fixtures: bool = False) -> int: options.use_builtins_fixtures = use_builtins_fixtures options.show_traceback = args.show_traceback options.pdb = args.pdb + options.pos_only_special_methods = False if options.config_file: diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 28263e20099d..9be499d9cb48 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1652,6 +1652,16 @@ def test_dunders(self) -> Iterator[Case]: runtime="class D:\n def __class_getitem__(cls, type): ...", error=None, ) + yield Case( + stub="class E:\n def __getitem__(self, item: object) -> object: ...", + runtime="class E:\n def __getitem__(self, item: object, /) -> object: ...", + error="E.__getitem__", + ) + yield Case( + stub="class F:\n def __getitem__(self, item: object, /) -> object: ...", + runtime="class F:\n def __getitem__(self, item: object) -> object: ...", + error=None, + ) @collect_cases def test_not_subclassable(self) -> Iterator[Case]: