Skip to content

"'field' in typed_dict_union" discrimination #13802

Closed

Description

@ikonst

Feature

Similar to tagged unions, I wish an in check could discriminate the following:

class A(TypedDict)
   foo: int

class B(TypedDict):
   bar: int

union = Union[A, B]
value: int
if 'foo' in union:
  value = union['foo']
else:
  value = union['bar']

Similarly:

value: int
if foo := union.get('foo'):
  value = foo
else:
  value = union['bar']

Activity

  1. erictraut commented on Oct 3, 2022

    @erictraut

    This has been discussed previously in various typing forums. (I can't find the threads currently, but perhaps someone else can find a pointer.)

    The problem here is that narrowing based on field discrimination within a TypedDict isn't type safe unless that TypedDict class is marked @final. Otherwise it would be possible for a subclass of B to add a field foo.

    With an @final decorator on A and B it should be possible for mypy to implement type narrowing based on field discrimination. I've implemented this support in pyright. Currently, mypy emits an error if you attempt to add a @final decorator to a TypedDict class.

    from typing import TypedDict, final
    
    @final
    class A(TypedDict):
        foo: int
    
    @final
    class B(TypedDict):
        bar: int
    
    def func(union: A | B):
        if "foo" in union:
            reveal_type(union)  # A
        else:
            reveal_type(union)  # B
  2. hauntsaninja commented on Oct 3, 2022

    @hauntsaninja
    Collaborator

    #7981 is probably the right mypy issue to track this

  3. ikonst commented on Oct 4, 2022

    @ikonst
    ContributorAuthor

    Thanks for the pointer @hauntsaninja, indeed appears to be addressed in #13557. Happy to test once it makes its way into the next release.

  4. hauntsaninja commented on Oct 4, 2022

    @hauntsaninja
    Collaborator

    Only half the feature is implemented; want to take a shot at completing it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions