New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for functools.partial #16939
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
Fixes python#1484 This is currently the most popular mypy issue that does not need a PEP. I'm sure there's stuff missing, but this should handle most cases.
ce0d0b6
to
5b56460
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks awesome! Thanks for working on this.
I suggest to test that first / second runs work correctly as well.
This comment has been minimized.
This comment has been minimized.
Looking randomly through primer, looks pretty good:
|
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent! This is a really old feature request and many users will be happy about this. Didn't do a full review yet, but left some ideas about test cases.
p1 = functools.partial(foo) | ||
p1(1, "a", 3) # OK | ||
p1(1, "a", c=3) # OK | ||
p1(1, b="a", c=3) # OK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using reveal_type(p1)
etc. in tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added one of these, it's not very useful because it'll just show you partial[return_type]
... would need a custom mypy type / some very involved generics logic / non-standard features to make it show up in the reveal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah makes sense. The current approach seems fine then.
def foo(fn: typing.Callable[[typing.Unpack[Ts]], None], /, *arg: typing.Unpack[Ts], kwarg: str) -> None: ... | ||
# just test that this doesn't crash | ||
functools.partial(foo, kwarg="asdf") | ||
[builtins fixtures/dict.pyi] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideas for test cases (it's not important to support all of these cases precisely, but they at least shouldn't crash or behave erratically):
- Test with a value of
type[x]
as an argument topartial
. - Test with a class reference as an argument to
partial
(e.g.partial(Foo)
). This is different from the above. - Test calling
partial
with*args
and/or**kwargs
. - Test passing
Callable[..., Foo]
topartial
(with explicit...
). - Test passing a type guard to
partial
. - Test passing an instance that has a
__call__
method topartial
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, thank you for working on this issue 🙏
FWIW pyright implemented partial as a special case here and the accompanying test cases may be useful for ideas. For example, there are tests specific to an overloaded function being passed.
Pyright Tests:
- https://github.com/microsoft/pyright/blob/main/packages/pyright-internal/src/tests/samples/partial1.py
- https://github.com/microsoft/pyright/blob/main/packages/pyright-internal/src/tests/samples/partial2.py
- https://github.com/microsoft/pyright/blob/main/packages/pyright-internal/src/tests/samples/partial3.py
- https://github.com/microsoft/pyright/blob/main/packages/pyright-internal/src/tests/samples/partial4.py
- https://github.com/microsoft/pyright/blob/main/packages/pyright-internal/src/tests/samples/partial5.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review! Added the various tests and some small fixes. The TypeGuard one surfaces a pre-existing bug, I can make a separate PR edit: already fixed by TypeIs PR. There's also some work to be done with overloads, but similarly gets into some pre-existing behaviour
This comment has been minimized.
This comment has been minimized.
Looks like callback protocol support hurts overloads more than previously. Probably need to improve |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Diff from mypy_primer, showing the effect of this PR on open source code: anyio (https://github.com/agronholm/anyio)
+ src/anyio/_backends/_asyncio.py:2259: error: Argument 1 to "_forcibly_shutdown_process_pool_on_exit" has incompatible type "set[anyio.abc._subprocesses.Process]"; expected "set[anyio._backends._asyncio.Process]" [arg-type]
pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/misc.py:136: error: "Callable[[FunctionType, Path, BaseException], Any] | Callable[[FunctionType, Path, tuple[type[BaseException], BaseException, TracebackType]], Any]" not callable [misc]
+ src/pip/_internal/cli/progress_bars.py:66: error: Argument 2 to "_rich_progress_bar" has incompatible type "int | None"; expected "int" [arg-type]
CPython (Argument Clinic) (https://github.com/python/cpython)
+ Tools/clinic/clinic.py:2799: error: "CConverterClassT" not callable [misc]
porcupine (https://github.com/Akuli/porcupine)
+ porcupine/plugins/git_status.py:139: error: Argument 1 to "run_git_status" has incompatible type "Path | None"; expected "Path" [arg-type]
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/window/rolling.py:1499: error: Argument 3 to "roll_apply" has incompatible type "bool | bool_"; expected "bool" [arg-type]
+ pandas/core/tools/datetimes.py:997: error: Argument 6 to "_convert_listlike_datetimes" has incompatible type "bool | Literal[_NoDefault.no_default]"; expected "bool" [arg-type]
+ pandas/core/groupby/groupby.py:3843: error: Argument "mask" to "group_fillna_indexer" has incompatible type "ndarray[Any, dtype[bool_]] | Any"; expected "ndarray[Any, dtype[unsignedinteger[_8Bit]]]" [arg-type]
+ pandas/core/groupby/groupby.py:4368: error: Argument 3 to "group_quantile" has incompatible type "str"; expected "Literal['linear', 'lower', 'higher', 'nearest', 'midpoint']" [arg-type]
+ pandas/core/groupby/groupby.py:4400: error: Argument "mask" to "group_quantile" has incompatible type "ndarray[Any, dtype[bool_]]"; expected "ndarray[Any, dtype[unsignedinteger[_8Bit]]]" [arg-type]
+ pandas/tests/frame/test_ufunc.py:69: error: "_UFunc_Nin2_Nout1[Literal['add'], Literal[22], Literal[0]]" not callable [misc]
+ pandas/tests/frame/test_ufunc.py:76: error: "_UFunc_Nin1_Nout1[Literal['negative'], Literal[19], None]" not callable [misc]
+ pandas/tests/indexes/test_base.py:135: error: Unexpected keyword argument "data" for "RangeIndex" [call-arg]
+ pandas/core/indexes/range.py:135: note: "RangeIndex" defined here
websockets (https://github.com/aaugustin/websockets)
+ src/websockets/legacy/server.py:1048: error: "type[WebSocketServerProtocol] | Callable[..., WebSocketServerProtocol]" not callable [misc]
+ src/websockets/legacy/client.py:496: error: "type[WebSocketClientProtocol] | Callable[..., WebSocketClientProtocol]" not callable [misc]
+ src/websockets/legacy/client.py:649: error: Redundant cast to "WebSocketClientProtocol" [redundant-cast]
+ src/websockets/legacy/auth.py:180: error: "type[BasicAuthWebSocketServerProtocol] | Callable[..., BasicAuthWebSocketServerProtocol]" not callable [misc]
prefect (https://github.com/PrefectHQ/prefect)
+ src/prefect/engine.py:1611: error: Argument 3 to "create_task_run_then_submit" has incompatible type "int"; expected "str" [arg-type]
+ src/prefect/cli/worker.py:206: error: Argument 2 to "start_healthcheck_server" has incompatible type "float"; expected "int" [arg-type]
koda-validate (https://github.com/keithasaurus/koda-validate)
+ koda_validate/signature.py:173: error: Argument 1 to "_get_validator" has incompatible type "tuple[Literal['return_key']]"; expected "str" [arg-type]
- koda_validate/signature.py:384: error: Returning Any from function declared to return "_DecoratedFunc" [no-any-return]
- koda_validate/signature.py:388: error: Returning Any from function declared to return "_DecoratedFunc | Callable[[_DecoratedFunc], _DecoratedFunc]" [no-any-return]
isort (https://github.com/pycqa/isort)
+ isort/exceptions.py:13: error: "Type[ISortError]" not callable [misc]
tornado (https://github.com/tornadoweb/tornado)
+ tornado/tcpclient.py:274: error: Argument 1 to "_create_stream" of "TCPClient" has incompatible type "Optional[int]"; expected "int" [arg-type]
+ tornado/curl_httpclient.py:362: error: Argument 2 to "_curl_header_callback" of "CurlAsyncHTTPClient" has incompatible type "Optional[Callable[[str], None]]"; expected "Callable[[str], None]" [arg-type]
vision (https://github.com/pytorch/vision)
+ torchvision/models/video/swin_transformer.py:518: error: Argument 2 to "VideoClassification" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
+ torchvision/models/video/swin_transformer.py:549: error: Argument 2 to "VideoClassification" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
+ torchvision/models/video/swin_transformer.py:580: error: Argument 2 to "VideoClassification" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
+ torchvision/models/video/swin_transformer.py:607: error: Argument 2 to "VideoClassification" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
+ torchvision/models/video/mvit.py:607: error: Argument 2 to "VideoClassification" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
+ torchvision/models/video/mvit.py:640: error: Argument 2 to "VideoClassification" has incompatible type "tuple[int]"; expected "tuple[int, int]" [arg-type]
kopf (https://github.com/nolar/kopf)
+ kopf/_core/actions/invocation.py:127: error: Incompatible types in assignment (expression has type "partial[partial[object | Coroutine[None, None, object]]]", variable has type "partial[object | Coroutine[None, None, object | None] | None]") [assignment]
+ kopf/_core/actions/invocation.py:127: error: Argument 1 to "run" of "Context" has incompatible type "partial[object | Coroutine[None, None, object | None] | None]"; expected "Callable[[VarArg(Any), KwArg(Any)], partial[object | Coroutine[None, None, object]]]" [arg-type]
+ kopf/_core/actions/invocation.py:127: note: "partial[object | Coroutine[None, None, object | None] | None].__call__" has type "Callable[[VarArg(Any), KwArg(Any)], object | Coroutine[None, None, object | None] | None]"
+ kopf/_core/reactor/orchestration.py:42: error: Unexpected keyword argument "resource" for "__call__" of "WatchStreamProcessor" [call-arg]
+ kopf/_core/reactor/queueing.py:42: note: "__call__" of "WatchStreamProcessor" defined here
graphql-core (https://github.com/graphql-python/graphql-core)
+ src/graphql/utilities/extend_schema.py:360: error: Argument 1 to "extend_input_object_type_fields" of "ExtendSchemaImpl" has incompatible type "GraphQLInputObjectTypeKwargs"; expected "dict[str, Any]" [arg-type]
+ src/graphql/utilities/extend_schema.py:427: error: Argument 1 to "extend_object_type_interfaces" of "ExtendSchemaImpl" has incompatible type "GraphQLObjectTypeKwargs"; expected "dict[str, Any]" [arg-type]
+ src/graphql/utilities/extend_schema.py:429: error: Argument 1 to "extend_object_type_fields" of "ExtendSchemaImpl" has incompatible type "GraphQLObjectTypeKwargs"; expected "dict[str, Any]" [arg-type]
+ src/graphql/utilities/extend_schema.py:467: error: Argument 1 to "extend_interface_type_interfaces" of "ExtendSchemaImpl" has incompatible type "GraphQLInterfaceTypeKwargs"; expected "dict[str, Any]" [arg-type]
+ src/graphql/utilities/extend_schema.py:469: error: Argument 1 to "extend_interface_type_fields" of "ExtendSchemaImpl" has incompatible type "GraphQLInterfaceTypeKwargs"; expected "dict[str, Any]" [arg-type]
+ src/graphql/utilities/extend_schema.py:491: error: Argument 1 to "extend_union_type_types" of "ExtendSchemaImpl" has incompatible type "GraphQLUnionTypeKwargs"; expected "dict[str, Any]" [arg-type]
+ tests/validation/test_variables_in_allowed_position.py:174: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:196: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:222: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:240: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:258: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:274: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:290: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:309: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_in_allowed_position.py:328: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_are_input_types.py:39: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_are_input_types.py:43: error: List item 1 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_variables_are_input_types.py:48: error: List item 2 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:176: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:193: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:210: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:227: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:245: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:262: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:280: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:297: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:314: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:332: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:349: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:366: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:384: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:401: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:418: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:436: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:454: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:472: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:490: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:509: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:527: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:545: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:564: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:582: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:600: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:664: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:681: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:810: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:814: error: List item 1 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:831: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:848: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:945: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:966: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:986: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:1006: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:1035: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
+ tests/validation/test_values_of_correct_type.py:1067: error: List item 0 has incompatible type "dict[str, Sequence[Sequence[object]]]"; expected "GraphQLError" [list-item]
... (truncated 428 lines) ...
jax (https://github.com/google/jax)
+ jax/_src/linear_util.py:339: error: Missing positional argument "tree" in call to "tree_map" [call-arg]
+ jax/_src/interpreters/partial_eval.py:2652: error: Argument 2 to "_eval_jaxpr_padded" has incompatible type "Sequence[Any]"; expected "list[Any]" [arg-type]
+ jax/_src/custom_derivatives.py:245: error: Missing positional argument "tree" in call to "tree_map" [call-arg]
+ jax/_src/nn/functions.py:483: error: Argument 1 to "custom_jvp" has incompatible type "Callable[[Array | Any | Any | Any | bool | int | float | complex, int | tuple[int, ...] | None, Array | Any | Any | Any | bool | int | float | complex | None, Array | Any | Any | Any | bool | int | float | complex | None], Array]"; expected "Callable[..., Never]" [arg-type]
+ jax/_src/scipy/special.py:579: error: Argument 1 to "custom_jvp" has incompatible type "Callable[[Array | Any | Any | Any | bool | int | float | complex, int], Array]"; expected "Callable[..., Never]" [arg-type]
+ jax/_src/scipy/special.py:1601: error: Argument 1 to "_expn3" has incompatible type "Array"; expected "int" [arg-type]
+ jax/_src/scipy/special.py:1602: error: Argument 1 to "_expn2" has incompatible type "Array"; expected "int" [arg-type]
+ jax/_src/scipy/special.py:1603: error: Argument 1 to "_expn1" has incompatible type "Array"; expected "int" [arg-type]
+ jax/_src/scipy/signal.py:430: error: Argument 1 to "detrend" has incompatible type "Literal[True] | str"; expected "str" [arg-type]
+ jax/experimental/rnn.py:245: error: Argument 1 to "custom_vjp" has incompatible type "Callable[[Array, Array, Array, Array, Array, int, int, int, float, bool, str | Precision | tuple[str, str] | tuple[Precision, Precision] | None], tuple[Array, Array, Array]]"; expected "Callable[..., Never]" [arg-type]
+ jax/_src/pallas/pallas_call.py:421: error: Argument 1 to "_batch_block_mapping" has incompatible type "tuple[int | None, ...]"; expected "tuple[int, ...]" [arg-type]
+ jax/_src/cudnn/fused_attention_stablehlo.py:747: error: Need type annotation for "output" [var-annotated]
+ jax/experimental/pallas/ops/rms_norm.py:225: error: Argument 1 to "custom_vjp" has incompatible type "list[int]"; expected "tuple[int, ...]" [arg-type]
+ jax/experimental/pallas/ops/layer_norm.py:244: error: Argument 1 to "custom_vjp" has incompatible type "list[int]"; expected "tuple[int, ...]" [arg-type]
+ jax/experimental/pallas/ops/attention.py:149: error: Argument 1 to "custom_vjp" has incompatible type "list[int]"; expected "tuple[int, ...]" [arg-type]
+ jax/experimental/pallas/ops/tpu/flash_attention.py:203: error: Argument 1 to "custom_vjp" has incompatible type "range"; expected "tuple[int, ...]" [arg-type]
+ jax/experimental/pallas/ops/tpu/flash_attention.py:1088: error: Argument 1 to "_flash_attention_dkv_kernel" has incompatible type "int | None"; expected "int" [arg-type]
+ jax/experimental/pallas/ops/tpu/flash_attention.py:1089: error: Argument 2 to "_flash_attention_dkv_kernel" has incompatible type "int | None"; expected "int" [arg-type]
+ jax/experimental/pallas/ops/tpu/flash_attention.py:1432: error: Argument 4 to "_flash_attention_dq_kernel" has incompatible type "int | None"; expected "int" [arg-type]
+ jax/experimental/pallas/ops/tpu/flash_attention.py:1568: error: Need type annotation for "res" [var-annotated]
cwltool (https://github.com/common-workflow-language/cwltool)
+ cwltool/workflow_job.py: note: In member "try_make_job" of class "WorkflowJob":
+ cwltool/workflow_job.py:616:57: error: Argument 3 to "receive_output" of "WorkflowJob" has incompatible type "OutputCallbackType | None"; expected "OutputCallbackType" [arg-type]
+ cwltool/command_line_tool.py: note: In member "job" of class "CommandLineTool":
+ cwltool/command_line_tool.py:960:52: error: Argument 1 to "update_status_output_callback" has incompatible type "OutputCallbackType | None"; expected "OutputCallbackType" [arg-type]
+ cwltool/workflow.py: note: In member "job" of class "WorkflowStep":
+ cwltool/workflow.py:463:56: error: Argument 1 to "receive_output" of "WorkflowStep" has incompatible type "OutputCallbackType | None"; expected "OutputCallbackType" [arg-type]
aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/web_app.py:56:37: error: Unexpected keyword argument "handler" [call-arg]
+ aiohttp/web_app.py:56:37: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-call-arg for more info
ibis (https://github.com/ibis-project/ibis)
+ ibis/expr/operations/tests/test_generic.py:147: error: Too many arguments for "Literal" [call-arg]
+ ibis/expr/operations/tests/test_generic.py:147: error: Unexpected keyword argument "name" for "Literal" [call-arg]
+ ibis/expr/operations/generic.py:147: note: "Literal" defined here
+ ibis/expr/operations/tests/test_generic.py:147: error: "Literal" gets multiple values for keyword argument "dtype" [misc]
+ ibis/backends/sql/datatypes.py:31: error: Argument 1 to "Map" has incompatible type "String"; expected "bool" [arg-type]
+ ibis/backends/sql/datatypes.py:48: error: Argument 1 to "Map" has incompatible type "String"; expected "bool" [arg-type]
+ ibis/backends/sql/datatypes.py:66: error: Argument 1 to "Array" has incompatible type "String"; expected "bool" [arg-type]
bokeh (https://github.com/bokeh/bokeh)
+ src/bokeh/driving.py: note: In function "bounce":
+ src/bokeh/driving.py:97:36: error: Argument 1 to "force" has incompatible type "Iterable[int]"; expected "Iterator[Any]" [arg-type]
+ src/bokeh/driving.py:97:36: note: "Iterable" is missing following "Iterator" protocol member:
+ src/bokeh/driving.py:97:36: note: __next__
+ src/bokeh/driving.py: note: In function "cosine":
+ src/bokeh/driving.py:116:36: error: Argument 1 to "force" has incompatible type "Iterable[float]"; expected "Iterator[Any]" [arg-type]
+ src/bokeh/driving.py:116:36: note: "Iterable" is missing following "Iterator" protocol member:
+ src/bokeh/driving.py:116:36: note: __next__
+ src/bokeh/driving.py: note: In function "count":
+ src/bokeh/driving.py:122:36: error: Argument 1 to "force" has incompatible type "Iterable[int]"; expected "Iterator[Any]" [arg-type]
+ src/bokeh/driving.py:122:36: note: "Iterable" is missing following "Iterator" protocol member:
+ src/bokeh/driving.py:122:36: note: __next__
+ src/bokeh/driving.py: note: In function "linear":
+ src/bokeh/driving.py:154:36: error: Argument 1 to "force" has incompatible type "Iterable[float]"; expected "Iterator[Any]" [arg-type]
+ src/bokeh/driving.py:154:36: note: "Iterable" is missing following "Iterator" protocol member:
+ src/bokeh/driving.py:154:36: note: __next__
+ src/bokeh/driving.py: note: In function "repeat":
+ src/bokeh/driving.py:172:36: error: Argument 1 to "force" has incompatible type "Iterable[int]"; expected "Iterator[Any]" [arg-type]
+ src/bokeh/driving.py:172:36: note: "Iterable" is missing following "Iterator" protocol member:
+ src/bokeh/driving.py:172:36: note: __next__
+ src/bokeh/driving.py: note: In function "sine":
+ src/bokeh/driving.py:191:36: error: Argument 1 to "force" has incompatible type "Iterable[float]"; expected "Iterator[Any]" [arg-type]
+ src/bokeh/driving.py:191:36: note: "Iterable" is missing following "Iterator" protocol member:
+ src/bokeh/driving.py:191:36: note: __next__
hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
+ src/hydra_zen/wrapper/_implementations.py:58: error: Too few arguments for "run" of "Context" [call-arg]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some potential issues, but overall looks good. At least the incremental mode bug seems important to fix, since this will likely cause issues.
) | ||
|
||
ret = ctx.api.named_generic_type("functools.partial", [ret_type]) | ||
ret = ret.copy_with_extra_attr("__mypy_partial", partially_applied) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra_attrs
is currently a bit poorly thought out, so this will cause some problems. First, it isn't serialized, so storing the additional information there breaks in incremental mode. For example, consider a module like this:
...
p = partial(f, 1)
Now if we import p
from another module, the second run which uses serialized data will produce a different type for p
compared to the first run.
I'm not sure what is the best way to fix this. Probably the simplest option would be to serialize extra_attrs
. It seems that everything we put there can be serialized -- it just hasn't been implemented.
Also it would be good to have an incremental mode test case.
It looks like mypy daemon doesn't keep track of extra_attrs
. mypy.server.astdiff
should look into extra_attrs
to detect changes in extra_attrs
, as these may need to be propagated.
if len(bound.arg_types) == len(fn_type.arg_types): | ||
arg_type = bound.arg_types[i] | ||
if isinstance(get_proper_type(arg_type), UninhabitedType): | ||
arg_type = fn_type.arg_types[i] # bit of a hack |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm this could refer to a type variable type, so I wonder if this can leak type variables, in the target function is a generic one, and one of the provided arguments can be used to bind the type variable.
else: | ||
# TODO: I assume that bound and fn_type have the same arguments. It appears this isn't | ||
# true when PEP 646 things are happening. See testFunctoolsPartialTypeVarTuple | ||
arg_type = fn_type.arg_types[i] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to above.
|
||
ret_type = bound.ret_type | ||
if isinstance(get_proper_type(ret_type), UninhabitedType): | ||
ret_type = fn_type.ret_type # same kind of hack as above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to above -- it seems that this might leak type variables. If that is the case, it would probably be better to fall back to the default return type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this doesn't leak type variables, because partially_applied
has the same variables as fn_type
(from copy_modified). partially_applied
just remains generic. See the test cases in testFunctoolsPartialGeneric
. I can add some more comments to the code
But let me know if I'm off the mark!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are right, and this is good already.
p1 = functools.partial(foo) | ||
p1(1, "a", 3) # OK | ||
p1(1, "a", c=3) # OK | ||
p1(1, b="a", c=3) # OK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah makes sense. The current approach seems fine then.
Hey folks, this looks amazing, but when are you planning to release the change to mypy? |
Fixes #1484
Turns out that this is currently the second most popular mypy issue (and first most popular is a type system feature request that would need a PEP). I'm sure there's stuff missing, but this should handle most cases.