-
Notifications
You must be signed in to change notification settings - Fork 239
fix: Narrowing for isinstance and type[T] is unsound #1984
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
base: main
Are you sure you want to change the base?
Conversation
| self.unions(res) | ||
| } | ||
|
|
||
| fn allow_negative_isinstance_classinfo( |
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.
Is it possible to specifically disallow type[T] rather than trying to enumerate everything that is allowed? This implementation makes me a bit nervous, since it seems easy to miss cases that we should allow.
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.
Let me check that
|
Diff from mypy_primer, showing the effect of this PR on open source code: stone (https://github.com/dropbox/stone)
- ERROR stone/backends/python_rsrc/stone_base.py:105:75-90: Expected class object, got `Never` [invalid-argument]
- ERROR stone/backends/python_rsrc/stone_base.py:155:69-83: Expected class object, got `Never` [invalid-argument]
pandera (https://github.com/pandera-dev/pandera)
+ ERROR pandera/backends/ibis/base.py:168:17-36: Object of class `NoneType` has no attribute `rename` [missing-attribute]
+ ERROR pandera/backends/polars/base.py:57:34-50: Object of class `object` has no attribute `sample` [missing-attribute]
+ ERROR pandera/backends/polars/base.py:178:24-49: Object of class `NoneType` has no attribute `columns` [missing-attribute]
+ ERROR pandera/backends/polars/base.py:181:40-70: Object of class `NoneType` has no attribute `with_columns` [missing-attribute]
+ ERROR pandera/backends/polars/base.py:183:29-51: Object of class `NoneType` has no attribute `rows` [missing-attribute]
+ ERROR pandera/backends/polars/base.py:187:40-64: Object of class `NoneType` has no attribute `rename` [missing-attribute]
+ ERROR pandera/backends/polars/base.py:188:26-54: Cannot index into `object` [bad-index]
porcupine (https://github.com/Akuli/porcupine)
- ERROR porcupine/plugins/highlight/pygments_highlighter.py:51:12-52: Object of class `type` has no attribute `get_tokens_unprocessed` [missing-attribute]
pytest-robotframework (https://github.com/detachhead/pytest-robotframework)
- ERROR pytest_robotframework/__init__.py:136:35-37: `TracebackType | None` is not assignable to attribute `__traceback__` with type `Never` [bad-assignment]
strawberry (https://github.com/strawberry-graphql/strawberry)
+ ERROR strawberry/http/__init__.py:28:26-39: Object of class `NoneType` has no attribute `errors` [missing-attribute]
+ ERROR strawberry/http/__init__.py:28:41-58: Object of class `NoneType` has no attribute `extensions` [missing-attribute]
+ ERROR strawberry/http/__init__.py:30:17-28: Object of class `NoneType` has no attribute `data` [missing-attribute]
+ ERROR strawberry/schema/schema.py:540:12-25: Object of class `NoneType` has no attribute `errors` [missing-attribute]
+ ERROR strawberry/schema/schema.py:541:44-57: `list[GraphQLError] | object | Unknown` is not assignable to attribute `pre_execution_errors` with type `list[GraphQLError] | None` [bad-assignment]
+ ERROR strawberry/schema/schema.py:543:38-51: Argument `list[GraphQLError] | object | Unknown` is not assignable to parameter `errors` with type `list[GraphQLError]` in function `strawberry.schema.base.BaseSchema._process_errors` [bad-argument-type]
+ ERROR strawberry/schema/schema.py:545:63-76: Argument `list[GraphQLError] | object | Unknown | None` is not assignable to parameter `errors` with type `list[GraphQLError] | None` in function `strawberry.types.execution.ExecutionResult.__init__` [bad-argument-type]
+ ERROR strawberry/schema/schema.py:546:9-26: Object of class `NoneType` has no attribute `extensions` [missing-attribute]
+ ERROR strawberry/schema/schema.py:548:16-22: Returned type `ExecutionResult | NoneType | Unknown` is not assignable to declared return type `ExecutionResult` [bad-return]
pylint (https://github.com/pycqa/pylint)
+ ERROR pylint/checkers/async_checker.py:74:25-41: Object of class `NoneType` has no attribute `getattr` [missing-attribute]
+ ERROR pylint/checkers/async_checker.py:75:25-41: Object of class `NoneType` has no attribute `getattr` [missing-attribute]
+ ERROR pylint/checkers/typecheck.py:1940:25-41: Object of class `NoneType` has no attribute `getattr` [missing-attribute]
+ ERROR pylint/checkers/typecheck.py:1941:25-41: Object of class `NoneType` has no attribute `getattr` [missing-attribute]
+ ERROR pylint/checkers/typecheck.py:1957:69-82: Object of class `NoneType` has no attribute `name` [missing-attribute]
pandas (https://github.com/pandas-dev/pandas)
+ ERROR pandas/core/apply.py:774:35-38: Cannot set item in `MutableMapping[Hashable, ((...) -> Unknown) | list[AggFuncTypeBase] | str]` [unsupported-operation]
+ ERROR pandas/core/arrays/arrow/array.py:598:24-45: Object of class `ExtensionArray` has no attribute `__arrow_array__`
+ Object of class `ndarray` has no attribute `__arrow_array__` [missing-attribute]
+ ERROR pandas/core/arrays/arrow/array.py:665:73-78: Argument `ExtensionArray | ndarray[tuple[Any, ...], dtype[Any]] | Any` is not assignable to parameter `values` with type `Collection[Unknown]` in function `pandas.core.dtypes.cast.construct_1d_object_array_from_listlike` [bad-argument-type]
- ERROR pandas/core/arrays/arrow/array.py:1209:16-60: Returned type `ArrowExtensionArray | Unknown` is not assignable to declared return type `NAType | bool` [bad-return]
+ ERROR pandas/core/arrays/arrow/array.py:1209:16-60: Returned type `ArrowExtensionArray | NAType | NaTType | Timedelta | Timestamp | Unknown` is not assignable to declared return type `NAType | bool` [bad-return]
- ERROR pandas/core/arrays/arrow/array.py:1273:16-60: Returned type `ArrowExtensionArray | Unknown` is not assignable to declared return type `NAType | bool` [bad-return]
+ ERROR pandas/core/arrays/arrow/array.py:1273:16-60: Returned type `ArrowExtensionArray | NAType | NaTType | Timedelta | Timestamp | Unknown` is not assignable to declared return type `NAType | bool` [bad-return]
+ ERROR pandas/core/arrays/string_arrow.py:521:24-37: Object of class `NAType` has no attribute `astype`
+ Object of class `NaTType` has no attribute `astype`
+ Object of class `Timedelta` has no attribute `astype`
+ Object of class `Timestamp` has no attribute `astype` [missing-attribute]
- ERROR pandas/core/construction.py:605:24-30: No matching overload found for function `list.__init__` called with arguments: (ndarray[tuple[Any, ...], dtype[Any]] | object) [no-matching-overload]
+ ERROR pandas/core/construction.py:605:24-30: No matching overload found for function `list.__init__` called with arguments: (ExtensionArray | ndarray[tuple[Any, ...], dtype[Any]] | object) [no-matching-overload]
- ERROR pandas/core/construction.py:658:20-26: No matching overload found for function `list.__init__` called with arguments: (object) [no-matching-overload]
+ ERROR pandas/core/construction.py:658:20-26: No matching overload found for function `list.__init__` called with arguments: (ExtensionArray | object) [no-matching-overload]
- ERROR pandas/core/ops/array_ops.py:129:48-57: Argument `ExtensionArray | ndarray[tuple[int], dtype[object_]] | ndarray[tuple[int], dtype[Any]]` is not assignable to parameter `right` with type `ndarray[tuple[Any, ...], dtype[object_]]` in function `pandas._libs.ops.vec_compare` [bad-argument-type]
+ ERROR pandas/core/ops/array_ops.py:129:48-57: Argument `ExtensionArray | Index | ndarray[tuple[int], dtype[object_]] | ndarray[tuple[int], dtype[Any]] | Unknown` is not assignable to parameter `right` with type `ndarray[tuple[Any, ...], dtype[object_]]` in function `pandas._libs.ops.vec_compare` [bad-argument-type]
- ERROR pandas/plotting/_matplotlib/core.py:443:16-19: Returned type `list[tuple[int | ndarray[tuple[Any, ...], dtype[Any]] | slice[Any, Any, Any]]]` is not assignable to declared return type `bool | list[tuple[int, ...]]` [bad-return]
+ ERROR pandas/plotting/_matplotlib/core.py:443:16-19: Returned type `list[tuple[int | ndarray[tuple[Any, ...], dtype[Any]] | slice[Any, Any, Any] | Unknown]]` is not assignable to declared return type `bool | list[tuple[int, ...]]` [bad-return]
+ ERROR pandas/tests/tseries/offsets/test_ticks.py:261:16-39: Object of class `Tick` has no attribute `_as_pd_timedelta` [missing-attribute]
+ ERROR pandas/tests/tseries/offsets/test_ticks.py:268:16-39: Object of class `Tick` has no attribute `_as_pd_timedelta` [missing-attribute]
static-frame (https://github.com/static-frame/static-frame)
+ ERROR static_frame/core/container_util.py:1332:22-33: Type `int` is not iterable [not-iterable]
+ ERROR static_frame/core/container_util.py:1771:49-60: Type `int` is not iterable [not-iterable]
+ ERROR static_frame/core/frame.py:2124:30-39: Argument `StringIO | str` is not assignable to parameter `fp` with type `SupportsRead[bytes | str]` in function `json.load` [bad-argument-type]
+ ERROR static_frame/core/frame.py:2170:30-39: Argument `StringIO | str` is not assignable to parameter `fp` with type `SupportsRead[bytes | str]` in function `json.load` [bad-argument-type]
+ ERROR static_frame/core/frame.py:2215:30-39: Argument `StringIO | str` is not assignable to parameter `fp` with type `SupportsRead[bytes | str]` in function `json.load` [bad-argument-type]
+ ERROR static_frame/core/frame.py:2256:30-39: Argument `StringIO | str` is not assignable to parameter `fp` with type `SupportsRead[bytes | str]` in function `json.load` [bad-argument-type]
+ ERROR static_frame/core/frame.py:2297:30-39: Argument `StringIO | str` is not assignable to parameter `fp` with type `SupportsRead[bytes | str]` in function `json.load` [bad-argument-type]
+ ERROR static_frame/core/frame.py:2329:30-39: Argument `StringIO | str` is not assignable to parameter `fp` with type `SupportsRead[bytes | str]` in function `json.load` [bad-argument-type]
+ ERROR static_frame/core/frame.py:4682:53-64: Type `int` is not iterable [not-iterable]
+ ERROR static_frame/core/frame.py:4684:67-87: `not in` is not supported between `int` and `int` [not-iterable]
+ ERROR static_frame/core/frame.py:6202:61-72: Type `int` is not iterable [not-iterable]
+ ERROR static_frame/core/index.py:941:31-44: No matching overload found for function `list.__init__` called with arguments: (int | list[int]) [no-matching-overload]
+ ERROR static_frame/core/index_hierarchy.py:1338:32-58: No matching overload found for function `map.__new__` called with arguments: (type[map[_S]], BoundMethod[Self@IndexHierarchy, (self: Self@IndexHierarchy, depth_level: TDepthLevelSpecifier = 0, /) -> ndarray[Any, Any]], int | list[int]) [no-matching-overload]
+ ERROR static_frame/core/index_hierarchy.py:1676:42-80: No matching overload found for function `zip.__new__` called with arguments: (type[zip[_T_co]], int | list[int], range) [no-matching-overload]
+ ERROR static_frame/core/index_hierarchy.py:1676:66-77: Argument `int | list[int]` is not assignable to parameter `obj` with type `Sized` in function `len` [bad-argument-type]
+ ERROR static_frame/core/index_hierarchy.py:1707:25-56: No matching overload found for function `map.__new__` called with arguments: (type[map[Index[Any]]], BoundMethod[list[Index[Any]], Overload[(self: list[Index[Any]], i: SupportsIndex, /) -> Index[Any], (self: list[Index[Any]], s: slice[Any, Any, Any], /) -> list[Index[Any]]]], int | list[int]) [no-matching-overload]
+ ERROR static_frame/core/index_hierarchy.py:1743:20-22: Argument `int | list[int]` is not assignable to parameter `obj` with type `Sized` in function `len` [bad-argument-type]
+ ERROR static_frame/core/index_hierarchy.py:1744:23-29: Object of class `int` has no attribute `pop` [missing-attribute]
+ ERROR static_frame/core/index_hierarchy.py:1858:24-28: No matching overload found for function `sorted` called with arguments: (int | list[int]) [no-matching-overload]
+ ERROR static_frame/core/index_hierarchy.py:2547:20-22: Argument `int | list[int]` is not assignable to parameter `obj` with type `Sized` in function `len` [bad-argument-type]
+ ERROR static_frame/core/index_hierarchy.py:2548:23-29: Object of class `int` has no attribute `pop` [missing-attribute]
+ ERROR static_frame/core/series.py:1154:25-33: `int | integer[Any] | list[int] | ndarray[Any, Any] | slice[Any, Any, Any] | None` is not assignable to variable `iloc_many` with type `list[int] | ndarray[Any, Any] | slice[Any, Any, Any] | None` [bad-assignment]
+ ERROR static_frame/core/type_blocks.py:1534:21-24: Argument `int | integer[Any] | list[int] | ndarray[Any, Any] | slice[Any, Any, Any]` is not assignable to parameter `__key` with type `list[int] | ndarray[tuple[Any, ...], dtype[Any]] | slice[Any, Any, Any]` in function `arraykit.BlockIndex.iter_contiguous` [bad-argument-type]
+ ERROR static_frame/core/yarn.py:498:21-28: Argument `int | ndarray[Any, dtype[signedinteger[_64Bit]]]` is not assignable to parameter `indexer` with type `ndarray[Any, dtype[signedinteger[_64Bit]]] | None` in function `Yarn.__init__` [bad-argument-type]
optuna (https://github.com/optuna/optuna)
+ ERROR tests/visualization_tests/test_slice.py:85:16-25: Cannot index into `Axes` [bad-index]
kopf (https://github.com/nolar/kopf)
+ ERROR kopf/_cogs/structs/dicts.py:244:19-23: Type of yielded value `(Iterable[Iterable[_T] | _T] & KubernetesModel) | (Iterable[_T] & KubernetesModel) | (KubernetesModel & _T)` is not assignable to declared return type `_T` [invalid-yield]
|
Summary
Fix unsound isinstance negative narrowing by skipping else-branch refinement when the classinfo is a runtime type[T] value rather than a literal class/ tuple/union of classes.
Fixes #713
Test Plan