[pypy-commit] pypy py3k: Update zipimport for the change in pyc format (fixes zipimport -A tests)

2016-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: py3k
Changeset: r84182:f8f5beaa6782
Date: 2016-05-04 01:23 +0100
http://bitbucket.org/pypy/pypy/changeset/f8f5beaa6782/

Log:Update zipimport for the change in pyc format (fixes zipimport -A
tests)

diff --git a/pypy/module/zipimport/interp_zipimport.py 
b/pypy/module/zipimport/interp_zipimport.py
--- a/pypy/module/zipimport/interp_zipimport.py
+++ b/pypy/module/zipimport/interp_zipimport.py
@@ -200,7 +200,8 @@
 timestamp = importing._get_long(buf[4:8])
 if not self.can_use_pyc(space, filename, magic, timestamp):
 return None
-buf = buf[8:] # XXX ugly copy, should use sequential read instead
+# zipimport ignores the size field
+buf = buf[12:] # XXX ugly copy, should use sequential read instead
 w_mod = w(Module(space, w(modname)))
 real_name = self.filename + os.path.sep + self.corr_zname(filename)
 space.setattr(w_mod, w('__loader__'), space.wrap(self))
@@ -305,8 +306,9 @@
 if not self.can_use_pyc(space, filename + ext,
 magic, timestamp):
 continue
+# zipimport ignores the size field
 code_w = importing.read_compiled_module(
-space, filename + ext, source[8:])
+space, filename + ext, source[12:])
 else:
 co_filename = self.make_co_filename(filename+ext)
 code_w = importing.parse_source_module(
@@ -327,7 +329,7 @@
 w_data = self.get_data(space, fname)
 # XXX CPython does not handle the coding cookie either.
 return space.call_method(w_data, "decode",
- space.wrap("utf-8")) 
+ space.wrap("utf-8"))
 else:
 found = True
 if found:
diff --git a/pypy/module/zipimport/test/test_zipimport.py 
b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -93,8 +93,9 @@
 def get_file():
 return __file__"""
 data = marshal.dumps(compile(source, 'uuu.py', 'exec'))
+size = len(data).to_bytes(4, 'little', signed=True)
 
-return imp.get_magic() + mtimeb + data
+return imp.get_magic() + mtimeb + size + data
 
 def w_now_in_the_future(self, delta):
 self.now += delta
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Give better error messages for '%d' % 'not an int' (and %x, %o).

2016-05-03 Thread devin.jeanpierre
Author: Devin Jeanpierre 
Branch: 
Changeset: r84181:75c1b672983d
Date: 2016-05-03 16:19 -0700
http://bitbucket.org/pypy/pypy/changeset/75c1b672983d/

Log:Give better error messages for '%d' % 'not an int' (and %x, %o).

Before: TypeError: unsupported operand type for long(): 'str' After:
TypeError: %d format: a number is required, not str (same as
CPython).

diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -551,7 +551,15 @@
 try:
 w_value = maybe_int(space, w_value)
 except OperationError:
-w_value = space.long(w_value)
+try:
+w_value = space.long(w_value)
+except OperationError as operr:
+if operr.match(space, space.w_TypeError):
+raise oefmt(
+space.w_TypeError,
+"%s format: a number is required, not %T", fmt, 
w_value)
+else:
+raise
 try:
 value = space.int_w(w_value)
 return fmt % (value,)
diff --git a/pypy/objspace/std/test/test_bytesobject.py 
b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -103,6 +103,12 @@
 assert result == "a foo b"
 assert isinstance(result, cls)
 
+def test_format_wrongtype(self):
+for int_format in '%d', '%o', '%x':
+exc_info = raises(TypeError, int_format.__mod__, '123')
+expected = int_format + ' format: a number is required, not str'
+assert str(exc_info.value) == expected
+
 def test_split(self):
 assert "".split() == []
 assert "".split('x') == ['']
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy gc-del-3: fix the XXXXXX

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84178:3502aa349b77
Date: 2016-05-03 21:50 +0200
http://bitbucket.org/pypy/pypy/changeset/3502aa349b77/

Log:fix the XX

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -33,30 +33,26 @@
 self.config = config
 assert isinstance(translated_to_c, bool)
 self.translated_to_c = translated_to_c
+self._finalizer_queue_objects = []
 
 def setup(self):
 # all runtime mutable values' setup should happen here
 # and in its overriden versions! for the benefit of test_transformed_gc
 self.finalizer_lock = False
-if we_are_translated():
-XX
-else:
-self._finalizer_queue_objects = []# XXX FIX ME
 
 def register_finalizer_index(self, fq, index):
+"NOT_RPYTHON"
 while len(self._finalizer_queue_objects) <= index:
 self._finalizer_queue_objects.append(None)
 if self._finalizer_queue_objects[index] is None:
 fq._reset()
+fq._gc_deque = self.AddressDeque()
 self._finalizer_queue_objects[index] = fq
 else:
 assert self._finalizer_queue_objects[index] is fq
 
-def add_finalizer_to_run(self, fq_index, obj):
-if we_are_translated():
-XX
-else:
-self._finalizer_queue_objects[fq_index]._queue.append(obj)
+def mark_finalizer_to_run(self, fq_index, obj):
+self._finalizer_queue_objects[fq_index]._gc_deque.append(obj)
 
 def post_setup(self):
 # More stuff that needs to be initialized when the GC is already
@@ -65,7 +61,7 @@
 self.DEBUG = env.read_from_env('PYPY_GC_DEBUG')
 
 def _teardown(self):
-pass
+self._finalizer_queue_objects = [] # for tests
 
 def can_optimize_clean_setarrayitems(self):
 return True # False in case of card marking
@@ -345,11 +341,12 @@
 enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
 def enum_pending_finalizers(self, callback, arg):
-if we_are_translated():
-XX#. foreach(callback, arg)
-for fq in self._finalizer_queue_objects:
-for obj in fq._queue:
-callback(obj, arg)
+i = 0
+while i < len(self._finalizer_queue_objects):
+fq = self._finalizer_queue_objects[i]
+if fq is not None:
+fq._gc_deque.foreach(callback, arg)
+i += 1
 enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
 
 def debug_check_consistency(self):
@@ -395,11 +392,12 @@
 return  # the outer invocation of execute_finalizers() will do it
 self.finalizer_lock = True
 try:
-if we_are_translated():
-XX
-for i, fq in enumerate(self._finalizer_queue_objects):
-if len(fq._queue) > 0:
+i = 0
+while i < len(self._finalizer_queue_objects):
+fq = self._finalizer_queue_objects[i]
+if fq is not None and fq._gc_deque.non_empty():
 self.finalizer_trigger(i)
+i += 1
 finally:
 self.finalizer_lock = False
 
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2679,7 +2679,7 @@
 if state == 2:
 from rpython.rtyper.lltypesystem import rffi
 fq_index = rffi.cast(lltype.Signed, fq_nr)
-self.add_finalizer_to_run(fq_index, x)
+self.mark_finalizer_to_run(fq_index, x)
 # we must also fix the state from 2 to 3 here, otherwise
 # we leave the GCFLAG_FINALIZATION_ORDERING bit behind
 # which will confuse the next collection
diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py
--- a/rpython/memory/gcwrapper.py
+++ b/rpython/memory/gcwrapper.py
@@ -215,8 +215,9 @@
 
 def gc_fq_next_dead(self, fq_tag):
 fq, _ = self.get_finalizer_queue_index(fq_tag)
-addr = fq.next_dead()
-if addr is None:
+if fq._gc_deque.non_empty():
+addr = fq._gc_deque.popleft()
+else:
 addr = llmemory.NULL
 return llmemory.cast_adr_to_ptr(addr, rclass.OBJECTPTR)
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy gc-del-3: fix

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84180:83a6a474a555
Date: 2016-05-03 22:51 +0200
http://bitbucket.org/pypy/pypy/changeset/83a6a474a555/

Log:fix

diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py
--- a/rpython/memory/gcwrapper.py
+++ b/rpython/memory/gcwrapper.py
@@ -211,17 +211,17 @@
 assert index == len(self.finalizer_queues)
 self.finalizer_queue_indexes[fq] = index
 self.finalizer_queues.append(fq)
-return (fq, index)
+self.gc.register_finalizer_index(fq, index)
+return index
 
 def gc_fq_next_dead(self, fq_tag):
-fq, index = self.get_finalizer_queue_index(fq_tag)
+index = self.get_finalizer_queue_index(fq_tag)
 return lltype.cast_opaque_ptr(rclass.OBJECTPTR,
   self.gc.finalizer_next_dead(index))
 
 def gc_fq_register(self, fq_tag, ptr):
-fq, index = self.get_finalizer_queue_index(fq_tag)
+index = self.get_finalizer_queue_index(fq_tag)
 ptr = lltype.cast_opaque_ptr(llmemory.GCREF, ptr)
-self.gc.register_finalizer_index(fq, index)
 self.gc.register_finalizer(index, ptr)
 
 # 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy gc-del-3: in-progress

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84179:979bc16d2cc9
Date: 2016-05-03 22:48 +0200
http://bitbucket.org/pypy/pypy/changeset/979bc16d2cc9/

Log:in-progress

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -6,6 +6,9 @@
 from rpython.memory.support import DEFAULT_CHUNK_SIZE
 from rpython.memory.support import get_address_stack, get_address_deque
 from rpython.memory.support import AddressDict, null_address_dict
+from rpython.memory.support import make_list_of_nongc_instances
+from rpython.memory.support import list_set_nongc_instance
+from rpython.memory.support import list_get_nongc_instance
 from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage
 
 TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed),
@@ -33,7 +36,7 @@
 self.config = config
 assert isinstance(translated_to_c, bool)
 self.translated_to_c = translated_to_c
-self._finalizer_queue_objects = []
+self.run_finalizer_queues = make_list_of_nongc_instances(0)
 
 def setup(self):
 # all runtime mutable values' setup should happen here
@@ -42,17 +45,23 @@
 
 def register_finalizer_index(self, fq, index):
 "NOT_RPYTHON"
-while len(self._finalizer_queue_objects) <= index:
-self._finalizer_queue_objects.append(None)
-if self._finalizer_queue_objects[index] is None:
-fq._reset()
-fq._gc_deque = self.AddressDeque()
-self._finalizer_queue_objects[index] = fq
-else:
-assert self._finalizer_queue_objects[index] is fq
+if len(self.run_finalizer_queues) <= index:
+array = make_list_of_nongc_instances(index + 1)
+for i in range(len(self.run_finalizer_queues)):
+array[i] = self.run_finalizer_queues[i]
+self.run_finalizer_queues = array
+#
+fdold = list_get_nongc_instance(self.AddressDeque,
+   self.run_finalizer_queues, index)
+list_set_nongc_instance(self.run_finalizer_queues, index,
+self.AddressDeque())
+if fdold is not None:
+fdold.delete()
 
 def mark_finalizer_to_run(self, fq_index, obj):
-self._finalizer_queue_objects[fq_index]._gc_deque.append(obj)
+fdeque = list_get_nongc_instance(self.AddressDeque,
+ self.run_finalizer_queues, fq_index)
+fdeque.append(obj)
 
 def post_setup(self):
 # More stuff that needs to be initialized when the GC is already
@@ -61,7 +70,7 @@
 self.DEBUG = env.read_from_env('PYPY_GC_DEBUG')
 
 def _teardown(self):
-self._finalizer_queue_objects = [] # for tests
+pass
 
 def can_optimize_clean_setarrayitems(self):
 return True # False in case of card marking
@@ -342,10 +351,11 @@
 
 def enum_pending_finalizers(self, callback, arg):
 i = 0
-while i < len(self._finalizer_queue_objects):
-fq = self._finalizer_queue_objects[i]
-if fq is not None:
-fq._gc_deque.foreach(callback, arg)
+while i < len(self.run_finalizer_queues):
+fdeque = list_get_nongc_instance(self.AddressDeque,
+ self.run_finalizer_queues, i)
+if fdeque is not None:
+fdeque.foreach(callback, arg)
 i += 1
 enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
 
@@ -393,14 +403,24 @@
 self.finalizer_lock = True
 try:
 i = 0
-while i < len(self._finalizer_queue_objects):
-fq = self._finalizer_queue_objects[i]
-if fq is not None and fq._gc_deque.non_empty():
+while i < len(self.run_finalizer_queues):
+fdeque = list_get_nongc_instance(self.AddressDeque,
+ self.run_finalizer_queues, i)
+if fdeque is not None and fdeque.non_empty():
 self.finalizer_trigger(i)
 i += 1
 finally:
 self.finalizer_lock = False
 
+def finalizer_next_dead(self, fq_index):
+fdeque = list_get_nongc_instance(self.AddressDeque,
+ self.run_finalizer_queues, fq_index)
+if fdeque.non_empty():
+obj = fdeque.popleft()
+else:
+obj = llmemory.NULL
+return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+
 
 class MovingGCBase(GCBase):
 moving_gc = True
diff --git a/rpython/memory/gctransform/framework.py 
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -255,6 +255,7 @@
 
 self.layoutbuilder.encode_type_shapes_now()
 

[pypy-commit] pypy gc-del-3: hg merge default

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84177:769877b8ea60
Date: 2016-05-03 21:33 +0200
http://bitbucket.org/pypy/pypy/changeset/769877b8ea60/

Log:hg merge default

diff too long, truncating to 2000 out of 10007 lines

diff --git a/TODO b/TODO
deleted file mode 100644
--- a/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-* reduce size of generated c code from slot definitions in slotdefs.
-* remove broken DEBUG_REFCOUNT from pyobject.py
diff --git a/pypy/doc/index-of-release-notes.rst 
b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -6,6 +6,7 @@
 
 .. toctree::
 
+   release-5.1.1.rst
release-5.1.0.rst
release-5.0.1.rst
release-5.0.0.rst
diff --git a/pypy/doc/tool/mydot.py b/pypy/doc/tool/mydot.py
--- a/pypy/doc/tool/mydot.py
+++ b/pypy/doc/tool/mydot.py
@@ -68,7 +68,7 @@
   help="output format")
 options, args = parser.parse_args()
 if len(args) != 1:
-raise ValueError, "need exactly one argument"
+raise ValueError("need exactly one argument")
 epsfile = process_dot(py.path.local(args[0]))
 if options.format == "ps" or options.format == "eps":
 print epsfile.read()
diff --git a/pypy/goal/targetpypystandalone.py 
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -63,7 +63,7 @@
 ##from pypy.interpreter import main, interactive, error
 ##con = interactive.PyPyConsole(space)
 ##con.interact()
-except OperationError, e:
+except OperationError as e:
 debug("OperationError:")
 debug(" operror-type: " + e.w_type.getname(space))
 debug(" operror-value: " + 
space.str_w(space.str(e.get_w_value(space
@@ -71,7 +71,7 @@
 finally:
 try:
 space.finish()
-except OperationError, e:
+except OperationError as e:
 debug("OperationError:")
 debug(" operror-type: " + e.w_type.getname(space))
 debug(" operror-value: " + 
space.str_w(space.str(e.get_w_value(space
@@ -115,7 +115,7 @@
 space.wrap('__import__'))
 space.call_function(import_, space.wrap('site'))
 return rffi.cast(rffi.INT, 0)
-except OperationError, e:
+except OperationError as e:
 if verbose:
 debug("OperationError:")
 debug(" operror-type: " + e.w_type.getname(space))
@@ -167,7 +167,7 @@
 sys._pypy_execute_source.append(glob)
 exec stmt in glob
 """)
-except OperationError, e:
+except OperationError as e:
 debug("OperationError:")
 debug(" operror-type: " + e.w_type.getname(space))
 debug(" operror-value: " + 
space.str_w(space.str(e.get_w_value(space
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -84,7 +84,7 @@
 space = self.space
 try:
 args_w = space.fixedview(w_stararg)
-except OperationError, e:
+except OperationError as e:
 if e.match(space, space.w_TypeError):
 raise oefmt(space.w_TypeError,
 "argument after * must be a sequence, not %T",
@@ -111,7 +111,7 @@
 else:
 try:
 w_keys = space.call_method(w_starstararg, "keys")
-except OperationError, e:
+except OperationError as e:
 if e.match(space, space.w_AttributeError):
 raise oefmt(space.w_TypeError,
 "argument after ** must be a mapping, not %T",
@@ -134,11 +134,11 @@
 """The simplest argument parsing: get the 'argcount' arguments,
 or raise a real ValueError if the length is wrong."""
 if self.keywords:
-raise ValueError, "no keyword arguments expected"
+raise ValueError("no keyword arguments expected")
 if len(self.arguments_w) > argcount:
-raise ValueError, "too many arguments (%d expected)" % argcount
+raise ValueError("too many arguments (%d expected)" % argcount)
 elif len(self.arguments_w) < argcount:
-raise ValueError, "not enough arguments (%d expected)" % argcount
+raise ValueError("not enough arguments (%d expected)" % argcount)
 return self.arguments_w
 
 def firstarg(self):
@@ -279,7 +279,7 @@
 try:
 self._match_signature(w_firstarg,
   scope_w, signature, defaults_w, 0)
-except ArgErr, e:
+except ArgErr as e:
 raise oefmt(self.space.w_TypeError, "%s() %s", fnname, e.getmsg())
 return 

[pypy-commit] pypy gc-del-3: Pass all of test_incminimark_gc

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84176:a12a83151bb7
Date: 2016-05-03 21:31 +0200
http://bitbucket.org/pypy/pypy/changeset/a12a83151bb7/

Log:Pass all of test_incminimark_gc

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2587,20 +2587,23 @@
 # --
 # Finalizers
 
+def call_destructor(self, obj):
+destructor = self.destructor_or_custom_trace(self.get_type_id(obj))
+ll_assert(bool(destructor), "no destructor found")
+destructor(obj)
+
 def deal_with_young_objects_with_destructors(self):
 """We can reasonably assume that destructors don't do
 anything fancy and *just* call them. Among other things
 they won't resurrect objects
 """
-while self.young_objects_with_light_finalizers.non_empty():
-obj = self.young_objects_with_light_finalizers.pop()
+while self.young_objects_with_destructors.non_empty():
+obj = self.young_objects_with_destructors.pop()
 if not self.is_forwarded(obj):
-finalizer = self.getlightfinalizer(self.get_type_id(obj))
-ll_assert(bool(finalizer), "no light finalizer found")
-finalizer(obj)
+self.call_destructor(obj)
 else:
 obj = self.get_forwarding_address(obj)
-self.old_objects_with_light_finalizers.append(obj)
+self.old_objects_with_destructors.append(obj)
 
 def deal_with_old_objects_with_destructors(self):
 """We can reasonably assume that destructors don't do
@@ -2608,18 +2611,16 @@
 they won't resurrect objects
 """
 new_objects = self.AddressStack()
-while self.old_objects_with_light_finalizers.non_empty():
-obj = self.old_objects_with_light_finalizers.pop()
+while self.old_objects_with_destructors.non_empty():
+obj = self.old_objects_with_destructors.pop()
 if self.header(obj).tid & GCFLAG_VISITED:
 # surviving
 new_objects.append(obj)
 else:
 # dying
-finalizer = self.getlightfinalizer(self.get_type_id(obj))
-ll_assert(bool(finalizer), "no light finalizer found")
-finalizer(obj)
-self.old_objects_with_light_finalizers.delete()
-self.old_objects_with_light_finalizers = new_objects
+self.call_destructor(obj)
+self.old_objects_with_destructors.delete()
+self.old_objects_with_destructors = new_objects
 
 def deal_with_young_objects_with_finalizers(self):
 while self.probably_young_objects_with_finalizers.non_empty():
diff --git a/rpython/memory/test/gc_test_base.py 
b/rpython/memory/test/gc_test_base.py
--- a/rpython/memory/test/gc_test_base.py
+++ b/rpython/memory/test/gc_test_base.py
@@ -282,7 +282,7 @@
 llop.gc__collect(lltype.Void)
 aid = b.a.id
 b.a = None
-# check that __del__ is not called again
+# check that finalizer_trigger() is not called again
 llop.gc__collect(lltype.Void)
 llop.gc__collect(lltype.Void)
 return b.num_deleted * 10 + aid + 100 * (b.a is None)
@@ -409,23 +409,32 @@
 res = self.interpret(f, [])
 assert res
 
-def test_cycle_with_weakref_and_del(self):
+def test_cycle_with_weakref_and_finalizer(self):
 import weakref
 class A(object):
 count = 0
 a = A()
 class B(object):
-def __del__(self):
-# when __del__ is called, the weakref to c should be dead
-if self.ref() is None:
-a.count += 10  # ok
-else:
-a.count = 666  # not ok
+pass
+class FQ(rgc.FinalizerQueue):
+Class = B
+def finalizer_trigger(self):
+while True:
+b = self.next_dead()
+if b is None:
+break
+# when we are here, the weakref to c should be dead
+if b.ref() is None:
+a.count += 10  # ok
+else:
+a.count = 666  # not ok
+fq = FQ()
 class C(object):
 pass
 def g():
 c = C()
 c.b = B()
+fq.register_finalizer(c.b)
 ref = weakref.ref(c)
 c.b.ref = ref
 return ref
@@ -445,23 +454,32 @@
 a = A()
 expected_invalid = self.WREF_IS_INVALID_BEFORE_DEL_IS_CALLED
 class B(object):
-def __del__(self):
-# when __del__ is called, the weakref to myself is still valid
+pass
+class 

[pypy-commit] pypy gc-del-3: Pass test_incminimark_gc -k test_finalizer

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84175:270bb3186930
Date: 2016-05-03 21:18 +0200
http://bitbucket.org/pypy/pypy/changeset/270bb3186930/

Log:Pass test_incminimark_gc -k test_finalizer

diff --git a/rpython/memory/test/gc_test_base.py 
b/rpython/memory/test/gc_test_base.py
--- a/rpython/memory/test/gc_test_base.py
+++ b/rpython/memory/test/gc_test_base.py
@@ -192,18 +192,27 @@
 def __init__(self):
 self.id = b.nextid
 b.nextid += 1
-def __del__(self):
-b.num_deleted += 1
-C()
+fq.register_finalizer(self)
 class C(A):
-def __del__(self):
-b.num_deleted += 1
+pass
+class FQ(rgc.FinalizerQueue):
+Class = A
+def finalizer_trigger(self):
+while True:
+a = self.next_dead()
+if a is None:
+break
+b.num_deleted += 1
+if not isinstance(a, C):
+C()
+fq = FQ()
 def f(x):
 a = A()
 i = 0
 while i < x:
 i += 1
 a = A()
+a = None
 llop.gc__collect(lltype.Void)
 llop.gc__collect(lltype.Void)
 return b.num_deleted
@@ -220,15 +229,21 @@
 def __init__(self):
 self.id = b.nextid
 b.nextid += 1
-def __del__(self):
-b.num_deleted += 1
-llop.gc__collect(lltype.Void)
+fq.register_finalizer(self)
+class FQ(rgc.FinalizerQueue):
+Class = A
+def finalizer_trigger(self):
+while self.next_dead() is not None:
+b.num_deleted += 1
+llop.gc__collect(lltype.Void)
+fq = FQ()
 def f(x):
 a = A()
 i = 0
 while i < x:
 i += 1
 a = A()
+a = None
 llop.gc__collect(lltype.Void)
 llop.gc__collect(lltype.Void)
 return b.num_deleted
@@ -245,15 +260,24 @@
 def __init__(self):
 self.id = b.nextid
 b.nextid += 1
-def __del__(self):
-b.num_deleted += 1
-b.a = self
+fq.register_finalizer(self)
+class FQ(rgc.FinalizerQueue):
+Class = A
+def finalizer_trigger(self):
+while True:
+a = self.next_dead()
+if a is None:
+break
+b.num_deleted += 1
+b.a = a
+fq = FQ()
 def f(x):
 a = A()
 i = 0
 while i < x:
 i += 1
 a = A()
+a = None
 llop.gc__collect(lltype.Void)
 llop.gc__collect(lltype.Void)
 aid = b.a.id
@@ -320,7 +344,7 @@
 res = self.interpret(f, [])
 assert res
 
-def test_weakref_to_object_with_finalizer(self):
+def test_weakref_to_object_with_destructor(self):
 import weakref
 class A(object):
 count = 0
@@ -340,6 +364,32 @@
 res = self.interpret(f, [])
 assert res
 
+def test_weakref_to_object_with_finalizer(self):
+import weakref
+class A(object):
+count = 0
+a = A()
+class B(object):
+pass
+class FQ(rgc.FinalizerQueue):
+Class = B
+def finalizer_trigger(self):
+while self.next_dead() is not None:
+a.count += 1
+fq = FQ()
+def g():
+b = B()
+fq.register_finalizer(b)
+return weakref.ref(b)
+def f():
+ref = g()
+llop.gc__collect(lltype.Void)
+llop.gc__collect(lltype.Void)
+result = a.count == 1 and (ref() is None)
+return result
+res = self.interpret(f, [])
+assert res
+
 def test_bug_1(self):
 import weakref
 class B(object):
@@ -478,9 +528,14 @@
 def __init__(self):
 self.id = b.nextid
 b.nextid += 1
-def __del__(self):
-b.num_deleted += 1
-b.all.append(D(b.num_deleted))
+fq.register_finalizer(self)
+class FQ(rgc.FinalizerQueue):
+Class = A
+def finalizer_trigger(self):
+while self.next_dead() is not None:
+b.num_deleted += 1
+b.all.append(D(b.num_deleted))
+fq = FQ()
 class D(object):
 # make a big object that does not use malloc_varsize
 def __init__(self, x):
@@ -491,6 +546,7 @@

[pypy-commit] pypy py3k: Remove evil hack

2016-05-03 Thread rlamy
Author: Ronan Lamy 
Branch: py3k
Changeset: r84174:a7070af42caa
Date: 2016-05-03 19:15 +0100
http://bitbucket.org/pypy/pypy/changeset/a7070af42caa/

Log:Remove evil hack

diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -215,13 +215,6 @@
 MARSHAL_VERSION_FOR_PYC = 2
 
 def get_pyc_magic(space):
-# XXX CPython testing hack: delegate to the real imp.get_magic
-if not we_are_translated():
-if '__pypy__' not in space.builtin_modules:
-import struct
-magic = __import__('imp').get_magic()
-return struct.unpack('

[pypy-commit] pypy py3k: Update islice to not accept floats to match cpython and update own tests to match islice's reference-holding behavior in cpython.

2016-05-03 Thread marky1991
Author: Mark Young 
Branch: py3k
Changeset: r84170:acbc6e257771
Date: 2016-05-01 15:58 -0400
http://bitbucket.org/pypy/pypy/changeset/acbc6e257771/

Log:Update islice to not accept floats to match cpython and update own
tests to match islice's reference-holding behavior in cpython.

diff --git a/pypy/module/itertools/interp_itertools.py 
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -319,7 +319,7 @@
 def arg_int_w(self, w_obj, minimum, errormsg):
 space = self.space
 try:
-result = space.int_w(space.int(w_obj))# CPython allows floats 
as parameters
+result = space.int_w(w_obj)
 except OperationError, e:
 if e.async(space):
 raise
diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -198,11 +198,8 @@
 assert next(it) == x
 raises(StopIteration, next, it)
 
-# CPython implementation allows floats
-it = itertools.islice([1, 2, 3, 4, 5], 0.0, 3.0, 2.0)
-for x in [1, 3]:
-assert next(it) == x
-raises(StopIteration, next, it)
+#Do not allow floats
+raises(ValueError, itertools.islice, [1, 2, 3, 4, 5], 0.0, 3.0, 2.0)
 
 it = itertools.islice([1, 2, 3], 0, None)
 for x in [1, 2, 3]:
@@ -216,8 +213,6 @@
 assert list(itertools.islice(range(10), None,None)) == list(range(10))
 assert list(itertools.islice(range(10), None,None,None)) == 
list(range(10))
 
-# check source iterator is not referenced from islice()
-# after the latter has been exhausted
 import weakref
 for args in [(1,), (None,), (0, None, 2)]:
 it = (x for x in (1, 2, 3))
@@ -226,7 +221,7 @@
 assert wr() is not None
 list(it)  # exhaust the iterator
 import gc; gc.collect()
-assert wr() is None
+assert wr() is not None
 raises(StopIteration, next, it)
 
 def test_islice_dropitems_exact(self):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: Hopefully merged correctly.

2016-05-03 Thread marky1991
Author: Mark Young 
Branch: py3k
Changeset: r84172:230df15b48da
Date: 2016-05-03 10:36 -0400
http://bitbucket.org/pypy/pypy/changeset/230df15b48da/

Log:Hopefully merged correctly.

diff --git a/pypy/module/itertools/interp_itertools.py 
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -360,7 +360,7 @@
 def arg_int_w(self, w_obj, minimum, errormsg):
 space = self.space
 try:
-result = space.int_w(space.int(w_obj))# CPython allows floats 
as parameters
+result = space.int_w(w_obj)
 except OperationError as e:
 if e.async(space):
 raise
@@ -581,7 +581,7 @@
 space = self.space
 try:
 return space.next(w_iter)
-except OperationError as e:
+except OperationError, e:
 if not e.match(space, space.w_StopIteration):
 raise
 self.active -= 1
diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -199,11 +199,8 @@
 assert next(it) == x
 raises(StopIteration, next, it)
 
-# CPython implementation allows floats
-it = itertools.islice([1, 2, 3, 4, 5], 0.0, 3.0, 2.0)
-for x in [1, 3]:
-assert next(it) == x
-raises(StopIteration, next, it)
+# Do not allow floats
+raises(ValueError, itertools.islice, [1, 2, 3, 4, 5], 0.0, 3.0, 2.0)
 
 it = itertools.islice([1, 2, 3], 0, None)
 for x in [1, 2, 3]:
@@ -217,8 +214,6 @@
 assert list(itertools.islice(range(10), None,None)) == list(range(10))
 assert list(itertools.islice(range(10), None,None,None)) == 
list(range(10))
 
-# check source iterator is not referenced from islice()
-# after the latter has been exhausted
 import weakref
 for args in [(1,), (None,), (0, None, 2)]:
 it = (x for x in (1, 2, 3))
@@ -227,7 +222,7 @@
 assert wr() is not None
 list(it)  # exhaust the iterator
 import gc; gc.collect()
-assert wr() is None
+assert wr() is not None
 raises(StopIteration, next, it)
 
 def test_islice_dropitems_exact(self):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: Fix pep 8 issue.

2016-05-03 Thread marky1991
Author: Mark Young 
Branch: py3k
Changeset: r84171:6db07c7d7059
Date: 2016-05-02 06:53 -0400
http://bitbucket.org/pypy/pypy/changeset/6db07c7d7059/

Log:Fix pep 8 issue.

diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -198,7 +198,7 @@
 assert next(it) == x
 raises(StopIteration, next, it)
 
-#Do not allow floats
+# Do not allow floats
 raises(ValueError, itertools.islice, [1, 2, 3, 4, 5], 0.0, 3.0, 2.0)
 
 it = itertools.islice([1, 2, 3], 0, None)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy.org extradoc: update and rebuild

2016-05-03 Thread mattip
Author: Matti Picus 
Branch: extradoc
Changeset: r744:abd477cc44a9
Date: 2016-05-03 17:37 +0300
http://bitbucket.org/pypy/pypy.org/changeset/abd477cc44a9/

Log:update and rebuild

diff --git a/download.html b/download.html
--- a/download.html
+++ b/download.html
@@ -74,7 +74,7 @@
 performance improvements.
 We provide binaries for x86, ARM, and PPC Linux, Mac OS/X and Windows 
for:
 
-the Python2.7 compatible release  PyPy 5.1  
(http://doc.pypy.org/en/latest/release-5.1.0.html;>what's new in PyPy 
5.1?)
+the Python2.7 compatible release  PyPy 5.1.1 
 (http://doc.pypy.org/en/latest/release-5.1.0.html;>what's new in PyPy 
5.1? and http://doc.pypy.org/en/latest/release-5.1.1.html;>what's new in PyPy 
5.1.1? )
 the Python3.2.5 compatible release  PyPy3 2.4.0 
 (http://doc.pypy.org/en/latest/release-pypy3-2.4.0.html;>what's new in 
PyPy3 2.4.0?).
 the Python2.7 Software Transactional Memory special release  
PyPy-STM 2.5.1 (Linux x86-64 only)
 
@@ -116,18 +116,18 @@
 
 Python2.7 compatible PyPy 5.1
 
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-linux.tar.bz2;>Linux 
x86 binary (32bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-linux64.tar.bz2;>Linux
 x86-64 binary (64bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-linux-armhf-raspbian.tar.bz2;>ARM
 Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Raspbian) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-linux-armhf-raring.tar.bz2;>ARM
 Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Ubuntu Raring) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-linux-armel.tar.bz2;>ARM
 Softfloat Linux binary (ARMEL/gnueabi, tar.bz2,  Ubuntu Precise) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-osx64.tar.bz2;>Mac 
OS/X binary (64bit)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-linux.tar.bz2;>Linux 
x86 binary (32bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-linux64.tar.bz2;>Linux
 x86-64 binary (64bit, tar.bz2 built on Ubuntu 12.04 - 14.04) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-linux-armhf-raspbian.tar.bz2;>ARM
 Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Raspbian) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-linux-armhf-raring.tar.bz2;>ARM
 Hardfloat Linux binary (ARMHF/gnueabihf, tar.bz2, Ubuntu Raring) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-linux-armel.tar.bz2;>ARM
 Softfloat Linux binary (ARMEL/gnueabi, tar.bz2,  Ubuntu Precise) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-osx64.tar.bz2;>Mac 
OS/X binary (64bit)
 FreeBSD 9.2 x86 64 bit (hopefully availabe soon) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-win32.zip;>Windows 
binary (32bit) (you might need the VS 2008 runtime library
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-win32.zip;>Windows 
binary (32bit) (you might need the VS 2008 runtime library
 installer http://www.microsoft.com/en-us/download/details.aspx?id=5582;>vcredist_x86.exe.)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0++-ppc64.tar.bz2;>PowerPC
 PPC64 Linux binary (64bit big-endian, Fedora 20) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0+-ppc64le.tar.bz2;>PowerPC
 PPC64le Linux binary (64bit little-endian, Fedora 21) (see [1] below)
-https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-src.tar.bz2;>Source 
(tar.bz2); https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.0-src.zip;>Source 
(zip).  See below for more about the sources.
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1++-ppc64.tar.bz2;>PowerPC
 PPC64 Linux binary (64bit big-endian, Fedora 20) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1+-ppc64le.tar.bz2;>PowerPC
 PPC64le Linux binary (64bit little-endian, Fedora 21) (see [1] below)
+https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-src.tar.bz2;>Source 
(tar.bz2); https://bitbucket.org/pypy/pypy/downloads/pypy-5.1.1-src.zip;>Source 
(zip).  See below for more about the sources.
 https://bitbucket.org/pypy/pypy/downloads;>All our downloads, 
including previous versions.  We also have a
 http://buildbot.pypy.org/mirror/;>mirror, but please use only if you 
have troubles accessing the links above
 
@@ -196,7 +196,7 @@
 uncompressed, they run in-place.  For now you can uncompress them
 either somewhere in your home directory or, say, in /opt, and
 if you want, put a symlink from somewhere like
-/usr/local/bin/pypy to /path/to/pypy-5.1.0/bin/pypy.  Do
+/usr/local/bin/pypy to /path/to/pypy-5.1.1/bin/pypy.  Do
 not move or copy the executable pypy outside 
the tree  put
 a symlink to it, otherwise it will not find its libraries.
 
@@ -217,10 +217,7 @@
 If you have pip:
 
 pypy -m pip install 

[pypy-commit] pypy default: document branch

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r84169:4d09e9d8eb6e
Date: 2016-05-03 12:39 +0200
http://bitbucket.org/pypy/pypy/changeset/4d09e9d8eb6e/

Log:document branch

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -61,3 +61,8 @@
 calls PyXxx", we now silently acquire/release the GIL.  Helps with
 CPython C extension modules that call some PyXxx() functions without
 holding the GIL (arguably, they are theorically buggy).
+
+.. branch: cpyext-test-A
+
+Get the cpyext tests to pass with "-A" (i.e. when tested directly with
+CPython).
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy.org extradoc: update the values

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r743:71a15c30baf9
Date: 2016-05-03 12:40 +0200
http://bitbucket.org/pypy/pypy.org/changeset/71a15c30baf9/

Log:update the values

diff --git a/don1.html b/don1.html
--- a/don1.html
+++ b/don1.html
@@ -15,7 +15,7 @@
 
 

-   $63928 of $105000 (60.9%)
+   $63957 of $105000 (60.9%)


 
@@ -23,7 +23,7 @@
   
   This donation goes towards supporting Python 3 in 
PyPy.
   Current status:
-we have $8995 left
+we have $9021 left
   in the account. Read proposal
   
   
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy gc-del-3: still progressing, slowly

2016-05-03 Thread arigo
Author: Armin Rigo 
Branch: gc-del-3
Changeset: r84168:67a03224c02d
Date: 2016-05-03 09:26 +0200
http://bitbucket.org/pypy/pypy/changeset/67a03224c02d/

Log:still progressing, slowly

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -1,6 +1,7 @@
 from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, rffi
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rlib.debug import ll_assert
+from rpython.rlib.objectmodel import we_are_translated
 from rpython.memory.gcheader import GCHeaderBuilder
 from rpython.memory.support import DEFAULT_CHUNK_SIZE
 from rpython.memory.support import get_address_stack, get_address_deque
@@ -36,8 +37,26 @@
 def setup(self):
 # all runtime mutable values' setup should happen here
 # and in its overriden versions! for the benefit of test_transformed_gc
-self.finalizer_lock_count = 0
-self.run_finalizers = self.AddressDeque()
+self.finalizer_lock = False
+if we_are_translated():
+XX
+else:
+self._finalizer_queue_objects = []# XXX FIX ME
+
+def register_finalizer_index(self, fq, index):
+while len(self._finalizer_queue_objects) <= index:
+self._finalizer_queue_objects.append(None)
+if self._finalizer_queue_objects[index] is None:
+fq._reset()
+self._finalizer_queue_objects[index] = fq
+else:
+assert self._finalizer_queue_objects[index] is fq
+
+def add_finalizer_to_run(self, fq_index, obj):
+if we_are_translated():
+XX
+else:
+self._finalizer_queue_objects[fq_index]._queue.append(obj)
 
 def post_setup(self):
 # More stuff that needs to be initialized when the GC is already
@@ -60,6 +79,7 @@
 
 def set_query_functions(self, is_varsize, has_gcptr_in_varsize,
 is_gcarrayofgcptr,
+finalizer_trigger,
 destructor_or_custom_trace,
 offsets_to_gc_pointers,
 fixed_size, varsize_item_sizes,
@@ -73,6 +93,7 @@
 fast_path_tracing,
 has_gcptr,
 cannot_pin):
+self.finalizer_trigger = finalizer_trigger
 self.destructor_or_custom_trace = destructor_or_custom_trace
 self.is_varsize = is_varsize
 self.has_gcptr_in_varsize = has_gcptr_in_varsize
@@ -320,9 +341,17 @@
 callback2, attrname = _convert_callback_formats(callback)# :-/
 setattr(self, attrname, arg)
 self.root_walker.walk_roots(callback2, callback2, callback2)
-self.run_finalizers.foreach(callback, arg)
+self.enum_pending_finalizers(callback, arg)
 enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
+def enum_pending_finalizers(self, callback, arg):
+if we_are_translated():
+XX#. foreach(callback, arg)
+for fq in self._finalizer_queue_objects:
+for obj in fq._queue:
+callback(obj, arg)
+enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
+
 def debug_check_consistency(self):
 """To use after a collection.  If self.DEBUG is set, this
 enumerates all roots and traces all objects to check if we didn't
@@ -362,17 +391,17 @@
 pass
 
 def execute_finalizers(self):
-self.finalizer_lock_count += 1
+if self.finalizer_lock:
+return  # the outer invocation of execute_finalizers() will do it
+self.finalizer_lock = True
 try:
-while self.run_finalizers.non_empty():
-if self.finalizer_lock_count > 1:
-# the outer invocation of execute_finalizers() will do it
-break
-obj = self.run_finalizers.popleft()
-finalizer = self.getfinalizer(self.get_type_id(obj))
-finalizer(obj)
+if we_are_translated():
+XX
+for i, fq in enumerate(self._finalizer_queue_objects):
+if len(fq._queue) > 0:
+self.finalizer_trigger(i)
 finally:
-self.finalizer_lock_count -= 1
+self.finalizer_lock = False
 
 
 class MovingGCBase(GCBase):
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2422,7 +2422,7 @@
 #
 # If we are in an inner collection caused by a call to a finalizer,
 # the 'run_finalizers' objects also need to be kept alive.
-self.run_finalizers.foreach(self._collect_obj, None)
+self.enum_pending_finalizers(self._collect_obj, None)
 
 def enumerate_all_roots(self,