Skip to content

Commit 6eb7299

Browse files
committed
BUG: break reference cycle in Index._engine
Fixes #27585
1 parent 3b96ada commit 6eb7299

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

doc/source/whatsnew/v0.25.1.rst

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Other enhancements
2525
Bug fixes
2626
~~~~~~~~~
2727

28+
- Break reference cycle in :meth:`Index._engine` (:issue:`27585`)
29+
2830

2931
Categorical
3032
^^^^^^^^^^^

pandas/core/indexes/base.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import datetime, timedelta
2+
from functools import partial
23
import operator
34
from textwrap import dedent
45
from typing import Union
@@ -163,6 +164,13 @@ def _new_Index(cls, d):
163164
return cls.__new__(cls, **d)
164165

165166

167+
def _return_obj(obj):
168+
"""
169+
Helper function to avoid reference cycles created by lambdas / nested functions.
170+
"""
171+
return obj
172+
173+
166174
class Index(IndexOpsMixin, PandasObject):
167175
"""
168176
Immutable ndarray implementing an ordered, sliceable set. The basic object
@@ -687,7 +695,7 @@ def _cleanup(self):
687695
@cache_readonly
688696
def _engine(self):
689697
# property, for now, slow to look up
690-
return self._engine_type(lambda: self._ndarray_values, len(self))
698+
return self._engine_type(partial(_return_obj, self._ndarray_values), len(self))
691699

692700
# --------------------------------------------------------------------
693701
# Array-Like Methods

pandas/tests/indexes/test_base.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from collections import defaultdict
22
from datetime import datetime, timedelta
3+
import gc
34
from io import StringIO
45
import math
56
import operator
@@ -2424,6 +2425,13 @@ def test_deprecated_contains(self):
24242425
with tm.assert_produces_warning(FutureWarning):
24252426
index.contains(1)
24262427

2428+
def test_engine_reference_cycle(self):
2429+
# https://github.com/pandas-dev/pandas/issues/27585
2430+
index = pd.Index([1, 2, 3])
2431+
nrefs_pre = len(gc.get_referrers(index))
2432+
index._engine
2433+
assert len(gc.get_referrers(index)) == nrefs_pre
2434+
24272435

24282436
class TestMixedIntIndex(Base):
24292437
# Mostly the tests from common.py for which the results differ

0 commit comments

Comments
 (0)