You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MyPy does not understand types exclusion using operator "is" #15788
main.py:8: error: Argument 1 to "chain" has incompatible type "tuple[object]"; expected "Iterable[int]" [arg-type]
Which is obviously incorrect, since we checked that first_item is not an object(). I can not check for isinstance(fist_item, object) because every object is object :). Seems, MyPy understands isinstance() assertions, but does not understand is.
Seems, type of next(xxx, yyy) should be xxx[0] | Literal[yyy] instead of xxx[0] | yyy (pseudocode, I don't know how to express correctly)
Which is obviously incorrect, since we checked that first_item is not an object().
Not really, no. All you checked was that it isn't the stopper sentinel by identity. It can still be any other object() object, so that comparison doesn't prove object | T can't be object anymore.
suggests that first_item is just object and that's it, it appears to have forgotten all about T. Perhaps object destroys union types.
For test purposes using dict() as a sentinel reveals that type(x) is dict type narrows inside the if, but doesn't type narrow in an else branch. type(x) is not dict doesn't appear to narrow at all?
typing.Literal[] is what you want, but it doesn't support arbitrary object() sentinels. The best method right now is a 1-item enum, or alternatively a @final-ed class if/once #15646 is merged. See also python/typing#689, and the draft PEP 661.
Or for this code in particular, you could use a try-except StopIteration, which would be fully typesafe.
Activity
eli-schwartz commentedon Aug 3, 2023
Not really, no. All you checked was that it isn't the
stoppersentinel by identity. It can still be any otherobject()object, so that comparison doesn't proveobject | Tcan't be object anymore.https://mypy.readthedocs.io/en/stable/type_narrowing.html suggests that for type narrowing you can use
type(first_item) is objectbut this doesn't work either, perhaps because:suggests that first_item is just object and that's it, it appears to have forgotten all about T. Perhaps
objectdestroys union types.For test purposes using dict() as a sentinel reveals that
type(x) is dicttype narrows inside the if, but doesn't type narrow in an else branch.type(x) is not dictdoesn't appear to narrow at all?socketpair commentedon Aug 3, 2023
What I said, return type of
nextshould not beT| type(sentinel). It should beT | literally(sentinel).Is it possible in Python type system ? In MyPy?
So check
is stopperwould reduce the union down to justT.TeamSpen210 commentedon Aug 3, 2023
typing.Literal[]is what you want, but it doesn't support arbitraryobject()sentinels. The best method right now is a 1-item enum, or alternatively a@final-ed class if/once #15646 is merged. See also python/typing#689, and the draft PEP 661.Or for this code in particular, you could use a
try-except StopIteration, which would be fully typesafe.erictraut commentedon Aug 14, 2023
I think mypy is working correctly (as designed) in this case. Is there anything actionable from this issue, or should it be closed?