-
-
Notifications
You must be signed in to change notification settings - Fork 579
Enable subscripting generic types in annotations. #461
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
base: master
Are you sure you want to change the base?
Conversation
Some classes like lxml.etree.ElementTree are generic types that can contain different kinds of elements. The type of these elements has to be specified in type annotations. For example: element_tree: lxml.etree.ElementTree[lxml.etree.Element] This requires adding a __class_getitem__ class method to these class, as specified in PEP 560. This commit adds these class methods. The list of generic types in lxml was taken from: https://github.com/abelcheung/types-lxml/wiki/Using-specialised-class-directly
Hmm, is it still a good idea to return a string from |
I will look into the |
Make ElementTree a subclass of typing.Generic instead of adding a __class_getattr__ method. For the other scriptable classes, subclassing Generic conflicts with cython, so we stick to __class_getattr__ returning GenericAlias. For testing, check the return values of typing.get_origin and typing.get_args. These functions seem to be the cannonical consumers of this data.
Rather than doing a version check on each use, in all cdef object _GenericAlias # only in .pyx files, to store it outside of the module dict
try:
from types import GenericAlias as _GenericAlias
except ImportError:
# Python 3.8 - we only need this as return value from "__class_getitem__"
def _GenericAlias(cls, item):
return f"{cls.__name__}[{item.__name__}]" EDIT: In general, I prefer code that prefers the future proof solution and makes the fallback easy to remove. At some point, the fallback will be removed and that works best if it touches little to nothing of the remaining implementation. |
I made the change you requested. Originally, I was trying to follow your "lazy import" code style. But eventually, this is only executed once per annotation when the code gets loaded, so I don't think it makes much difference for performance. |
Some classes like lxml.etree.ElementTree are generic types that can contain different kinds of elements. The type of these elements has to be specified in type annotations. For example:
element_tree: lxml.etree.ElementTree[lxml.etree.Element]
This requires adding a class_getitem class method to these class, as specified in PEP 560. This commit adds these class methods.
The list of generic types in lxml was taken from:
https://github.com/abelcheung/types-lxml/wiki/Using-specialised-class-directly
This PR is a reincarnation of PR #401. The difference is that now there is no reference to private classes anymore.