[pypy-commit] pypy gc-hooks: chage the API: instead of using the ugly set_hook (and having to implement get_on_gc_*), we expose a hooks object on which we can simply get/set the various on_gc_* fields

antocuni pypy.commits at gmail.com
Thu Apr 5 08:53:19 EDT 2018


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: gc-hooks
Changeset: r94250:47b121de440b
Date: 2018-04-05 14:28 +0200
http://bitbucket.org/pypy/pypy/changeset/47b121de440b/

Log:	chage the API: instead of using the ugly set_hook (and having to
	implement get_on_gc_*), we expose a hooks object on which we can
	simply get/set the various on_gc_* fields

diff --git a/pypy/module/gc/__init__.py b/pypy/module/gc/__init__.py
--- a/pypy/module/gc/__init__.py
+++ b/pypy/module/gc/__init__.py
@@ -34,7 +34,7 @@
                 'get_typeids_z': 'referents.get_typeids_z',
                 'get_typeids_list': 'referents.get_typeids_list',
                 'GcRef': 'referents.W_GcRef',
-                'set_hooks': 'hook.set_hooks',
+                'hooks': 'space.fromcache(hook.W_AppLevelHooks)',
                 'GcCollectStepStats': 'hook.W_GcCollectStepStats',
                 })
         MixedModule.__init__(self, space, w_name)
diff --git a/pypy/module/gc/hook.py b/pypy/module/gc/hook.py
--- a/pypy/module/gc/hook.py
+++ b/pypy/module/gc/hook.py
@@ -4,14 +4,14 @@
 from rpython.rlib.rarithmetic import r_uint
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
 from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.typedef import TypeDef, interp_attrproperty
+from pypy.interpreter.typedef import TypeDef, interp_attrproperty, GetSetProperty
 from pypy.interpreter.executioncontext import AsyncAction
 
 class LowLevelGcHooks(GcHooks):
 
     def __init__(self, space):
         self.space = space
-        self.hooks = space.fromcache(AppLevelHooks)
+        self.hooks = space.fromcache(W_AppLevelHooks)
 
     def is_gc_minor_enabled(self):
         return self.hooks.gc_minor_enabled
@@ -47,7 +47,7 @@
         action.fire()
 
 
-class AppLevelHooks(object):
+class W_AppLevelHooks(W_Root):
 
     def __init__(self, space):
         self.space = space
@@ -58,26 +58,39 @@
         self.gc_collect_step = GcCollectStepHookAction(space)
         self.gc_collect = GcCollectHookAction(space)
 
-    def set_hooks(self, space, w_on_gc_minor, w_on_gc_collect_step,
-                  w_on_gc_collect):
-        self.gc_minor_enabled = not space.is_none(w_on_gc_minor)
-        self.gc_minor.w_callable = w_on_gc_minor
+    def descr_get_on_gc_minor(self, space):
+        return self.gc_minor.w_callable
+
+    def descr_set_on_gc_minor(self, space, w_obj):
+        self.gc_minor_enabled = not space.is_none(w_obj)
+        self.gc_minor.w_callable = w_obj
         self.gc_minor.fix_annotation()
-        #
-        self.gc_collect_step_enabled = not space.is_none(w_on_gc_collect_step)
-        self.gc_collect_step.w_callable = w_on_gc_collect_step
+
+    def descr_get_on_gc_collect_step(self, space):
+        return self.gc_collect_step.w_callable
+
+    def descr_set_on_gc_collect_step(self, space, w_obj):
+        self.gc_collect_step_enabled = not space.is_none(w_obj)
+        self.gc_collect_step.w_callable = w_obj
         self.gc_collect_step.fix_annotation()
-        #
-        self.gc_collect_enabled = not space.is_none(w_on_gc_collect)
-        self.gc_collect.w_callable = w_on_gc_collect
+
+    def descr_get_on_gc_collect(self, space):
+        return self.gc_collect.w_callable
+
+    def descr_set_on_gc_collect(self, space, w_obj):
+        self.gc_collect_enabled = not space.is_none(w_obj)
+        self.gc_collect.w_callable = w_obj
         self.gc_collect.fix_annotation()
 
 
 class GcMinorHookAction(AsyncAction):
-    w_callable = None
     total_memory_used = 0
     pinned_objects = 0
 
+    def __init__(self, space):
+        AsyncAction.__init__(self, space)
+        self.w_callable = space.w_None
+
     def fix_annotation(self):
         # the annotation of the class and its attributes must be completed
         # BEFORE we do the gc transform; this makes sure that everything is
@@ -93,10 +106,13 @@
 
 
 class GcCollectStepHookAction(AsyncAction):
-    w_callable = None
     oldstate = 0
     newstate = 0
 
+    def __init__(self, space):
+        AsyncAction.__init__(self, space)
+        self.w_callable = space.w_None
+
     def fix_annotation(self):
         # the annotation of the class and its attributes must be completed
         # BEFORE we do the gc transform; this makes sure that everything is
@@ -112,7 +128,6 @@
 
 
 class GcCollectHookAction(AsyncAction):
-    w_callable = None
     count = 0
     arenas_count_before = 0
     arenas_count_after = 0
@@ -120,6 +135,10 @@
     rawmalloc_bytes_before = 0
     rawmalloc_bytes_after = 0
 
+    def __init__(self, space):
+        AsyncAction.__init__(self, space)
+        self.w_callable = space.w_None
+
     def fix_annotation(self):
         # the annotation of the class and its attributes must be completed
         # BEFORE we do the gc transform; this makes sure that everything is
@@ -176,6 +195,22 @@
         d[name] = interp_attrproperty(name, cls=cls, wrapfn="newint")
     return d
 
+
+W_AppLevelHooks.typedef = TypeDef(
+    "GcHooks",
+    on_gc_minor = GetSetProperty(
+        W_AppLevelHooks.descr_get_on_gc_minor,
+        W_AppLevelHooks.descr_set_on_gc_minor),
+
+    on_gc_collect_step = GetSetProperty(
+        W_AppLevelHooks.descr_get_on_gc_collect_step,
+        W_AppLevelHooks.descr_set_on_gc_collect_step),
+
+    on_gc_collect = GetSetProperty(
+        W_AppLevelHooks.descr_get_on_gc_collect,
+        W_AppLevelHooks.descr_set_on_gc_collect),
+    )
+
 W_GcMinorStats.typedef = TypeDef(
     "GcMinorStats",
     **wrap_many_ints(W_GcMinorStats, (
@@ -205,14 +240,3 @@
         "rawmalloc_bytes_before",
         "rawmalloc_bytes_after"))
     )
-
-
- at unwrap_spec(w_on_gc_minor=WrappedDefault(None),
-             w_on_gc_collect_step=WrappedDefault(None),
-             w_on_gc_collect=WrappedDefault(None))
-def set_hooks(space, w_on_gc_minor=None,
-              w_on_gc_collect_step=None,
-              w_on_gc_collect=None):
-    hooks = space.fromcache(AppLevelHooks)
-    hooks.set_hooks(space, w_on_gc_minor, w_on_gc_collect_step, w_on_gc_collect)
-                                             
diff --git a/pypy/module/gc/test/test_hook.py b/pypy/module/gc/test/test_hook.py
--- a/pypy/module/gc/test/test_hook.py
+++ b/pypy/module/gc/test/test_hook.py
@@ -32,12 +32,18 @@
         cls.w_fire_gc_collect = space.wrap(interp2app(fire_gc_collect))
         cls.w_fire_many = space.wrap(interp2app(fire_many))
 
+    def test_default(self):
+        import gc
+        assert gc.hooks.on_gc_minor is None
+        assert gc.hooks.on_gc_collect_step is None
+        assert gc.hooks.on_gc_collect is None
+
     def test_on_gc_minor(self):
         import gc
         lst = []
         def on_gc_minor(stats):
             lst.append((stats.total_memory_used, stats.pinned_objects))
-        gc.set_hooks(on_gc_minor=on_gc_minor)
+        gc.hooks.on_gc_minor = on_gc_minor
         self.fire_gc_minor(10, 20)
         self.fire_gc_minor(30, 40)
         assert lst == [
@@ -45,7 +51,7 @@
             (30, 40),
             ]
         #
-        gc.set_hooks(on_gc_minor=None)
+        gc.hooks.on_gc_minor = None
         self.fire_gc_minor(50, 60)  # won't fire because the hooks is disabled
         assert lst == [
             (10, 20),
@@ -57,7 +63,7 @@
         lst = []
         def on_gc_collect_step(stats):
             lst.append((stats.oldstate, stats.newstate))
-        gc.set_hooks(on_gc_collect_step=on_gc_collect_step)
+        gc.hooks.on_gc_collect_step = on_gc_collect_step
         self.fire_gc_collect_step(10, 20)
         self.fire_gc_collect_step(30, 40)
         assert lst == [
@@ -65,7 +71,7 @@
             (30, 40),
             ]
         #
-        gc.set_hooks(on_gc_collect_step=None)
+        gc.hooks.on_gc_collect_step = None
         self.fire_gc_collect_step(50, 60)  # won't fire
         assert lst == [
             (10, 20),
@@ -82,7 +88,7 @@
                         stats.arenas_bytes,
                         stats.rawmalloc_bytes_before,
                         stats.rawmalloc_bytes_after))
-        gc.set_hooks(on_gc_collect=on_gc_collect)
+        gc.hooks.on_gc_collect = on_gc_collect
         self.fire_gc_collect(1, 2, 3, 4, 5, 6)
         self.fire_gc_collect(7, 8, 9, 10, 11, 12)
         assert lst == [
@@ -90,7 +96,7 @@
             (7, 8, 9, 10, 11, 12),
             ]
         #
-        gc.set_hooks(on_gc_collect=None)
+        gc.hooks.on_gc_collect = None
         self.fire_gc_collect(42, 42, 42, 42, 42, 42)  # won't fire
         assert lst == [
             (1, 2, 3, 4, 5, 6),
@@ -112,9 +118,9 @@
         def on_gc_minor(stats):        lst.append('minor')
         def on_gc_collect_step(stats): lst.append('step')
         def on_gc_collect(stats):      lst.append('collect')
-        gc.set_hooks(on_gc_minor=on_gc_minor,
-                     on_gc_collect_step=on_gc_collect_step,
-                     on_gc_collect=on_gc_collect)
+        gc.hooks.on_gc_minor = on_gc_minor
+        gc.hooks.on_gc_collect_step = on_gc_collect_step
+        gc.hooks.on_gc_collect = on_gc_collect
         #
         self.fire_many()
         assert lst == ['minor', 'step', 'collect']


More information about the pypy-commit mailing list