Skip to content
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

TypedDict handles unicode names and keys inconsistently in Python 2 #6123

Closed
Michael0x2a opened this issue Jan 1, 2019 · 5 comments
Closed
Assignees
Labels
bug mypy got something wrong priority-1-normal topic-python2 issues only applicable to Python 2 topic-typed-dict

Comments

@Michael0x2a
Copy link
Collaborator

I noticed an minor inconsistency in the way mypy handles the following program in Python 2:

from __future__ import unicode_literals
from mypy_extensions import TypedDict

MyDict = TypedDict('MyDict', {'foo': int})

Mypy type-checks this problem without errors. However, if you actually try running this program at runtime, you get the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\mypy_extensions.py", line 40, in _typeddict_new
    '__total__': total})
  File "C:\Python27\lib\site-packages\mypy_extensions.py", line 52, in __new__
    tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns)
TypeError: type() argument 1 must be string, not unicode

You have to do MyDict = TypedDict(b'MyDict', {'foo': int}) to get this program to both typecheck and run.

I'm not sure whether the correct thing to do is modify mypy to report an error or to relax the runtime implementation.

On one hand, type(name, bases, dict) legitimately won't accept unicode names in Python 2 so perhaps we should add a check to mypy. On the other, we don't get the same kind of runtime error when creating NamedTuples, so perhaps it's better to try and convert the unicode name to str inside TypedDict for consistency.

@Michael0x2a Michael0x2a self-assigned this Jan 1, 2019
@Michael0x2a Michael0x2a changed the title TypedDict constructor first argument types are handled inconsistently in Python 2 TypedDict handles unicode names and keys inconsistently in Python 2 Jan 1, 2019
@Michael0x2a
Copy link
Collaborator Author

Hmm, it also seems like the keys are also handled inconsistently at well.

Mypy and the Python runtime both let you have unicode keys. They also both accept some_typed_dict["blah"] and some_typed_dict[u"blah"] in Python 2, regardless of how the typed dict is defined.

However, mypy will report an error when doing some_typed_dict.get(u"blah") since the get(...) method is defined to only accept strings. This operation succeeds at runtime though.

@gvanrossum
Copy link
Member

Why isn’t this a typeshed issue?

@Michael0x2a
Copy link
Collaborator Author

@gvanrossum -- I wasn't sure what the correct fix for the first TypedDict(u"Name", ...) issue is -- we could either change typeshed or relax the runtime implementation of mypy_extensions.TypedDict.

The issue in the second comment (the inconsistency between some_typed_dict["blah"] and some_typed_dict.get(u"blah")) probably needs both a typeshed and a mypy fix.

Basically, mypy special-cases both methods and hard-codes in the assumption that some_typed_dict[...] can accept both StrExpr and UnicodeExpr, but also hard-codes in that .get(...) and similar methods can accept only StrExpr. (And as before, I'm not actually sure what the correct behavior is supposed to be.)

@JukkaL
Copy link
Collaborator

JukkaL commented Jan 2, 2019

I think that unicode literals should be accepted everywhere, since using b'foo' won't work in Python 3. It would be good if TypedDict was compatible with unicode_literals.

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 31, 2022

Closing due to Python 2 feature freeze (#12237).

@JukkaL JukkaL closed this as completed Mar 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-1-normal topic-python2 issues only applicable to Python 2 topic-typed-dict
Projects
None yet
Development

No branches or pull requests

4 participants