[pypy-commit] pypy py3k: Fix the cpyext module, at least py.py can import it without segfaulting
amauryfa
noreply at buildbot.pypy.org
Sat Oct 22 00:28:36 CEST 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r48329:928a4651aa4e
Date: 2011-10-22 00:24 +0200
http://bitbucket.org/pypy/pypy/changeset/928a4651aa4e/
Log: Fix the cpyext module, at least py.py can import it without
segfaulting
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
@@ -86,14 +86,13 @@
w_code = space.wrap(func.code)
return borrow_from(w_func, w_code)
- at cpython_api([PyObject, PyObject, PyObject], PyObject)
-def PyMethod_New(space, w_func, w_self, w_cls):
- """Return a new method object, with func being any callable object; this is the
- function that will be called when the method is called. If this method should
- be bound to an instance, self should be the instance and class should be the
- class of self, otherwise self should be NULL and class should be the
- class which provides the unbound method."""
- return Method(space, w_func, w_self, w_cls)
+ at cpython_api([PyObject, PyObject], PyObject)
+def PyMethod_New(space, w_func, w_self):
+ """Return a new method object, with func being any callable object
+ and self the instance the method should be bound. func is the
+ function that will be called when the method is called. self must
+ not be NULL."""
+ return Method(space, w_func, w_self)
@cpython_api([PyObject], PyObject)
def PyMethod_Function(space, w_method):
diff --git a/pypy/module/cpyext/include/unicodeobject.h b/pypy/module/cpyext/include/unicodeobject.h
--- a/pypy/module/cpyext/include/unicodeobject.h
+++ b/pypy/module/cpyext/include/unicodeobject.h
@@ -22,6 +22,7 @@
PyObject_HEAD
Py_UNICODE *buffer;
Py_ssize_t size;
+ char *utf8buffer;
} PyUnicodeObject;
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
@@ -186,13 +186,10 @@
return ret
def cmethod_descr_get(space, w_function, w_obj, w_cls=None):
- asking_for_bound = (space.is_w(w_cls, space.w_None) or
- not space.is_w(w_obj, space.w_None) or
- space.is_w(w_cls, space.type(space.w_None)))
- if asking_for_bound:
- return space.wrap(Method(space, w_function, w_obj, w_cls))
+ if w_obj is None or space.is_w(w_obj, space.w_None):
+ return w_function
else:
- return w_function
+ return space.wrap(Method(space, w_function, w_obj))
W_PyCFunctionObject.typedef = TypeDef(
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
@@ -73,8 +73,8 @@
interpreter object. The buffer may be mutated, until string_realize() is
called.
"""
- typedescr = get_typedescr(space.w_str.instancetypedef)
- py_obj = typedescr.allocate(space, space.w_str)
+ typedescr = get_typedescr(space.w_bytes.instancetypedef)
+ py_obj = typedescr.allocate(space, space.w_bytes)
py_str = rffi.cast(PyStringObject, py_obj)
buflen = length + 1
@@ -89,7 +89,7 @@
buffer must not be modified.
"""
py_str = rffi.cast(PyStringObject, py_obj)
- py_str.c_size = len(space.str_w(w_obj))
+ py_str.c_size = len(space.bytes_w(w_obj))
py_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
def string_realize(space, py_obj):
@@ -119,14 +119,14 @@
def PyString_FromStringAndSize(space, char_p, length):
if char_p:
s = rffi.charpsize2str(char_p, length)
- return make_ref(space, space.wrap(s))
+ return make_ref(space, space.wrapbytes(s))
else:
return rffi.cast(PyObject, new_empty_str(space, length))
@cpython_api([CONST_STRING], PyObject)
def PyString_FromString(space, char_p):
s = rffi.charp2str(char_p)
- return space.wrap(s)
+ return space.wrapbytes(s)
@cpython_api([PyObject], rffi.CCHARP, error=0)
def PyString_AsString(space, ref):
@@ -134,7 +134,7 @@
if not ref_str.c_buffer:
# copy string buffer
w_str = from_ref(space, ref)
- s = space.str_w(w_str)
+ s = space.bytes_w(w_str)
ref_str.c_buffer = rffi.str2charp(s)
return ref_str.c_buffer
@@ -147,7 +147,7 @@
if not ref_str.c_buffer:
# copy string buffer
w_str = from_ref(space, ref)
- s = space.str_w(w_str)
+ s = space.bytes_w(w_str)
ref_str.c_buffer = rffi.str2charp(s)
buffer[0] = ref_str.c_buffer
if length:
@@ -235,12 +235,6 @@
PyString_Concat(space, ref, newpart)
Py_DecRef(space, newpart)
- at cpython_api([PyObject, PyObject], PyObject)
-def PyString_Format(space, w_format, w_args):
- """Return a new string object from format and args. Analogous to format %
- args. The args argument must be a tuple."""
- return space.mod(w_format, w_args)
-
@cpython_api([CONST_STRING], PyObject)
def PyString_InternFromString(space, string):
"""A combination of PyString_FromString() and
@@ -250,25 +244,6 @@
s = rffi.charp2str(string)
return space.new_interned_str(s)
- at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject)
-def PyString_AsEncodedObject(space, w_str, encoding, errors):
- """Encode a string object using the codec registered for encoding and return
- the result as Python object. encoding and errors have the same meaning as
- the parameters of the same name in the string encode() method. The codec to
- be used is looked up using the Python codec registry. Return NULL if an
- exception was raised by the codec.
-
- This function is not available in 3.x and does not have a PyBytes alias."""
- if not PyString_Check(space, w_str):
- PyErr_BadArgument(space)
-
- w_encoding = w_errors = space.w_None
- if encoding:
- w_encoding = space.wrap(rffi.charp2str(encoding))
- if errors:
- w_errors = space.wrap(rffi.charp2str(errors))
- return space.call_method(w_str, 'encode', w_encoding, w_errors)
-
@cpython_api([PyObject, PyObject], PyObject)
def _PyString_Join(space, w_sep, w_seq):
return space.call_method(w_sep, 'join', w_seq)
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
@@ -203,6 +203,9 @@
if filename is None, the module name will be used to construct the
filename.
"""
+ name = name.encode()
+ init = init.encode()
+ body = body.encode()
if init is not None:
code = """
#include <Python.h>
diff --git a/pypy/module/cpyext/test/test_funcobject.py b/pypy/module/cpyext/test/test_funcobject.py
--- a/pypy/module/cpyext/test/test_funcobject.py
+++ b/pypy/module/cpyext/test/test_funcobject.py
@@ -31,13 +31,11 @@
w_function = space.getattr(w_method, space.wrap("im_func"))
w_self = space.getattr(w_method, space.wrap("im_self"))
- w_class = space.getattr(w_method, space.wrap("im_class"))
assert space.is_w(api.PyMethod_Function(w_method), w_function)
assert space.is_w(api.PyMethod_Self(w_method), w_self)
- assert space.is_w(api.PyMethod_Class(w_method), w_class)
- w_method2 = api.PyMethod_New(w_function, w_self, w_class)
+ w_method2 = api.PyMethod_New(w_function, w_self)
assert space.eq_w(w_method, w_method2)
def test_getcode(self, space, api):
@@ -67,7 +65,6 @@
api.Py_DecRef(ref)
return co_flags
assert get_flags("x") == CO_NESTED | CO_OPTIMIZED | CO_NEWLOCALS
- assert get_flags("x", "exec x") == CO_NESTED | CO_NEWLOCALS
assert get_flags("x, *args") & CO_VARARGS
assert get_flags("x, **kw") & CO_VARKEYWORDS
assert get_flags("x", "yield x") & CO_GENERATOR
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_stringobject.py
@@ -45,12 +45,12 @@
"""
return PyBool_FromLong(PyString_Check(PyTuple_GetItem(args, 0)));
""")])
- assert module.get_hello1() == 'Hello world'
- assert module.get_hello2() == 'Hello world'
+ assert module.get_hello1() == b'Hello world'
+ assert module.get_hello2() == b'Hello world'
assert module.test_Size()
raises(TypeError, module.test_Size_exception)
- assert module.test_is_string("")
+ assert module.test_is_string(b"")
assert not module.test_is_string(())
def test_string_buffer_init(self):
@@ -93,7 +93,7 @@
"""),
])
s = module.getstring()
- assert s == 'test'
+ assert s == b'test'
def test_py_string_as_string(self):
module = self.import_extension('foo', [
@@ -103,7 +103,7 @@
PyTuple_GetItem(args, 0)), 4);
'''
)])
- assert module.string_as_string("huheduwe") == "huhe"
+ assert module.string_as_string(b"huheduwe") == b"huhe"
def test_AsStringAndSize(self):
module = self.import_extension('foo', [
@@ -150,7 +150,7 @@
return res;
}
''')
- res = module.test_string_format_v(1, "xyz")
+ res = module.test_string_format_v(1, b"xyz")
assert res == "bla 1 ble xyz\n"
def test_format(self):
@@ -163,7 +163,7 @@
'''
)
])
- res = module.test_string_format(1, "xyz")
+ res = module.test_string_format(1, b"xyz")
assert res == "bla 1 ble xyz\n"
class TestString(BaseApiTest):
@@ -205,41 +205,37 @@
Py_DecRef(space, py_obj)
def test_Concat(self, space, api):
- ref = make_ref(space, space.wrap('abc'))
+ ref = make_ref(space, space.wrapbytes('abc'))
ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
ptr[0] = ref
- api.PyString_Concat(ptr, space.wrap('def'))
- assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
+ api.PyString_Concat(ptr, space.wrapbytes('def'))
+ assert space.bytes_w(from_ref(space, ptr[0])) == 'abcdef'
api.PyString_Concat(ptr, space.w_None)
assert not ptr[0]
ptr[0] = lltype.nullptr(PyObject.TO)
- api.PyString_Concat(ptr, space.wrap('def')) # should not crash
+ api.PyString_Concat(ptr, space.wrapbytes('def')) # should not crash
lltype.free(ptr, flavor='raw')
def test_ConcatAndDel(self, space, api):
- ref1 = make_ref(space, space.wrap('abc'))
- ref2 = make_ref(space, space.wrap('def'))
+ ref1 = make_ref(space, space.wrapbytes('abc'))
+ ref2 = make_ref(space, space.wrapbytes('def'))
ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
ptr[0] = ref1
api.PyString_ConcatAndDel(ptr, ref2)
- assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
+ assert space.bytes_w(from_ref(space, ptr[0])) == 'abcdef'
assert ref2.c_ob_refcnt == 0
Py_DecRef(space, ptr[0])
ptr[0] = lltype.nullptr(PyObject.TO)
- ref2 = make_ref(space, space.wrap('foo'))
+ ref2 = make_ref(space, space.wrapbytes('foo'))
api.PyString_ConcatAndDel(ptr, ref2) # should not crash
assert ref2.c_ob_refcnt == 0
lltype.free(ptr, flavor='raw')
- def test_format(self, space, api):
- assert "1 2" == space.unwrap(
- api.PyString_Format(space.wrap('%s %d'), space.wrap((1, 2))))
-
def test_asbuffer(self, space, api):
bufp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
- w_text = space.wrap("text")
+ w_text = space.wrapbytes("text")
assert api.PyObject_AsCharBuffer(w_text, bufp, lenp) == 0
assert lenp[0] == 4
assert rffi.charp2str(bufp[0]) == 'text'
@@ -254,42 +250,12 @@
rffi.free_charp(buf)
assert w_s1 is w_s2
- def test_AsEncodedObject(self, space, api):
- ptr = space.wrap('abc')
-
- errors = rffi.str2charp("strict")
-
- encoding = rffi.str2charp("hex")
- res = api.PyString_AsEncodedObject(
- ptr, encoding, errors)
- assert space.unwrap(res) == "616263"
-
- res = api.PyString_AsEncodedObject(
- ptr, encoding, lltype.nullptr(rffi.CCHARP.TO))
- assert space.unwrap(res) == "616263"
- rffi.free_charp(encoding)
-
- encoding = rffi.str2charp("unknown_encoding")
- self.raises(space, api, LookupError, api.PyString_AsEncodedObject,
- ptr, encoding, errors)
- rffi.free_charp(encoding)
-
- rffi.free_charp(errors)
-
- res = api.PyString_AsEncodedObject(
- ptr, lltype.nullptr(rffi.CCHARP.TO), lltype.nullptr(rffi.CCHARP.TO))
- assert space.unwrap(res) == "abc"
-
- self.raises(space, api, TypeError, api.PyString_AsEncodedObject,
- space.wrap(2), lltype.nullptr(rffi.CCHARP.TO), lltype.nullptr(rffi.CCHARP.TO)
- )
-
def test_eq(self, space, api):
- assert 1 == api._PyString_Eq(space.wrap("hello"), space.wrap("hello"))
- assert 0 == api._PyString_Eq(space.wrap("hello"), space.wrap("world"))
+ assert 1 == api._PyString_Eq(space.wrapbytes("hello"), space.wrapbytes("hello"))
+ assert 0 == api._PyString_Eq(space.wrapbytes("hello"), space.wrapbytes("world"))
def test_join(self, space, api):
- w_sep = space.wrap('<sep>')
- w_seq = space.wrap(['a', 'b'])
+ w_sep = space.wrapbytes('<sep>')
+ w_seq = space.newtuple([space.wrapbytes('a'), space.wrapbytes('b')])
w_joined = api._PyString_Join(w_sep, w_seq)
- assert space.unwrap(w_joined) == 'a<sep>b'
+ assert space.bytes_w(w_joined) == 'a<sep>b'
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
@@ -493,8 +493,8 @@
w_typename = space.getattr(w_type, space.wrap('__name__'))
heaptype = rffi.cast(PyHeapTypeObject, pto)
heaptype.c_ht_name = make_ref(space, w_typename)
- from pypy.module.cpyext.stringobject import PyString_AsString
- pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name)
+ from pypy.module.cpyext.unicodeobject import _PyUnicode_AsString
+ pto.c_tp_name = _PyUnicode_AsString(space, heaptype.c_ht_name)
else:
pto.c_tp_name = rffi.str2charp(w_type.getname(space))
pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out
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
@@ -21,7 +21,8 @@
PyUnicodeObjectStruct = lltype.ForwardReference()
PyUnicodeObject = lltype.Ptr(PyUnicodeObjectStruct)
PyUnicodeObjectFields = (PyObjectFields +
- (("buffer", rffi.CWCHARP), ("size", Py_ssize_t)))
+ (("buffer", rffi.CWCHARP), ("size", Py_ssize_t),
+ ("utf8buffer", rffi.CCHARP)))
cpython_struct("PyUnicodeObject", PyUnicodeObjectFields, PyUnicodeObjectStruct)
@bootstrap_function
@@ -79,6 +80,8 @@
py_unicode = rffi.cast(PyUnicodeObject, py_obj)
if py_unicode.c_buffer:
lltype.free(py_unicode.c_buffer, flavor="raw")
+ if py_unicode.c_utf8buffer:
+ lltype.free(py_unicode.c_utf8buffer, flavor="raw")
from pypy.module.cpyext.object import PyObject_dealloc
PyObject_dealloc(space, py_obj)
@@ -196,6 +199,17 @@
space.wrap("expected unicode object"))
return PyUnicode_AS_UNICODE(space, ref)
+ at cpython_api([PyObject], rffi.CCHARP)
+def _PyUnicode_AsString(space, ref):
+ ref_unicode = rffi.cast(PyUnicodeObject, ref)
+ if not ref_unicode.c_utf8buffer:
+ # Copy unicode buffer
+ w_unicode = from_ref(space, ref)
+ w_encoded = unicodetype.encode_object(space, w_unicode, "utf-8", "strict")
+ s = space.bytes_w(w_encoded)
+ ref_unicode.c_utf8buffer = rffi.str2charp(s)
+ return ref_unicode.c_utf8buffer
+
@cpython_api([PyObject], Py_ssize_t, error=-1)
def PyUnicode_GetSize(space, ref):
if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_unicode:
More information about the pypy-commit
mailing list