Skip to content

@final(TypedDict).get() with unknown key returns object instead of None #12143

Closed

Description

@Dreamsorcerer

See: #12143 (comment)


Original report:

With:

from typing import TypedDict, final

@final
class A(TypedDict):
    """Empty"""

a: A = {}
reveal_type(a.get("foo", None))

I expect to get None, but instead get object | Any.

Maybe the object should be replaced with None here? https://github.com/python/typeshed/blob/master/stdlib/typing.pyi#L717-L728
I'm not too sure how that works.

Activity

  1. 97littleleaf11 commented on Mar 19, 2022

    @97littleleaf11
    Collaborator

    Actually the issue is get("missing_key", foo) cannot infer correct type. #9906 (comment) Jukka explained this before.

  2. jhance commented on Mar 19, 2022

    @jhance
    Collaborator

    Does object | Any not still seem wrong? Going with the spirit of the comment we shouldn't be inferring an Any at all, it seems object | None would make more sense no?

  3. 97littleleaf11 commented on Mar 19, 2022

    @97littleleaf11
    Collaborator

    Does object | Any not still seem wrong?

    I can only get object on master branch

  4. Dreamsorcerer commented on Mar 19, 2022

    @Dreamsorcerer
    ContributorAuthor

    Actually the issue is get("missing_key", foo) cannot infer correct type. #9906 (comment) Jukka explained this before.

    I think the real issue why this can't be inferred is the allowance of inheritance. I think there was a conversation about this elsewhere, but my example can't work, as you could create a subclass with any other type like:

    class A(TypedDict): ...
    
    class B(A):
        foo: str
    
    b: B = {"foo": "bar"}
    a: A = b
    reveal_type(a.get("foo", None))
    

    In the future, it might be possible to support my example using final types:

    @final
    class A(TypedDict): ...
    

    At that point, there is no reason it can't be inferred. The key is a literal and it can be checked what type it should return (or no type if not present).

  5. changed the title [-]Empty TypedDict returns object[/-] [+]@final(TypedDict).get() with unknown key returns object instead of None[/+] on Jun 9, 2023
  6. roganov commented on Apr 2, 2024

    @roganov

    Another example of the issue:

    import typing
    
    
    @typing.final
    class Node(typing.TypedDict):
        name: str
        children: list[typing.Union['Node', 'Leaf']]
    
    
    @typing.final
    class Leaf(typing.TypedDict):
        name: str
    
    
    x: Node | Leaf
    reveal_type(x.get('children', []))
    

    The inferred type should be list[Node], not builtins.object.

  7. ilevkivskyi commented on Jun 2, 2026

    @ilevkivskyi
    Member

    Just to confirm for more visibility: @final decorator on TypedDicts is now soft-deprecated (and is only supported on the best effort basis), for all relevant use cases, please use PEP 728 closed=True.

  8. added a commit that references this issue on Jun 2, 2026
    0ce09a1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions