Author: Devin Jeanpierre <[email protected]>
Branch: cpyext-macros-cast
Changeset: r84390:f53e46cf5a82
Date: 2016-05-11 14:07 -0700
http://bitbucket.org/pypy/pypy/changeset/f53e46cf5a82/
Log: Accept PyObject*s through void* for the macro implementations that
cast.
This entails a change to the cpython_api wrapper/unwrapper so that
it understands that void* is a valid place to get a python object
from, and a valid place to store a python object to (as a
PyObject*).
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -366,14 +366,14 @@
assert len(args) == len(api_function.argtypes)
for i, (ARG, is_wrapped) in types_names_enum_ui:
input_arg = args[i]
- if is_PyObject(ARG) and not is_wrapped:
+ if (is_PyObject(ARG) or ARG == rffi.VOIDP) and not
is_wrapped:
# build a 'PyObject *' (not holding a reference)
if not is_pyobj(input_arg):
keepalives += (input_arg,)
arg = rffi.cast(ARG, as_pyobj(space, input_arg))
else:
arg = rffi.cast(ARG, input_arg)
- elif is_PyObject(ARG) and is_wrapped:
+ elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and
is_wrapped:
# build a W_Root, possibly from a 'PyObject *'
if is_pyobj(input_arg):
arg = from_ref(space, input_arg)
@@ -859,6 +859,10 @@
if is_PyObject(typ) and is_wrapped:
assert is_pyobj(arg)
arg_conv = from_ref(space, rffi.cast(PyObject, arg))
+ elif typ == rffi.VOIDP and is_wrapped:
+ # Many macros accept a void* so that one can pass a
+ # PyObject* or a PySomeSubtype*.
+ arg_conv = from_ref(space, rffi.cast(PyObject, arg))
else:
arg_conv = arg
boxed_args += (arg_conv, )
diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py
--- a/pypy/module/cpyext/cdatetime.py
+++ b/pypy/module/cpyext/cdatetime.py
@@ -178,67 +178,67 @@
# Accessors
-@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_GET_YEAR(space, w_obj):
"""Return the year, as a positive int.
"""
return space.int_w(space.getattr(w_obj, space.wrap("year")))
-@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_GET_MONTH(space, w_obj):
"""Return the month, as an int from 1 through 12.
"""
return space.int_w(space.getattr(w_obj, space.wrap("month")))
-@cpython_api([PyDateTime_Date], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_GET_DAY(space, w_obj):
"""Return the day, as an int from 1 through 31.
"""
return space.int_w(space.getattr(w_obj, space.wrap("day")))
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_HOUR(space, w_obj):
"""Return the hour, as an int from 0 through 23.
"""
return space.int_w(space.getattr(w_obj, space.wrap("hour")))
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_MINUTE(space, w_obj):
"""Return the minute, as an int from 0 through 59.
"""
return space.int_w(space.getattr(w_obj, space.wrap("minute")))
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_SECOND(space, w_obj):
"""Return the second, as an int from 0 through 59.
"""
return space.int_w(space.getattr(w_obj, space.wrap("second")))
-@cpython_api([PyDateTime_DateTime], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DATE_GET_MICROSECOND(space, w_obj):
"""Return the microsecond, as an int from 0 through 999999.
"""
return space.int_w(space.getattr(w_obj, space.wrap("microsecond")))
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_HOUR(space, w_obj):
"""Return the hour, as an int from 0 through 23.
"""
return space.int_w(space.getattr(w_obj, space.wrap("hour")))
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_MINUTE(space, w_obj):
"""Return the minute, as an int from 0 through 59.
"""
return space.int_w(space.getattr(w_obj, space.wrap("minute")))
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_SECOND(space, w_obj):
"""Return the second, as an int from 0 through 59.
"""
return space.int_w(space.getattr(w_obj, space.wrap("second")))
-@cpython_api([PyDateTime_Time], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_TIME_GET_MICROSECOND(space, w_obj):
"""Return the microsecond, as an int from 0 through 999999.
"""
@@ -248,14 +248,14 @@
# But it does not seem possible to expose a different structure
# for types defined in a python module like lib/datetime.py.
-@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DELTA_GET_DAYS(space, w_obj):
return space.int_w(space.getattr(w_obj, space.wrap("days")))
-@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DELTA_GET_SECONDS(space, w_obj):
return space.int_w(space.getattr(w_obj, space.wrap("seconds")))
-@cpython_api([PyDateTime_Delta], rffi.INT_real, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
def PyDateTime_DELTA_GET_MICROSECONDS(space, w_obj):
return space.int_w(space.getattr(w_obj, space.wrap("microseconds")))
diff --git a/pypy/module/cpyext/floatobject.py
b/pypy/module/cpyext/floatobject.py
--- a/pypy/module/cpyext/floatobject.py
+++ b/pypy/module/cpyext/floatobject.py
@@ -48,7 +48,7 @@
def PyFloat_AsDouble(space, w_obj):
return space.float_w(space.float(w_obj))
-@cpython_api([PyObject], lltype.Float, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], lltype.Float, error=CANNOT_FAIL)
def PyFloat_AS_DOUBLE(space, w_float):
"""Return a C double representation of the contents of w_float, but
without error checking."""
diff --git a/pypy/module/cpyext/include/listobject.h
b/pypy/module/cpyext/include/listobject.h
--- a/pypy/module/cpyext/include/listobject.h
+++ b/pypy/module/cpyext/include/listobject.h
@@ -1,1 +1,1 @@
-#define PyList_GET_ITEM PyList_GetItem
+#define PyList_GET_ITEM(o, i) PyList_GetItem((PyObject*)(o), (i))
diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
--- a/pypy/module/cpyext/intobject.py
+++ b/pypy/module/cpyext/intobject.py
@@ -104,7 +104,7 @@
num = space.bigint_w(w_int)
return num.ulonglongmask()
-@cpython_api([PyObject], lltype.Signed, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], lltype.Signed, error=CANNOT_FAIL)
def PyInt_AS_LONG(space, w_int):
"""Return the value of the object w_int. No error checking is performed."""
return space.int_w(w_int)
diff --git a/pypy/module/cpyext/listobject.py b/pypy/module/cpyext/listobject.py
--- a/pypy/module/cpyext/listobject.py
+++ b/pypy/module/cpyext/listobject.py
@@ -21,7 +21,7 @@
"""
return space.newlist([None] * len)
-@cpython_api([PyObject, Py_ssize_t, PyObject], PyObject, error=CANNOT_FAIL,
+@cpython_api([rffi.VOIDP, Py_ssize_t, PyObject], PyObject, error=CANNOT_FAIL,
result_borrowed=True)
def PyList_SET_ITEM(space, w_list, index, w_item):
"""Macro form of PyList_SetItem() without error checking. This is normally
@@ -87,7 +87,7 @@
space.call_method(space.w_list, "insert", w_list, space.wrap(index),
w_item)
return 0
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
def PyList_GET_SIZE(space, w_list):
"""Macro form of PyList_Size() without error checking.
"""
diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py
--- a/pypy/module/cpyext/sequence.py
+++ b/pypy/module/cpyext/sequence.py
@@ -54,7 +54,7 @@
except OperationError:
raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m)))
-@cpython_api([PyObject, Py_ssize_t], PyObject, result_borrowed=True)
+@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject, result_borrowed=True)
def PySequence_Fast_GET_ITEM(space, w_obj, index):
"""Return the ith element of o, assuming that o was returned by
PySequence_Fast(), o is not NULL, and that i is within bounds.
@@ -67,7 +67,7 @@
"PySequence_Fast_GET_ITEM called but object is not a list or "
"sequence")
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
def PySequence_Fast_GET_SIZE(space, w_obj):
"""Returns the length of o, assuming that o was returned by
PySequence_Fast() and that o is not NULL. The size can also be
@@ -82,7 +82,7 @@
"PySequence_Fast_GET_SIZE called but object is not a list or "
"sequence")
-@cpython_api([PyObject], PyObjectP)
+@cpython_api([rffi.VOIDP], PyObjectP)
def PySequence_Fast_ITEMS(space, w_obj):
"""Return the underlying array of PyObject pointers. Assumes that o was
returned
by PySequence_Fast() and o is not NULL.
@@ -119,7 +119,7 @@
space.delslice(w_obj, space.wrap(start), space.wrap(end))
return 0
-@cpython_api([PyObject, Py_ssize_t], PyObject)
+@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject)
def PySequence_ITEM(space, w_obj, i):
"""Return the ith element of o or NULL on failure. Macro form of
PySequence_GetItem() but without checking that
diff --git a/pypy/module/cpyext/setobject.py b/pypy/module/cpyext/setobject.py
--- a/pypy/module/cpyext/setobject.py
+++ b/pypy/module/cpyext/setobject.py
@@ -74,7 +74,7 @@
space.call_method(space.w_set, 'clear', w_set)
return 0
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
def PySet_GET_SIZE(space, w_s):
"""Macro form of PySet_Size() without error checking."""
return space.int_w(space.len(w_s))
diff --git a/pypy/module/cpyext/unicodeobject.py
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -188,33 +188,33 @@
"""Get the maximum ordinal for a Unicode character."""
return runicode.UNICHR(runicode.MAXUNICODE)
-@cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL)
-def PyUnicode_AS_DATA(space, ref):
+@cpython_api([rffi.VOIDP], rffi.CCHARP, error=CANNOT_FAIL)
+def PyUnicode_AS_DATA(space, w_obj):
"""Return a pointer to the internal buffer of the object. o has to be a
PyUnicodeObject (not checked)."""
- return rffi.cast(rffi.CCHARP, PyUnicode_AS_UNICODE(space, ref))
+ return rffi.cast(rffi.CCHARP, PyUnicode_AS_UNICODE(space, w_obj))
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
def PyUnicode_GET_DATA_SIZE(space, w_obj):
"""Return the size of the object's internal buffer in bytes. o has to be a
PyUnicodeObject (not checked)."""
return rffi.sizeof(lltype.UniChar) * PyUnicode_GET_SIZE(space, w_obj)
-@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
def PyUnicode_GET_SIZE(space, w_obj):
"""Return the size of the object. o has to be a PyUnicodeObject (not
checked)."""
assert isinstance(w_obj, unicodeobject.W_UnicodeObject)
return space.len_w(w_obj)
-@cpython_api([PyObject], rffi.CWCHARP, error=CANNOT_FAIL)
+@cpython_api([rffi.VOIDP], rffi.CWCHARP, error=CANNOT_FAIL)
def PyUnicode_AS_UNICODE(space, ref):
"""Return a pointer to the internal Py_UNICODE buffer of the object. ref
has to be a PyUnicodeObject (not checked)."""
ref_unicode = rffi.cast(PyUnicodeObject, ref)
if not ref_unicode.c_str:
# Copy unicode buffer
- w_unicode = from_ref(space, ref)
+ w_unicode = from_ref(space, rffi.cast(PyObject, ref))
u = space.unicode_w(w_unicode)
ref_unicode.c_str = rffi.unicode2wcharp(u)
return ref_unicode.c_str
diff --git a/pypy/module/cpyext/weakrefobject.py
b/pypy/module/cpyext/weakrefobject.py
--- a/pypy/module/cpyext/weakrefobject.py
+++ b/pypy/module/cpyext/weakrefobject.py
@@ -1,6 +1,7 @@
from pypy.module.cpyext.api import cpython_api
from pypy.module.cpyext.pyobject import PyObject
from pypy.module._weakref.interp__weakref import W_Weakref, proxy
+from rpython.rtyper.lltypesystem import rffi
@cpython_api([PyObject, PyObject], PyObject)
def PyWeakref_NewRef(space, w_obj, w_callback):
@@ -37,7 +38,7 @@
"""
return space.call_function(w_ref) # borrowed ref
-@cpython_api([PyObject], PyObject, result_borrowed=True)
+@cpython_api([rffi.VOIDP], PyObject, result_borrowed=True)
def PyWeakref_GET_OBJECT(space, w_ref):
"""Similar to PyWeakref_GetObject(), but implemented as a macro that does
no
error checking.
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit