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

Make TypeVars with only one constraint illegal #2626

Merged

Conversation

Michael0x2a
Copy link
Collaborator

At runtime, doing something like T = TypeVar('T', str) results in the following exception:

TypeError: A single constraint is not allowed

However, mypy itself seems to ignore this particular error, which feels incongruous.

This pull request slightly tweaks the semanal phase to emit an error message in this case to mirror the existing runtime behavior implemented in the typing module.

At runtime, doing something like `T = TypeVar('T', str)` results in the
following exception:

    TypeError: A single constraint is not allowed

However, mypy itself seems to ignore this particular error, which feels
incongruous.

This commit slightly tweaks the semanal phase to emit an error message
in this case to mirror the existing runtime behavior implemented in the
typing module.
This commit fixes some broken unit tests that appeared to have been
using TypeVar incorrectly.

This commit does not cause the entire test suite to pass due to existing
errors within typeshed that need to be fixed first.
Michael0x2a added a commit to Michael0x2a/typeshed that referenced this pull request Jan 1, 2017
According to the documentation in the typing module, TypeVars cannot
have only a single constraint. Attempting to do so will actually result
in an exception at runtime. (However, this error is currently ignored
by mypy -- see python/mypy#2626 for a related
pending pull request).

This commit changes all instances of TypeVars using a single constraint
(e.g. `T = TypeVar('T', Foo)`) to use bounds instead (e.g.
`T = TypeVar('T', bound=Foo)`.

This seems to be the correct fix for plistlib after reading the module
docs, but it's less obvious this is correct for unittest. The unittest
module originally had `_FT = TypeVar('_FT', Callable[[Any], Any])` -- an
alternative fix would have been to do `_FT = Callable[[Any], Any]`.

Although I'm not entirely sure what it means to have a bound be a
Callable, I decided to make the assumption that the original authors
probably meant to use TypeVars instead of type aliases for a reason
(possibly to handle classes implementing `__call__`?)
@Michael0x2a
Copy link
Collaborator Author

...well, I thought this would be a quick fix, but it turned out to be a little more involved then I expected.

The tests are currently failing because typeshed is using single-constraint TypeVars in a few places. I have a pull request to fix this at python/typeshed#804. Once that's accepted and mypy syncs typeshed, I can rebase this pull request and hopefully that'll make the tests pass.

ambv pushed a commit to python/typeshed that referenced this pull request Jan 1, 2017
According to the documentation in the typing module, TypeVars cannot
have only a single constraint. Attempting to do so will actually result
in an exception at runtime. (However, this error is currently ignored
by mypy -- see python/mypy#2626 for a related
pending pull request).

This commit changes all instances of TypeVars using a single constraint
(e.g. `T = TypeVar('T', Foo)`) to use bounds instead (e.g.
`T = TypeVar('T', bound=Foo)`.

This seems to be the correct fix for plistlib after reading the module
docs, but it's less obvious this is correct for unittest. The unittest
module originally had `_FT = TypeVar('_FT', Callable[[Any], Any])` -- an
alternative fix would have been to do `_FT = Callable[[Any], Any]`.

Although I'm not entirely sure what it means to have a bound be a
Callable, I decided to make the assumption that the original authors
probably meant to use TypeVars instead of type aliases for a reason
(possibly to handle classes implementing `__call__`?)
@ambv
Copy link
Contributor

ambv commented Jan 1, 2017

I merged your PR in typeshed.

@gvanrossum
Copy link
Member

Can you do the typeshed sync in this PR? Then the tests will hopefully pass and we can merge it.

@gvanrossum
Copy link
Member

Sorry, there's a complication. See my comments in python/typeshed#804, which I am going to revert. :-(

gvanrossum pushed a commit to python/typeshed that referenced this pull request Mar 29, 2017
gvanrossum added a commit to python/typeshed that referenced this pull request Mar 29, 2017
@gvanrossum
Copy link
Member

I guess I need to sync typeshed and then try again.

But with synced typeshed.
@gvanrossum gvanrossum merged commit 428a536 into python:master Mar 29, 2017
@gvanrossum
Copy link
Member

Whee! Finally this is merged. Sorry for the long delay!

@Michael0x2a
Copy link
Collaborator Author

@gvanrossum wow, I haven't had time to think about this at all this quarter -- I can't believe this actually got pushed through! Thanks!

@Michael0x2a Michael0x2a deleted the make-single-constraint-typevar-fail branch June 3, 2017 20:26
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