Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
3a955f5c
Commit
3a955f5c
authored
Jun 26, 2009
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
class decorators for Python classes - disabled for cdef classes (see transform)
parent
a554c993
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
47 additions
and
15 deletions
+47
-15
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+7
-1
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+33
-7
Cython/Compiler/Parsing.pxd
Cython/Compiler/Parsing.pxd
+1
-1
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+6
-6
No files found.
Cython/Compiler/Nodes.py
View file @
3a955f5c
...
...
@@ -2479,6 +2479,7 @@ class PyClassDefNode(ClassDefNode):
# body StatNode Attribute definition code
# entry Symtab.Entry
# scope PyClassScope
# decorators [DecoratorNode] list of decorators or None
#
# The following subnodes are constructed internally:
#
...
...
@@ -2487,12 +2488,14 @@ class PyClassDefNode(ClassDefNode):
# target NameNode Variable to assign class object to
child_attrs
=
[
"body"
,
"dict"
,
"classobj"
,
"target"
]
decorators
=
None
def
__init__
(
self
,
pos
,
name
,
bases
,
doc
,
body
):
def
__init__
(
self
,
pos
,
name
,
bases
,
doc
,
body
,
decorators
=
None
):
StatNode
.
__init__
(
self
,
pos
)
self
.
name
=
name
self
.
doc
=
doc
self
.
body
=
body
self
.
decorators
=
decorators
import
ExprNodes
self
.
dict
=
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
[])
if
self
.
doc
and
Options
.
docstrings
:
...
...
@@ -2538,6 +2541,7 @@ class PyClassDefNode(ClassDefNode):
class_name
=
self
.
name
,
base_class_module
=
base_class_module
,
base_class_name
=
base_class_name
,
decorators
=
self
.
decorators
,
body
=
self
.
body
,
in_pxd
=
False
,
doc
=
self
.
doc
)
...
...
@@ -2594,6 +2598,7 @@ class CClassDefNode(ClassDefNode):
# objstruct_name string or None Specified C name of object struct
# typeobj_name string or None Specified C name of type object
# in_pxd boolean Is in a .pxd file
# decorators [DecoratorNode] list of decorators or None
# doc string or None
# body StatNode or None
# entry Symtab.Entry
...
...
@@ -2608,6 +2613,7 @@ class CClassDefNode(ClassDefNode):
api
=
False
objstruct_name
=
None
typeobj_name
=
None
decorators
=
None
def
analyse_declarations
(
self
,
env
):
#print "CClassDefNode.analyse_declarations:", self.class_name
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
3a955f5c
...
...
@@ -597,22 +597,48 @@ class WithTransform(CythonTransform, SkipDeclarations):
class
DecoratorTransform
(
CythonTransform
,
SkipDeclarations
):
def
visit_DefNode
(
self
,
func_node
):
self
.
visitchildren
(
func_node
)
if
not
func_node
.
decorators
:
return
func_node
decorator_result
=
NameNode
(
func_node
.
pos
,
name
=
func_node
.
name
)
for
decorator
in
func_node
.
decorators
[::
-
1
]:
return
self
.
_handle_decorators
(
func_node
,
func_node
.
name
)
def
_visit_CClassDefNode
(
self
,
class_node
):
# This doesn't currently work, so it's disabled (also in the
# parser).
#
# Problem: assignments to cdef class names do not work. They
# would require an additional check anyway, as the extension
# type must not change its C type, so decorators cannot
# replace an extension type, just alter it and return it.
self
.
visitchildren
(
class_node
)
if
not
class_node
.
decorators
:
return
class_node
return
self
.
_handle_decorators
(
class_node
,
class_node
.
class_name
)
def
visit_ClassDefNode
(
self
,
class_node
):
self
.
visitchildren
(
class_node
)
if
not
class_node
.
decorators
:
return
class_node
return
self
.
_handle_decorators
(
class_node
,
class_node
.
name
)
def
_handle_decorators
(
self
,
node
,
name
):
decorator_result
=
NameNode
(
node
.
pos
,
name
=
name
)
for
decorator
in
node
.
decorators
[::
-
1
]:
decorator_result
=
SimpleCallNode
(
decorator
.
pos
,
function
=
decorator
.
decorator
,
args
=
[
decorator_result
])
func_name_node
=
NameNode
(
func_node
.
pos
,
name
=
func_node
.
name
)
name_node
=
NameNode
(
node
.
pos
,
name
=
name
)
reassignment
=
SingleAssignmentNode
(
func_
node
.
pos
,
lhs
=
func_
name_node
,
node
.
pos
,
lhs
=
name_node
,
rhs
=
decorator_result
)
return
[
func_
node
,
reassignment
]
return
[
node
,
reassignment
]
class
AnalyseDeclarationsTransform
(
CythonTransform
):
...
...
Cython/Compiler/Parsing.pxd
View file @
3a955f5c
...
...
@@ -141,7 +141,7 @@ cpdef p_ctypedef_statement(PyrexScanner s, ctx)
cpdef
p_decorators
(
PyrexScanner
s
)
cpdef
p_def_statement
(
PyrexScanner
s
,
decorators
=
*
)
cpdef
p_py_arg_decl
(
PyrexScanner
s
)
cpdef
p_class_statement
(
PyrexScanner
s
)
cpdef
p_class_statement
(
PyrexScanner
s
,
decorators
=
*
)
cpdef
p_c_class_definition
(
PyrexScanner
s
,
pos
,
ctx
)
cpdef
p_c_class_options
(
PyrexScanner
s
)
cpdef
p_property_decl
(
PyrexScanner
s
)
...
...
Cython/Compiler/Parsing.py
View file @
3a955f5c
...
...
@@ -1574,8 +1574,8 @@ def p_statement(s, ctx, first_statement = 0):
s
.
error
(
'decorator not allowed here'
)
s
.
level
=
ctx
.
level
decorators
=
p_decorators
(
s
)
if
s
.
sy
not
in
(
'def'
,
'cdef'
,
'cpdef'
):
s
.
error
(
"Decorators can only be followed by functions "
)
if
s
.
sy
not
in
(
'def'
,
'cdef'
,
'cpdef'
,
'class'
):
s
.
error
(
"Decorators can only be followed by functions
or classes
"
)
elif
s
.
sy
==
'pass'
and
cdef_flag
:
# empty cdef block
return
p_pass_statement
(
s
,
with_newline
=
1
)
...
...
@@ -1595,7 +1595,7 @@ def p_statement(s, ctx, first_statement = 0):
node
=
p_cdef_statement
(
s
,
ctx
(
overridable
=
overridable
))
if
decorators
is
not
None
:
if
not
isinstance
(
node
,
(
Nodes
.
CFuncDefNode
,
Nodes
.
CVarDefNode
)):
s
.
error
(
"Decorators can only be followed by functions "
)
s
.
error
(
"Decorators can only be followed by functions
or Python classes
"
)
node
.
decorators
=
decorators
return
node
else
:
...
...
@@ -1609,7 +1609,7 @@ def p_statement(s, ctx, first_statement = 0):
elif
s
.
sy
==
'class'
:
if
ctx
.
level
!=
'module'
:
s
.
error
(
"class definition not allowed here"
)
return
p_class_statement
(
s
)
return
p_class_statement
(
s
,
decorators
)
elif
s
.
sy
==
'include'
:
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
):
s
.
error
(
"include statement not allowed here"
)
...
...
@@ -2426,7 +2426,7 @@ def p_py_arg_decl(s):
name
=
p_ident
(
s
)
return
Nodes
.
PyArgDeclNode
(
pos
,
name
=
name
)
def
p_class_statement
(
s
):
def
p_class_statement
(
s
,
decorators
):
# s.sy == 'class'
pos
=
s
.
position
()
s
.
next
()
...
...
@@ -2442,7 +2442,7 @@ def p_class_statement(s):
return
Nodes
.
PyClassDefNode
(
pos
,
name
=
class_name
,
bases
=
ExprNodes
.
TupleNode
(
pos
,
args
=
base_list
),
doc
=
doc
,
body
=
body
)
doc
=
doc
,
body
=
body
,
decorators
=
decorators
)
def
p_c_class_definition
(
s
,
pos
,
ctx
):
# s.sy == 'class'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment