File tree Expand file tree Collapse file tree 2 files changed +19
-1
lines changed Expand file tree Collapse file tree 2 files changed +19
-1
lines changed Original file line number Diff line number Diff line change 10
10
import sys
11
11
import itertools
12
12
import warnings
13
+ import weakref
13
14
from operator import itemgetter
14
15
15
16
from cPickle import load as _cload , loads
@@ -108,7 +109,8 @@ class BagObj(object):
108
109
109
110
"""
110
111
def __init__ (self , obj ):
111
- self ._obj = obj
112
+ # Use weakref to make NpzFile objects collectable by refcount
113
+ self ._obj = weakref .proxy (obj )
112
114
def __getattribute__ (self , key ):
113
115
try :
114
116
return object .__getattribute__ (self , '_obj' )[key ]
@@ -212,6 +214,7 @@ def close(self):
212
214
if self .fid is not None :
213
215
self .fid .close ()
214
216
self .fid = None
217
+ self .f = None # break reference cycle
215
218
216
219
def __del__ (self ):
217
220
self .close ()
Original file line number Diff line number Diff line change 6
6
import time
7
7
from datetime import datetime
8
8
import warnings
9
+ import gc
9
10
from numpy .testing .utils import WarningManager
10
11
11
12
import numpy as np
@@ -1525,6 +1526,20 @@ def test_npzfile_dict():
1525
1526
1526
1527
assert_ ('x' in list (z .iterkeys ()))
1527
1528
1529
+ def test_load_refcount ():
1530
+ # Check that objects returned by np.load are directly freed based on
1531
+ # their refcount, rather than needing the gc to collect them.
1532
+
1533
+ f = StringIO ()
1534
+ np .savez (f , [1 , 2 , 3 ])
1535
+ f .seek (0 )
1536
+
1537
+ gc .collect ()
1538
+ n_before = len (gc .get_objects ())
1539
+ np .load (f )
1540
+ n_after = len (gc .get_objects ())
1541
+
1542
+ assert_equal (n_before , n_after )
1528
1543
1529
1544
if __name__ == "__main__" :
1530
1545
run_module_suite ()
You can’t perform that action at this time.
0 commit comments