Author: Matti Picus <[email protected]>
Branch: cpyext-null-slots
Changeset: r87375:c85aef87f0df
Date: 2016-09-25 15:37 +0300
http://bitbucket.org/pypy/pypy/changeset/c85aef87f0df/
Log: cpython compatible slot lookup does not traverse mro, implement and
ensure slots are filled at PyType_Ready
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -40,7 +40,7 @@
def _PyObject_New(space, type):
return _PyObject_NewVar(space, type, 0)
-@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject, result_is_ll=True)
+@cpython_api([PyTypeObjectPtr, Py_ssize_t], PyVarObject, result_is_ll=True)
def _PyObject_NewVar(space, type, itemcount):
w_type = from_ref(space, rffi.cast(PyObject, type))
assert isinstance(w_type, W_TypeObject)
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
@@ -453,6 +453,23 @@
api_func = slot_func.api_func
handled = True
+ # unary functions returning Py_ssize_t
+ for tp_name, attr in [('tp_as_sequence.c_sq_length', '__len__'),
+ #('tp_as_mapping.c_mp_length', '__len__'),
+ ]:
+ if name == tp_name:
+ slot_fn = w_type.getdictvalue(space, attr)
+ if slot_fn is None:
+ return
+
+ @cpython_api([PyObject], Py_ssize_t, header=header, error=-1)
+ @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'),
typedef.name))
+ def slot_func(space, w_self):
+ ret = space.call_function(slot_fn, w_self)
+ return space.int_w(ret)
+ api_func = slot_func.api_func
+ handled = True
+
# binary functions
for tp_name, attr in [('tp_as_number.c_nb_add', '__add__'),
('tp_as_number.c_nb_subtract', '__sub__'),
diff --git a/pypy/module/cpyext/test/test_bytesobject.py
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -480,6 +480,7 @@
a = module.newsubstr('abc')
assert type(a).__name__ == 'string_'
assert a == 'abc'
+ assert str(a) == 'abc'
#print type(a).mro(type(a))
raises(ValueError, int, a)
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
@@ -479,6 +479,10 @@
if pto.c_tp_doc:
self.w_doc = space.wrap(rffi.charp2str(pto.c_tp_doc))
+ def lookup(self, name):
+ # do not traverse the mro, look only in self
+ return self.getdictvalue(self.space, name)
+
@bootstrap_function
def init_typeobject(space):
make_typedescr(space.w_type.layout.typedef,
@@ -819,15 +823,24 @@
# inheriting tp_as_* slots
base = py_type.c_tp_base
if base:
+ remap_slots = False
if not py_type.c_tp_as_number:
py_type.c_tp_as_number = base.c_tp_as_number
py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_CHECKTYPES
py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
+ remap_slots = True
if not py_type.c_tp_as_sequence:
py_type.c_tp_as_sequence = base.c_tp_as_sequence
py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
- if not py_type.c_tp_as_mapping: py_type.c_tp_as_mapping =
base.c_tp_as_mapping
- if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer =
base.c_tp_as_buffer
+ remap_slots = True
+ if not py_type.c_tp_as_mapping:
+ py_type.c_tp_as_mapping = base.c_tp_as_mapping
+ remap_slots = True
+ if not py_type.c_tp_as_buffer:
+ py_type.c_tp_as_buffer = base.c_tp_as_buffer
+ remap_slots = True
+ if remap_slots:
+ add_operators(space, w_obj.dict_w, py_type)
return w_obj
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit