Description
Some modules (for example, re
) don't expose some of the underlying type objects, which makes it tricky to annotate code that uses these types. Mypy defines custom type aliases in typing
for some of the more common types (including pattern and match object types for re
), but this does not easily extend to 3rd party libraries.
Example:
>>> import re
>>> r = re.compile('x')
>>> type(r)
<class '_sre.SRE_Pattern'>
>>> import _sre
>>> _sre.SRE_Pattern
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'SRE_Pattern'
A related issue is types that are implicit, such as protocol types / structural types (in case we support them). Where should a structural type needed for annotating a library module be defined?
Also, generic library types pose a similar problem, since vanilla Python classes don't support indexing, and we'd have to use the string escape syntax to use a library class as a generic type.
Here are alternatives I've came up with:
- Fall back to the type
Any
if the type object is not available. This is clearly suboptimal. - Define the type in
typing
or a related module as an alias. This does not scale to an arbitrary number of modules, but it would probably work for the most common cases. We could fall back toAny
elsewhere. - Define a parallel module hierarchy for additional typing-related definitions, such as
typing.re
forre
. Not sure how this will work if these modules come from multiple sources. Should this hierarchy be managed centrally? - Expose the type objects of standard library modules in Python 3.5 (as was suggested by Guido). This does not help with earlier Python releases. In addition to just exposing the types they should also have meaningful names, unlike
_sre.SRE_Pattern
in the above example.