summaryrefslogtreecommitdiff
path: root/Cython/Compiler/ParseTreeTransforms.py
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2015-11-07 11:21:09 +0100
committerStefan Behnel <stefan_ml@behnel.de>2015-11-07 11:21:09 +0100
commitac48e447bcf64754143016ecbd6e10464062d1f0 (patch)
tree79f02b96cbd55416ee14a1ada6e3b6b92b53d36b /Cython/Compiler/ParseTreeTransforms.py
parenta27d22597eb272876222cfcebc94033cdc3dc498 (diff)
downloadcython-ac48e447bcf64754143016ecbd6e10464062d1f0.tar.gz
reject properties with additional decorators in cdef classes
Diffstat (limited to 'Cython/Compiler/ParseTreeTransforms.py')
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py56
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):