8000 Accept compatible dict in place of TypedDict by pkch · Pull Request #3035 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Accept compatible dict in place of TypedDict #3035

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

Merged
merged 6 commits into from
Mar 31, 2017

Conversation

pkch
Copy link
Contributor
@pkch pkch commented Mar 20, 2017

Fixes #2487, #2488


f({'x': 1, 'y': 3})
f({'x': 1, 'y': 'z'}) # E: Argument 1 to "f" has incompatible type "TypedDict(x=int, y=str)"; expected "Point"
# E:-1: Incompatible types (expression has type "str", TypedDict item "y" has type "int")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think only one of these error messages should be shown, not both.

@@ -379,7 +379,7 @@ def expand_errors(input: List[str], output: List[str], fnam: str) -> None:
# The first in the split things isn't a comment
for possible_err_comment in input[i].split('#')[1:]:
m = re.search(
'^([ENW]):((?P<col>\d+):)? (?P<message>.*)$',
'^([ENW]):((?P<col>\d+):)?((?P<backtrack>-\d+):)? (?P<message>.*)$',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this as a separate PR, proposed syntax is debatable and could only delay this PR.

@@ -29,7 +29,11 @@ Add the test in this format anywhere in the file:
- `# E: abc...` indicates that this line should result in type check error
with text "abc..."
- note a space after `E:` and `flags:`
- lines without `# E: ` should cause no type check errors
- `# E:12` adds column number to the expected error
- `# E:-1` means that the error was expected 2 lines ago (helpful for multiple errors in a line)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you already do 4 = 3 # E: error one # E: error two?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JelleZijlstra Yup ;)
@ilevkivskyi One error is about TypedDict not matching the dict structure. But it then infers the wrong TypedDict anyway (to keep going), and that doesn't fit the function call. I can probably change it to make it one error, but it would require more logic elsewhere in the code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pkch

but it would require more logic elsewhere in the code.

Yes.

kwargs=e,
context=e
)
return self.type_context[-1].copy_modified()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please and a comment here about why you do it like this, and how it works?

f({'x': 1, 'y': 'z'}) # E: Incompatible types (expression has type "str", TypedDict item "y" has type "int")

f(dict(x=1, y=3))
f(dict(x=1, y=3, z=4)) # E: Expected items ['x', 'y'] but found ['x', 'y', 'z'].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add one more test case with few tests where you assign to variables with explicit types, like:

p: Point = {'x', 'hi'}

and/or

p: Point
p = dict(x='bye')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also maybe a test for

p = Point(x=1, y=2)
p = {x='hi'}


Point = TypedDict('Point', {'x': int, 'y': int})

p1: Point = {'x': 'hi'} # # E: Expected items ['x', 'y'] but found ['x'].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: # # E: -> # E:

@@ -1694,6 +1694,9 @@ def visit_dict_expr(self, e: DictExpr) -> Type:

Translate it into a call to dict(), with provisions for **expr.
"""
# if we find a DictExpr inside a context that expected TypedDict,
# we try to convert the dictionary into TypedDict
# w 8000 e warn if they are not compatible or if we don't have enough info to verify
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not what I wanted. I wanted an explanation that we need to silence one of two errors, and why the code below actually silences the second error. Sorry for misunderstanding.

@ilevkivskyi
Copy link
Member

OK, now it LGTM.

@ilevkivskyi ilevkivskyi merged commit 6b93e63 into python:master Mar 31, 2017
@ilevkivskyi
Copy link
Member

@pkch Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0