Repository: cython/cython

Issue:
[BUG] Cython 3.0.0b1 miscompilation on `memoryview`
### Describe the bug

The example code blow produces a miscompilation on 3.0.0b1 while it used to work on 3.0.0a11. This is the relevant error:

```
      pytact/data_reader.c:2082:46: error: ‘None’ undeclared (first use in this function)
       2082 |     __pyx_t_4 = __Pyx_PyObject_LookupSpecial(None, __pyx_n_s_enter); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2, __pyx_L3_error)
            |      
```

### Code to reproduce the behaviour:

```cython
def reader():
    with memoryview(b'abcefg') as mv:
        print(mv)
```


### Expected behaviour

_No response_

### Environment

OS: Arch linux
Python version 3.10.9
Cython version 3.0.0b1


### Additional context

_No response_


Discussion:
Presumably this is related to https://github.com/cython/cython/pull/5073
Thanks. Yes, probably related to the change you suggest.

Resolving patch:
diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py
--- a/Cython/Compiler/Builtin.py
+++ b/Cython/Compiler/Builtin.py
@@ -364,21 +364,21 @@ def declare_in_type(self, self_type):
         # 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
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -1555,6 +1555,7 @@ def visit_WithStatNode(self, node):
         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
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -1459,6 +1459,9 @@ def type_check_function(self, exact=True):
         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'):


Test patch:
diff --git a/tests/run/builtin_memory_view.pyx b/tests/run/builtin_memory_view.pyx
--- 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])