TYP: Fix typing in ExtensionDtype registry
State: closed

Simplifying #40421 to just fix up typing in the registry for Extension Dtypes, and return type for `construct_from_string` in `pandas/core/dtypes/base.py`


Labels:
name: ExtensionArray
description: Extending pandas with custom dtypes or arrays.
name: Typing
description: type annotations, mypy/pyright type checking

Comments:
@simonjayhawkins can you review, please?
cc @simonjayhawkins if you can (a few open by @Dr-Irv )
@Dr-Irv removing the milestones on these typing PRs as our types are not public so the 1.3.0rc date is not a concern
@simonjayhawkins  pushed changes a week ago, so looking forward to a new review.
This pull request is stale because it has been open for thirty days with no activity. Please update or respond to this comment if you're still interested in working on this.
Merged to master to remove stale label and to see that it passes tests.
> adding another overload for string type (and maybe using npt.DTypeLike) can get us closer?

So if you do:
```python
    @overload
    def find(self, dtype: type_t[ExtensionDtypeT]) -> type_t[ExtensionDtypeT]:
        ...

    @overload
    def find(self, dtype: ExtensionDtypeT) -> ExtensionDtypeT:
        ...

    @overload
    def find(self, dtype: str) -> ExtensionDtype | None:
        ...

    @overload
    def find(
        self, dtype: npt.DTypeLike
    ) ->None:
        ...

```
you get this from mypy:
```
pandas\core\dtypes\base.py:431: error: Overloaded function signatures 1 and 4 overlap with incompatible return types  [misc]
pandas\core\dtypes\base.py:439: error: Overloaded function signatures 3 and 4 overlap with incompatible return types  [misc]
```
That's because `npt.DTypeLike` includes `str` and `type` as possible values.  If we get a `str`, we can return `ExtensionDtype` or `None`.  

In the next commit, I changed the 4th overload to be:
```python
    @overload
    def find(
        self, dtype: npt.DTypeLike
    ) -> type_t[ExtensionDtype] | ExtensionDtype | None:
        ...
```

That's because the `npt.DTypeLike` is too wide, and there is not a way to just say "the numpy types" plus "the base types"




Thanks @Dr-Irv can you post the output of the code sample in https://github.com/pandas-dev/pandas/pull/41203#pullrequestreview-698655949 with the latest changes.
> Thanks @Dr-Irv can you post the output of the code sample in [#41203 (review)](https://github.com/pandas-dev/pandas/pull/41203#pullrequestreview-698655949) with the latest changes.
```
mypytest.py:7: note: Revealed type is "Union[pandas.core.dtypes.base.ExtensionDtype, None]"
mypytest.py:8: note: Revealed type is "Union[Type[pandas.core.dtypes.base.ExtensionDtype], pandas.core.dtypes.base.ExtensionDtype, None]"
mypytest.py:9: note: Revealed type is "Union[Type[pandas.core.dtypes.base.ExtensionDtype], pandas.core.dtypes.base.ExtensionDtype, None]"
mypytest.py:10: note: Revealed type is "Union[Type[pandas.core.dtypes.base.ExtensionDtype], pandas.core.dtypes.base.ExtensionDtype, None]"
mypytest.py:11: note: Revealed type is "Type[pandas.core.arrays.integer.Int64Dtype*]"
mypytest.py:12: note: Revealed type is "pandas.core.arrays.integer.Int64Dtype*"
```
@simonjayhawkins ping...
pinging @simonjayhawkins 
@Dr-Irv if you can rebase

cc @simonjayhawkins