[pypy-commit] pypy missing-tp_new: Starting to support this: fill the slots of a PyTypeObject corresponding
arigo
pypy.commits at gmail.com
Sun Oct 30 12:26:38 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: missing-tp_new
Changeset: r87995:ae922c5e17f2
Date: 2016-10-30 17:26 +0100
http://bitbucket.org/pypy/pypy/changeset/ae922c5e17f2/
Log: Starting to support this: fill the slots of a PyTypeObject
corresponding to an app-level class which defines some '__xxx__'
special methods
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
@@ -17,6 +17,7 @@
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.module.cpyext.memoryobject import fill_Py_buffer
from pypy.module.cpyext.state import State
+from pypy.module.cpyext import userslot
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.argument import Arguments
from rpython.rlib.buffer import Buffer
@@ -430,6 +431,10 @@
@specialize.memo()
def get_slot_tp_function(space, typedef, 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.
+ """
key = (typedef, name)
try:
return SLOTS[key]
@@ -680,7 +685,7 @@
else:
assert False
- function = globals().get(FUNCTION, None)
+ function = getattr(userslot, FUNCTION or '!missing', None)
assert FLAGS == 0 or FLAGS == PyWrapperFlag_KEYWORDS
if FLAGS:
if wrapper is Ellipsis:
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
@@ -1,7 +1,7 @@
import os
from rpython.rlib import jit
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, we_are_translated
from rpython.rlib.rstring import rsplit
from rpython.rtyper.annlowlevel import llhelper
from rpython.rtyper.lltypesystem import rffi, lltype
@@ -37,8 +37,6 @@
from pypy.objspace.std.typeobject import W_TypeObject, find_best_base
-WARN_ABOUT_MISSING_SLOT_FUNCTIONS = False
-
PyType_Check, PyType_CheckExact = build_type_checkers("Type", "w_type")
PyHeapTypeObjectStruct = lltype.ForwardReference()
@@ -246,33 +244,32 @@
# overwrite slots that are already set: these ones are probably
# coming from a parent C type.
- typedef = w_type.layout.typedef
+ if w_type.is_heaptype():
+ typedef = None
+ else:
+ typedef = w_type.layout.typedef
+
for method_name, slot_name, slot_names, slot_func in slotdefs_for_tp_slots:
w_descr = w_type.lookup(method_name)
if w_descr is None:
# XXX special case iternext
continue
- slot_func_helper = None
+ if slot_func is None:
+ slot_func_helper = None
+ else:
+ slot_func_helper = llhelper(slot_func.api_func.functype,
+ slot_func.api_func.get_wrapper(space))
- if slot_func is None and typedef is not None:
- # XXX note that the w_type is retrieved inside this call via
- # w_type = space.gettypeobject(typedef)
- if w_type.name == 'Date' and slot_name == 'tp_new':
- name = space.gettypeobject(typedef).name
- print 'w_type inside build_slot_tp_function is "%s", wanted "%s"' %(
- name, w_type.name)
+ if typedef is not None:
get_slot = get_slot_tp_function(space, typedef, slot_name)
if get_slot:
slot_func_helper = get_slot()
- elif slot_func:
- slot_func_helper = llhelper(slot_func.api_func.functype,
- slot_func.api_func.get_wrapper(space))
if slot_func_helper is None:
- if WARN_ABOUT_MISSING_SLOT_FUNCTIONS:
- os.write(2, "%s defined by %s but no slot function defined!\n" % (
- method_name, w_type.getname(space)))
+ if not we_are_translated():
+ print "missing slot %r/%r for %r" % (
+ method_name, slot_name, w_type.getname(space))
continue
# XXX special case wrapper-functions and use a "specific" slot func
diff --git a/pypy/module/cpyext/userslot.py b/pypy/module/cpyext/userslot.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/userslot.py
@@ -0,0 +1,26 @@
+"""
+These are the default implementation for type slots that we put
+in user-defined app-level Python classes, if the class implements
+the corresponding '__xxx__' special method. It should mostly just
+call back the general version of the space operation.
+
+This is only approximately correct. One problem is that some
+details are likely subtly wrong. Another problem is that we don't
+track changes to an app-level Python class (addition or removal of
+'__xxx__' special methods) after initalization of the PyTypeObject.
+"""
+
+from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t
+
+
+ at cpython_api([PyObject], Py_ssize_t, error=-1, header=None)
+def slot_sq_length(space, w_obj):
+ return space.int_w(space.len(w_obj))
+
+ at cpython_api([PyObject, Py_ssize_t], PyObject, header=None)
+def slot_sq_item(space, w_obj, index):
+ return space.getitem(w_obj, space.wrap(index))
+
+ at cpython_api([PyObject, PyObject], PyObject, header=None)
+def slot_nb_add(space, w_obj1, w_obj2):
+ return space.add(w_obj1, w_obj2)
More information about the pypy-commit
mailing list