Skip to content

Commit b41ef8f

Browse files
author
Nick Eubank
committed
Add back reference to origin df to protect against broken chains of views
1 parent 8cf0bbd commit b41ef8f

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

pandas/core/generic.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class NDFrame(PandasObject):
8585
'is_copy', '_subtyp', '_index',
8686
'_default_kind', '_default_fill_value', '_metadata',
8787
'__array_struct__', '__array_interface__', '_children',
88-
'_is_column_view']
88+
'_is_column_view', '_original_parent']
8989
_internal_names_set = set(_internal_names)
9090
_accessors = frozenset([])
9191
_metadata = []
@@ -109,6 +109,7 @@ def __init__(self, data, axes=None, copy=False, dtype=None,
109109
object.__setattr__(self, '_item_cache', {})
110110
object.__setattr__(self, '_children', weakref.WeakValueDictionary())
111111
object.__setattr__(self, '_is_column_view', False)
112+
object.__setattr__(self, '_original_parent', weakref.WeakValueDictionary())
112113

113114

114115
def _validate_dtype(self, dtype):
@@ -1242,7 +1243,11 @@ def _execute_copy_on_write(self):
12421243
def _add_to_children(self, view_to_append):
12431244
self._children[id(view_to_append)] = view_to_append
12441245

1245-
1246+
if len(self._original_parent) is 0:
1247+
view_to_append._original_parent['parent'] = self
1248+
else:
1249+
self._original_parent['parent']._add_to_children(view_to_append)
1250+
12461251
def __delitem__(self, key):
12471252
"""
12481253
Delete item

pandas/tests/test_generic.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,23 @@ def test_copy_on_write(self):
18081808
self.assertTrue(v.loc[0] == -88)
18091809
self.assertTrue(v._is_view)
18101810

1811+
###
1812+
# Make sure that no problems if view created on view and middle-view
1813+
# gets deleted
1814+
#
1815+
df = pd.DataFrame({'col1':[1,2], 'col2':[3,4]})
1816+
v1 = df.loc[0:0,]
1817+
self.assertTrue(len(df._children)==1)
1818+
1819+
v2 = v1.loc[0:0,]
1820+
v2_copy = v2.copy()
1821+
self.assertTrue(len(df._children)==2)
1822+
1823+
del v1
1824+
1825+
df.loc[0:0, 'col1'] = -88
1826+
1827+
tm.assert_frame_equal(v2, v2_copy)
18111828

18121829

18131830

0 commit comments

Comments
 (0)