Commit f510accf authored by Stefan Behnel's avatar Stefan Behnel

Allow @final class decorator in pure mode. Was previously rejected for Python...

Allow @final class decorator in pure mode. Was previously rejected for Python classes with an @cclass decorator.
Closes #2040.
parent bae7fdc4
......@@ -79,6 +79,9 @@ Bugs fixed
* Some declaration types in ``libc.limits`` were corrected.
Patch by Jeroen Demeyer. (Github issue #2016)
* ``@cython.final`` was not accepted on Python classes with an ``@cython.cclass``
decorator. (Github issue #2040)
Other changes
-------------
......
......@@ -1033,7 +1033,8 @@ class InterpretCompilerDirectives(CythonTransform):
directives = []
realdecs = []
both = []
for dec in node.decorators:
# Decorators coming first take precedence.
for dec in node.decorators[::-1]:
new_directives = self.try_to_parse_directives(dec.decorator)
if new_directives is not None:
for directive in new_directives:
......@@ -1043,15 +1044,17 @@ class InterpretCompilerDirectives(CythonTransform):
directives.append(directive)
if directive[0] == 'staticmethod':
both.append(dec)
# Adapt scope type based on decorators that change it.
if directive[0] == 'cclass' and scope_name == 'class':
scope_name = 'cclass'
else:
realdecs.append(dec)
if realdecs and isinstance(node, (Nodes.CFuncDefNode, Nodes.CClassDefNode, Nodes.CVarDefNode)):
if realdecs and (scope_name == 'cclass' or
isinstance(node, (Nodes.CFuncDefNode, Nodes.CClassDefNode, Nodes.CVarDefNode))):
raise PostParseError(realdecs[0].pos, "Cdef functions/classes cannot take arbitrary decorators.")
else:
node.decorators = realdecs + both
node.decorators = realdecs[::-1] + both[::-1]
# merge or override repeated directives
optdict = {}
directives.reverse() # Decorators coming first take precedence
for directive in directives:
name, value = directive
if name in optdict:
......
......@@ -341,3 +341,22 @@ def ccall_except_check_always(x):
if x == 0:
raise ValueError
return x+1
@cython.final
@cython.cclass
class CClass(object):
"""
>>> c = CClass(2)
>>> c.get_attr()
int
2
"""
cython.declare(attr=cython.int)
def __init__(self, attr):
self.attr = attr
def get_attr(self):
print(cython.typeof(self.attr))
return self.attr
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