8000 TypedDict doesn't respect subtypes or promoted types. · Issue #2610 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

TypedDict doesn't respect subtypes or promoted types. #2610

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

Closed
rowillia opened this issue Dec 27, 2016 · 3 comments
Closed

TypedDict doesn't respect subtypes or promoted types. #2610

rowillia opened this issue Dec 27, 2016 · 3 comments
Labels

Comments

@rowillia
Copy link
Contributor
rowillia commented Dec 27, 2016

Repro:

test_typed_dict_return_value.py

from mypy_extensions import TypedDict

TaggedPoint = TypedDict('TaggedPoint', {'type': str, 'x': float, 'y': float})

def create_tagged_point():
    # type: () -> TaggedPoint
    return TaggedPoint(type='2d', x=42, y=1337)
$ mypy test_typed_dict_return_value.py
test_typed_dict_return_value.py:9: error: Incompatible return value type (got "TypedDict(type=str, x=int, y=int)", expected "TaggedPoint")

As an aside, the error message above is fairly hard to decode. It took me a few hours to realize what was going on.

The problem also exists with Any types:

from mypy_extensions import TypedDict

TaggedPoint = TypedDict('TaggedPoint', {'type': str, 'x': int, 'y': int})

def create_tagged_point(some_value):
    # type: (Any) -> TaggedPoint
    return TaggedPoint(type=some_value.type, x=some_value.x, y=some_value.y)
rowillia pushed a commit to rowillia/mypy that referenced this issue Dec 30, 2016
TypedDicts appear to have explicitly decided not to accept subtypes on fields,
but this behavior is counter intuitive.  This made it so TypedDicts didn't
respect `Any` and caused problems with what should have been ducktype
compatible.  This also brings TypedDicts more in line with other container
types and with how fields on classes behave.

```python
from typing import Dict

def foo() -> Dict[float, object]:
    return {
        1: 32
    }
```

This fixes python#2610
@gvanrossum
Copy link
Member

It took me some time to understand the bug report too... It seems that the failure (with --py2 only) is due to str not being an exact match for Text?

(I wouldn't call that duck typing (mypy makes special allowances for str -> Text and int -> float called "type promotions"), so the subject didn't help me.)

@rowillia
Copy link
Contributor Author

@gvanrossum Sorry for the obtuse bug report...it took me a bit to figure out what was going on. I changed the example to not rely on the --py2 flag. The core of the issue is SubtypeVisitor.visit_typeddict_type was checking for type equivalence rather than a subtype - https://github.com/python/mypy/blob/master/mypy/subtypes.py#L214. I have a PR that fixes this - #2621

@rowillia rowillia changed the title TypedDict doesn't respect duck typing TypedDict doesn't respect subtypes or promoted types. Dec 31, 2016
@JukkaL
Copy link
Collaborator
JukkaL commented Jan 3, 2017

#2621 (comment) describes an alternative way to fix this.

rowillia pushed a commit to rowillia/mypy that referenced this issue Jan 6, 2017
TypedDicts appear to have explicitly decided not to accept subtypes on fields,
but this behavior is counter intuitive.  This made it so TypedDicts didn't
respect `Any` and caused problems with what should have been ducktype
compatible.  This also brings TypedDicts more in line with other container
types and with how fields on classes behave.

```python
from typing import Dict

def foo() -> Dict[float, object]:
    return {
        1: 32
    }
```

This fixes python#2610
rowillia pushed a commit to rowillia/mypy that referenced this issue Jan 11, 2017
TypedDicts appear to have explicitly decided not to accept subtypes on fields,
but this behavior is counter intuitive.  This made it so TypedDicts didn't
respect `Any` and caused problems with what should have been ducktype
compatible.  This also brings TypedDicts more in line with other container
types and with how fields on classes behave.

```python
from typing import Dict

def foo() -> Dict[float, object]:
    return {
        1: 32
    }
```

This fixes python#2610
rowillia pushed a commit to lyft/mypy that referenced this issue Jan 12, 2017
TypedDicts appear to have explicitly decided not to accept subtypes on fields,
but this behavior is counter intuitive.  This made it so TypedDicts didn't
respect `Any` and caused problems with what should have been ducktype
compatible.  This also brings TypedDicts more in line with other container
types and with how fields on classes behave.

```python
from typing import Dict

def foo() -> Dict[float, object]:
    return {
        1: 32
    }
```

This fixes python#2610
@JukkaL JukkaL added bug mypy got something wrong priority-0-high labels Jan 16, 2017
@JukkaL JukkaL closed this as completed in 2f6d620 Mar 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants
0