-
-
Notifications
You must be signed in to change notification settings - Fork 18.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: Infinite recursion on inheritance and overloading __getattr__
in v2.1.0
#55120
Comments
@JoschD thanks a lot for the report! (and sorry for the slow response; I actually had looked at it earlier because I had a related PR (#54922) that might also fix this, but didn't get around to posting here) So your analysis is mostly correct I think. What changed in pandas (#53871) is that we no longer pass a Manager object to the subclass constructor (which you would pass to As a result of that, your I do have a PR that tries to fix this regression (#54922), but long term, you will also have to make some changes to your subclass implementation:
I tested that both options work with your example above, and they would look like: class TfsDataFrame(pd.DataFrame):
_metadata = ["headers"]
headers = None # <-- added line
def __init__(self, *args, **kwargs):
.... or class TfsDataFrame(pd.DataFrame):
_metadata = ["headers"]
....
@property
def _constructor(self):
return TfsDataFrame
def _constructor_from_mgr(self, mgr, axes):
obj = self._from_mgr(mgr, axes)
obj.headers = {}
return obj |
Hello @jorisvandenbossche , I hope you have a great day, may all your issues have easy-to-implement solutions like this :) Cheers! |
Pandas version checks
I have checked that this issue has not already been reported.
I have confirmed this bug exists on the latest version of pandas.
I have confirmed this bug exists on the main branch of pandas.
Reproducible Example
Issue Description
This is a reduced example of a
DataFrame
extension, that we have been using for years now and it worked fine until version2.0.3
(including), but broke with2.1.0
.From
2.1.0
the code above runs into an infinite recursion loop, asdf[["A", "B"]]
creates a newTfsDataFrame
(due to the_constructor
).In its
__init__
theargs[0]
is then already aTfsDataFrame
object butargs[0].headers
for some reason calls__getattr__()
as doesself.headers[name]
in the__getattr__()
function, causing the infinite recursion.This was not the case in the past, as
.headers
should be finding the attributeheaders
"directly", without even going to__getattr__()
.Interestingly,
are indeed working as intended.
This is the most direct recursion loop I could find, but actually with
2.1.0
we have experienced extended recursion loops, which can create infinite runtime.Expected Behavior
Should not end up in an infinite recursion.
As is the case e.g. in
pandas
version2.0.3
.Thank you very much for your help and your effort maintaining
pandas
.Its amazing set of features have made our work with measurement data much more comfortable and streamlined,
not to mention the highly increased readability of our code compared to anno BP (before pandas).
Installed Versions
INSTALLED VERSIONS
commit : ba1cccd
python : 3.9.7.final.0
python-bits : 64
OS : Linux
OS-release : 5.14.0-162.18.1.el9_1.x86_64
Version : #1 SMP PREEMPT_DYNAMIC Tue Feb 28 03:54:43 EST 2023
machine : x86_64
processor : x86_64
byteorder : little
LC_ALL : None
LANG : C.UTF-8
LOCALE : en_US.UTF-8
pandas : 2.1.0
numpy : 1.25.2
pytz : 2023.3
dateutil : 2.8.2
setuptools : 59.5.0
pip : 21.3.1
Cython : 0.29.35
pytest : 7.3.1
hypothesis : 6.75.8
sphinx : 6.2.1
blosc : None
feather : None
xlsxwriter : None
lxml.etree : None
html5lib : None
pymysql : None
psycopg2 : None
jinja2 : 3.1.2
IPython : 8.14.0
pandas_datareader : None
bs4 : None
bottleneck : None
dataframe-api-compat: None
fastparquet : None
fsspec : None
gcsfs : None
matplotlib : 3.7.1
numba : None
numexpr : 2.8.4
odfpy : None
openpyxl : None
pandas_gbq : None
pyarrow : None
pyreadstat : None
pyxlsb : None
s3fs : None
scipy : 1.11.2
sqlalchemy : None
tables : 3.8.0
tabulate : None
xarray : None
xlrd : None
zstandard : None
tzdata : 2023.3
qtpy : 2.3.1
pyqt5 : None
The text was updated successfully, but these errors were encountered: