TYP: Add cast to ABC classes.
State: closed

- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] passes `black pandas`
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry

Implements the idea of @simonjayhawkins from https://github.com/pandas-dev/pandas/issues/27353#issuecomment-526391462 to use cast on ABC classes. Currently only implements ABCDataFrame, ABCNDFrame, and ABCSeries. Previously, mypy would resolve e.g. ABCSeries as any, now it gets resolved as Series.

One issue remains: I don't understand why the code below generates this complaint.

> pandas/core/common.py:472: error: Incompatible return value type (got "Union[Any, List[Any], Series]", expected "Union[List[Any], ExtensionArray]")  [return-value]

```
def convert_to_list_like(
    values: Union[Scalar, Iterable, AnyArrayLike]
) -> Union[List, AnyArrayLike]:
    if isinstance(values, (list, np.ndarray, ABCIndex, ABCSeries, ABCExtensionArray)):
        return values
    ...
```

One can add Series to the return Union to resolve this, but it doesn't seem like that should be necessary.

I'm also getting:

> pandas/core/base.py:923: note: Internal mypy error checking function redefinition

on the lines

```
def map_f(values, f):
    return lib.map_infer_mask(values, f, isna(values).view(np.uint8))
```

where `map_f` is defined in various ways in if-else blocks. I'm not sure if this is a mypy bug.

Labels:
name: Typing
description: type annotations, mypy/pyright type checking

Comments:
> One issue remains: I don't understand why the code below generates this complaint.
> 
> > pandas/core/common.py:472: error: Incompatible return value type (got "Union[Any, List[Any], Series]", expected "Union[List[Any], ExtensionArray]")  [return-value]
> 
> ```
> def convert_to_list_like(
>     values: Union[Scalar, Iterable, AnyArrayLike]
> ) -> Union[List, AnyArrayLike]:
>     if isinstance(values, (list, np.ndarray, ABCIndex, ABCSeries, ABCExtensionArray)):
>         return values
>     ...
> ```
> 
> One can add Series to the return Union to resolve this, but it doesn't seem like that should be necessary.

AnyArrayLike is a TypeVar so that a type of AnyArrayLike is returned as is. I'm guessing this is a False positive that may be down to either np.ndarray resolving to `Any` or down to ABCIndex and ABCExtensionArray not yet updated to not resolve to `Any`. I would just ignore these errors for now.
> I'm also getting:
> 
> > pandas/core/base.py:923: note: Internal mypy error checking function redefinition
> 
> on the lines
> 
> ```
> def map_f(values, f):
>     return lib.map_infer_mask(values, f, isna(values).view(np.uint8))
> ```
> 
> where `map_f` is defined in various ways in if-else blocks. I'm not sure if this is a mypy bug.

changing the def to a lambda fixes. probably a mypy issue.
Thanks for all the feedback @jbrockmendel  and @simonjayhawkins; I believe I've address everything thus far. 
Thanks @simonjayhawkins, change made. I also used your lambda to work around the internal mypy error for a lack of any other solutions. Using `# type: ignore` worked to silence mypy, but there is no error type and so it doesn't pass the pre-commit style checks. On a whim I attempted `# type: ignore[note]` but it did not work. I'll be raising an issue with mypy later tonight.
> Using `# type: ignore` worked to silence mypy, but there is no error type and so it doesn't pass the pre-commit style checks. On a whim I attempted `# type: ignore[note]` but it did not work. I'll be raising an issue with mypy later tonight.

we could perhaps change our code check to allow, say, # noqa to be added to allow this through.
@jreback changes made and green. Just the label vs hashable issue is outstanding.
thanks @rhshadrach