Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Description
Summary
Thedata
keyword argument presents a tricky edge case for typing that is currently not ideal.
#25632 Provides the first step, untyped but present in the type stubs (sostubtest
will check them at least.
Proposed fix
The OO api type hints: overloads
The most properly the type hint would look something like:
@overloaddefhlines(self,y:float|ArrayLike,xmin:float|ArrayLike,xmax:float|ArrayLike,colors:Sequence[ColorType]|None= ...,linestyles:LineStyleType= ...,label:str= ...,*,data:None=...,**kwargs )->LineCollection: ...@overloaddefhlines(self,y:float|ArrayLike|str,xmin:float|ArrayLike|str,xmax:float|ArrayLike|str,colors:Sequence[ColorType]|None|str= ...,linestyles:LineStyleType= ...,label:str= ...,*,data:Mapping[str,ArrayLike],**kwargs )->LineCollection: ...
That is to say:
An overloaded call where one call hasdata
of typeNone
, and the other hasdata
with typeMapping[str, ArrayLike]
(and also appendsstr
to the valid types for affected parameters)
Note that technicallystr
does pass asArrayLike
, as that is a broad union which includes scalars (andstr
specifically), but communicating explicitly thatstr
is expected for the case where data is not None is a bit better.
If**kwargs
is not included, the first overload could simply omitdata
all together, making it a required keyword arg.
The problem: pyplot
Current pyplot generation code (tools/boilerplate.py)only looks at thefirst signature of overloads.
This currently only affects a small number of methods that are in the autogenerated portion of pyplot and have overloads in their definitions (e.g. Axes.legend), which simply don't get the full type hints in pyplot.
Currently, none of the affected methods result in a type hint being added which is not correct, just type hints being omitted (and thus to mypy areAny
) and so not deriving the value of having type hints for that small number of methods
The above overload fordata
would not be the same, as it would either getNone
ORMapping[...]
, not the union. In the latter case, this would be a problem as the default would not match the hint. In the former, it would fail if you tried to use the arg. If no**kwargs
and data is simply omitted, it would simply be as it already was where pyplot gets no type hint fordata
, but it does appear in the signature.
The pyplot generation code may need to be be more comprehensive and explicitly handle the case of overloads. This is certainly possible, but not easy.
Considerations for inline type hints
Sincedata
does not appear in the actual signature this is mildly complicated for if we ever do want to move towards inline type hints. Such a move is not in the current plans, but worth writing down why this is a complicating factor.
If we use overloads, I think it may actually just wash away, so maybe not as complicated as otherwise.
PEP 612 addresses allowing static typing of decorators which modify signatures by addingpositional arguments, butexplicitly excludes the case of adding akeyword-only arg, as is the case for the_preprocess_data
. So statically using the decorator to transparently modify the signature for the type checker is not possible.