Commit 3226074e authored by da-woods's avatar da-woods Committed by GitHub

Ban templating C++ classes with reference counted types (GH-4337)

Specifically this disallows memoryviews, but it extends to any future type that Cython has to generate manual reference counting code for.

Closes https://github.com/cython/cython/issues/3085
parent 254ea20e
......@@ -3897,10 +3897,12 @@ class CppClassType(CType):
return error_type
has_object_template_param = False
for value in template_values:
if value.is_pyobject:
if value.is_pyobject or value.needs_refcounting:
has_object_template_param = True
type_description = "Python object" if value.is_pyobject else "Reference-counted"
error(pos,
"Python object type '%s' cannot be used as a template argument" % value)
"%s type '%s' cannot be used as a template argument" % (
type_description, value))
if has_object_template_param:
return error_type
return self.specialize(dict(zip(self.templates, template_values)))
......
......@@ -2021,7 +2021,7 @@ class StructOrUnionScope(Scope):
def declare_var(self, name, type, pos,
cname = None, visibility = 'private',
api = 0, in_pxd = 0, is_cdef = 0,
allow_pyobject=False, allow_memoryview=False):
allow_pyobject=False, allow_memoryview=False, allow_refcounted=False):
# Add an entry for an attribute.
if not cname:
cname = name
......@@ -2032,11 +2032,16 @@ class StructOrUnionScope(Scope):
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
self.var_entries.append(entry)
if type.is_pyobject and not allow_pyobject:
error(pos, "C struct/union member cannot be a Python object")
elif type.is_memoryviewslice and not allow_memoryview:
# Memory views wrap their buffer owner as a Python object.
error(pos, "C struct/union member cannot be a memory view")
if type.is_pyobject:
if not allow_pyobject:
error(pos, "C struct/union member cannot be a Python object")
elif type.is_memoryviewslice:
if not allow_memoryview:
# Memory views wrap their buffer owner as a Python object.
error(pos, "C struct/union member cannot be a memory view")
elif type.needs_refcounting:
if not allow_refcounted:
error(pos, "C struct/union member cannot be reference-counted type '%s'" % type)
if visibility != 'private':
error(pos, "C struct/union member cannot be declared %s" % visibility)
return entry
......
......@@ -12,7 +12,13 @@ def main():
cdef vector[A] va
va.push_back(A())
def memview():
import array
cdef vector[int[:]] vmv
vmv.push_back(array.array("i", [1,2,3]))
_ERRORS = u"""
10:16: Python object type 'Python object' cannot be used as a template argument
12:16: Python object type 'A' cannot be used as a template argument
17:16: Reference-counted type 'int[:]' cannot be used as a template argument
"""
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment