[pypy-commit] pypy unicode-utf8-py3: merge unicode-utf8 into branch
mattip
pypy.commits at gmail.com
Tue Sep 11 16:33:09 EDT 2018
Author: Matti Picus <matti.picus at gmail.com>
Branch: unicode-utf8-py3
Changeset: r95097:d9069a2d3f11
Date: 2018-09-11 22:38 +0300
http://bitbucket.org/pypy/pypy/changeset/d9069a2d3f11/
Log: merge unicode-utf8 into branch
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -330,7 +330,8 @@
-------------
* Hash randomization (``-R``) `is ignored in PyPy`_. In CPython
- before 3.4 it has `little point`_.
+ before 3.4 it has `little point`_. Both CPython >= 3.4 and PyPy3
+ implement the randomized SipHash algorithm and ignore ``-R``.
* You can't store non-string keys in type objects. For example::
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -32,11 +32,14 @@
The reverse-debugger branch has been merged. For more information, see
https://bitbucket.org/pypy/revdb
+.. branch: pyparser-improvements-3
+
+Small refactorings in the Python parser.
+
.. branch: unicode-utf8-re
.. branch: utf8-io
Utf8 handling for unicode
.. branch: pyparser-improvements-3
-
-Small refactorings in the Python parser.
+Small refactorings in the Python parser.
\ No newline at end of file
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1250,7 +1250,6 @@
def test_revdb_metavar(self):
from pypy.interpreter.reverse_debugging import dbstate, setup_revdb
- self.space.config.translation.reverse_debugger = True
self.space.reverse_debugging = True
try:
setup_revdb(self.space)
diff --git a/pypy/module/cpyext/test0/test_abstract.py b/pypy/module/cpyext/test0/test_abstract.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test0/test_abstract.py
@@ -0,0 +1,130 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+import pytest
+
+class AppTestBufferProtocol(AppTestCpythonExtensionBase):
+ """Tests for the old buffer protocol."""
+
+ def w_get_buffer_support(self):
+ return self.import_extension('buffer_support', [
+ ("charbuffer_as_string", "METH_O",
+ """
+ char *ptr;
+ Py_ssize_t size;
+ if (PyObject_AsCharBuffer(args, (const char **)&ptr, &size) < 0)
+ return NULL;
+ return PyString_FromStringAndSize(ptr, size);
+ """),
+ ("check_readbuffer", "METH_O",
+ """
+ return PyBool_FromLong(PyObject_CheckReadBuffer(args));
+ """),
+ ("readbuffer_as_string", "METH_O",
+ """
+ const void *ptr;
+ Py_ssize_t size;
+ if (PyObject_AsReadBuffer(args, &ptr, &size) < 0)
+ return NULL;
+ return PyString_FromStringAndSize((char*)ptr, size);
+ """),
+ ("writebuffer_as_string", "METH_O",
+ """
+ void *ptr;
+ Py_ssize_t size;
+ if (PyObject_AsWriteBuffer(args, &ptr, &size) < 0)
+ return NULL;
+ return PyString_FromStringAndSize((char*)ptr, size);
+ """),
+ ("zero_out_writebuffer", "METH_O",
+ """
+ void *ptr;
+ Py_ssize_t size;
+ Py_ssize_t i;
+ if (PyObject_AsWriteBuffer(args, &ptr, &size) < 0)
+ return NULL;
+ for (i = 0; i < size; i++) {
+ ((char*)ptr)[i] = 0;
+ }
+ Py_RETURN_NONE;
+ """),
+ ])
+
+ def test_string(self):
+ buffer_support = self.get_buffer_support()
+
+ s = 'a\0x'
+
+ assert buffer_support.check_readbuffer(s)
+ assert s == buffer_support.readbuffer_as_string(s)
+ assert raises(TypeError, buffer_support.writebuffer_as_string, s)
+ assert s == buffer_support.charbuffer_as_string(s)
+
+ def test_buffer(self):
+ buffer_support = self.get_buffer_support()
+
+ s = 'a\0x'
+ buf = buffer(s)
+
+ assert buffer_support.check_readbuffer(buf)
+ assert s == buffer_support.readbuffer_as_string(buf)
+ assert raises(TypeError, buffer_support.writebuffer_as_string, buf)
+ assert s == buffer_support.charbuffer_as_string(buf)
+
+ def test_mmap(self):
+ import mmap
+ buffer_support = self.get_buffer_support()
+
+ s = 'a\0x'
+ mm = mmap.mmap(-1, 3)
+ mm[:] = s
+
+ assert buffer_support.check_readbuffer(mm)
+ assert s == buffer_support.readbuffer_as_string(mm)
+ assert s == buffer_support.writebuffer_as_string(mm)
+ assert s == buffer_support.charbuffer_as_string(mm)
+
+ s = '\0' * 3
+ buffer_support.zero_out_writebuffer(mm)
+ assert s == ''.join(mm)
+ assert s == buffer_support.readbuffer_as_string(mm)
+ assert s == buffer_support.writebuffer_as_string(mm)
+ assert s == buffer_support.charbuffer_as_string(mm)
+
+ s = '\0' * 3
+ ro_mm = mmap.mmap(-1, 3, access=mmap.ACCESS_READ)
+ assert buffer_support.check_readbuffer(ro_mm)
+ assert s == buffer_support.readbuffer_as_string(ro_mm)
+ assert raises(TypeError, buffer_support.writebuffer_as_string, ro_mm)
+ assert s == buffer_support.charbuffer_as_string(ro_mm)
+
+ def test_array(self):
+ import array
+ buffer_support = self.get_buffer_support()
+
+ s = 'a\0x'
+ a = array.array('B', [5, 0, 10])
+
+ buffer_support.zero_out_writebuffer(a)
+ assert list(a) == [0, 0, 0]
+
+ def test_nonbuffer(self):
+ # e.g. int
+ buffer_support = self.get_buffer_support()
+
+ assert not buffer_support.check_readbuffer(42)
+ assert raises(TypeError, buffer_support.readbuffer_as_string, 42)
+ assert raises(TypeError, buffer_support.writebuffer_as_string, 42)
+ assert raises(TypeError, buffer_support.charbuffer_as_string, 42)
+
+ def test_user_class(self):
+ class MyBuf(str):
+ pass
+ s = 'a\0x'
+ buf = MyBuf(s)
+ buffer_support = self.get_buffer_support()
+
+ assert buffer_support.check_readbuffer(buf)
+ assert s == buffer_support.readbuffer_as_string(buf)
+ assert raises(TypeError, buffer_support.writebuffer_as_string, buf)
+ assert s == buffer_support.charbuffer_as_string(buf)
+
+
diff --git a/pypy/module/cpyext/test0/test_bufferobject.py b/pypy/module/cpyext/test0/test_bufferobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test0/test_bufferobject.py
@@ -0,0 +1,123 @@
+from rpython.rtyper.lltypesystem import lltype
+from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.api import PyObject
+
+class AppTestBufferObject(AppTestCpythonExtensionBase):
+
+ def test_FromMemory(self):
+ module = self.import_extension('foo', [
+ ("get_FromMemory", "METH_NOARGS",
+ """
+ cbuf = malloc(4);
+ cbuf[0] = 'a';
+ cbuf[1] = 'b';
+ cbuf[2] = 'c';
+ cbuf[3] = '\\0';
+ return PyBuffer_FromMemory(cbuf, 4);
+ """),
+ ("free_buffer", "METH_NOARGS",
+ """
+ free(cbuf);
+ Py_RETURN_NONE;
+ """),
+ ("check_ascharbuffer", "METH_O",
+ """
+ char *ptr;
+ Py_ssize_t size;
+ if (PyObject_AsCharBuffer(args, (const char **)&ptr, &size) < 0)
+ return NULL;
+ return PyString_FromStringAndSize(ptr, size);
+ """)
+ ], prologue = """
+ static char* cbuf = NULL;
+ """)
+ buf = module.get_FromMemory()
+ assert str(buf) == 'abc\0'
+
+ assert module.check_ascharbuffer(buf) == 'abc\0'
+
+ module.free_buffer()
+
+ def test_Buffer_New(self):
+ module = self.import_extension('foo', [
+ ("buffer_new", "METH_NOARGS",
+ """
+ return PyBuffer_New(150);
+ """),
+ ])
+ b = module.buffer_new()
+ raises(AttributeError, getattr, b, 'x')
+
+ def test_array_buffer(self):
+ if self.runappdirect:
+ skip('PyBufferObject not available outside buffer object.c')
+ module = self.import_extension('foo', [
+ ("roundtrip", "METH_O",
+ """
+ PyBufferObject *buf = (PyBufferObject *)args;
+ return PyString_FromStringAndSize(buf->b_ptr, buf->b_size);
+ """),
+ ])
+ import array
+ a = array.array('c', 'text')
+ b = buffer(a)
+ assert module.roundtrip(b) == 'text'
+
+
+ def test_issue2752(self):
+ iterations = 10
+ if self.runappdirect:
+ iterations = 2000
+ module = self.import_extension('foo', [
+ ("test_mod", 'METH_VARARGS',
+ """
+ PyObject *obj;
+ Py_buffer bp;
+ if (!PyArg_ParseTuple(args, "O", &obj))
+ return NULL;
+
+ if (PyObject_GetBuffer(obj, &bp, PyBUF_SIMPLE) == -1)
+ return NULL;
+
+ if (((unsigned char*)bp.buf)[0] != '0') {
+ void * buf = (void*)bp.buf;
+ unsigned char val[4];
+ char * s = PyString_AsString(obj);
+ memcpy(val, bp.buf, 4);
+ PyBuffer_Release(&bp);
+ if (PyObject_GetBuffer(obj, &bp, PyBUF_SIMPLE) == -1)
+ return NULL;
+ PyErr_Format(PyExc_ValueError,
+ "mismatch: %p [%x %x %x %x...] now %p [%x %x %x %x...] as str '%s'",
+ buf, val[0], val[1], val[2], val[3],
+ (void *)bp.buf,
+ ((unsigned char*)bp.buf)[0],
+ ((unsigned char*)bp.buf)[1],
+ ((unsigned char*)bp.buf)[2],
+ ((unsigned char*)bp.buf)[3],
+ s);
+ PyBuffer_Release(&bp);
+ return NULL;
+ }
+
+ PyBuffer_Release(&bp);
+ Py_RETURN_NONE;
+ """),
+ ])
+ bufsize = 4096
+ def getdata(bufsize):
+ data = b'01234567'
+ for x in range(18):
+ data += data
+ if len(data) >= bufsize:
+ break
+ return data
+ for j in range(iterations):
+ block = getdata(bufsize)
+ assert block[:8] == '01234567'
+ try:
+ module.test_mod(block)
+ except ValueError as e:
+ print("%s at it=%d" % (e, j))
+ assert False
diff --git a/pypy/module/cpyext/test0/test_bytesobject.py b/pypy/module/cpyext/test0/test_bytesobject.py
--- a/pypy/module/cpyext/test0/test_bytesobject.py
+++ b/pypy/module/cpyext/test0/test_bytesobject.py
@@ -314,3 +314,298 @@
w_obj = space.wrap(u"test")
with raises_w(space, TypeError):
api.PyBytes_FromObject(w_obj)
+ PyString_AS_STRING(o);
+ PyString_AS_STRING(u);
+
+ return o;
+ """)])
+ assert module.test_macro_invocations() == ''
+
+ def test_hash_and_state(self):
+ module = self.import_extension('foo', [
+ ("test_hash", "METH_VARARGS",
+ '''
+ PyObject* obj = (PyTuple_GetItem(args, 0));
+ long hash = ((PyBytesObject*)obj)->ob_shash;
+ return PyLong_FromLong(hash);
+ '''
+ ),
+ ("test_sstate", "METH_NOARGS",
+ '''
+ PyObject *s = PyString_FromString("xyz");
+ /*int sstate = ((PyBytesObject*)s)->ob_sstate;
+ printf("sstate now %d\\n", sstate);*/
+ PyString_InternInPlace(&s);
+ /*sstate = ((PyBytesObject*)s)->ob_sstate;
+ printf("sstate now %d\\n", sstate);*/
+ Py_DECREF(s);
+ return PyBool_FromLong(1);
+ '''),
+ ], prologue='#include <stdlib.h>')
+ res = module.test_hash("xyz")
+ assert res == hash('xyz')
+ # doesn't really test, but if printf is enabled will prove sstate
+ assert module.test_sstate()
+
+ def test_subclass(self):
+ # taken from PyStringArrType_Type in numpy's scalartypes.c.src
+ module = self.import_extension('bar', [
+ ("newsubstr", "METH_O",
+ """
+ PyObject * obj;
+ char * data;
+ int len;
+
+ data = PyString_AS_STRING(args);
+ len = PyString_GET_SIZE(args);
+ if (data == NULL)
+ Py_RETURN_NONE;
+ obj = PyArray_Scalar(data, len);
+ return obj;
+ """),
+ ("get_len", "METH_O",
+ """
+ return PyLong_FromLong(PyObject_Size(args));
+ """),
+ ('has_nb_add', "METH_O",
+ '''
+ if (args->ob_type->tp_as_number == NULL) {
+ Py_RETURN_FALSE;
+ }
+ if (args->ob_type->tp_as_number->nb_add == NULL) {
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+ '''),
+ ], prologue="""
+ #include <Python.h>
+ PyTypeObject PyStringArrType_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "bar.string_", /* tp_name*/
+ sizeof(PyBytesObject), /* tp_basicsize*/
+ 0 /* tp_itemsize */
+ };
+
+ static PyObject *
+ stringtype_repr(PyObject *self)
+ {
+ const char *dptr, *ip;
+ int len;
+ PyObject *new;
+
+ ip = dptr = PyString_AS_STRING(self);
+ len = PyString_GET_SIZE(self);
+ dptr += len-1;
+ while(len > 0 && *dptr-- == 0) {
+ len--;
+ }
+ new = PyString_FromStringAndSize(ip, len);
+ if (new == NULL) {
+ return PyString_FromString("");
+ }
+ return new;
+ }
+
+ static PyObject *
+ stringtype_str(PyObject *self)
+ {
+ const char *dptr, *ip;
+ int len;
+ PyObject *new;
+
+ ip = dptr = PyString_AS_STRING(self);
+ len = PyString_GET_SIZE(self);
+ dptr += len-1;
+ while(len > 0 && *dptr-- == 0) {
+ len--;
+ }
+ new = PyString_FromStringAndSize(ip, len);
+ if (new == NULL) {
+ return PyString_FromString("");
+ }
+ return new;
+ }
+
+ PyObject *
+ PyArray_Scalar(char *data, int n)
+ {
+ PyTypeObject *type = &PyStringArrType_Type;
+ PyObject *obj;
+ void *destptr;
+ int itemsize = n;
+ obj = type->tp_alloc(type, itemsize);
+ if (obj == NULL) {
+ return NULL;
+ }
+ destptr = PyString_AS_STRING(obj);
+ ((PyBytesObject *)obj)->ob_shash = -1;
+ memcpy(destptr, data, itemsize);
+ return obj;
+ }
+ """, more_init = '''
+ PyStringArrType_Type.tp_alloc = NULL;
+ PyStringArrType_Type.tp_free = NULL;
+
+ PyStringArrType_Type.tp_repr = stringtype_repr;
+ PyStringArrType_Type.tp_str = stringtype_str;
+ PyStringArrType_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
+ PyStringArrType_Type.tp_itemsize = sizeof(char);
+ PyStringArrType_Type.tp_base = &PyString_Type;
+ PyStringArrType_Type.tp_hash = PyString_Type.tp_hash;
+ if (PyType_Ready(&PyStringArrType_Type) < 0) INITERROR;
+ ''')
+
+ a = module.newsubstr('abc')
+ assert module.has_nb_add('a') is False
+ assert module.has_nb_add(a) is False
+ assert type(a).__name__ == 'string_'
+ assert a == 'abc'
+ assert 3 == module.get_len(a)
+ b = module.newsubstr('')
+ assert 0 == module.get_len(b)
+
+class TestBytes(BaseApiTest):
+ def test_bytes_resize(self, space):
+ py_str = new_empty_str(space, 10)
+ ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+ py_str.c_ob_sval[0] = 'a'
+ py_str.c_ob_sval[1] = 'b'
+ py_str.c_ob_sval[2] = 'c'
+ ar[0] = rffi.cast(PyObject, py_str)
+ _PyString_Resize(space, ar, 3)
+ py_str = rffi.cast(PyBytesObject, ar[0])
+ assert py_str.c_ob_size == 3
+ assert py_str.c_ob_sval[1] == 'b'
+ assert py_str.c_ob_sval[3] == '\x00'
+ # the same for growing
+ ar[0] = rffi.cast(PyObject, py_str)
+ _PyString_Resize(space, ar, 10)
+ py_str = rffi.cast(PyBytesObject, ar[0])
+ assert py_str.c_ob_size == 10
+ assert py_str.c_ob_sval[1] == 'b'
+ assert py_str.c_ob_sval[10] == '\x00'
+ decref(space, ar[0])
+ lltype.free(ar, flavor='raw')
+
+ def test_string_buffer(self, space):
+ py_str = new_empty_str(space, 10)
+ c_buf = py_str.c_ob_type.c_tp_as_buffer
+ assert c_buf
+ py_obj = rffi.cast(PyObject, py_str)
+ assert generic_cpy_call(space, c_buf.c_bf_getsegcount,
+ py_obj, lltype.nullptr(Py_ssize_tP.TO)) == 1
+ ref = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
+ assert generic_cpy_call(space, c_buf.c_bf_getsegcount,
+ py_obj, ref) == 1
+ assert ref[0] == 10
+ lltype.free(ref, flavor='raw')
+ ref = lltype.malloc(rffi.VOIDPP.TO, 1, flavor='raw')
+ assert generic_cpy_call(space, c_buf.c_bf_getreadbuffer,
+ py_obj, 0, ref) == 10
+ lltype.free(ref, flavor='raw')
+ decref(space, py_obj)
+
+ def test_Concat(self, space):
+ ref = make_ref(space, space.wrap('abc'))
+ ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+ ptr[0] = ref
+ prev_refcnt = ref.c_ob_refcnt
+ PyString_Concat(space, ptr, space.wrap('def'))
+ assert ref.c_ob_refcnt == prev_refcnt - 1
+ assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
+ with pytest.raises(OperationError):
+ PyString_Concat(space, ptr, space.w_None)
+ assert not ptr[0]
+ ptr[0] = lltype.nullptr(PyObject.TO)
+ PyString_Concat(space, ptr, space.wrap('def')) # should not crash
+ lltype.free(ptr, flavor='raw')
+
+ def test_ConcatAndDel(self, space):
+ ref1 = make_ref(space, space.wrap('abc'))
+ ref2 = make_ref(space, space.wrap('def'))
+ ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+ ptr[0] = ref1
+ prev_refcnf = ref2.c_ob_refcnt
+ PyString_ConcatAndDel(space, ptr, ref2)
+ assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
+ assert ref2.c_ob_refcnt == prev_refcnf - 1
+ decref(space, ptr[0])
+ ptr[0] = lltype.nullptr(PyObject.TO)
+ ref2 = make_ref(space, space.wrap('foo'))
+ prev_refcnf = ref2.c_ob_refcnt
+ PyString_ConcatAndDel(space, ptr, ref2) # should not crash
+ assert ref2.c_ob_refcnt == prev_refcnf - 1
+ lltype.free(ptr, flavor='raw')
+
+ def test_format(self, space):
+ assert "1 2" == space.unwrap(
+ PyString_Format(space, space.wrap('%s %d'), space.wrap((1, 2))))
+
+ def test_asbuffer(self, space):
+ bufp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
+ lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
+
+ w_text = space.wrap("text")
+ ref = make_ref(space, w_text)
+ prev_refcnt = ref.c_ob_refcnt
+ assert PyObject_AsCharBuffer(space, ref, bufp, lenp) == 0
+ assert ref.c_ob_refcnt == prev_refcnt
+ assert lenp[0] == 4
+ assert rffi.charp2str(bufp[0]) == 'text'
+ lltype.free(bufp, flavor='raw')
+ lltype.free(lenp, flavor='raw')
+ decref(space, ref)
+
+ def test_intern(self, space):
+ buf = rffi.str2charp("test")
+ w_s1 = PyString_InternFromString(space, buf)
+ w_s2 = PyString_InternFromString(space, buf)
+ rffi.free_charp(buf)
+ assert w_s1 is w_s2
+
+ def test_AsEncodedObject(self, space):
+ ptr = space.wrap('abc')
+
+ errors = rffi.str2charp("strict")
+
+ encoding = rffi.str2charp("hex")
+ res = PyString_AsEncodedObject(space, ptr, encoding, errors)
+ assert space.unwrap(res) == "616263"
+
+ res = PyString_AsEncodedObject(space,
+ ptr, encoding, lltype.nullptr(rffi.CCHARP.TO))
+ assert space.unwrap(res) == "616263"
+ rffi.free_charp(encoding)
+
+ encoding = rffi.str2charp("unknown_encoding")
+ with raises_w(space, LookupError):
+ PyString_AsEncodedObject(space, ptr, encoding, errors)
+ rffi.free_charp(encoding)
+
+ rffi.free_charp(errors)
+
+ NULL = lltype.nullptr(rffi.CCHARP.TO)
+ res = PyString_AsEncodedObject(space, ptr, NULL, NULL)
+ assert space.unwrap(res) == "abc"
+ with raises_w(space, TypeError):
+ PyString_AsEncodedObject(space, space.wrap(2), NULL, NULL)
+
+ def test_AsDecodedObject(self, space):
+ w_str = space.wrap('caf\xe9')
+ encoding = rffi.str2charp("latin-1")
+ w_res = PyString_AsDecodedObject(space, w_str, encoding, None)
+ rffi.free_charp(encoding)
+ assert w_res._utf8 == u"caf\xe9".encode('utf8')
+
+ def test_eq(self, space):
+ assert 1 == _PyString_Eq(
+ space, space.wrap("hello"), space.wrap("hello"))
+ assert 0 == _PyString_Eq(
+ space, space.wrap("hello"), space.wrap("world"))
+
+ def test_join(self, space):
+ w_sep = space.wrap('<sep>')
+ w_seq = space.wrap(['a', 'b'])
+ w_joined = _PyString_Join(space, w_sep, w_seq)
+ assert space.unwrap(w_joined) == 'a<sep>b'
diff --git a/pypy/module/cpyext/test0/test_intobject.py b/pypy/module/cpyext/test0/test_intobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test0/test_intobject.py
@@ -0,0 +1,247 @@
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.intobject import (
+ PyInt_Check, PyInt_AsLong, PyInt_AS_LONG,
+ PyInt_AsUnsignedLong, PyInt_AsUnsignedLongMask,
+ PyInt_AsUnsignedLongLongMask)
+from pypy.module.cpyext.pyobject import (decref, make_ref,
+ get_w_obj_and_decref)
+from pypy.module.cpyext.state import State
+import sys
+
+class TestIntObject(BaseApiTest):
+ def test_intobject(self, space):
+ state = space.fromcache(State)
+ assert PyInt_Check(space, space.wrap(3))
+ assert PyInt_Check(space, space.w_True)
+ assert not PyInt_Check(space, space.wrap((1, 2, 3)))
+ for i in [3, -5, -1, -sys.maxint, sys.maxint - 1]:
+ x = PyInt_AsLong(space, space.wrap(i))
+ y = PyInt_AS_LONG(space, space.wrap(i))
+ assert x == i
+ assert y == i
+ py_x = state.C.PyInt_FromLong(x + 1)
+ w_x = get_w_obj_and_decref(space, py_x)
+ assert space.type(w_x) is space.w_int
+ assert space.eq_w(w_x, space.wrap(i + 1))
+
+ with raises_w(space, TypeError):
+ PyInt_AsLong(space, space.w_None)
+
+ with raises_w(space, TypeError):
+ PyInt_AsLong(space, None)
+
+ assert PyInt_AsUnsignedLong(space, space.wrap(sys.maxint)) == sys.maxint
+ with raises_w(space, ValueError):
+ PyInt_AsUnsignedLong(space, space.wrap(-5))
+
+ assert (PyInt_AsUnsignedLongMask(space, space.wrap(sys.maxint))
+ == sys.maxint)
+ assert (PyInt_AsUnsignedLongMask(space, space.wrap(10 ** 30))
+ == 10 ** 30 % ((sys.maxint + 1) * 2))
+
+ assert (PyInt_AsUnsignedLongLongMask(space, space.wrap(sys.maxint))
+ == sys.maxint)
+ assert (PyInt_AsUnsignedLongLongMask(space, space.wrap(10 ** 30))
+ == 10 ** 30 % (2 ** 64))
+
+ def test_freelist_direct(self, space):
+ state = space.fromcache(State)
+ p_x = state.C.PyInt_FromLong(12345678)
+ decref(space, p_x)
+ p_y = state.C.PyInt_FromLong(87654321)
+ # check that the address is the same, i.e. that the freelist did its
+ # job
+ assert p_x == p_y
+ decref(space, p_y)
+
+ def test_freelist_make_ref(self, space):
+ w_x = space.newint(12345678)
+ w_y = space.newint(87654321)
+ p_x = make_ref(space, w_x)
+ decref(space, p_x)
+ p_y = make_ref(space, w_y)
+ # check that the address is the same: note that w_x does NOT keep p_x
+ # alive, because in make_ref we have a special case for ints
+ assert p_x == p_y
+ decref(space, p_y)
+
+ def test_freelist_int_subclass(self, space):
+ w_MyInt = space.appexec([], """():
+ class MyInt(int):
+ pass
+ return MyInt""")
+ w_x = space.call_function(w_MyInt, space.newint(12345678))
+ w_y = space.call_function(w_MyInt, space.newint(87654321))
+ p_x = make_ref(space, w_x)
+ decref(space, p_x)
+ p_y = make_ref(space, w_y)
+ # now the address is different because the freelist does not work for
+ # int subclasses
+ assert p_x != p_y
+ decref(space, p_y)
+
+ def test_coerce(self, space):
+ w_obj = space.appexec([], """():
+ class Coerce(object):
+ def __int__(self):
+ return 42
+ return Coerce()""")
+ assert PyInt_AsLong(space, w_obj) == 42
+
+class AppTestIntObject(AppTestCpythonExtensionBase):
+ def test_fromstring(self):
+ module = self.import_extension('foo', [
+ ("from_string", "METH_NOARGS",
+ """
+ return PyInt_FromString("1234", NULL, 16);
+ """),
+ ])
+ assert module.from_string() == 0x1234
+ assert type(module.from_string()) is int
+
+ def test_size_t(self):
+ module = self.import_extension('foo', [
+ ("values", "METH_NOARGS",
+ """
+ return Py_BuildValue("NNNN",
+ PyInt_FromSize_t(123),
+ PyInt_FromSize_t((size_t)-1),
+ PyInt_FromSsize_t(123),
+ PyInt_FromSsize_t((size_t)-1));
+ """),
+ ])
+ values = module.values()
+ types = [type(x) for x in values]
+ assert types == [int, long, int, int]
+
+ def test_int_subtype(self):
+ module = self.import_extension(
+ 'foo', [
+ ("newEnum", "METH_VARARGS",
+ """
+ EnumObject *enumObj;
+ int intval;
+ PyObject *name;
+
+ if (!PyArg_ParseTuple(args, "Oi", &name, &intval))
+ return NULL;
+
+ enumObj = PyObject_New(EnumObject, &Enum_Type);
+ if (!enumObj) {
+ return NULL;
+ }
+
+ enumObj->ob_ival = intval;
+ Py_INCREF(name);
+ enumObj->ob_name = name;
+
+ return (PyObject *)enumObj;
+ """),
+ ],
+ prologue="""
+ #include "structmember.h"
+ typedef struct
+ {
+ PyObject_HEAD
+ long ob_ival;
+ PyObject* ob_name;
+ } EnumObject;
+
+ static void
+ enum_dealloc(PyObject *op)
+ {
+ Py_DECREF(((EnumObject *)op)->ob_name);
+ Py_TYPE(op)->tp_free(op);
+ }
+
+ static PyMemberDef enum_members[] = {
+ {"name", T_OBJECT, offsetof(EnumObject, ob_name), 0, NULL},
+ {NULL} /* Sentinel */
+ };
+
+ PyTypeObject Enum_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ /*tp_name*/ "Enum",
+ /*tp_basicsize*/ sizeof(EnumObject),
+ /*tp_itemsize*/ 0,
+ /*tp_dealloc*/ enum_dealloc,
+ /*tp_print*/ 0,
+ /*tp_getattr*/ 0,
+ /*tp_setattr*/ 0,
+ /*tp_compare*/ 0,
+ /*tp_repr*/ 0,
+ /*tp_as_number*/ 0,
+ /*tp_as_sequence*/ 0,
+ /*tp_as_mapping*/ 0,
+ /*tp_hash*/ 0,
+ /*tp_call*/ 0,
+ /*tp_str*/ 0,
+ /*tp_getattro*/ 0,
+ /*tp_setattro*/ 0,
+ /*tp_as_buffer*/ 0,
+ /*tp_flags*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+ /*tp_doc*/ 0,
+ /*tp_traverse*/ 0,
+ /*tp_clear*/ 0,
+ /*tp_richcompare*/ 0,
+ /*tp_weaklistoffset*/ 0,
+ /*tp_iter*/ 0,
+ /*tp_iternext*/ 0,
+ /*tp_methods*/ 0,
+ /*tp_members*/ enum_members,
+ /*tp_getset*/ 0,
+ /*tp_base*/ 0, /* set to &PyInt_Type in init function for MSVC */
+ /*tp_dict*/ 0,
+ /*tp_descr_get*/ 0,
+ /*tp_descr_set*/ 0,
+ /*tp_dictoffset*/ 0,
+ /*tp_init*/ 0,
+ /*tp_alloc*/ 0,
+ /*tp_new*/ 0
+ };
+ """, more_init = '''
+ Enum_Type.tp_base = &PyInt_Type;
+ if (PyType_Ready(&Enum_Type) < 0) INITERROR;
+ ''')
+
+ a = module.newEnum("ULTIMATE_ANSWER", 42)
+ assert type(a).__name__ == "Enum"
+ assert isinstance(a, int)
+ assert a == int(a) == 42
+ assert a.name == "ULTIMATE_ANSWER"
+
+ def test_int_cast(self):
+ mod = self.import_extension('foo', [
+ #prove it works for ints
+ ("test_int", "METH_NOARGS",
+ """
+ PyObject * obj = PyInt_FromLong(42);
+ PyObject * val;
+ if (!PyInt_Check(obj)) {
+ Py_DECREF(obj);
+ PyErr_SetNone(PyExc_ValueError);
+ return NULL;
+ }
+ val = PyInt_FromLong(((PyIntObject *)obj)->ob_ival);
+ Py_DECREF(obj);
+ return val;
+ """
+ ),
+ ])
+ i = mod.test_int()
+ assert isinstance(i, int)
+ assert i == 42
+
+ def test_int_macros(self):
+ mod = self.import_extension('foo', [
+ ("test_macros", "METH_NOARGS",
+ """
+ PyObject * obj = PyInt_FromLong(42);
+ PyIntObject * i = (PyIntObject*)obj;
+ PyInt_AS_LONG(obj);
+ PyInt_AS_LONG(i);
+ Py_RETURN_NONE;
+ """
+ ),
+ ])
diff --git a/pypy/module/select/__init__.py b/pypy/module/select/__init__.py
--- a/pypy/module/select/__init__.py
+++ b/pypy/module/select/__init__.py
@@ -3,6 +3,7 @@
import sys
import os
+from rpython.rlib import _rsocket_rffi as _c
class Module(MixedModule):
@@ -31,6 +32,10 @@
for symbol in symbol_map:
interpleveldefs[symbol] = "space.wrap(interp_kqueue.%s)" % symbol
+ if _c.PIPE_BUF is not None:
+ interpleveldefs['PIPE_BUF'] = 'space.wrap(%r)' % _c.PIPE_BUF
+
+
def buildloaders(cls):
from rpython.rlib import rpoll
for name in rpoll.eventnames:
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -319,6 +319,11 @@
# ^^^ CPython gives 100, PyPy gives 1. I think both are OK as
# long as there is no crash.
+ def test_PIPE_BUF(self):
+ # no PIPE_BUF on Windows; this test class is skipped on Windows.
+ import select
+ assert isinstance(select.PIPE_BUF, int)
+
class AppTestSelectWithSockets(_AppTestSelect):
"""Same tests with connected sockets.
diff --git a/pypy/module/test_lib_pypy/test_code_extra.py b/pypy/module/test_lib_pypy/test_code_extra.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/test_code_extra.py
@@ -0,0 +1,19 @@
+import py
+import sys
+import cStringIO
+import code
+
+
+def test_flush_stdout_on_error():
+ runner = code.InteractiveInterpreter()
+ old_stdout = sys.stdout
+ try:
+ mystdout = cStringIO.StringIO()
+ sys.stdout = mystdout
+ runner.runcode(compile("print 5,;0/0", "<interactive>", "exec"))
+ finally:
+ sys.stdout = old_stdout
+
+ if '__pypy__' not in sys.builtin_module_names:
+ py.test.skip('pypy only test')
+ assert mystdout.getvalue() == "5\n"
diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -1164,3 +1164,31 @@
assert u'A\u03a3\u0345'.lower() == u'a\u03c2\u0345'
assert u'\u03a3\u0345 '.lower() == u'\u03c3\u0345 '
+ def test_unicode_constructor_misc(self):
+ x = u'foo'
+ x += u'bar'
+ assert unicode(x) is x
+ #
+ class U(unicode):
+ def __unicode__(self):
+ return u'BOK'
+ u = U(x)
+ assert unicode(u) == u'BOK'
+ #
+ class U2(unicode):
+ pass
+ z = U2(u'foobaz')
+ assert type(unicode(z)) is unicode
+ assert unicode(z) == u'foobaz'
+ #
+ # two completely corner cases where we differ from CPython:
+ #assert unicode(encoding='supposedly_the_encoding') == u''
+ #assert unicode(errors='supposedly_the_error') == u''
+ e = raises(TypeError, unicode, u'', 'supposedly_the_encoding')
+ assert str(e.value) == 'decoding Unicode is not supported'
+ e = raises(TypeError, unicode, u'', errors='supposedly_the_error')
+ assert str(e.value) == 'decoding Unicode is not supported'
+ e = raises(TypeError, unicode, u, 'supposedly_the_encoding')
+ assert str(e.value) == 'decoding Unicode is not supported'
+ e = raises(TypeError, unicode, z, 'supposedly_the_encoding')
+ assert str(e.value) == 'decoding Unicode is not supported'
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -122,7 +122,7 @@
@staticmethod
def convert_arg_to_w_unicode(space, w_other, strict=None):
- if isinstance(w_other, W_UnicodeObject):
+ if space.is_w(space.type(w_other), space.w_unicode):
return w_other
if space.isinstance_w(w_other, space.w_bytes):
raise oefmt(space.w_TypeError,
@@ -130,7 +130,7 @@
if strict:
raise oefmt(space.w_TypeError,
"%s arg must be None, unicode or str", strict)
- return unicode_from_encoded_object(space, w_other, None, "strict")
+ return unicode_from_encoded_object(space, w_other, 'utf8', "strict")
def convert_to_w_unicode(self, space):
return self
diff --git a/rpython/doc/examples.rst b/rpython/doc/examples.rst
--- a/rpython/doc/examples.rst
+++ b/rpython/doc/examples.rst
@@ -19,7 +19,7 @@
* Typhon, 'A virtual machine for Monte', in active development,
https://github.com/monte-language/typhon
* Tulip, an untyped functional language, in language design mode, maintained,
- https://github.com/tulip-lang/tulip/
+ https://github.com/tulip-lang/tulip/
* Pycket, a Racket implementation, proof of concept, small language core
working, a lot of primitives are missing. Slow development
https://github.com/samth/pycket
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -33,6 +33,7 @@
'arpa/inet.h',
'stdint.h',
'errno.h',
+ 'limits.h',
)
if _HAS_AF_PACKET:
includes += ('netpacket/packet.h',
@@ -113,6 +114,7 @@
F_GETFL = platform.DefinedConstantInteger('F_GETFL')
F_SETFL = platform.DefinedConstantInteger('F_SETFL')
FIONBIO = platform.DefinedConstantInteger('FIONBIO')
+ PIPE_BUF = platform.DefinedConstantInteger('PIPE_BUF')
INVALID_SOCKET = platform.DefinedConstantInteger('INVALID_SOCKET')
INET_ADDRSTRLEN = platform.DefinedConstantInteger('INET_ADDRSTRLEN')
@@ -1085,6 +1087,7 @@
WSAEWOULDBLOCK = cConfig.WSAEWOULDBLOCK or cConfig.EWOULDBLOCK
WSAEAFNOSUPPORT = cConfig.WSAEAFNOSUPPORT or cConfig.EAFNOSUPPORT
EISCONN = cConfig.EISCONN or cConfig.WSAEISCONN
+PIPE_BUF = cConfig.PIPE_BUF # may be None
linux = cConfig.linux
WIN32 = cConfig.WIN32
More information about the pypy-commit
mailing list