File tree 2 files changed +53
-33
lines changed
2 files changed +53
-33
lines changed Original file line number Diff line number Diff line change @@ -444,46 +444,46 @@ def _view_is_safe(oldtype, newtype):
444
444
}
445
445
_pep3118_standard_typechars = '' .join (_pep3118_standard_map .keys ())
446
446
447
- def _dtype_from_pep3118 (spec ):
448
447
449
- class Stream (object ):
450
- def __init__ (self , s ):
451
- self .s = s
452
- self .byteorder = '@'
448
+ class _Stream (object ):
449
+ def __init__ (self , s ):
450
+ self .s = s
451
+ self .byteorder = '@'
453
452
454
- def advance (self , n ):
455
- res = self .s [:n ]
456
- self .s = self .s [n :]
457
- return res
453
+ def advance (self , n ):
454
+ res = self .s [:n ]
455
+ self .s = self .s [n :]
456
+ return res
458
457
459
- def consume (self , c ):
460
- if self .s [:len (c )] == c :
461
- self .advance (len (c ))
462
- return True
463
- return False
464
-
465
- def consume_until (self , c ):
466
- if callable (c ):
467
- i = 0
468
- while i < len (self .s ) and not c (self .s [i ]):
469
- i = i + 1
470
- return self .advance (i )
471
- else :
472
- i = self .s .index (c )
473
- res = self .advance (i )
474
- self .advance (len (c ))
475
- return res
458
+ def consume (self , c ):
459
+ if self .s [:len (c )] == c :
460
+ self .advance (len (c ))
461
+ return True
462
+ return False
476
463
477
- @property
478
- def next (self ):
479
- return self .s [0 ]
464
+ def consume_until (self , c ):
465
+ if callable (c ):
466
+ i = 0
467
+ while i < len (self .s ) and not c (self .s [i ]):
468
+ i = i + 1
469
+ return self .advance (i )
470
+ else :
471
+ i = self .s .index (c )
472
+ res = self .advance (i )
473
+ self .advance (len (c ))
474
+ return res
480
475
481
- def __bool__ ( self ):
482
- return bool (self . s )
483
- __nonzero__ = __bool__
476
+ @ property
477
+ def next (self ):
478
+ return self . s [ 0 ]
484
479
485
- stream = Stream (spec )
480
+ def __bool__ (self ):
481
+ return bool (self .s )
482
+ __nonzero__ = __bool__
486
483
484
+
485
+ def _dtype_from_pep3118 (spec ):
486
+ stream = _Stream (spec )
487
487
dtype , align = __dtype_from_pep3118 (stream , is_subdtype = False )
488
488
return dtype
489
489
Original file line number Diff line number Diff line change @@ -170,3 +170,23 @@ def check(x):
170
170
check (as_array (pointer (c_array ), shape = ()))
171
171
check (as_array (pointer (c_array [0 ]), shape = (2 ,)))
172
172
check (as_array (pointer (c_array [0 ][0 ]), shape = (2 , 3 )))
173
+
174
+ def test_reference_cycles (self ):
175
+ # related to gh-6511
176
+ import ctypes
177
+
178
+ # create array to work with
179
+ # don't use int/long to avoid running into bpo-10746
180
+ N = 100
181
+ a = np .arange (N , dtype = np .short )
182
+
183
+ # get pointer to array
184
+ pnt = np .ctypeslib .as_ctypes (a )
185
+
186
+ with np .testing .assert_no_gc_cycles ():
187
+ # decay the array above to a pointer to its first element
188
+ newpnt = ctypes .cast (pnt , ctypes .POINTER (ctypes .c_short ))
189
+ # and construct an array using this data
190
+ b = np .ctypeslib .as_array (newpnt , (N ,))
191
+ # now delete both, which should cleanup both objects
192
+ del newpnt , b
You can’t perform that action at this time.
0 commit comments