[pypy-commit] pypy py3.5-refactor-slots: hg merge refactor-slots

rlamy pypy.commits at gmail.com
Fri Jan 12 12:34:00 EST 2018


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5-refactor-slots
Changeset: r93658:5eda67de1f64
Date: 2017-10-02 17:48 +0200
http://bitbucket.org/pypy/pypy/changeset/5eda67de1f64/

Log:	hg merge refactor-slots

diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -418,39 +418,19 @@
 
     return space.newint(generic_cpy_call(space, func_target, w_self, w_other))
 
-from rpython.rlib.nonconst import NonConstant
+SLOT_FACTORIES = {}
+def slot_factory(tp_name):
+    def decorate(func):
+        SLOT_FACTORIES[tp_name] = func
+        return func
+    return decorate
 
-def build_slot_tp_function(space, typedef, name):
+
+def build_slot_tp_function(space, typedef, name, method_name):
     w_type = space.gettypeobject(typedef)
 
     handled = False
     # unary functions
-    for tp_name, attr in [('tp_as_async.c_am_await', '__await__'),
-                          ('tp_as_async.c_am_anext', '__anext__'),
-                          ('tp_as_async.c_am_aiter', '__aiter__'),
-                          ('tp_as_number.c_nb_int', '__int__'),
-                          ('tp_as_number.c_nb_long', '__long__'),
-                          ('tp_as_number.c_nb_float', '__float__'),
-                          ('tp_as_number.c_nb_negative', '__neg__'),
-                          ('tp_as_number.c_nb_positive', '__pos__'),
-                          ('tp_as_number.c_nb_absolute', '__abs__'),
-                          ('tp_as_number.c_nb_invert', '__invert__'),
-                          ('tp_as_number.c_nb_index', '__index__'),
-                          ('tp_str', '__str__'),
-                          ('tp_repr', '__repr__'),
-                          ('tp_iter', '__iter__'),
-                          ]:
-        if name == tp_name:
-            slot_fn = w_type.lookup(attr)
-            if slot_fn is None:
-                return
-
-            @slot_function([PyObject], PyObject)
-            @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
-            def slot_func(space, w_self):
-                return space.call_function(slot_fn, w_self)
-            handled = True
-
     for tp_name, attr in [('tp_hash', '__hash__'),
                           ('tp_as_sequence.c_sq_length', '__len__'),
                           ('tp_as_mapping.c_mp_length', '__len__'),
@@ -669,27 +649,8 @@
                 w_obj = space.w_None
             return space.call_function(get_fn, w_self, w_obj, w_value)
         slot_func = slot_tp_descr_get
-    elif name == 'tp_descr_set':
-        set_fn = w_type.lookup('__set__')
-        delete_fn = w_type.lookup('__delete__')
-        if set_fn is None and delete_fn is None:
-            return
-
-        @slot_function([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
-        @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
-        def slot_tp_descr_set(space, w_self, w_obj, w_value):
-            if w_value is not None:
-                if set_fn is None:
-                    raise oefmt(space.w_TypeError,
-                                "%s object has no __set__", typedef.name)
-                space.call_function(set_fn, w_self, w_obj, w_value)
-            else:
-                if delete_fn is None:
-                    raise oefmt(space.w_TypeError,
-                                "%s object has no __delete__", typedef.name)
-                space.call_function(delete_fn, w_self, w_obj)
-            return 0
-        slot_func = slot_tp_descr_set
+    elif name in SLOT_FACTORIES:
+        return SLOT_FACTORIES[name](space, typedef, name, method_name)
     else:
         # missing: tp_as_number.nb_nonzero, tp_as_number.nb_coerce
         # tp_as_sequence.c_sq_contains, tp_as_sequence.c_sq_length
@@ -698,6 +659,64 @@
 
     return slot_func
 
+def make_unary_slot(space, typedef, name, attr):
+    w_type = space.gettypeobject(typedef)
+    slot_fn = w_type.lookup(attr)
+    if slot_fn is None:
+        return
+
+    @slot_function([PyObject], PyObject)
+    @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
+    def slot_func(space, w_self):
+        return space.call_function(slot_fn, w_self)
+    return slot_func
+
+
+UNARY_SLOTS = [
+    'tp_as_async.c_am_await',
+    'tp_as_async.c_am_anext',
+    'tp_as_async.c_am_aiter',
+    'tp_as_number.c_nb_int',
+    'tp_as_number.c_nb_long',
+    'tp_as_number.c_nb_float',
+    'tp_as_number.c_nb_negative',
+    'tp_as_number.c_nb_positive',
+    'tp_as_number.c_nb_absolute',
+    'tp_as_number.c_nb_invert',
+    'tp_as_number.c_nb_index',
+    'tp_as_number.c_nb_hex',
+    'tp_as_number.c_nb_oct',
+    'tp_str',
+    'tp_repr',
+    'tp_iter']
+for name in UNARY_SLOTS:
+    slot_factory(name)(make_unary_slot)
+
+ at slot_factory('tp_descr_set')
+def make_tp_descr_set(space, typedef, name, attr):
+    w_type = space.gettypeobject(typedef)
+    name = 'descr_set'
+    set_fn = w_type.lookup('__set__')
+    delete_fn = w_type.lookup('__delete__')
+    if set_fn is None and delete_fn is None:
+        return
+
+    @slot_function([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
+    @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
+    def slot_tp_descr_set(space, w_self, w_obj, w_value):
+        if w_value is not None:
+            if set_fn is None:
+                raise oefmt(space.w_TypeError,
+                            "%s object has no __set__", typedef.name)
+            space.call_function(set_fn, w_self, w_obj, w_value)
+        else:
+            if delete_fn is None:
+                raise oefmt(space.w_TypeError,
+                            "%s object has no __delete__", typedef.name)
+            space.call_function(delete_fn, w_self, w_obj)
+        return 0
+    return slot_tp_descr_set
+
 
 def slot_from___buffer__(space, typedef, buff_fn):
     name = 'bf_getbuffer'
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -228,7 +228,7 @@
 
 SLOTS = {}
 @specialize.memo()
-def get_slot_tp_function(space, typedef, name):
+def get_slot_tp_function(space, typedef, name, method_name):
     """Return a description of the slot C function to use for the built-in
     type for 'typedef'.  The 'name' is the slot name.  This is a memo
     function that, after translation, returns one of a built-in finite set.
@@ -237,7 +237,7 @@
     try:
         return SLOTS[key]
     except KeyError:
-        slot_func = build_slot_tp_function(space, typedef, name)
+        slot_func = build_slot_tp_function(space, typedef, name, method_name)
         api_func = slot_func.api_func if slot_func else None
         SLOTS[key] = api_func
         return api_func
@@ -281,7 +281,7 @@
 def update_all_slots_builtin(space, w_type, pto):
     typedef = w_type.layout.typedef
     for method_name, slot_name, slot_names, slot_apifunc in slotdefs_for_tp_slots:
-        slot_apifunc = get_slot_tp_function(space, typedef, slot_name)
+        slot_apifunc = get_slot_tp_function(space, typedef, slot_name, method_name)
         if not slot_apifunc:
             warn_missing_slot(space, method_name, slot_name, w_type)
             continue


More information about the pypy-commit mailing list