Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Type inference: Mapping from TypedDict? #2007

Answered by erictraut
Pringauss asked this question in Q&A
Discussion options

Trying to learn how to write statically typed Python, but got confused for quite some time. Here is a toy example:

from typing import TypedDict
from collections.abc import Mapping
# represent the loose idea of a point as a mapping (i.e. dict or variants) from coordinates to floats
type PointLike = Mapping[str, float]
# a specific type of point
class Point2D(TypedDict):
 x: float
 y: float
# other types of points may be defined here or elsewhere (thanks to duck typing)
# examples: 3D space, RGB...
# the point (pun intended) is to implement transformations between different point types
# those should be abstracted with a Protocol later on
# here is a trivial transformation
def identity_transform[T: PointLike](p: T) -> T:
 # return the point unchanged
 return p
# let's test it
my_point = Point2D(x=0.7, y=-0.3)
identity_transform(my_point) # runs fine, but type checker error!

Both mypy and pyright will error on the last line, as can be seen in the playground links provided.

My main question is: why is this? After thinking about it for way too long, my guess would be that, since Python dictionaries are mutable, there is nothing stopping you from adding another key of a different type to my_point. Therefore, type checkers cannot infer its type as Mapping[str, float], and are inferring the TypedDict instance to be like Mapping[str, Any]. Please correct me if I am wrong.

A second question is: what would, then, be the appropriate way to implement the idea in the problem while keeping static type checkers happy?

You must be logged in to vote

To understand why your TypedDict isn't assignable to Mapping[str, float], check out this section of the typing spec. (Scroll down to the last bullet point in that section.)

There is a draft PEP 728 that proposes to add the concept of "closed TypedDicts" to the type system. Pyright has experimental support for this PEP if you want to play around with it. Here's what that looks like in the pyright playground.

Replies: 1 comment 1 reply

Comment options

To understand why your TypedDict isn't assignable to Mapping[str, float], check out this section of the typing spec. (Scroll down to the last bullet point in that section.)

There is a draft PEP 728 that proposes to add the concept of "closed TypedDicts" to the type system. Pyright has experimental support for this PEP if you want to play around with it. Here's what that looks like in the pyright playground.

You must be logged in to vote
1 reply
Comment options

This is it, thanks!

Answer selected by Pringauss
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /