Skip to content

[functools] Use ParamSpec for single dispatch#15635

Draft
srittau wants to merge 14 commits intopython:mainfrom
srittau:singledispatch
Draft

[functools] Use ParamSpec for single dispatch#15635
srittau wants to merge 14 commits intopython:mainfrom
srittau:singledispatch

Conversation

@srittau
Copy link
Copy Markdown
Collaborator

@srittau srittau commented Apr 8, 2026

No description provided.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@srittau
Copy link
Copy Markdown
Collaborator Author

srittau commented Apr 8, 2026

This is some weird interaction where CI was using the main branch for some tests.


I'm really stumped about the mypy and pyright errors:

stubs/aiofiles/aiofiles/threadpool/__init__.pyi:102: error: "_SingleDispatchCallable" expects 2 type arguments, but 1 given  [type-arg]
/home/runner/work/typeshed/typeshed/stubs/aiofiles/aiofiles/threadpool/__init__.pyi
  /home/runner/work/typeshed/typeshed/stubs/aiofiles/aiofiles/threadpool/__init__.pyi:102:31 - error: Too few type arguments provided for "_SingleDispatchCallable"; expected 2 but received 1 (reportInvalidTypeArguments)

This looks to be the same error, but the aiofiles stubs have no relation to functools and the line in question doesn't either:

stdin: AsyncTextIndirectIOWrapper
stdout: AsyncTextIndirectIOWrapper  # it errors here and only here
stderr: AsyncTextIndirectIOWrapper
stdin_bytes: AsyncIndirectBufferedIOBase
stdout_bytes: AsyncIndirectBufferedIOBase
stderr_bytes: AsyncIndirectBufferedIOBase

# type: ignore is also ineffective and _SingleDispatchCallable is only ever used in functools (apart from a different one in stubs/singledispatch).

@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

Diff from mypy_primer, showing the effect of this PR on open source code:

dd-trace-py (https://github.com/DataDog/dd-trace-py)
+ ddtrace/internal/symbol_db/symbols.py:171: error: Argument 1 to "singledispatchmethod" has incompatible type "Callable[[type[Scope], Any, ScopeData], Scope | None]"; expected "Callable[[object, Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:171: note: This is likely because "_get_from of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:182: error: Argument 1 has incompatible type "Callable[[type[Scope], Module, ScopeData], Scope | None]"; expected "Callable[[Module, Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:182: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:184: error: "self" parameter missing for a non-static method (or an invalid type for self)  [misc]
+ ddtrace/internal/symbol_db/symbols.py:204: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:235: error: Argument 1 has incompatible type "def _(cls: type[Scope], obj: type, data: ScopeData) -> Scope | None"; expected "def (type, /, _: Any, data: ScopeData) -> Scope | None"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:235: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:271: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:325: error: Argument 1 has incompatible type "Callable[[type[Scope], CodeType, ScopeData], Scope | None]"; expected "Callable[[CodeType, Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:325: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:327: error: "self" parameter missing for a non-static method (or an invalid type for self)  [misc]
+ ddtrace/internal/symbol_db/symbols.py:354: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:354: error: Argument 1 has incompatible type "CodeType"; expected "Scope | None"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:358: error: Argument 1 has incompatible type "Callable[[type[Scope], FunctionType, ScopeData], Scope | None]"; expected "Callable[[FunctionType, Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:358: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:360: error: "self" parameter missing for a non-static method (or an invalid type for self)  [misc]
+ ddtrace/internal/symbol_db/symbols.py:369: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:369: error: Argument 1 has incompatible type "Any | CodeType"; expected "Scope | None"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:406: error: Argument 1 has incompatible type "Callable[[type[Scope], classmethod[Any, Any, Any], ScopeData], Scope | None]"; expected "Callable[[classmethod[Any, Any, Any], Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:406: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:408: error: "self" parameter missing for a non-static method (or an invalid type for self)  [misc]
+ ddtrace/internal/symbol_db/symbols.py:409: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:409: error: Argument 1 has incompatible type "def (type[Any], /, *Any, **Any) -> Any"; expected "Scope | None"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:416: error: Argument 1 has incompatible type "Callable[[type[Scope], staticmethod[Any, Any], ScopeData], Scope | None]"; expected "Callable[[staticmethod[Any, Any], Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:416: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:418: error: "self" parameter missing for a non-static method (or an invalid type for self)  [misc]
+ ddtrace/internal/symbol_db/symbols.py:419: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:419: error: Argument 1 has incompatible type "def (*Any, **Any) -> Any"; expected "Scope | None"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:426: error: Argument 1 has incompatible type "Callable[[type[Scope], property, ScopeData], Scope | None]"; expected "Callable[[property, Any, ScopeData], Scope | None]"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:426: note: This is likely because "_ of Scope" has named arguments: "cls". Consider marking them positional-only
+ ddtrace/internal/symbol_db/symbols.py:428: error: "self" parameter missing for a non-static method (or an invalid type for self)  [misc]
+ ddtrace/internal/symbol_db/symbols.py:451: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:451: error: Argument 1 has incompatible type "Callable[[Any], Any] | Callable[[Any, Any], None] | Callable[[Any], None]"; expected "Scope | None"  [arg-type]
+ ddtrace/internal/symbol_db/symbols.py:469: error: Too few arguments  [call-arg]
+ ddtrace/internal/symbol_db/symbols.py:469: error: Argument 1 has incompatible type Module; expected "Scope | None"  [arg-type]
+ ddtrace/debugging/_signal/model.py:262: error: Argument 1 to "singledispatch" has incompatible type "Callable[[Probe, FrameType, Thread, Any | None, Meter], Signal]"; expected "Callable[[object, FrameType, Thread, Any | None, Meter], Signal]"  [arg-type]
+ ddtrace/debugging/_signal/model.py:262: note: This is likely because "probe_to_signal" has named arguments: "probe". Consider marking them positional-only

mypy (https://github.com/python/mypy)
+ mypy/stubtest.py:286: error: Argument 1 to "singledispatch" has incompatible type "Callable[[Node | Missing, Any | Missing, list[str]], Iterator[Error]]"; expected "Callable[[object, Any | Missing, list[str]], Iterator[Error]]"  [arg-type]
+ mypy/stubtest.py:286: note: This is likely because "verify" has named arguments: "stub". Consider marking them positional-only
+ mypy/stubtest.py:1221: error: Only concrete class can be given where "type[FuncItem]" is expected  [type-abstract]
+ mypy/stubtest.py:1221: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-type-abstract for more info

mkosi (https://github.com/systemd/mkosi)
+ mkosi/resources/__init__.py:58:2: error: Argument 1 to "singledispatch" has incompatible type "Callable[[Traversable], AbstractContextManager[Path, bool | None]]"; expected "Callable[[object], AbstractContextManager[Path, bool | None]]"  [arg-type]
+ mkosi/resources/__init__.py:58:2: note: This is likely because "as_file" has named arguments: "path". Consider marking them positional-only

sympy (https://github.com/sympy/sympy)
+ sympy/tensor/array/expressions/arrayexpr_derivatives.py:247: error: Only concrete class can be given where "type[MatrixBase]" is expected  [type-abstract]
+ sympy/stats/crv_types.py:153: error: Only concrete class can be given where "type[MatrixBase]" is expected  [type-abstract]

ibis (https://github.com/ibis-project/ibis)
+ ibis/expr/format.py:213: error: Only concrete class can be given where "type[Relation]" is expected  [type-abstract]
+ ibis/expr/format.py:223: error: Only concrete class can be given where "type[PhysicalTable]" is expected  [type-abstract]
+ ibis/expr/format.py:389: error: Only concrete class can be given where "type[Value[Any, Any]]" is expected  [type-abstract]
+ ibis/expr/format.py:400: error: Only concrete class can be given where "type[Binary]" is expected  [type-abstract]
+ ibis/expr/format.py:420: error: Only concrete class can be given where "type[GeoSpatialBinOp]" is expected  [type-abstract]
+ ibis/expr/decompile.py:91: error: Only concrete class can be given where "type[Value[Any, Any]]" is expected  [type-abstract]
+ ibis/expr/decompile.py:258: error: Only concrete class can be given where "type[Reduction]" is expected  [type-abstract]
+ ibis/expr/decompile.py:270: error: Only concrete class can be given where "type[Constant]" is expected  [type-abstract]
+ ibis/expr/types/_rich.py:101: error: Only concrete class can be given where "type[Integer]" is expected  [type-abstract]
+ ibis/expr/types/_rich.py:106: error: Only concrete class can be given where "type[Floating]" is expected  [type-abstract]
+ ibis/backends/polars/compiler.py:1179: error: Only concrete class can be given where "type[Unary]" is expected  [type-abstract]
+ ibis/backends/polars/compiler.py:1269: error: Only concrete class can be given where "type[Binary]" is expected  [type-abstract]
+ ibis/backends/polars/compiler.py:1406: error: Only concrete class can be given where "type[Reference]" is expected  [type-abstract]
+ ibis/backends/polars/compiler.py:1439: error: Only concrete class can be given where "type[ScalarUDF]" is expected  [type-abstract]
+ ibis/backends/polars/compiler.py:1461: error: Only concrete class can be given where "type[AggUDF]" is expected  [type-abstract]

tornado (https://github.com/tornadoweb/tornado)
+ tornado/gen.py:887: error: Incompatible types in assignment (expression has type "_SingleDispatchCallable[[], _asyncio.Future[Any], Callable[[Awaitable[Any] | list[Awaitable[Any]] | dict[Any, Awaitable[Any]] | concurrent.futures._base.Future[Any] | None], _asyncio.Future[Any]]]", variable has type "Callable[[Awaitable[Any] | list[Awaitable[Any]] | dict[Any, Awaitable[Any]] | concurrent.futures._base.Future[Any] | None], _asyncio.Future[Any]]")  [assignment]
+ tornado/gen.py:887: note: "_SingleDispatchCallable[[], _asyncio.Future[Any], Callable[[Awaitable[Any] | list[Awaitable[Any]] | dict[Any, Awaitable[Any]] | concurrent.futures._base.Future[Any] | None], _asyncio.Future[Any]]].__call__" has type "Callable[[object], Future[Any]]"
+ tornado/gen.py:887: error: Argument 1 to "singledispatch" has incompatible type "Callable[[Awaitable[Any] | list[Awaitable[Any]] | dict[Any, Awaitable[Any]] | concurrent.futures._base.Future[Any] | None], _asyncio.Future[Any]]"; expected "Callable[[object], _asyncio.Future[Any]]"  [arg-type]
+ tornado/gen.py:887: note: This is likely because "convert_yielded" has named arguments: "yielded". Consider marking them positional-only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant