Author: mattip <[email protected]>
Branch:
Changeset: r82153:c9a273a1a16d
Date: 2016-02-11 00:05 +0200
http://bitbucket.org/pypy/pypy/changeset/c9a273a1a16d/
Log: merge seperate-strucmember_h which moves structmember.h out of
Python.h
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
@@ -59,7 +59,7 @@
class CConfig:
_compilation_info_ = ExternalCompilationInfo(
include_dirs=include_dirs,
- includes=['Python.h', 'stdarg.h'],
+ includes=['Python.h', 'stdarg.h', 'structmember.h'],
compile_extra=['-DPy_BUILD_CORE'],
)
@@ -129,6 +129,7 @@
for name in constant_names:
setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name))
udir.join('pypy_decl.h').write("/* Will be filled later */\n")
+udir.join('pypy_structmember_decl.h').write("/* Will be filled later */\n")
udir.join('pypy_macros.h').write("/* Will be filled later */\n")
globals().update(rffi_platform.configure(CConfig_constants))
@@ -147,7 +148,7 @@
# XXX: 20 lines of code to recursively copy a directory, really??
assert dstdir.check(dir=True)
headers = include_dir.listdir('*.h') + include_dir.listdir('*.inl')
- for name in ("pypy_decl.h", "pypy_macros.h"):
+ for name in ("pypy_decl.h", "pypy_macros.h", "pypy_structmember_decl.h"):
headers.append(udir.join(name))
_copy_header_files(headers, dstdir)
@@ -232,7 +233,7 @@
wrapper.c_name = cpyext_namespace.uniquename(self.c_name)
return wrapper
-def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, external=True,
+def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header='pypy_decl.h',
gil=None):
"""
Declares a function to be exported.
@@ -241,8 +242,8 @@
special value 'CANNOT_FAIL' (also when restype is Void) turns an eventual
exception into a wrapped SystemError. Unwrapped exceptions also cause a
SytemError.
- - set `external` to False to get a C function pointer, but not exported by
- the API headers.
+ - `header` is the header file to export the function in, Set to None to get
+ a C function pointer, but not exported by the API headers.
- set `gil` to "acquire", "release" or "around" to acquire the GIL,
release the GIL, or both
"""
@@ -263,7 +264,7 @@
def decorate(func):
func_name = func.func_name
- if external:
+ if header is not None:
c_name = None
else:
c_name = func_name
@@ -271,7 +272,7 @@
c_name=c_name, gil=gil)
func.api_func = api_function
- if external:
+ if header is not None:
assert func_name not in FUNCTIONS, (
"%s already registered" % func_name)
@@ -363,8 +364,9 @@
unwrapper_catch = make_unwrapper(True)
unwrapper_raise = make_unwrapper(False)
- if external:
+ if header is not None:
FUNCTIONS[func_name] = api_function
+ FUNCTIONS_BY_HEADER.setdefault(header, {})[func_name] =
api_function
INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
return unwrapper_raise # used in 'normal' RPython code.
return decorate
@@ -383,6 +385,7 @@
INTERPLEVEL_API = {}
FUNCTIONS = {}
+FUNCTIONS_BY_HEADER = {}
# These are C symbols which cpyext will export, but which are defined in .c
# files somewhere in the implementation of cpyext (rather than being defined in
@@ -811,6 +814,7 @@
global_code = '\n'.join(global_objects)
prologue = ("#include <Python.h>\n"
+ "#include <structmember.h>\n"
"#include <src/thread.c>\n")
code = (prologue +
struct_declaration_code +
@@ -960,7 +964,8 @@
"NOT_RPYTHON"
# implement function callbacks and generate function decls
functions = []
- pypy_decls = []
+ decls = {}
+ pypy_decls = decls['pypy_decl.h'] = []
pypy_decls.append("#ifndef _PYPY_PYPY_DECL_H\n")
pypy_decls.append("#define _PYPY_PYPY_DECL_H\n")
pypy_decls.append("#ifndef PYPY_STANDALONE\n")
@@ -973,17 +978,23 @@
for decl in FORWARD_DECLS:
pypy_decls.append("%s;" % (decl,))
- for name, func in sorted(FUNCTIONS.iteritems()):
- restype, args = c_function_signature(db, func)
- pypy_decls.append("PyAPI_FUNC(%s) %s(%s);" % (restype, name, args))
- if api_struct:
- callargs = ', '.join('arg%d' % (i,)
- for i in range(len(func.argtypes)))
- if func.restype is lltype.Void:
- body = "{ _pypyAPI.%s(%s); }" % (name, callargs)
- else:
- body = "{ return _pypyAPI.%s(%s); }" % (name, callargs)
- functions.append('%s %s(%s)\n%s' % (restype, name, args, body))
+ for header_name, header_functions in FUNCTIONS_BY_HEADER.iteritems():
+ if header_name not in decls:
+ header = decls[header_name] = []
+ else:
+ header = decls[header_name]
+
+ for name, func in sorted(header_functions.iteritems()):
+ restype, args = c_function_signature(db, func)
+ header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, name, args))
+ if api_struct:
+ callargs = ', '.join('arg%d' % (i,)
+ for i in range(len(func.argtypes)))
+ if func.restype is lltype.Void:
+ body = "{ _pypyAPI.%s(%s); }" % (name, callargs)
+ else:
+ body = "{ return _pypyAPI.%s(%s); }" % (name, callargs)
+ functions.append('%s %s(%s)\n%s' % (restype, name, args, body))
for name in VA_TP_LIST:
name_no_star = process_va_name(name)
header = ('%s pypy_va_get_%s(va_list* vp)' %
@@ -1007,8 +1018,9 @@
pypy_decls.append("#endif /*PYPY_STANDALONE*/\n")
pypy_decls.append("#endif /*_PYPY_PYPY_DECL_H*/\n")
- pypy_decl_h = udir.join('pypy_decl.h')
- pypy_decl_h.write('\n'.join(pypy_decls))
+ for header_name, header_decls in decls.iteritems():
+ decl_h = udir.join(header_name)
+ decl_h.write('\n'.join(header_decls))
return functions
separate_module_files = [source_dir / "varargwrapper.c",
diff --git a/pypy/module/cpyext/bufferobject.py
b/pypy/module/cpyext/bufferobject.py
--- a/pypy/module/cpyext/bufferobject.py
+++ b/pypy/module/cpyext/bufferobject.py
@@ -73,7 +73,7 @@
"Don't know how to realize a buffer"))
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def buffer_dealloc(space, py_obj):
py_buf = rffi.cast(PyBufferObject, py_obj)
if py_buf.c_b_base:
diff --git a/pypy/module/cpyext/frameobject.py
b/pypy/module/cpyext/frameobject.py
--- a/pypy/module/cpyext/frameobject.py
+++ b/pypy/module/cpyext/frameobject.py
@@ -39,7 +39,7 @@
py_frame.c_f_locals = make_ref(space, frame.get_w_locals())
rffi.setintfield(py_frame, 'c_f_lineno', frame.getorcreatedebug().f_lineno)
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def frame_dealloc(space, py_obj):
py_frame = rffi.cast(PyFrameObject, py_obj)
py_code = rffi.cast(PyObject, py_frame.c_f_code)
diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py
--- a/pypy/module/cpyext/funcobject.py
+++ b/pypy/module/cpyext/funcobject.py
@@ -56,7 +56,7 @@
assert isinstance(w_obj, Function)
py_func.c_func_name = make_ref(space, space.wrap(w_obj.name))
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def function_dealloc(space, py_obj):
py_func = rffi.cast(PyFunctionObject, py_obj)
Py_DecRef(space, py_func.c_func_name)
@@ -75,7 +75,7 @@
rffi.setintfield(py_code, 'c_co_flags', co_flags)
rffi.setintfield(py_code, 'c_co_argcount', w_obj.co_argcount)
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def code_dealloc(space, py_obj):
py_code = rffi.cast(PyCodeObject, py_obj)
Py_DecRef(space, py_code.c_co_name)
diff --git a/pypy/module/cpyext/include/Python.h
b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -132,9 +132,6 @@
/* Missing definitions */
#include "missing.h"
-// XXX This shouldn't be included here
-#include "structmember.h"
-
#include <pypy_decl.h>
/* Define macros for inline documentation. */
diff --git a/pypy/module/cpyext/include/structmember.h
b/pypy/module/cpyext/include/structmember.h
--- a/pypy/module/cpyext/include/structmember.h
+++ b/pypy/module/cpyext/include/structmember.h
@@ -4,54 +4,85 @@
extern "C" {
#endif
+
+/* Interface to map C struct members to Python object attributes */
+
#include <stddef.h> /* For offsetof */
+
+/* The offsetof() macro calculates the offset of a structure member
+ in its structure. Unfortunately this cannot be written down
+ portably, hence it is provided by a Standard C header file.
+ For pre-Standard C compilers, here is a version that usually works
+ (but watch out!): */
+
#ifndef offsetof
#define offsetof(type, member) ( (int) & ((type*)0) -> member )
#endif
+/* An array of memberlist structures defines the name, type and offset
+ of selected members of a C structure. These can be read by
+ PyMember_Get() and set by PyMember_Set() (except if their READONLY flag
+ is set). The array must be terminated with an entry whose name
+ pointer is NULL. */
+
+
typedef struct PyMemberDef {
- /* Current version, use this */
- char *name;
- int type;
- Py_ssize_t offset;
- int flags;
- char *doc;
+ /* Current version, use this */
+ char *name;
+ int type;
+ Py_ssize_t offset;
+ int flags;
+ char *doc;
} PyMemberDef;
+/* Types */
+#define T_SHORT 0
+#define T_INT 1
+#define T_LONG 2
+#define T_FLOAT 3
+#define T_DOUBLE 4
+#define T_STRING 5
+#define T_OBJECT 6
+/* XXX the ordering here is weird for binary compatibility */
+#define T_CHAR 7 /* 1-character string */
+#define T_BYTE 8 /* 8-bit signed int */
+/* unsigned variants: */
+#define T_UBYTE 9
+#define T_USHORT 10
+#define T_UINT 11
+#define T_ULONG 12
-/* Types. These constants are also in structmemberdefs.py. */
-#define T_SHORT 0
-#define T_INT 1
-#define T_LONG 2
-#define T_FLOAT 3
-#define T_DOUBLE 4
-#define T_STRING 5
-#define T_OBJECT 6
-#define T_CHAR 7 /* 1-character string */
-#define T_BYTE 8 /* 8-bit signed int */
-#define T_UBYTE 9
-#define T_USHORT 10
-#define T_UINT 11
-#define T_ULONG 12
-#define T_STRING_INPLACE 13 /* Strings contained in the structure */
-#define T_BOOL 14
-#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError
- when the value is NULL, instead of
- converting to None. */
-#define T_LONGLONG 17
-#define T_ULONGLONG 18
-#define T_PYSSIZET 19
+/* Added by Jack: strings contained in the structure */
+#define T_STRING_INPLACE 13
+
+/* Added by Lillo: bools contained in the structure (assumed char) */
+#define T_BOOL 14
+
+#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError
+ when the value is NULL, instead of
+ converting to None. */
+#ifdef HAVE_LONG_LONG
+#define T_LONGLONG 17
+#define T_ULONGLONG 18
+#endif /* HAVE_LONG_LONG */
+
+#define T_PYSSIZET 19 /* Py_ssize_t */
/* Flags. These constants are also in structmemberdefs.py. */
-#define READONLY 1
-#define RO READONLY /* Shorthand */
+#define READONLY 1
+#define RO READONLY /* Shorthand */
#define READ_RESTRICTED 2
#define PY_WRITE_RESTRICTED 4
-#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED)
+#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED)
+
+
+/* API functions. */
+#include "pypy_structmember_decl.h"
#ifdef __cplusplus
}
#endif
#endif /* !Py_STRUCTMEMBER_H */
+
diff --git a/pypy/module/cpyext/methodobject.py
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -50,7 +50,7 @@
py_func.c_m_self = make_ref(space, w_obj.w_self)
py_func.c_m_module = make_ref(space, w_obj.w_module)
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def cfunction_dealloc(space, py_obj):
py_func = rffi.cast(PyCFunctionObject, py_obj)
Py_DecRef(space, py_func.c_m_self)
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -70,7 +70,7 @@
alloc : allocate and basic initialization of a raw PyObject
attach : Function called to tie a raw structure to a pypy object
realize : Function called to create a pypy object from a raw struct
- dealloc : a cpython_api(external=False), similar to PyObject_dealloc
+ dealloc : a cpython_api(header=None), similar to PyObject_dealloc
"""
tp_basestruct = kw.pop('basestruct', PyObject.TO)
diff --git a/pypy/module/cpyext/pytraceback.py
b/pypy/module/cpyext/pytraceback.py
--- a/pypy/module/cpyext/pytraceback.py
+++ b/pypy/module/cpyext/pytraceback.py
@@ -41,7 +41,7 @@
rffi.setintfield(py_traceback, 'c_tb_lasti', traceback.lasti)
rffi.setintfield(py_traceback, 'c_tb_lineno',traceback.get_lineno())
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def traceback_dealloc(space, py_obj):
py_traceback = rffi.cast(PyTracebackObject, py_obj)
Py_DecRef(space, rffi.cast(PyObject, py_traceback.c_tb_next))
diff --git a/pypy/module/cpyext/sliceobject.py
b/pypy/module/cpyext/sliceobject.py
--- a/pypy/module/cpyext/sliceobject.py
+++ b/pypy/module/cpyext/sliceobject.py
@@ -36,7 +36,7 @@
py_slice.c_stop = make_ref(space, w_obj.w_stop)
py_slice.c_step = make_ref(space, w_obj.w_step)
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def slice_dealloc(space, py_obj):
"""Frees allocated PyStringObject resources.
"""
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
@@ -309,7 +309,7 @@
return space.wrap(generic_cpy_call(space, func_target, w_self, w_other))
-@cpython_api([PyTypeObjectPtr, PyObject, PyObject], PyObject, external=False)
+@cpython_api([PyTypeObjectPtr, PyObject, PyObject], PyObject, header=None)
def slot_tp_new(space, type, w_args, w_kwds):
from pypy.module.cpyext.tupleobject import PyTuple_Check
pyo = rffi.cast(PyObject, type)
@@ -320,30 +320,30 @@
w_args_new = space.newtuple(args_w)
return space.call(w_func, w_args_new, w_kwds)
-@cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1,
external=False)
+@cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1,
header=None)
def slot_tp_init(space, w_self, w_args, w_kwds):
w_descr = space.lookup(w_self, '__init__')
args = Arguments.frompacked(space, w_args, w_kwds)
space.get_and_call_args(w_descr, w_self, args)
return 0
-@cpython_api([PyObject, PyObject, PyObject], PyObject, external=False)
+@cpython_api([PyObject, PyObject, PyObject], PyObject, header=None)
def slot_tp_call(space, w_self, w_args, w_kwds):
return space.call(w_self, w_args, w_kwds)
-@cpython_api([PyObject], PyObject, external=False)
+@cpython_api([PyObject], PyObject, header=None)
def slot_tp_str(space, w_self):
return space.str(w_self)
-@cpython_api([PyObject], PyObject, external=False)
+@cpython_api([PyObject], PyObject, header=None)
def slot_nb_int(space, w_self):
return space.int(w_self)
-@cpython_api([PyObject], PyObject, external=False)
+@cpython_api([PyObject], PyObject, header=None)
def slot_tp_iter(space, w_self):
return space.iter(w_self)
-@cpython_api([PyObject], PyObject, external=False)
+@cpython_api([PyObject], PyObject, header=None)
def slot_tp_iternext(space, w_self):
return space.next(w_self)
@@ -371,7 +371,7 @@
return
@cpython_api([PyObject, PyObject, PyObject], rffi.INT_real,
- error=-1, external=True) # XXX should not be exported
+ error=-1) # XXX should be header=None
@func_renamer("cpyext_tp_setattro_%s" % (typedef.name,))
def slot_tp_setattro(space, w_self, w_name, w_value):
if w_value is not None:
@@ -385,8 +385,7 @@
if getattr_fn is None:
return
- @cpython_api([PyObject, PyObject], PyObject,
- external=True)
+ @cpython_api([PyObject, PyObject], PyObject)
@func_renamer("cpyext_tp_getattro_%s" % (typedef.name,))
def slot_tp_getattro(space, w_self, w_name):
return space.call_function(getattr_fn, w_self, w_name)
diff --git a/pypy/module/cpyext/stringobject.py
b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -103,7 +103,7 @@
track_reference(space, py_obj, w_obj)
return w_obj
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def string_dealloc(space, py_obj):
"""Frees allocated PyStringObject resources.
"""
diff --git a/pypy/module/cpyext/structmember.py
b/pypy/module/cpyext/structmember.py
--- a/pypy/module/cpyext/structmember.py
+++ b/pypy/module/cpyext/structmember.py
@@ -31,8 +31,10 @@
(T_PYSSIZET, rffi.SSIZE_T, PyLong_AsSsize_t),
])
+_HEADER = 'pypy_structmember_decl.h'
-@cpython_api([PyObject, lltype.Ptr(PyMemberDef)], PyObject)
+
+@cpython_api([PyObject, lltype.Ptr(PyMemberDef)], PyObject, header=_HEADER)
def PyMember_GetOne(space, obj, w_member):
addr = rffi.cast(ADDR, obj)
addr += w_member.c_offset
@@ -83,7 +85,8 @@
return w_result
-@cpython_api([PyObject, lltype.Ptr(PyMemberDef), PyObject], rffi.INT_real,
error=-1)
+@cpython_api([PyObject, lltype.Ptr(PyMemberDef), PyObject], rffi.INT_real,
+ error=-1, header=_HEADER)
def PyMember_SetOne(space, obj, w_member, w_value):
addr = rffi.cast(ADDR, obj)
addr += w_member.c_offset
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -863,3 +863,15 @@
os.unlink('_imported_already')
except OSError:
pass
+
+ def test_no_structmember(self):
+ """structmember.h should not be included by default."""
+ mod = self.import_extension('foo', [
+ ('bar', 'METH_NOARGS',
+ '''
+ /* reuse a name that is #defined in structmember.h */
+ int RO;
+ Py_RETURN_NONE;
+ '''
+ ),
+ ])
diff --git a/pypy/module/cpyext/test/test_intobject.py
b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -99,6 +99,7 @@
"""),
],
prologue="""
+ #include "structmember.h"
typedef struct
{
PyObject_HEAD
diff --git a/pypy/module/cpyext/test/test_translate.py
b/pypy/module/cpyext/test/test_translate.py
--- a/pypy/module/cpyext/test/test_translate.py
+++ b/pypy/module/cpyext/test/test_translate.py
@@ -19,7 +19,7 @@
@specialize.memo()
def get_tp_function(space, typedef):
- @cpython_api([], lltype.Signed, error=-1, external=False)
+ @cpython_api([], lltype.Signed, error=-1, header=None)
def slot_tp_function(space):
return typedef.value
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
@@ -183,7 +183,7 @@
if pto.c_tp_new:
add_tp_new_wrapper(space, dict_w, pto)
-@cpython_api([PyObject, PyObject, PyObject], PyObject, external=False)
+@cpython_api([PyObject, PyObject, PyObject], PyObject, header=None)
def tp_new_wrapper(space, self, w_args, w_kwds):
tp_new = rffi.cast(PyTypeObjectPtr, self).c_tp_new
@@ -311,7 +311,7 @@
dealloc=type_dealloc)
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def subtype_dealloc(space, obj):
pto = obj.c_ob_type
base = pto
@@ -327,7 +327,7 @@
# hopefully this does not clash with the memory model assumed in
# extension modules
-@cpython_api([PyObject, Py_ssize_tP], lltype.Signed, external=False,
+@cpython_api([PyObject, Py_ssize_tP], lltype.Signed, header=None,
error=CANNOT_FAIL)
def str_segcount(space, w_obj, ref):
if ref:
@@ -335,7 +335,7 @@
return 1
@cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
- external=False, error=-1)
+ header=None, error=-1)
def str_getreadbuffer(space, w_str, segment, ref):
from pypy.module.cpyext.stringobject import PyString_AsString
if segment != 0:
@@ -348,7 +348,7 @@
return space.len_w(w_str)
@cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
- external=False, error=-1)
+ header=None, error=-1)
def str_getcharbuffer(space, w_str, segment, ref):
from pypy.module.cpyext.stringobject import PyString_AsString
if segment != 0:
@@ -361,7 +361,7 @@
return space.len_w(w_str)
@cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
- external=False, error=-1)
+ header=None, error=-1)
def buf_getreadbuffer(space, pyref, segment, ref):
from pypy.module.cpyext.bufferobject import PyBufferObject
if segment != 0:
@@ -393,7 +393,7 @@
buf_getreadbuffer.api_func.get_wrapper(space))
pto.c_tp_as_buffer = c_buf
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def type_dealloc(space, obj):
from pypy.module.cpyext.object import PyObject_dealloc
obj_pto = rffi.cast(PyTypeObjectPtr, obj)
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
@@ -75,7 +75,7 @@
track_reference(space, py_obj, w_obj)
return w_obj
-@cpython_api([PyObject], lltype.Void, external=False)
+@cpython_api([PyObject], lltype.Void, header=None)
def unicode_dealloc(space, py_obj):
py_unicode = rffi.cast(PyUnicodeObject, py_obj)
if py_unicode.c_buffer:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit