Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r88895:ed147e0d8844
Date: 2016-12-06 11:00 +0100
http://bitbucket.org/pypy/pypy/changeset/ed147e0d8844/

Log:    hg merge default

diff --git a/pypy/interpreter/executioncontext.py 
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -534,6 +534,8 @@
 
     @jit.dont_look_inside
     def _run_finalizers(self):
+        # called by perform() when we have to "perform" this action,
+        # and also directly at the end of gc.collect).
         while True:
             w_obj = self.space.finalizer_queue.next_dead()
             if w_obj is None:
diff --git a/pypy/module/gc/interp_gc.py b/pypy/module/gc/interp_gc.py
--- a/pypy/module/gc/interp_gc.py
+++ b/pypy/module/gc/interp_gc.py
@@ -23,9 +23,18 @@
     # specifically rely on that.  This is similar to how, in CPython, an
     # explicit gc.collect() will invoke finalizers from cycles and fully
     # ignore the gc.disable() mode.
-    if not space.user_del_action.enabled_at_app_level:
+    temp_reenable = not space.user_del_action.enabled_at_app_level
+    if temp_reenable:
         enable_finalizers(space)
-        disable_finalizers(space)
+    try:
+        # fetch the pending finalizers from the queue, where they are
+        # likely to have been added by rgc.collect() above, and actually
+        # run them now.  This forces them to run before this function
+        # returns, and also always in the enable_finalizers() mode.
+        space.user_del_action._run_finalizers()
+    finally:
+        if temp_reenable:
+            disable_finalizers(space)
 
     return space.wrap(0)
 
diff --git a/pypy/module/gc/test/test_gc.py b/pypy/module/gc/test/test_gc.py
--- a/pypy/module/gc/test/test_gc.py
+++ b/pypy/module/gc/test/test_gc.py
@@ -70,6 +70,19 @@
         gc.enable()
         assert gc.isenabled()
 
+    def test_gc_collect_overrides_gc_disable(self):
+        import gc
+        deleted = []
+        class X(object):
+            def __del__(self):
+                deleted.append(1)
+        assert gc.isenabled()
+        gc.disable()
+        X()
+        gc.collect()
+        assert deleted == [1]
+        gc.enable()
+
 
 class AppTestGcDumpHeap(object):
     pytestmark = py.test.mark.xfail(run=False)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1779,22 +1779,19 @@
         lltype.free(l_utsbuf, flavor='raw')
 
 # These are actually macros on some/most systems
-c_makedev = external('makedev', [rffi.INT, rffi.INT], rffi.INT)
-c_major = external('major', [rffi.INT], rffi.INT)
-c_minor = external('minor', [rffi.INT], rffi.INT)
+c_makedev = external('makedev', [rffi.INT, rffi.INT], rffi.INT, macro=True)
+c_major = external('major', [rffi.INT], rffi.INT, macro=True)
+c_minor = external('minor', [rffi.INT], rffi.INT, macro=True)
 
 @replace_os_function('makedev')
-@jit.dont_look_inside
 def makedev(maj, min):
     return c_makedev(maj, min)
 
 @replace_os_function('major')
-@jit.dont_look_inside
 def major(dev):
     return c_major(dev)
 
 @replace_os_function('minor')
-@jit.dont_look_inside
 def minor(dev):
     return c_minor(dev)
 
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -281,6 +281,11 @@
     def test_isatty(self):
         assert rposix.isatty(-1) is False
 
+    def test_makedev(self):
+        dev = rposix.makedev(24, 7)
+        assert rposix.major(dev) == 24
+        assert rposix.minor(dev) == 7
+
 
 @py.test.mark.skipif("not hasattr(os, 'ttyname')")
 class TestOsExpect(ExpectTest):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to