BUG: RecursionError when attempting to replace np.nan values (#45725)
State: closed

- [x] closes #45725
- [x] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [x] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [x] Added an entry in the latest `doc/source/whatsnew/v1.5.0.rst` file if fixing a bug or adding a new feature.


Labels:
name: Missing-data
description: np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
name: replace
description: replace method

Comments:
@github-actions pre-commit
thanks @roib20 very nice! keep em coming!
The tests added in this PR don't seem to fail on master with `value = self._standardize_fill_value(value) # GH#45725` removed.

Also before #45568, which maybe the cause of the regression, the values were replaced.

```
2022-03-16T22:14:48.3750817Z 1.5.0.dev0+209.g0f5d934be7
2022-03-16T22:14:48.3751119Z 0    <NA>
2022-03-16T22:14:48.3751330Z 1    <NA>
2022-03-16T22:14:48.3751555Z dtype: object
2022-03-16T22:14:48.3751789Z       0
2022-03-16T22:14:48.3751988Z 0  None
2022-03-16T22:14:48.3752170Z 1  None
```

from bisect with following code sample

```
# BUG: RecursionError when attempting to replace np.nan values under main branch #45725


import numpy as np

import pandas as pd

print(pd.__version__)

NaN_values = [np.nan, np.nan]
ser = pd.Series(data=NaN_values)
df = pd.DataFrame(data=NaN_values)


ser = ser.replace({np.nan: pd.NA})
print(ser)

df = df.replace({np.nan: None})
print(df)
```

on master, same code sample gives

```
1.5.0.dev0+544.g49937b935d
0   NaN
1   NaN
dtype: float64
    0
0 NaN
1 NaN
```

not sure yet, but I think we will need to remove the ``value = self._standardize_fill_value(value) # GH#45725` added in this PR to fix #45601 and #45836

might propose reverting this PR until the regressions in 1.4.0 are fixed
> The tests added in this PR don't seem to fail on master with `value = self._standardize_fill_value(value) # GH#45725` removed.

but to be clear, the recursion error still exists when the fix added here is removed. Looks like need to revisit these tests.

For the record the traceback is currently

```python-traceback
Traceback (most recent call last):
  File "/home/simon/45725.py", line 15, in <module>
    ser = ser.replace({np.nan: pd.NA})
  File "/home/simon/pandas/pandas/core/series.py", line 5000, in replace
    return super().replace(
  File "/home/simon/pandas/pandas/core/generic.py", line 6681, in replace
    return self.replace(
  File "/home/simon/pandas/pandas/core/series.py", line 5000, in replace
    return super().replace(
  File "/home/simon/pandas/pandas/core/generic.py", line 6730, in replace
    new_data = self._mgr.replace_list(
  File "/home/simon/pandas/pandas/core/internals/managers.py", line 421, in replace_list
    bm = self.apply(
  File "/home/simon/pandas/pandas/core/internals/managers.py", line 304, in apply
    applied = getattr(b, f)(**kwargs)
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 725, in replace_list
    result = blk._replace_coerce(
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 780, in _replace_coerce
    return self.replace(
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 605, in replace
    return blk.replace(
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 605, in replace
    return blk.replace(
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 605, in replace
    return blk.replace(
  [Previous line repeated 977 more times]
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 604, in replace
    blk = self.coerce_to_target_dtype(value)
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 449, in coerce_to_target_dtype
    return self.astype(new_dtype, copy=False)
  File "/home/simon/pandas/pandas/core/internals/blocks.py", line 523, in astype
    new_values = astype_array_safe(values, dtype, copy=copy, errors=errors)
  File "/home/simon/pandas/pandas/core/dtypes/astype.py", line 283, in astype_array_safe
    new_values = astype_array(values, dtype, copy=copy)
  File "/home/simon/pandas/pandas/core/dtypes/astype.py", line 215, in astype_array
    if is_datetime64tz_dtype(dtype) and is_datetime64_dtype(values.dtype):
  File "/home/simon/pandas/pandas/core/dtypes/common.py", line 386, in is_datetime64tz_dtype
    return DatetimeTZDtype.is_dtype(arr_or_dtype)
  File "/home/simon/pandas/pandas/core/dtypes/base.py", line 312, in is_dtype
    if isinstance(dtype, (ABCSeries, ABCIndex, ABCDataFrame, np.dtype)):
  File "/home/simon/pandas/pandas/core/dtypes/generic.py", line 45, in _check
    return getattr(inst, attr, "_typ") in comp
RecursionError: maximum recursion depth exceeded while calling a Python object
```
Because the behavior no longer matches the pre-regression behavior and the fact that the tests do not actually catch the reported regression, I now propose to revert this PR and reopen #45725.

Even though this fix prevents the recursion, I think it will be cleaner to undo this and redo properly rather than patching it up.