diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 701e449f8f33..b2ec89ff81b8 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -913,7 +913,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 3dc72c7e3051..f3309473972b 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -413,6 +413,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 a6780984c1f5..204680961ab6 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1081,7 +1081,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 ' @@ -2293,6 +2292,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 45cc46c40108..e32081bb1a27 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1708,6 +1708,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]: