diff options
author | da-woods <dw-git@d-woods.co.uk> | 2023-03-01 08:01:34 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-01 09:01:34 +0100 |
commit | a8f4f066b547c6d76466a4a814160124534acd99 (patch) | |
tree | 42433ccbcc6d0bb7afcaaf060889a3c0f76e3d0a | |
parent | 038f94e9fd9e3b7ff279b3bd2627e974b94cb946 (diff) | |
download | cython-a8f4f066b547c6d76466a4a814160124534acd99.tar.gz |
Fix some issues when optimising the builtin memoryview (GH-5271)
Error in capitalization.
Closes https://github.com/cython/cython/issues/5270
Context managers were being optimized into a non-working state when involving a CloneNode.
Closes https://github.com/cython/cython/issues/5268
-rw-r--r-- | Cython/Compiler/Builtin.py | 6 | ||||
-rw-r--r-- | Cython/Compiler/ParseTreeTransforms.py | 1 | ||||
-rw-r--r-- | Cython/Compiler/PyrexTypes.py | 3 | ||||
-rw-r--r-- | Cython/Utility/Builtins.c | 6 | ||||
-rw-r--r-- | tests/run/builtin_memory_view.pyx | 26 |
5 files changed, 36 insertions, 6 deletions
diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index 6e5a65b85..cfdb25123 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -364,21 +364,21 @@ builtin_types_table = [ # TODO - format would be nice, but hard to get # __len__ can be accessed through a direct lookup of the buffer (but probably in Optimize.c) # error checking would ideally be limited api only - BuiltinProperty("ndim", PyrexTypes.c_int_type, '__Pyx_PyMemoryview_Get_ndim', + BuiltinProperty("ndim", PyrexTypes.c_int_type, '__Pyx_PyMemoryView_Get_ndim', exception_value="-1", exception_check=True, utility_code=TempitaUtilityCode.load_cached( "memoryview_get_from_buffer", "Builtins.c", context=dict(name="ndim") ) ), - BuiltinProperty("readonly", PyrexTypes.c_bint_type, '__Pyx_PyMemoryview_Get_readonly', + BuiltinProperty("readonly", PyrexTypes.c_bint_type, '__Pyx_PyMemoryView_Get_readonly', exception_value="-1", exception_check=True, utility_code=TempitaUtilityCode.load_cached( "memoryview_get_from_buffer", "Builtins.c", context=dict(name="readonly") ) ), - BuiltinProperty("itemsize", PyrexTypes.c_py_ssize_t_type, '__Pyx_PyMemoryview_Get_itemsize', + BuiltinProperty("itemsize", PyrexTypes.c_py_ssize_t_type, '__Pyx_PyMemoryView_Get_itemsize', exception_value="-1", exception_check=True, utility_code=TempitaUtilityCode.load_cached( "memoryview_get_from_buffer", "Builtins.c", diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 73af75cf7..4a3958a9c 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -1555,6 +1555,7 @@ class WithTransform(VisitorTransform, SkipDeclarations): pos = node.pos is_async = node.is_async body, target, manager = node.body, node.target, node.manager + manager = node.manager = ExprNodes.ProxyNode(manager) node.enter_call = ExprNodes.SimpleCallNode( pos, function=ExprNodes.AttributeNode( pos, obj=ExprNodes.CloneNode(manager), diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index b431255e4..f3d279356 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -1459,6 +1459,9 @@ class BuiltinObjectType(PyObjectType): elif type_name == 'int': # For backwards compatibility of (Py3) 'x: int' annotations in Py2, we also allow 'long' there. type_check = '__Pyx_Py3Int_Check' + elif type_name == "memoryview": + # captialize doesn't catch the 'V' + type_check = "PyMemoryView_Check" else: type_check = 'Py%s_Check' % type_name.capitalize() if exact and type_name not in ('bool', 'slice', 'Exception'): diff --git a/Cython/Utility/Builtins.c b/Cython/Utility/Builtins.c index b9de4104c..cf0c69e62 100644 --- a/Cython/Utility/Builtins.c +++ b/Cython/Utility/Builtins.c @@ -546,7 +546,7 @@ static CYTHON_INLINE int __Pyx_PySet_Update(PyObject* set, PyObject* it) { // buffer is in limited api from Py3.11 #if !CYTHON_COMPILING_IN_LIMITED_API || CYTHON_LIMITED_API >= 0x030b0000 -#define __Pyx_PyMemoryview_Get_{{name}}(o) PyMemoryView_GET_BUFFER(o)->{{name}} +#define __Pyx_PyMemoryView_Get_{{name}}(o) PyMemoryView_GET_BUFFER(o)->{{name}} #else {{py: out_types = dict( @@ -554,7 +554,7 @@ out_types = dict( len='Py_ssize_t', itemsize='Py_ssize_t') }} // can't get format like this unfortunately. It's unicode via getattr {{py: out_type = out_types[name]}} -static {{out_type}} __Pyx_PyMemoryview_Get_{{name}}(PyObject *obj); /* proto */ +static {{out_type}} __Pyx_PyMemoryView_Get_{{name}}(PyObject *obj); /* proto */ #endif ////////////// memoryview_get_from_buffer ///////////////////////// @@ -567,7 +567,7 @@ out_types = dict( len='Py_ssize_t', itemsize='Py_ssize_t') }} {{py: out_type = out_types[name]}} -static {{out_type}} __Pyx_PyMemoryview_Get_{{name}}(PyObject *obj) { +static {{out_type}} __Pyx_PyMemoryView_Get_{{name}}(PyObject *obj) { {{out_type}} result; PyObject *attr = PyObject_GetAttr(obj, PYIDENT("{{name}}")); if (!attr) { diff --git a/tests/run/builtin_memory_view.pyx b/tests/run/builtin_memory_view.pyx index 709be3b7d..34dd32ba7 100644 --- a/tests/run/builtin_memory_view.pyx +++ b/tests/run/builtin_memory_view.pyx @@ -4,6 +4,8 @@ from __future__ import print_function +import sys + cimport cython #from cpython.memoryview cimport PyMemoryView_GET_BUFFER @@ -38,3 +40,27 @@ def test_optimized_attributes(memoryview view): 1 1 True """ print(view.itemsize, view.ndim, view.readonly) + +def test_isinstance(x): + """ + >>> test_isinstance(b"abc") + False + >>> test_isinstance(memoryview(b"abc")) + True + """ + return isinstance(x, memoryview) + +def test_in_with(x): + """ + This is really just a compile test. An optimization was being + applied in a way that generated invalid code + >>> test_in_with(b"abc") + 98 + """ + if sys.version_info[0] < 3: + # Python 2 doesn't support memoryviews as context-managers + # so just skip the test + print(98) + return + with memoryview(x) as xv: + print(xv[1]) |