Skip to content

TypeVar equality broken? #512

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
pitrou opened this issue Dec 7, 2017 · 8 comments · Fixed by python/cpython#6216
Closed

TypeVar equality broken? #512

pitrou opened this issue Dec 7, 2017 · 8 comments · Fixed by python/cpython#6216
Assignees

Comments

@pitrou
Copy link
Member

pitrou commented Dec 7, 2017

This looks unexpected to me:

>>> import typing
>>> typing.TypeVar('T') == typing.TypeVar('T')
False
>>> 
@ilevkivskyi
Copy link
Member

ilevkivskyi commented Dec 7, 2017

FWIW this is actually intentional. I think it was discussed briefly on this tracker, the main motivation is that from the point of view of static type checkers two type variables even with the same name can be different, they follow special scoping rules specified by PEP 484, for example:

T = TypeVar('T')

def f(x: T) -> T: ... # the two T's here are the same
def g(x: T) -> T: ... # the two T's here are the same, but different from the two T's above 

Also this is how type variables work in some other statically typed languages with generics/templates/etc. They get (re-)bound by a class or function definition.

I however don't have any strong opinion on their runtime behavior. @gvanrossum may add to this.

@gvanrossum
Copy link
Member

gvanrossum commented Dec 7, 2017 via email

@pitrou
Copy link
Member Author

pitrou commented Dec 7, 2017

This occurred during unit testing.

@pitrou
Copy link
Member Author

pitrou commented Dec 7, 2017

Sorry, a bit more context: I was trying to add serialization support for typing hints in cloudpickle (see issue #511), and tried to use assertEqual to compare the original type and the unpickled result.

@gvanrossum
Copy link
Member

gvanrossum commented Dec 7, 2017 via email

@ilevkivskyi
Copy link
Member

Hm, I'd expect a TypeVar to be pickled as a reference, not as a value (just like references to classes and functions). Though for that to work we'd need to add __module__ to TypeVars.

If we all agree that type variables should be treated as "immutable", i.e. copy(T) is T and loads(dumps(T)) is T then I can make a PR for this.

@ilevkivskyi ilevkivskyi self-assigned this Dec 11, 2017
@gvanrossum
Copy link
Member

There is no API to mutate a TypeVar and IMO there shouldn't be -- conceptually it really is just a token. So I agree. Hopefully this is acceptable to Antoine?

@pitrou
Copy link
Member Author

pitrou commented Dec 11, 2017

Yes, it sounds ok.

miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 26, 2018
… by copy and pickle (pythonGH-6216)

This also fixes python/typingGH-512
This also fixes python/typingGH-511

As was discussed in both issues, some typing forms deserve to be treated
as immutable by copy and pickle modules, so that:
* copy(X) is X
* deepcopy(X) is X
* loads(dumps(X)) is X  GH- pickled by reference

This PR adds such behaviour to:
* Type variables
* Special forms like Union, Any, ClassVar
* Unsubscripted generic aliases to containers like List, Mapping, Iterable

This not only resolves inconsistencies mentioned in the issues, but also
improves backwards compatibility with previous versions of Python
(including 3.6).

Note that this requires some dances with __module__ for type variables
(similar to NamedTuple) because the class TypeVar itself is define in typing,
while type variables should get module where they were defined.

https://bugs.python.org/issue32873
(cherry picked from commit 8349403)

Co-authored-by: Ivan Levkivskyi <[email protected]>
ilevkivskyi added a commit to python/cpython that referenced this issue Mar 26, 2018
… by copy and pickle (GH-6216)

This also fixes python/typing#512
This also fixes python/typing#511

As was discussed in both issues, some typing forms deserve to be treated
as immutable by copy and pickle modules, so that:
* copy(X) is X
* deepcopy(X) is X
* loads(dumps(X)) is X  # pickled by reference

This PR adds such behaviour to:
* Type variables
* Special forms like Union, Any, ClassVar
* Unsubscripted generic aliases to containers like List, Mapping, Iterable

This not only resolves inconsistencies mentioned in the issues, but also
improves backwards compatibility with previous versions of Python
(including 3.6).

Note that this requires some dances with __module__ for type variables
(similar to NamedTuple) because the class TypeVar itself is define in typing,
while type variables should get module where they were defined.

https://bugs.python.org/issue32873
miss-islington added a commit to python/cpython that referenced this issue Mar 26, 2018
… by copy and pickle (GH-6216)

This also fixes python/typingGH-512
This also fixes python/typingGH-511

As was discussed in both issues, some typing forms deserve to be treated
as immutable by copy and pickle modules, so that:
* copy(X) is X
* deepcopy(X) is X
* loads(dumps(X)) is X  GH- pickled by reference

This PR adds such behaviour to:
* Type variables
* Special forms like Union, Any, ClassVar
* Unsubscripted generic aliases to containers like List, Mapping, Iterable

This not only resolves inconsistencies mentioned in the issues, but also
improves backwards compatibility with previous versions of Python
(including 3.6).

Note that this requires some dances with __module__ for type variables
(similar to NamedTuple) because the class TypeVar itself is define in typing,
while type variables should get module where they were defined.

https://bugs.python.org/issue32873
(cherry picked from commit 8349403)

Co-authored-by: Ivan Levkivskyi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants