Repository: modin-project/modin

Issue:
BUG: 'DataFrame' object has no attribute '_cache'
### Modin version checks

- [X] I have checked that this issue has not already been reported.

- [X] I have confirmed this bug exists on the latest released version of Modin.

- [ ] I have confirmed this bug exists on the main branch of Modin. (In order to do this you can follow [this guide](https://modin.readthedocs.io/en/stable/getting_started/installation.html#installing-from-the-github-master-branch).)


### Reproducible Example

```python
import modin.config as cfg
import modin.pandas as pd
import pandas
import numpy as np

cfg.LogMode.enable()

df = pandas.DataFrame(
    {
        "name": ['Alfred', 'Batman', 'Catwoman'],
        "toy": [np.nan, 'Batmobile', 'Bullwhip'],
        "born": [pd.NaT, pd.Timestamp("1940-04-25"), pd.NaT]
    }
)
df = pd.DataFrame(df)
df2 = df.dropna(subset=["toy"]).copy()
```


### Issue Description

When enabling logging for some of our workloads I checked recently I see multiple errors like `'DataFrame' object has no attribute '_cache'` or `'Series' object has no attribute '_cache'` in log files. On one of the workloads these errors are printed out even in stdout. I wonder if this is already known issue?

cc-ing @mvashishtha because you are probably the latest person who had a deal with `_cache` attribute and @vnlitvinov who is most aware of Modin logging.

### Expected Behavior

Do not have there errors.

### Error Logs

<details>

```python-traceback

Traceback (most recent call last):
  File "modin/logging/logger_decorator.py", line 134, in run_and_log
    result = obj(*args, **kwargs)
  File "modin/pandas/dataframe.py", line 2368, in __getattr__
    raise err
  File "modin/pandas/dataframe.py", line 2364, in __getattr__
    return object.__getattribute__(self, key)
AttributeError: 'DataFrame' object has no attribute '_cache'
Stack (most recent call last):
  File "test4.py", line 16, in <module>
    df2 = df.dropna(subset=["toy"]).copy()
  File "modin/logging/logger_decorator.py", line 134, in run_and_log
    result = obj(*args, **kwargs)
  File "modin/pandas/base.py", line 1114, in copy
    return self.__constructor__(query_compiler=self._query_compiler.copy())
  File "modin/pandas/base.py", line 3890, in __getattribute__
    attr = super().__getattribute__(item)
  File "modin/logging/logger_decorator.py", line 142, in run_and_log
    get_logger("modin.logger.errors").exception(

```

</details>


### Installed Versions

<details>

2a6aafed41f7758d75dab88517c76b5cdb1905fc

</details>



Discussion:
UPD:

> On one of the workloads these errors are printed out even in stdout.

Checked more thoroughly this workload. It configures `logging` to print in stdout. So probably the error occurs only in logs. But still, I am wondering if this is an issue that needs to be fixed?
@YarShev yes we always get this in the logs. It comes from `cache_readonly`, which will try and fail to access `_cache`: https://github.com/pandas-dev/pandas/blob/bdfaca634e9946c0612c497456332fee80e7db37/pandas/_libs/properties.pyx#L19
Should we apply `@disable_logging` to `DataFrame.__getattr__` as we do for `__getattribute__`?
> Should we apply `@disable_logging` to `DataFrame.__getattr__` as we do for `__getattribute__`?

That is a good question. I think so because it is confusing to get multiple errors in stdout if the user has configured logging in that way.
Can we instead ignore errors whose messages contain the substring `has no attribute '_cache'`?
We can get other errors like `'DataFrame' object has no attribute '__array_struct__'`, `'DataFrame' object has no attribute '__array_interface__'`, etc.
Disabling logging for `__getattr__` is okay with me.

Resolving patch:
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -42,6 +42,7 @@
 from typing import IO, Optional, Union, Iterator, Hashable, Sequence
 import warnings
 
+from modin.logging import disable_logging
 from modin.pandas import Categorical
 from modin.error_message import ErrorMessage
 from modin.utils import (
@@ -2342,6 +2343,7 @@ def _getitem_column(self, key):
             s._parent_axis = 1
         return s
 
+    @disable_logging
     def __getattr__(self, key):
         """
         Return item identified by `key`.
diff --git a/modin/pandas/groupby.py b/modin/pandas/groupby.py
--- a/modin/pandas/groupby.py
+++ b/modin/pandas/groupby.py
@@ -25,7 +25,7 @@
 from collections.abc import Iterable
 
 from modin.error_message import ErrorMessage
-from modin.logging import ClassLogger
+from modin.logging import ClassLogger, disable_logging
 from modin.utils import (
     _inherit_docstrings,
     try_cast_to_pandas,
@@ -161,6 +161,7 @@ def _override(self, **kwargs):
         new_kw.update(kwargs)
         return type(self)(**new_kw)
 
+    @disable_logging
     def __getattr__(self, key):
         """
         Alter regular attribute access, looks up the name in the columns.
diff --git a/modin/pandas/series.py b/modin/pandas/series.py
--- a/modin/pandas/series.py
+++ b/modin/pandas/series.py
@@ -31,6 +31,7 @@
 from typing import Union, Optional, Hashable, TYPE_CHECKING, IO
 import warnings
 
+from modin.logging import disable_logging
 from modin.utils import (
     _inherit_docstrings,
     to_pandas,
@@ -294,6 +295,7 @@ def __floordiv__(self, right):
     def __rfloordiv__(self, right):
         return self.rfloordiv(right)
 
+    @disable_logging
     def __getattr__(self, key):
         """
         Return item identified by `key`.


Test patch: