diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2015-11-07 11:21:09 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2015-11-07 11:21:09 +0100 |
commit | ac48e447bcf64754143016ecbd6e10464062d1f0 (patch) | |
tree | 79f02b96cbd55416ee14a1ada6e3b6b92b53d36b /Cython/Compiler/ParseTreeTransforms.py | |
parent | a27d22597eb272876222cfcebc94033cdc3dc498 (diff) | |
download | cython-ac48e447bcf64754143016ecbd6e10464062d1f0.tar.gz |
reject properties with additional decorators in cdef classes
Diffstat (limited to 'Cython/Compiler/ParseTreeTransforms.py')
-rw-r--r-- | Cython/Compiler/ParseTreeTransforms.py | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 039d371ff..60d2d9618 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -1299,30 +1299,40 @@ class PropertyTransform(ScopeTrackingTransform): if self.scope_type != 'cclass' or not node.decorators: return node properties = self._properties[-1] - # restrict transformation to outermost decorator as wrapped properties will probably not work - decorator_node = node.decorators[-1] - decorator = decorator_node.decorator - if decorator.is_name and decorator.name == 'property': - name = node.name - node.name = '__get__' - node.decorators.remove(decorator_node) - stat_list = [node] - if name in properties: - prop = properties[name] - prop.pos = node.pos + for decorator_node in node.decorators[::-1]: + decorator = decorator_node.decorator + if decorator.is_name and decorator.name == 'property': + if len(node.decorators) > 1: + return self._reject_decorated_property(node, decorator_node) + name = node.name + node.name = '__get__' + node.decorators.remove(decorator_node) + stat_list = [node] + if name in properties: + prop = properties[name] + prop.pos = node.pos + prop.doc = node.doc + prop.body.stats = stat_list + return [] + prop = Nodes.PropertyNode(node.pos, name=name) prop.doc = node.doc - prop.body.stats = stat_list - return [] - prop = Nodes.PropertyNode(node.pos, name=name) - prop.doc = node.doc - prop.body = Nodes.StatListNode(node.pos, stats=stat_list) - properties[name] = prop - return [prop] - elif decorator.is_attribute and decorator.obj.name in properties: - handler_name = self._map_property_attribute(decorator.attribute) - if handler_name: - assert decorator.obj.name == node.name - return self._add_to_property(properties, node, handler_name, decorator_node) + prop.body = Nodes.StatListNode(node.pos, stats=stat_list) + properties[name] = prop + return [prop] + elif decorator.is_attribute and decorator.obj.name in properties: + handler_name = self._map_property_attribute(decorator.attribute) + if handler_name: + assert decorator.obj.name == node.name + if len(node.decorators) > 1: + return self._reject_decorated_property(node, decorator_node) + return self._add_to_property(properties, node, handler_name, decorator_node) + return node + + def _reject_decorated_property(self, node, decorator_node): + # restrict transformation to outermost decorator as wrapped properties will probably not work + for deco in node.decorators: + if deco != decorator_node: + error(deco.pos, "Property methods with additional decorators are not supported") return node def _add_to_property(self, properties, node, name, decorator): |