summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2023-03-01 08:01:34 +0000
committerGitHub <noreply@github.com>2023-03-01 09:01:34 +0100
commita8f4f066b547c6d76466a4a814160124534acd99 (patch)
tree42433ccbcc6d0bb7afcaaf060889a3c0f76e3d0a
parent038f94e9fd9e3b7ff279b3bd2627e974b94cb946 (diff)
downloadcython-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.py6
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py1
-rw-r--r--Cython/Compiler/PyrexTypes.py3
-rw-r--r--Cython/Utility/Builtins.c6
-rw-r--r--tests/run/builtin_memory_view.pyx26
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])