[pypy-commit] pypy unicode-utf8-py3: merge unicode-utf8 into branch
mattip
pypy.commits at gmail.com
Sun Nov 4 07:46:10 EST 2018
Author: Matti Picus <matti.picus at gmail.com>
Branch: unicode-utf8-py3
Changeset: r95272:f2ad44a9d50b
Date: 2018-11-04 07:25 -0500
http://bitbucket.org/pypy/pypy/changeset/f2ad44a9d50b/
Log: merge unicode-utf8 into branch
diff --git a/pypy/module/cpyext/test/buffer_test.c b/pypy/module/cpyext/test/buffer_test.c
--- a/pypy/module/cpyext/test/buffer_test.c
+++ b/pypy/module/cpyext/test/buffer_test.c
@@ -192,6 +192,10 @@
*/
#define GET_PYBUF_FLAG(FLAG) \
buf_flag = PyUnicode_FromString(#FLAG); \
+ if (buf_flag == NULL) { \
+ Py_DECREF(tmp); \
+ return NULL; \
+ } \
flag_matches = PyObject_RichCompareBool(buf_flag, tmp, Py_EQ); \
Py_DECREF(buf_flag); \
if (flag_matches == 1) { \
diff --git a/pypy/module/cpyext/test/test_abstract.py b/pypy/module/cpyext/test/test_abstract.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/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/test/test_bufferobject.py b/pypy/module/cpyext/test/test_bufferobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/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/test/test_intobject.py b/pypy/module/cpyext/test/test_intobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/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/cpyext/test/test_pycobject.py b/pypy/module/cpyext/test/test_pycobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_pycobject.py
@@ -0,0 +1,30 @@
+import py
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+class AppTestStringObject(AppTestCpythonExtensionBase):
+ def test_pycobject_import(self):
+ module = self.import_extension('foo', [
+ ("set_ptr", "METH_O",
+ """
+ PyObject *pointer, *module;
+ void *ptr = PyLong_AsVoidPtr(args);
+ if (PyErr_Occurred()) return NULL;
+ pointer = PyCObject_FromVoidPtr(ptr, NULL);
+ if (PyErr_Occurred()) return NULL;
+ module = PyImport_ImportModule("foo");
+ PyModule_AddObject(module, "_ptr", pointer);
+ Py_DECREF(module);
+ if (PyErr_Occurred()) return NULL;
+ Py_RETURN_NONE;
+ """),
+ ("get_ptr", "METH_NOARGS",
+ """
+ void *ptr = PyCObject_Import("foo", "_ptr");
+ if (PyErr_Occurred()) return NULL;
+ return PyLong_FromVoidPtr(ptr);
+ """)])
+ module.set_ptr(1234)
+ assert "PyCObject object" in str(module._ptr)
+ import gc; gc.collect()
+ assert module.get_ptr() == 1234
+ del module._ptr
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -428,6 +428,9 @@
def utf8_w(self, space):
return self._value
+ def utf8_w(self, space):
+ return self._value
+
def buffer_w(self, space, flags):
space.check_buf_flags(flags, True)
return SimpleView(StringBuffer(self._value))
diff --git a/rpython/rlib/rsre/rsre_core.py b/rpython/rlib/rsre/rsre_core.py
--- a/rpython/rlib/rsre/rsre_core.py
+++ b/rpython/rlib/rsre/rsre_core.py
@@ -460,7 +460,7 @@
ptr = self.start_ptr
if not self.next_char_ok(ctx, pattern, ptr, self.ppos3):
return
- self.start_ptr = ptr + 1
+ self.start_ptr = ctx.next(ptr)
return self.find_first_result(ctx, pattern)
def next_char_ok(self, ctx, pattern, ptr, ppos):
@@ -736,9 +736,9 @@
startptr, length_bytes = get_group_ref(ctx, marks, pattern.pat(ppos))
if length_bytes < 0:
return # group was not previously defined
- if not match_repeated_ignore(ctx, ptr, startptr, length_bytes):
+ ptr = match_repeated_ignore(ctx, ptr, startptr, length_bytes)
+ if ptr < ctx.ZERO:
return # no match
- ptr = ctx.go_forward_by_bytes(ptr, length_bytes)
ppos += 1
elif op == OPCODE_GROUPREF_EXISTS:
diff --git a/rpython/rlib/rsre/rsre_utf8.py b/rpython/rlib/rsre/rsre_utf8.py
--- a/rpython/rlib/rsre/rsre_utf8.py
+++ b/rpython/rlib/rsre/rsre_utf8.py
@@ -66,12 +66,12 @@
return position_high - position_low
-def make_utf8_ctx(pattern, utf8string, bytestart, byteend, flags):
+def make_utf8_ctx(utf8string, bytestart, byteend, flags):
if bytestart < 0: bytestart = 0
elif bytestart > len(utf8string): bytestart = len(utf8string)
if byteend < 0: byteend = 0
elif byteend > len(utf8string): byteend = len(utf8string)
- ctx = Utf8MatchContext(pattern, utf8string, bytestart, byteend, flags)
+ ctx = Utf8MatchContext(utf8string, bytestart, byteend, flags)
ctx.debug_check_pos(bytestart)
ctx.debug_check_pos(byteend)
return ctx
@@ -81,8 +81,8 @@
# utf8string.
from rpython.rlib.rsre.rsre_core import search_context
- ctx = make_utf8_ctx(pattern, utf8string, bytestart, byteend, flags)
- if search_context(ctx):
+ ctx = make_utf8_ctx(utf8string, bytestart, byteend, flags)
+ if search_context(ctx, pattern):
return ctx
else:
return None
@@ -93,9 +93,9 @@
# utf8string.
from rpython.rlib.rsre.rsre_core import match_context
- ctx = make_utf8_ctx(pattern, utf8string, bytestart, byteend, flags)
+ ctx = make_utf8_ctx(utf8string, bytestart, byteend, flags)
ctx.fullmatch_only = fullmatch
- if match_context(ctx):
+ if match_context(ctx, pattern):
return ctx
else:
return None
More information about the pypy-commit
mailing list