diff --git a/mypy/fastparse.py b/mypy/fastparse.py index bb71242182f1..59ab4374ea98 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -929,7 +929,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 6d7eca772888..f2f003d52895 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -398,6 +398,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 ef8c8dc318e1..8419d7704acc 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -943,7 +943,6 @@ def _verify_signature( and not stub_arg.pos_only and not stub_arg.variable.name.startswith("__") and stub_arg.variable.name.strip("_") != "self" - and not is_dunder(function_name, exclude_special=True) # noisy for dunder methods ): yield ( f'stub argument "{stub_arg.variable.name}" should be positional-only ' @@ -2010,6 +2009,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 b071c0ee8ab6..15848ce129af 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1601,6 +1601,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]: