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

Revert "Fixing signature for Mapping.get's default parameter" #2817

Merged
merged 1 commit into from
Feb 27, 2019

Conversation

ilevkivskyi
Copy link
Member

Reverts #2810. cc @mrkmndz

#2810 causes significant troubles in real code. Consider this example:

m: Mapping[str, List[str]]

x = m.get('x', [])

reveal_type(x)

This used to produce builtins.list[builtins.str] but now it produces Union[builtins.list[builtins.str], builtins.list[<nothing>]] causing subsequent failures because of invariance.

The old signature provided type context for inference of the default argument, and was not wrong in any sense.

@mrkmndz Potentially we might need to do the same for werkzeug.datastructures.TypeConversionDict and werkzeug.datastructures.Headers, since this type signature is better for type inference.

@ilevkivskyi
Copy link
Member Author

The tests will likely fail because of an update in mypy tests, I will revert that now, and then re-run the tests here.

@srittau
Copy link
Collaborator

srittau commented Feb 27, 2019

Off topic, but this is one example why having a test suite for typeshed is a good idea. This could be used to test and document the reason why certain typings are as they are.

@JelleZijlstra
Copy link
Member

I'm OK with reverting. I'd like to hear more from the Pyre team on why they thought this change was necessary though.

@mrkmndz
Copy link
Contributor

mrkmndz commented Feb 27, 2019

The problem with this signature is that it results in a unbound type variable in the return type in the case of the default parameter coinciding with the value type of the mapping. Does mypy just drop elements with unbound type variables from unions in returns?

Arguably the other solution here is to keep my change and to allow literal empty lists to subclass any defined list (which is what pyre does, but currently in too many places) and thus collapse that union.

@ilevkivskyi
Copy link
Member Author

Does mypy just drop elements with unbound type variables from unions in returns?

Mypy infers List[str] for _T from Union[List[str], _T] :> List[str] (if there are no other constraints), we can probably do better, but I don't see how mypy's type inference is related to this. The problem is that with the new signature it is impossible to infer any meaningful type for any empty collection (not just list) used as a default, since there is no type context.

Arguably the other solution here is to keep my change and to allow literal empty lists to subclass any defined list

And how this can be put into the type system? Should we just special-case lists, what to do with user-defined generic collections? TBH, I don't think this is a good idea.

Unless this will cause some immediate troubles for you, I will merge this since it already causes troubles for us, otherwise I think we can wait couple days.

@mrkmndz
Copy link
Contributor

mrkmndz commented Feb 27, 2019

What we're doing is allowing SomeParametric[] to subclass any other SomeParametric, regardless of variance. This is only problematic if you allow that type to exist attached to a variable (which we're banning), but in the context of an argument or return it would be fine. In this case that means that List[] is a subclass of List[str] which collapses the union

@ilevkivskyi
Copy link
Member Author

[...] This is only problematic if you allow that type to exist attached to a variable (which we're banning)

Hm, actually mypy also bans assigning List[<nothing>] to a variable, but this change still looks a bit risky and it is probably better to consider it in calmer conditions. IIUC reverting will not cause immediate troubles for you, so I am merging this now.

@ilevkivskyi ilevkivskyi merged commit 3d638b0 into master Feb 27, 2019
@ilevkivskyi ilevkivskyi deleted the revert-2810-mappingget branch February 27, 2019 18:09
ilevkivskyi added a commit to python/mypy that referenced this pull request Feb 27, 2019
@mrkmndz
Copy link
Contributor

mrkmndz commented Feb 27, 2019

Sure, we can work around it, but I think it'd be worth considering allowing that special case exception to subclassing before changing werkzeug as well.

@ilevkivskyi
Copy link
Member Author

but I think it'd be worth considering allowing that special case exception to subclassing before changing werkzeug as well.

OK

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.

5 participants