Skip to content
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

Keep TypeVar arguments when narrowing generic subclasses with isinstance and issubclass. #17099

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

tyralla
Copy link
Contributor

@tyralla tyralla commented Apr 5, 2024

Fixes #16933

@finite-state-machine When I first read your issue, I thought only a special case was left unconsidered. However, I then realized that Mypy's narrowing of generic classes often tends to insert Any for type variables and so silently reduces type safety. I put some effort into handling all relevant cases I could think of (including variadic generics, which is new to me), but it is likely I missed some. Would you like to have a look at it?

This comment has been minimized.

This comment has been minimized.

@TeamSpen210
Copy link
Contributor

Went through some of these examples:

  • mitmproxy: True positive??. The problem is that a dict[K, V] | Iterable[tuple[K, V]] is being checked against dict, resulting in dict[K, V] | dict[tuple[K, V], Any]. I guess such a dict would be valid, but that's really not the intent of this code obviously. I think this needs type negation to be safely expressed.
  • jinja: Same as mitmproxy.
  • pandas: True positive. Sequence[date] | tuple[ndarray, ndarray, ndarray] with an instance check of tuple succeeds with both not just the tuple. Here they could swap to list I think?
  • bidict: Same as mitmproxy except with Mapping.
  • prefect: False positive, but looks like an existing join vs union issue? The inferred result for enumerate(list[str] | list[tuple[Hashable, str]]) is enumerate[Sequence[Hashable]].
  • antidote: A now-redundant cast() call.
  • mypy: A now-redundant cast() call.
  • aioredis: This is a true positive, the dict values should be constrained to only by ResponseError not any exception. This repo is archived though, should probably remove it?
  • urllib3: Same iterable/mapping overlap.
  • ibis: True positive, the return type is wrong I think.
  • werkzeug: Same iterable/dict issue, then a unpack-string error following on from the wrong inference.

Something does seem to need to be done about the mapping/iterable overlap, it seems a lot of projects have very similar code which will be basically untypable right now in a subtle way. Would a special case make sense, or maybe a rule about refusing to narrow if some of the typevars are underermined in that union element?

@finite-state-machine
Copy link

finite-state-machine commented Apr 5, 2024

@tyralla and @TeamSpen210: thank you so much for your work on this!

While I'm reasonably handy when it comes to using mypy, I have very little knowledge of its internals; I don't think I'm the right person to look over a patch.

(I would like to get comfortable with mypy's internals and start fixing bugs rather than just reporting them, but I'm not really sure where to start.)

@JelleZijlstra
Copy link
Member

(I would like to get comfortable with mypy's internals and start fixing bugs rather than just reporting them, but I'm not really sure where to start.)

I think few of us are really comfortable with mypy's internals. I would start simply by reading a PR like this, trying to understand the new code and reading related code, and that hopefully will eventually expand to a broader knowledge of how mypy works.

@tyralla
Copy link
Contributor Author

tyralla commented Apr 5, 2024

Something does seem to need to be done about the mapping/iterable overlap, it seems a lot of projects have very similar code which will be basically untypable right now in a subtle way. Would a special case make sense, or maybe a rule about refusing to narrow if some of the typevars are underermined in that union element?

Thank you for this very comprehensive analysis, @TeamSpen210. Given the amount of Mypy primer output, I'm happy that we seem to face only one problematic case. (I agree that the false positive for prefect is likely related to the joins issue but not this PR.)

I applied Pyright, Pyre (both on their playgrounds with the respective default settings), and Mypy (including the proposed changes) to this simplified mapping/iterable example:

from typing import Iterable

def f(x: dict[str, str] | Iterable[bytes]) -> None:
    if isinstance(x, dict):
        reveal_type(x)
  • Pyright: Type of "x" is "dict[str, str] | dict[bytes, Unknown]"
  • Pyre: Revealed type [-1]: Revealed type for x is typing.Dict[str, str].
  • Mypy: Revealed type is "Union[builtins.dict[builtins.str, builtins.str], builtins.dict[Any, Any], builtins.dict[builtins.bytes, Any]]"

So, Pyright and (changed) Mypy behave identically, except for the unnecessary dict[Any, Any] returned by Mypy. I will check if this has to do with the proposed changes.

On the other hand, Pyre only narrows to dict[str, str]. At first sight, this is due to Pyre only transferring type variable arguments if such a transfer would be complete. At least the following example leaves this impression:

def f(x: Iterable[bytes]) -> None:
    if isinstance(x, dict):
        reveal_type(x)  # Revealed type [-1]: Revealed type for `x` is `typing.Dict[typing.Any, typing.Any]`. (Pyre)

Personally, I would favour the Pyright-like approach. Adding an option for switching between Pyright's and Pyre's behaviour could also be an option. I also checked the typing specs' narrowing section, but this topic is not covered. Do you think it should, @JelleZijlstra?

This comment has been minimized.

…rrowing revealed by Mypy primer and pysparsk

This comment has been minimized.

…in narrowing revealed by Mypy primer and pysparsk

This comment has been minimized.

@tyralla
Copy link
Contributor Author

tyralla commented Apr 6, 2024

So, Pyright and (changed) Mypy behave identically, except for the unnecessary dict[Any, Any] returned by Mypy. I will check if this has to do with the proposed changes.

After a few modifications, this PR leads to a narrowing completely consistent with Pyright for the discussed example:

from typing import Iterable

def f(x: dict[str, str] | Iterable[bytes]) -> None:
    if isinstance(x, dict):
        reveal_type(x)
  • Pyright: Type of "x" is "dict[str, str] | dict[bytes, Unknown]"
  • Pyre: Revealed type [-1]: Revealed type for x is typing.Dict[str, str].
  • Mypy: Revealed type is "Union[builtins.dict[builtins.str, builtins.str], builtins.dict[builtins.bytes, Any]]"

The primer's response is nearly the same as the one analysed by @TeamSpen210. The differences between both primer outputs are due to different item orders in unions and the removal of unnecessary "any generics" like in the discussed example.

So, this PR seems ready for a more complete review.

@tyralla
Copy link
Contributor Author

tyralla commented Apr 12, 2024

An additional thought. Wouldn't it be preferable to warn more strictly that type narrowing results in code that is not type-safe? Maybe the --disallow-any-generics option is a candidate for enabling warnings like this:

# mypy: disallow-any-generics

from typing import Iterable

def f(x: Iterable[str]) -> None:
    if isinstance(x, dict):   # E: Iterable[str] does not provide parameters for all type variables of generic type "dict"
        x["I must be string"] = "I could be number"

@finite-state-machine
Copy link

Sorry I've been quiet on this; I've had a nasty bug for the past 10 days or so.

Is there anything I can do to help this along?

@tyralla
Copy link
Contributor Author

tyralla commented Apr 12, 2024

Thanks for offering help!

I think this is generally ready for a maintainer's review. Luckily, @hauntsaninja seems to have it already on his list. But if you have time and motivation, checking and eventually extending the new tests so that they cover as many potential flaws of this PR as possible would be nice. That would increase my confidence in not introducing a nasty 10-day bug in Mypy...

@finite-state-machine
Copy link

I suspect I've re-discovered this bug again, with the following code:

from __future__ import annotations
from typing import (
        Sequence,
        Tuple,
        Union,
        )

class Class1: pass
class Class2: pass
class Class3: pass

Class1Spec = Union[Class1, Tuple[Class2, Class3]]

def some_func(steps: Union[Class1Spec, Sequence[Class1Spec]]) -> None:

    if isinstance(steps, tuple):
        reveal_type(steps)
                # got: Tuple[Any, ...]
                # expected: Union[
                #       Tuple[Class2, Class3],
                #       Tuple[
                #           Class1Spec=Union[Class1, Tuple[Class2, Class3],
                #           ...
                #           ],
                #       ]
    else:
        reveal_type(steps)
                # as expected (only Tuple[Class2, Class3] is eliminated)

I've tried to verify this is fixed using @tyralla's branch, but the first reveal_type() at line 17 is giving:

Union[Tuple[Any, ...], Tuple[Union[Class1, Tuple[Class2, Class3]], ...]]

rather than

Union[Tuple[Class2, Class3], Tuple[Union[Class1, Tuple[Class2, Class3]], ...]]

Without the patch, it gives:

Tuple[Any, ...]

@tyralla
Copy link
Contributor Author

tyralla commented Apr 16, 2024

Thank you for finding this limitation (does "re-discovered" mean it's already reported?). This is because tuples are represented by TupleType instead of Instance, and this PR only captures (unions of) Instance for the current type. A simpler repro for the current state of this PR:

[case testKeepTypeVarArgsWhenNarrowingGenericsToTupleType]
from typing import Sequence, Tuple, Union

class C: ...
x: Union[Tuple[C], Sequence[Tuple[C]]]
if isinstance(x, tuple):
    reveal_type(x)  # N: Revealed type is "Union[builtins.tuple[Any, ...], builtins.tuple[Tuple[__main__.C], ...]]"
else:
    reveal_type(x)  # N: Revealed type is "typing.Sequence[Tuple[__main__.C]]"
[builtins fixtures/tuple.pyi]

@finite-state-machine
Copy link

@tyralla I was thinking "rediscovered" as in "this is a special case of #17099". If it's not, and it doesn't make sense to tack the extra work onto this PR, I'll file a separate issue.

@tyralla
Copy link
Contributor Author

tyralla commented Apr 16, 2024

No, I thought about it and now believe it should be included in this PR. I did this in a simple manner without considering that one could narrow a tuple to a tuple subclass (this should not happen often and seems more challenging to implement; I left a code comment).

The test case testKeepTypeVarArgsWhenNarrowingTupleTypeToTuple checks this additional feature.

Copy link
Contributor

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

mitmproxy (https://github.com/mitmproxy/mitmproxy)
+ mitmproxy/http.py:593: error: Generator has incompatible item type "tuple[None, bytes]"; expected "tuple[bytes, bytes]"  [misc]
+ mitmproxy/http.py:594: error: Argument 1 to "always_bytes" has incompatible type "str | bytes | Any | tuple[bytes, bytes]"; expected "None"  [arg-type]

jinja (https://github.com/pallets/jinja)
+ src/jinja2/filters.py:166: error: Incompatible types in assignment (expression has type "dict_items[Any, Any] | dict_items[str, Any] | dict_items[tuple[str, Any], Any]", variable has type "Iterable[tuple[str, Any]]")  [assignment]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/tests/extension/date/array.py:105: error: Item "date" of "date | Any" has no attribute "astype"  [union-attr]
+ pandas/tests/extension/date/array.py:106: error: Item "date" of "date | Any" has no attribute "astype"  [union-attr]
+ pandas/tests/extension/date/array.py:107: error: Item "date" of "date | Any" has no attribute "astype"  [union-attr]

bidict (https://github.com/jab/bidict)
+ bidict/_iter.py: note: In function "iteritems":
+ bidict/_iter.py:25:9: error: Incompatible types in "yield from" (actual type "tuple[Any, Any] | tuple[tuple[KT, VT], Any]", expected type "tuple[KT, VT]")  [misc]

antidote (https://github.com/Finistere/antidote)
+ src/antidote/lib/interface_ext/_interface.py:531: error: Unused "type: ignore" comment  [unused-ignore]

prefect (https://github.com/PrefectHQ/prefect)
+ src/prefect/cli/cloud/__init__.py:198: error: Incompatible types in assignment (expression has type "Hashable", variable has type "Sequence[Hashable]")  [assignment]

mypy (https://github.com/python/mypy)
+ mypy/types.py:3582: error: Redundant cast to "List[Type]"  [redundant-cast]
+ mypy/types.py:3582: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-redundant-cast for more info

aioredis (https://github.com/aio-libs/aioredis)
+ aioredis/connection.py:206: error: Incompatible return value type (got "Any | Exception", expected "ResponseError")  [return-value]

kopf (https://github.com/nolar/kopf)
+ kopf/_core/reactor/subhandling.py:70: error: Argument "id" to "generate_id" has incompatible type "Callable[[NamedArg(int, 'retry'), NamedArg(datetime, 'started'), NamedArg(timedelta, 'runtime'), NamedArg(Mapping[str, str], 'annotations'), NamedArg(Mapping[str, str], 'labels'), NamedArg(Body, 'body'), NamedArg(Meta, 'meta'), NamedArg(Spec, 'spec'), NamedArg(Status, 'status'), NamedArg(Resource, 'resource'), NamedArg(str | None, 'uid'), NamedArg(str | None, 'name'), NamedArg(str | None, 'namespace'), NamedArg(Patch, 'patch'), NamedArg(str, 'reason'), NamedArg(Diff, 'diff'), NamedArg(BodyEssence | Any | None, 'old'), NamedArg(BodyEssence | Any | None, 'new'), NamedArg(Logger | LoggerAdapter[Any], 'logger'), NamedArg(Any, 'memo'), DefaultNamedArg(Any, 'param'), KwArg(Any)], object | Coroutine[None, None, object | None] | None]"; expected "str | None"  [arg-type]

spark (https://github.com/apache/spark)
+ python/pyspark/ml/linalg/__init__.py:603: error: Incompatible types in assignment (expression has type "dict_items[Any, Any] | dict_items[float, Any] | dict_items[int, float] | dict_items[tuple[int, float], Any]", variable has type "bytes | tuple[int, float] | Iterable[float] | Iterable[tuple[int, float]] | dict[int, float]")  [assignment]
+ python/pyspark/sql/connect/expressions.py:941: error: Argument 1 to "join" of "str" has incompatible type "list[UnresolvedNamedLambdaVariable]"; expected "Iterable[str]"  [arg-type]
+ python/pyspark/mllib/linalg/__init__.py:661: error: Incompatible types in assignment (expression has type "dict_items[Any, Any] | dict_items[float, Any] | dict_items[int, float] | dict_items[tuple[int, float], Any]", variable has type "bytes | tuple[int, float] | Iterable[float] | Iterable[tuple[int, float]] | dict[int, float]")  [assignment]
+ python/pyspark/ml/functions.py:291: error: Incompatible types in assignment (expression has type "list[Any]", target has type "ndarray[Any, Any]")  [assignment]

cwltool (https://github.com/common-workflow-language/cwltool)
+ cwltool/process.py: note: In function "relocateOutputs":
+ cwltool/process.py:330:51: error: Argument 1 to "_collectDirEntries" has incompatible type "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None"; expected "CWLObjectType | MutableSequence[CWLObjectType] | None"  [arg-type]
+ tests/test_examples.py: note: In function "test_factory_partial_scatter":
+ tests/test_examples.py:327:12: error: Value of type "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None" is not indexable  [index]
+ tests/test_examples.py:327:12: error: Value of type "str | Any | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" is not indexable  [index]
+ tests/test_examples.py:327:12: error: No overload variant of "__getitem__" of "MutableSequence" matches argument type "str"  [call-overload]
+ tests/test_examples.py:327:12: note: Possible overload variants:
+ tests/test_examples.py:327:12: note:     def __getitem__(self, int, /) -> CWLOutputType
+ tests/test_examples.py:327:12: note:     def __getitem__(self, slice, /) -> MutableSequence[CWLOutputType]
+ tests/test_examples.py:327:26: error: Invalid index type "int" for "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None"; expected type "str"  [index]
+ tests/test_examples.py:327:29: error: Invalid index type "str" for "str | Any | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None"; expected type "SupportsIndex | slice"  [index]
+ tests/test_examples.py:328:12: error: Value of type "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None" is not indexable  [index]
+ tests/test_examples.py:328:26: error: Invalid index type "int" for "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None"; expected type "str"  [index]
+ tests/test_examples.py:329:12: error: Value of type "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None" is not indexable  [index]
+ tests/test_examples.py:329:12: error: Value of type "str | Any | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" is not indexable  [index]
+ tests/test_examples.py:329:12: error: No overload variant of "__getitem__" of "MutableSequence" matches argument type "str"  [call-overload]
+ tests/test_examples.py:329:12: note: Possible overload variants:
+ tests/test_examples.py:329:12: note:     def __getitem__(self, int, /) -> CWLOutputType
+ tests/test_examples.py:329:12: note:     def __getitem__(self, slice, /) -> MutableSequence[CWLOutputType]
+ tests/test_examples.py:329:26: error: Invalid index type "int" for "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None"; expected type "str"  [index]
+ tests/test_examples.py:329:29: error: Invalid index type "str" for "str | Any | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None"; expected type "SupportsIndex | slice"  [index]
+ tests/test_examples.py: note: In function "test_factory_partial_output":
+ tests/test_examples.py:342:12: error: Value of type "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None" is not indexable  [index]
+ tests/test_examples.py:342:12: error: No overload variant of "__getitem__" of "MutableSequence" matches argument type "str"  [call-overload]
+ tests/test_examples.py:342:12: note: Possible overload variants:
+ tests/test_examples.py:342:12: note:     def __getitem__(self, int, /) -> CWLOutputType
+ tests/test_examples.py:342:12: note:     def __getitem__(self, slice, /) -> MutableSequence[CWLOutputType]
+ tests/test_examples.py:342:27: error: Invalid index type "str" for "str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | Any | None"; expected type "SupportsIndex | slice"  [index]
+ tests/test_examples.py: note: In function "test_scatter_output_filenames":
+ tests/test_examples.py:1639:21: error: Value of type variable "SupportsRichComparisonT" of "sorted" cannot be "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None"  [type-var]
+ tests/test_examples.py:1639:28: error: Value of type "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" is not indexable  [index]
+ tests/test_examples.py:1639:28: error: No overload variant of "__getitem__" of "MutableSequence" matches argument type "str"  [call-overload]
+ tests/test_examples.py:1639:28: note: Possible overload variants:
+ tests/test_examples.py:1639:28: note:     def __getitem__(self, int, /) -> CWLOutputType
+ tests/test_examples.py:1639:28: note:     def __getitem__(self, slice, /) -> MutableSequence[CWLOutputType]
+ tests/test_examples.py:1639:36: error: Invalid index type "str" for "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None"; expected type "SupportsIndex | slice"  [index]
+ tests/test_examples.py:1639:63: error: Item "int" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "__iter__" (not iterable)  [union-attr]
+ tests/test_examples.py:1639:63: error: Item "float" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "__iter__" (not iterable)  [union-attr]
+ tests/test_examples.py:1639:63: error: Item "None" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "__iter__" (not iterable)  [union-attr]
+ tests/test_examples.py:1642:13: error: Item "None" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1642:13: error: Item "int" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1642:13: error: Item "float" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1642:13: error: Item "MutableSequence[CWLOutputType]" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1642:13: error: Item "MutableMapping[str, CWLOutputType]" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1643:17: error: Item "None" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1643:17: error: Item "int" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1643:17: error: Item "float" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1643:17: error: Item "MutableSequence[CWLOutputType]" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1643:17: error: Item "MutableMapping[str, CWLOutputType]" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1644:17: error: Item "None" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1644:17: error: Item "int" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1644:17: error: Item "float" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1644:17: error: Item "MutableSequence[CWLOutputType]" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]
+ tests/test_examples.py:1644:17: error: Item "MutableMapping[str, CWLOutputType]" of "Any | str | int | float | MutableSequence[CWLOutputType] | MutableMapping[str, CWLOutputType] | None" has no attribute "endswith"  [union-attr]

jax (https://github.com/google/jax)
- jax/_src/interpreters/xla.py:95: error: Unused "type: ignore" comment  [unused-ignore]

mongo-python-driver (https://github.com/mongodb/mongo-python-driver)
+ pymongo/helpers.py:126: error: Argument 1 to "append" of "list" has incompatible type "tuple[str, int | str | Mapping[str, Any]]"; expected "tuple[str, int]"  [arg-type]
+ pymongo/cursor.py:798: error: Argument 1 to "dict" has incompatible type "list[str | tuple[str, int | str | Mapping[str, Any]]] | list[Any] | tuple[str | tuple[str, int | str | Mapping[str, Any]], ...] | tuple[Any, ...]"; expected "Iterable[tuple[str | Any, Any]]"  [arg-type]
+ pymongo/cursor.py:820: error: Argument 1 to "dict" has incompatible type "list[str | tuple[str, int | str | Mapping[str, Any]]] | list[Any] | tuple[str | tuple[str, int | str | Mapping[str, Any]], ...] | tuple[Any, ...]"; expected "Iterable[tuple[str | Any, Any]]"  [arg-type]

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/cookiejar.py:178:23: error: Incompatible types in assignment (expression has type "ItemsView[str, str | BaseCookie[str] | Morsel[Any]] | ItemsView[tuple[str, str | BaseCookie[str] | Morsel[Any]], Any] | ItemsView[Any, Any] | dict_items[str, Morsel[str]]", variable has type "Mapping[str, str | BaseCookie[str] | Morsel[Any]] | Iterable[tuple[str, str | BaseCookie[str] | Morsel[Any]]] | BaseCookie[str]")  [assignment]
+ aiohttp/cookiejar.py:180:9: error: Unpacking a string is disallowed  [misc]
+ aiohttp/client_reqrep.py:412:19: error: Invalid index type "str | Any | tuple[str, str | BaseCookie[str] | Morsel[Any]]" for "SimpleCookie"; expected type "str"  [index]
+ aiohttp/client_reqrep.py:412:19: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-index for more info
+ aiohttp/client_reqrep.py:414:19: error: Invalid index type "str | Any | tuple[str, str | BaseCookie[str] | Morsel[Any]]" for "SimpleCookie"; expected type "str"  [index]
+ aiohttp/client_reqrep.py:414:19: note: Error code "index" not covered by "type: ignore" comment

urllib3 (https://github.com/urllib3/urllib3)
+ src/urllib3/_collections.py:352: error: Incompatible types in assignment (expression has type "tuple[str, str]", variable has type "str")  [assignment]

werkzeug (https://github.com/pallets/werkzeug)
+ src/werkzeug/middleware/shared_data.py:120: error: Incompatible types in assignment (expression has type "dict_items[str, str | tuple[str, str]] | dict_items[tuple[str, str | tuple[str, str]], Any]", variable has type "dict[str, str | tuple[str, str]] | Iterable[tuple[str, str | tuple[str, str]]]")  [assignment]
+ src/werkzeug/middleware/shared_data.py:122: error: Unpacking a string is disallowed  [misc]

streamlit (https://github.com/streamlit/streamlit)
+ lib/streamlit/elements/widgets/time_widgets.py: note: In function "_parse_date_value":
+ lib/streamlit/elements/widgets/time_widgets.py:94:25: error: List comprehension has incompatible type List[Union[date, None, Any]]; expected List[date]  [misc]

scrapy (https://github.com/scrapy/scrapy)
+ scrapy/utils/datatypes.py:96: error: Incompatible types in assignment (expression has type "Iterable[tuple[str, Any]] | ItemsView[tuple[str, Any], Any]", variable has type "Mapping[str, Any] | Iterable[tuple[str, Any]]")  [assignment]
+ scrapy/utils/datatypes.py:96: error: Incompatible types in assignment (expression has type "Iterable[tuple[bytes, Any]] | ItemsView[tuple[bytes, Any], Any]", variable has type "Mapping[bytes, Any] | Iterable[tuple[bytes, Any]]")  [assignment]
+ scrapy/utils/datatypes.py:97: error: Unpacking a string is disallowed  [misc]
+ scrapy/utils/datatypes.py:97: error: Value of type variable "AnyStr" of "normkey" of "CaselessDict" cannot be "int | bytes"  [type-var]
+ scrapy/http/headers.py:46: error: Incompatible types in assignment (expression has type "Iterable[tuple[str, Any]] | ItemsView[tuple[str, Any], Any]", variable has type "Mapping[str, Any] | Iterable[tuple[str, Any]]")  [assignment]
+ scrapy/http/headers.py:46: error: Incompatible types in assignment (expression has type "Iterable[tuple[bytes, Any]] | ItemsView[tuple[bytes, Any], Any]", variable has type "Mapping[bytes, Any] | Iterable[tuple[bytes, Any]]")  [assignment]
+ scrapy/http/headers.py:48: error: Unpacking a string is disallowed  [misc]
+ scrapy/http/headers.py:49: error: Value of type variable "AnyStr" of "normkey" of "Headers" cannot be "int | bytes"  [type-var]

ibis (https://github.com/ibis-project/ibis)
+ ibis/util.py:131: error: Incompatible return value type (got "tuple[Any, ...] | tuple[V, ...]", expected "tuple[V]")  [return-value]

@tyralla
Copy link
Contributor Author

tyralla commented Apr 16, 2024

The new primer output is practically identical to the last one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't narrow Sequence[<X>] to Tuple[<X>, ...] using isinstance(..., tuple)
5 participants