Author: Matti Picus <[email protected]>
Branch: unicode-utf8-py3
Changeset: r95098:b806e254dff4
Date: 2018-09-11 22:56 +0300
http://bitbucket.org/pypy/pypy/changeset/b806e254dff4/
Log: merge py3.5 into branch
diff --git a/pypy/module/_io/test/test_ztranslation.py
b/pypy/module/_io/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_io/test/test_ztranslation.py
@@ -0,0 +1,15 @@
+from pypy.interpreter.typedef import GetSetProperty
+from pypy.module.exceptions.interp_exceptions import W_BaseException
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ # XXX: PyTraceback usage in these methods blows up checkmodule
+ def descr_gettraceback(self, space):
+ return space.w_None
+ def descr_settraceback(self, space, w_newtraceback):
+ pass
+ W_BaseException.descr_gettraceback = descr_gettraceback
+ W_BaseException.descr_settraceback = descr_settraceback
+ W_BaseException.typedef.add_entries(
+ __traceback__=GetSetProperty(descr_gettraceback, descr_settraceback))
+ checkmodule('_io')
diff --git a/pypy/module/cpyext/test0/test_abstract.py
b/pypy/module/cpyext/test0/test_abstract.py
deleted file mode 100644
--- a/pypy/module/cpyext/test0/test_abstract.py
+++ /dev/null
@@ -1,130 +0,0 @@
-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
deleted file mode 100644
--- a/pypy/module/cpyext/test0/test_bufferobject.py
+++ /dev/null
@@ -1,123 +0,0 @@
-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_intobject.py
b/pypy/module/cpyext/test0/test_intobject.py
deleted file mode 100644
--- a/pypy/module/cpyext/test0/test_intobject.py
+++ /dev/null
@@ -1,247 +0,0 @@
-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/test_lib_pypy/test_code_extra.py
b/pypy/module/test_lib_pypy/test_code_extra.py
deleted file mode 100644
--- a/pypy/module/test_lib_pypy/test_code_extra.py
+++ /dev/null
@@ -1,19 +0,0 @@
-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,31 +1164,53 @@
assert u'A\u03a3\u0345'.lower() == u'a\u03c2\u0345'
assert u'\u03a3\u0345 '.lower() == u'\u03c3\u0345 '
+ def test_encode_wrong_errors(self):
+ assert ''.encode(errors='some_wrong_name') == b''
+
+ def test_casefold(self):
+ assert u'hello'.casefold() == u'hello'
+ assert u'hELlo'.casefold() == u'hello'
+ assert u'ß'.casefold() == u'ss'
+ assert u'fi'.casefold() == u'fi'
+ assert u'\u03a3'.casefold() == u'\u03c3'
+ assert u'A\u0345\u03a3'.casefold() == u'a\u03b9\u03c3'
+ assert u'\u00b5'.casefold() == u'\u03bc'
+
+ def test_lower_3a3(self):
+ # Special case for GREEK CAPITAL LETTER SIGMA U+03A3
+ assert u'\u03a3'.lower() == u'\u03c3'
+ assert u'\u0345\u03a3'.lower() == u'\u0345\u03c3'
+ assert u'A\u0345\u03a3'.lower() == u'a\u0345\u03c2'
+ assert u'A\u0345\u03a3a'.lower() == u'a\u0345\u03c3a'
+ assert u'A\u0345\u03a3'.lower() == u'a\u0345\u03c2'
+ 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
+ assert str(x) is x
#
- class U(unicode):
- def __unicode__(self):
+ class U(str):
+ def __str__(self):
return u'BOK'
u = U(x)
- assert unicode(u) == u'BOK'
+ assert str(u) == u'BOK'
#
- class U2(unicode):
+ class U2(str):
pass
z = U2(u'foobaz')
- assert type(unicode(z)) is unicode
- assert unicode(z) == u'foobaz'
+ assert type(str(z)) is str
+ assert str(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'
+ e = raises(TypeError, str, u'', 'supposedly_the_encoding')
+ assert str(e.value) == 'decoding str is not supported'
+ e = raises(TypeError, str, u'', errors='supposedly_the_error')
+ assert str(e.value) == 'decoding str is not supported'
+ e = raises(TypeError, str, u, 'supposedly_the_encoding')
+ assert str(e.value) == 'decoding str is not supported'
+ e = raises(TypeError, str, z, 'supposedly_the_encoding')
+ assert str(e.value) == 'decoding str 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
@@ -146,6 +146,9 @@
def _generic_name(self):
return "str"
+ def _generic_name(self):
+ return "str"
+
def _isupper(self, ch):
return unicodedb.isupper(ch)
@@ -1219,7 +1222,7 @@
try:
rutf8.check_ascii(utf8)
except rutf8.CheckError as a:
- eh = unicodehelper.encode_error_handler(space)
+ eh = unicodehelper.encode_error_handler(space)
eh(None, "ascii", "ordinal not in range(128)", utf8,
a.pos, a.pos + 1)
assert False, "always raises"
@@ -1257,6 +1260,7 @@
"use codecs.decode() to decode to arbitrary types",
encoding,
w_retval)
+ w_retval)
return w_retval
@@ -1280,7 +1284,6 @@
if space.lookup(w_obj, "__str__") is not None:
return space.str(w_obj)
return space.repr(w_obj)
-
def ascii_from_object(space, w_obj):
"""Implements builtins.ascii()"""
# repr is guaranteed to be unicode
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit