mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Fix Type Comparison Edge Cases

Open George-Ogden opened this issue 1 month ago • 14 comments

Fixes #20275 and #20041 This code snippet fails to type-check before this PR:

class X:
    y: int

    def __eq__(self, other: object) -> bool:
        return type(other) is type(self) and other.y == self.y


idx: int | float = 0
if type(idx) == int == int:
    x = [100][idx]

But type-checks afterwards. This is done by finding a least type as the upper bound when the equality succeeds.

George-Ogden avatar Nov 20 '25 20:11 George-Ogden

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

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/arrays/base.py:1502: error: Redundant cast to "ExtensionArray"  [redundant-cast]

ibis (https://github.com/ibis-project/ibis)
- ibis/common/patterns.py:658: error: "Pattern" has no attribute "type"  [attr-defined]
- ibis/common/patterns.py:934: error: "Pattern" has no attribute "patterns"  [attr-defined]

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/history/events/structures/base.py:161: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:162: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:163: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:164: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:165: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:166: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:167: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:168: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:169: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:170: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:171: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:172: error: Unused "type: ignore" comment  [unused-ignore]

pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/misc.py:551: error: Redundant cast to "HiddenText"  [redundant-cast]

github-actions[bot] avatar Nov 20 '25 20:11 github-actions[bot]

I don't quite understand what I should do with get_proper_type, but the mypy_primer diff seems to reduce the number of type errors.

George-Ogden avatar Nov 20 '25 21:11 George-Ogden

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

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/arrays/base.py:1502: error: Redundant cast to "ExtensionArray"  [redundant-cast]

ibis (https://github.com/ibis-project/ibis)
- ibis/common/patterns.py:658: error: "Pattern" has no attribute "type"  [attr-defined]
- ibis/common/patterns.py:934: error: "Pattern" has no attribute "patterns"  [attr-defined]

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/history/events/structures/base.py:161: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:162: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:163: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:164: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:165: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:166: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:167: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:168: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:169: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:170: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:171: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:172: error: Unused "type: ignore" comment  [unused-ignore]

pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/misc.py:551: error: Redundant cast to "HiddenText"  [redundant-cast]

github-actions[bot] avatar Nov 21 '25 09:11 github-actions[bot]

Thanks for the PR!

Also, just a short remark/question without any deep knowledge of the matter: If I understand #20275 correctly, calling reveal_type already helps. Doesn't this mean the required narrowing logic is already available and only needs to be activated somehow for (normal) cases where reveal_type is not used?

tyralla avatar Nov 21 '25 19:11 tyralla

@tyralla: before this PR, this worked best with direct comparison to types: type(x) == int => x: int (1) this also includes y: type[int]; type(x) == y => x: int (2) The previous logic looked at when type() was used to separate what was narrowed and what was constant However, it fails when comparing type(x) == type(y) (3) When reveal_type is used, it's equivalent to the second case. after PR analyses the third case is analysed so that it looks more like x: X; y: Y; type(x) == Y and type(y) == X (4) But this 4th case is all-or-nothing, so either both variables have the type of the meet or they retain the originals.

Let me know if this makes it clear or if any of that doesn't make sense.

George-Ogden avatar Nov 21 '25 21:11 George-Ogden

Huh, then couldn't we get rid of any special casing for looking for specifically type(x)? i.e. couldn't we just use case 1/2 always?

I imagine it's a bit strange (e.g. type(x) == int == str should like, be marked unreachable not be int & str) but maybe we just need to check for anything where the TypeRange.is_upper_bound is False and try using that, otherwise use the meet? I haven't really thought much about this so it's possible there's some flaw here. But this would mean e.g. for function f(x: T) -> T we would support f(type(x)) == int -- kind of silly, but maybe useful?

(I guess the flaw is actually that we need to know the relevant name to know what to narrow. Maybe that's why we don't do that)

A5rocks avatar Nov 22 '25 06:11 A5rocks

I never really thought about type narrowing with is (except for handling None, of course).

If I look at this example:

class X: x = 1
class Y: y = 1
class Z(X, Y): ...

z = Z()
x: X = z
y: Y = z
if x is y:
    x.y + y.x  # error: "X" has no attribute "y"
               # error: "Y" has no attribute "x

I ask myself if Mypy should not handle it like:

if isinstance(x, type(y)) and isinstance(y, type(x)):
    x.y + y.x

Which could eventually easily be implemented with the help of TypeChecker.intersect_instances or something similar?

tyralla avatar Nov 22 '25 08:11 tyralla

I never really thought about type narrowing with is (except for handling None, of course).

If I look at this example:

class X: x = 1
class Y: y = 1
class Z(X, Y): ...

z = Z()
x: X = z
y: Y = z
if x is y:
    x.y + y.x  # error: "X" has no attribute "y"
               # error: "Y" has no attribute "x

I ask myself if Mypy should not handle it like:

if isinstance(x, type(y)) and isinstance(y, type(x)):
    x.y + y.x

Which could eventually easily be implemented with the help of TypeChecker.intersect_instances or something similar?

I had a look at this and I've modified the implementation to allow this kind of checking. It just needs a bit of cleaning up.

George-Ogden avatar Nov 22 '25 21:11 George-Ogden

This cannot be directly handled here because == and is are handled together. However, we can compare types instead

class X: x = 1
class Y: y = 1
class Z(X, Y): ...

z = Z()
x: X = z
y: Y = z
if type(x) is type(y): # instead of x is y
    x.y + y.x  

George-Ogden avatar Nov 23 '25 10:11 George-Ogden

~The only part I'm not sure about is how to handle the error messages.~

George-Ogden avatar Nov 23 '25 10:11 George-Ogden

~I'm also not sure about the failures - should they be flagged?~

George-Ogden avatar Nov 23 '25 10:11 George-Ogden

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

beartype (https://github.com/beartype/beartype)
+ beartype/door/_cls/doormeta.py:164: error: Unused "type: ignore" comment  [unused-ignore]

hydpy (https://github.com/hydpy-dev/hydpy)
+ hydpy/core/variabletools.py:353: error: Statement is unreachable  [unreachable]
+ hydpy/core/variabletools.py:357: error: Statement is unreachable  [unreachable]
+ hydpy/core/variabletools.py:361: error: Statement is unreachable  [unreachable]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/tasks.py:535: error: Incompatible types in assignment (expression has type "CachePolicy", variable has type "_None")  [assignment]
- src/prefect/tasks.py:788: error: Argument "retry_jitter_factor" to "Task" has incompatible type "float | type[NotSet] | None"; expected "float | None"  [arg-type]
+ src/prefect/tasks.py:788: error: Argument "retry_jitter_factor" to "Task" has incompatible type "float | type[NotSet]"; expected "float | None"  [arg-type]
- src/prefect/tasks.py:793: error: Argument "persist_result" to "Task" has incompatible type "bool | type[NotSet] | None"; expected "bool | None"  [arg-type]
+ src/prefect/tasks.py:793: error: Argument "persist_result" to "Task" has incompatible type "bool | type[NotSet]"; expected "bool | None"  [arg-type]
- src/prefect/tasks.py:796: error: Argument "result_storage" to "Task" has incompatible type "WritableFileSystem | str | type[NotSet] | None"; expected "WritableFileSystem | str | None"  [arg-type]
+ src/prefect/tasks.py:796: error: Argument "result_storage" to "Task" has incompatible type "WritableFileSystem | str | type[NotSet]"; expected "WritableFileSystem | str | None"  [arg-type]
- src/prefect/tasks.py:799: error: Argument "result_storage_key" to "Task" has incompatible type "str | type[NotSet] | None"; expected "str | None"  [arg-type]
+ src/prefect/tasks.py:799: error: Argument "result_storage_key" to "Task" has incompatible type "str | type[NotSet]"; expected "str | None"  [arg-type]
- src/prefect/tasks.py:804: error: Argument "result_serializer" to "Task" has incompatible type "Serializer[Any] | str | type[NotSet] | None"; expected "Serializer[Any] | str | None"  [arg-type]
+ src/prefect/tasks.py:804: error: Argument "result_serializer" to "Task" has incompatible type "Serializer[Any] | str | type[NotSet]"; expected "Serializer[Any] | str | None"  [arg-type]
- src/prefect/tasks.py:816: error: Argument "log_prints" to "Task" has incompatible type "bool | type[NotSet] | None"; expected "bool | None"  [arg-type]
+ src/prefect/tasks.py:816: error: Argument "log_prints" to "Task" has incompatible type "bool | type[NotSet]"; expected "bool | None"  [arg-type]
- src/prefect/tasks.py:818: error: Argument "refresh_cache" to "Task" has incompatible type "bool | type[NotSet] | None"; expected "bool | None"  [arg-type]
+ src/prefect/tasks.py:818: error: Argument "refresh_cache" to "Task" has incompatible type "bool | type[NotSet]"; expected "bool | None"  [arg-type]
+ src/prefect/flow_engine.py:371: error: Unused "type: ignore" comment  [unused-ignore]
+ src/prefect/flow_engine.py:958: error: Unused "type: ignore" comment  [unused-ignore]
- src/prefect/task_engine.py:489: error: Missing return statement  [return]
- src/prefect/task_engine.py:499: error: Exception must be derived from BaseException  [misc]
- src/prefect/task_engine.py:502: error: Incompatible return value type (got "BaseException | type[NotSet]", expected "R | State[Any] | None")  [return-value]
- src/prefect/task_engine.py:1097: error: Missing return statement  [return]
- src/prefect/task_engine.py:1107: error: Exception must be derived from BaseException  [misc]
- src/prefect/task_engine.py:1110: error: Incompatible return value type (got "BaseException | type[NotSet]", expected "R | State[Any] | None")  [return-value]

typeshed-stats (https://github.com/AlexWaygood/typeshed-stats)
+ src/typeshed_stats/serialize.py:164: error: Statement is unreachable  [unreachable]

strawberry (https://github.com/strawberry-graphql/strawberry)
+ strawberry/types/arguments.py:233: error: Unused "type: ignore" comment  [unused-ignore]

core (https://github.com/home-assistant/core)
+ homeassistant/helpers/template/__init__.py:259: error: Statement is unreachable  [unreachable]
+ homeassistant/helpers/config_validation.py:705: error: Returning Any from function declared to return "str"  [no-any-return]
+ homeassistant/components/logbook/models.py:53: error: Statement is unreachable  [unreachable]
+ homeassistant/components/logbook/models.py:60: error: Cannot determine type of "data"  [has-type]
+ homeassistant/components/logbook/models.py:62: error: Cannot determine type of "data"  [has-type]
+ homeassistant/components/logbook/models.py:64: error: Cannot determine type of "data"  [has-type]
+ homeassistant/components/dlna_dmr/config_flow.py:376: error: Statement is unreachable  [unreachable]
+ homeassistant/components/logbook/processor.py:269: error: Cannot determine type of "data"  [has-type]
+ homeassistant/components/logbook/processor.py:333: error: Right operand of "and" is never evaluated  [unreachable]
+ homeassistant/components/logbook/processor.py:337: error: Statement is unreachable  [unreachable]
+ homeassistant/components/logbook/processor.py:356: error: Cannot determine type of "data"  [has-type]
+ homeassistant/components/logbook/processor.py:430: error: Statement is unreachable  [unreachable]
+ homeassistant/components/script/logbook.py:31: error: Cannot determine type of "data"  [has-type]
+ homeassistant/components/automation/logbook.py:33: error: Cannot determine type of "data"  [has-type]

pytest (https://github.com/pytest-dev/pytest)
+ src/_pytest/config/__init__.py:396: error: Statement is unreachable  [unreachable]

steam.py (https://github.com/Gobot1234/steam.py)
+ steam/ext/commands/converters.py:532: error: Unused "type: ignore" comment  [unused-ignore]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/arrays/base.py:1502: error: Redundant cast to "ExtensionArray"  [redundant-cast]
+ pandas/core/arrays/datetimelike.py:791: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/io/parsers/base_parser.py:533: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/core/frame.py:2359: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/core/internals/managers.py:664: error: Need type annotation for "new_blocks" (hint: "new_blocks: list[<type>] = ...")  [var-annotated]
+ pandas/core/indexes/base.py:7096: error: Unused "type: ignore" comment  [unused-ignore]

ibis (https://github.com/ibis-project/ibis)
- ibis/common/patterns.py:658: error: "Pattern" has no attribute "type"  [attr-defined]
- ibis/common/patterns.py:934: error: "Pattern" has no attribute "patterns"  [attr-defined]

discord.py (https://github.com/Rapptz/discord.py)
+ discord/state.py:970: error: Unused "type: ignore" comment  [unused-ignore]

trio (https://github.com/python-trio/trio)
+ src/trio/_core/_local.py:57: error: Unused "type: ignore" comment  [unused-ignore]

jax (https://github.com/google/jax)
+ jax/_src/random.py:175: error: Incompatible return value type (got "PRNGImpl", expected "PRNGImpl")  [return-value]
+ jax/_src/third_party/scipy/special.py:264: error: Cannot determine type of "fresnl_sd"  [has-type]
+ jax/_src/third_party/scipy/special.py:265: error: Cannot determine type of "fresnl_cd"  [has-type]
+ jax/_src/third_party/scipy/special.py:287: error: Cannot determine type of "fresnl_fd"  [has-type]
+ jax/_src/third_party/scipy/special.py:288: error: Cannot determine type of "fresnl_gd"  [has-type]

koda-validate (https://github.com/keithasaurus/koda-validate)
+ koda_validate/_internal.py:50: error: Incompatible return value type (got "tuple[bool, object]", expected "tuple[Literal[True], A] | tuple[Literal[False], Invalid]")  [return-value]

pwndbg (https://github.com/pwndbg/pwndbg)
+ pwndbg/commands/__init__.py: note: In member "register_command" of class "CommandObj":
+ pwndbg/commands/__init__.py:208: error: Cannot determine type of "help_str"  [has-type]
+ pwndbg/commands/__init__.py:211: error: Cannot determine type of "help_str"  [has-type]
+ pwndbg/commands/__init__.py: note: In member "__call__" of class "CommandObj":
+ pwndbg/commands/__init__.py:372: error: Cannot determine type of "description"  [has-type]
+ pwndbg/commands/misc.py: note: In function "list_and_filter_commands":
+ pwndbg/commands/misc.py:144: error: Cannot determine type of "description"  [has-type]

yarl (https://github.com/aio-libs/yarl)
+ yarl/_query.py:22:9: error: Statement is unreachable  [unreachable]
+ yarl/_query.py:22:9: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-unreachable for more info
+ yarl/_query.py:31:8: error: Left operand of "and" is always true  [redundant-expr]
+ yarl/_query.py:31:8: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-redundant-expr for more info
+ yarl/_url.py:371:13: error: Statement is unreachable  [unreachable]

materialize (https://github.com/MaterializeInc/materialize)
+ misc/python/materialize/zippy/framework.py:86: error: List comprehension has incompatible type List[Capability]; expected List[T]  [misc]

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/history/events/structures/base.py:161: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:162: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:163: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:164: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:165: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:166: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:167: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:168: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:169: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:170: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:171: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:172: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/assets/utils.py:598: error: Statement is unreachable  [unreachable]
+ rotkehlchen/assets/utils.py:599: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/assets/utils.py:601: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/api/v1/fields.py:615: error: Statement is unreachable  [unreachable]
+ rotkehlchen/api/v1/fields.py:620: error: Statement is unreachable  [unreachable]
+ rotkehlchen/api/v1/fields.py:622: error: Statement is unreachable  [unreachable]
+ rotkehlchen/api/v1/fields.py:624: error: Statement is unreachable  [unreachable]
+ rotkehlchen/api/v1/fields.py:626: error: Statement is unreachable  [unreachable]

pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/misc.py:551: error: Redundant cast to "HiddenText"  [redundant-cast]

static-frame (https://github.com/static-frame/static-frame)
+ static_frame/core/util.py:445: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:446: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:447: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:448: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:449: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:452: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:453: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:457: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:459: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:2304: error: Statement is unreachable  [unreachable]
+ static_frame/core/util.py:2307: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:2309: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:2310: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:2311: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/util.py:2312: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:151: error: Statement is unreachable  [unreachable]
+ static_frame/core/loc_map.py:157: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:167: error: Statement is unreachable  [unreachable]
+ static_frame/core/loc_map.py:169: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:171: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:174: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:176: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:177: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:181: error: Statement is unreachable  [unreachable]
+ static_frame/core/loc_map.py:199: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:202: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:204: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/loc_map.py:207: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/node_fill_value.py:125: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/node_fill_value.py:126: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/node_fill_value.py:129: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/node_fill_value.py:131: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/display.py:516: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/container_util.py:1075: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/container_util.py:1382: error: Statement is unreachable  [unreachable]
+ static_frame/core/container_util.py:1383: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/container_util.py:1528: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/container_util.py:1541: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:492: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1523: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/type_blocks.py:1631: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1750: error: Statement is unreachable  [unreachable]
+ static_frame/core/type_blocks.py:1751: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1752: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1756: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1829: error: Statement is unreachable  [unreachable]
+ static_frame/core/type_blocks.py:1833: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1834: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1918: error: Statement is unreachable  [unreachable]
+ static_frame/core/type_blocks.py:1922: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:1923: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:2718: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:2720: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/type_blocks.py:2742: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/type_blocks.py:2805: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/type_blocks.py:2806: error: Statement is unreachable  [unreachable]
+ static_frame/core/type_blocks.py:2913: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/index.py:459: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index.py:692: error: Statement is unreachable  [unreachable]
+ static_frame/core/index.py:1024: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index.py:1025: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index.py:1028: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index.py:1108: error: Statement is unreachable  [unreachable]
+ static_frame/core/index.py:1117: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:557: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:558: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:1201: error: Statement is unreachable  [unreachable]
+ static_frame/core/index_hierarchy.py:1203: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:2097: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/index_hierarchy.py:2156: error: Statement is unreachable  [unreachable]
+ static_frame/core/index_hierarchy.py:2158: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:2165: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:2167: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:2171: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/index_hierarchy.py:2175: error: Statement is unreachable  [unreachable]
+ static_frame/core/index_hierarchy.py:2177: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/series.py:397: error: Statement is unreachable  [unreachable]
+ static_frame/core/series.py:2108: error: Statement is unreachable  [unreachable]
+ static_frame/core/pivot.py:248: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/pivot.py:249: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/pivot.py:250: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/pivot.py:252: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/pivot.py:253: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/pivot.py:260: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:3490: error: Statement is unreachable  [unreachable]
+ static_frame/core/frame.py:3491: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:3494: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:3496: error: Statement is unreachable  [unreachable]
+ static_frame/core/frame.py:3497: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:3499: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:5327: error: Statement is unreachable  [unreachable]
+ static_frame/core/frame.py:5335: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:5346: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/frame.py:10610: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/frame.py:10611: error: Statement is unreachable  [unreachable]
+ static_frame/core/reduce.py:460: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/reduce.py:461: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/reduce.py:484: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/reduce.py:485: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/bus.py:526: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/bus.py:528: error: Unused "type: ignore" comment  [unused-ignore]
+ static_frame/core/bus.py:555: error: Statement is unreachable  [unreachable]
+ static_frame/core/bus.py:931: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/bus.py:932: error: Statement is unreachable  [unreachable]
+ static_frame/core/bus.py:1057: error: Right operand of "and" is never evaluated  [unreachable]
+ static_frame/core/bus.py:1058: error: Statement is unreachable  [unreachable]

xarray (https://github.com/pydata/xarray)
+ xarray/indexes/nd_point_index.py: note: In member "equals" of class "NDPointIndex":
+ xarray/indexes/nd_point_index.py:302: error: Argument 1 to "equals" of "TreeAdapter" has incompatible type "TreeAdapter"; expected "T_TreeAdapter"  [arg-type]
+ xarray/computation/weighted.py: note: In member "_sum_of_weights" of class "Weighted":
+ xarray/computation/weighted.py:255: error: Incompatible return value type (got "DataArray", expected "T_DataArray")  [return-value]

isort (https://github.com/pycqa/isort)
+ isort/settings.py:890: error: Unused "type: ignore" comment  [unused-ignore]

github-actions[bot] avatar Nov 23 '25 10:11 github-actions[bot]

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

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/arrays/base.py:1502: error: Redundant cast to "ExtensionArray"  [redundant-cast]

ibis (https://github.com/ibis-project/ibis)
- ibis/common/patterns.py:658: error: "Pattern" has no attribute "type"  [attr-defined]
- ibis/common/patterns.py:934: error: "Pattern" has no attribute "patterns"  [attr-defined]

archinstall (https://github.com/archlinux/archinstall)
+ archinstall/tui/ui/result.py:26: error: Redundant cast to "list[ValueT]"  [redundant-cast]

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/history/events/structures/base.py:161: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:162: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:163: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:164: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:165: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:166: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:167: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:168: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:169: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:170: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:171: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:172: error: Unused "type: ignore" comment  [unused-ignore]

pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/misc.py:551: error: Redundant cast to "HiddenText"  [redundant-cast]

github-actions[bot] avatar Nov 23 '25 15:11 github-actions[bot]

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

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/arrays/base.py:1502: error: Redundant cast to "ExtensionArray"  [redundant-cast]

ibis (https://github.com/ibis-project/ibis)
- ibis/common/patterns.py:658: error: "Pattern" has no attribute "type"  [attr-defined]
- ibis/common/patterns.py:934: error: "Pattern" has no attribute "patterns"  [attr-defined]

jax (https://github.com/google/jax)
+ jax/_src/interpreters/partial_eval.py:96: error: Unused "type: ignore" comment  [unused-ignore]
+ jax/_src/interpreters/partial_eval.py:99: error: No overload variant of "get" of "dict" matches argument types "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx", "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx"  [call-overload]
+ jax/_src/interpreters/partial_eval.py:99: note: Possible overload variants:
+ jax/_src/interpreters/partial_eval.py:99: note:     def get(self, Name, None = ..., /) -> DBIdx | None
+ jax/_src/interpreters/partial_eval.py:99: note:     def get(self, Name, DBIdx, /) -> DBIdx
+ jax/_src/interpreters/partial_eval.py:99: note:     def [_T] get(self, Name, _T, /) -> DBIdx | _T
+ jax/_src/interpreters/batching.py:231: error: Unused "type: ignore" comment  [unused-ignore]
+ jax/_src/interpreters/batching.py:232: error: Unused "type: ignore" comment  [unused-ignore]
+ jax/_src/interpreters/batching.py:234: error: No overload variant of "get" of "dict" matches argument types "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx", "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx"  [call-overload]
+ jax/_src/interpreters/batching.py:234: note: Possible overload variants:
+ jax/_src/interpreters/batching.py:234: note:     def get(self, Name, None = ..., /) -> DBIdx | None
+ jax/_src/interpreters/batching.py:234: note:     def get(self, Name, DBIdx, /) -> DBIdx
+ jax/_src/interpreters/batching.py:234: note:     def [_T] get(self, Name, _T, /) -> DBIdx | _T
+ jax/_src/interpreters/batching.py:258: error: Unused "type: ignore" comment  [unused-ignore]

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/history/events/structures/base.py:161: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:162: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:163: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:164: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:165: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:166: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:167: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:168: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:169: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:170: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:171: error: Unused "type: ignore" comment  [unused-ignore]
+ rotkehlchen/history/events/structures/base.py:172: error: Unused "type: ignore" comment  [unused-ignore]

pip (https://github.com/pypa/pip)
+ src/pip/_internal/utils/misc.py:551: error: Redundant cast to "HiddenText"  [redundant-cast]

github-actions[bot] avatar Nov 24 '25 18:11 github-actions[bot]