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
Boxiang Sun
cython
Commits
5f3824b8
Commit
5f3824b8
authored
Jun 27, 2009
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
0ee7c0c9
6a6f9b58
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
107 additions
and
24 deletions
+107
-24
Cython/Compiler/DebugFlags.py
Cython/Compiler/DebugFlags.py
+1
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+1
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+7
-1
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+14
-7
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
tests/run/classdecorators_T336.pyx
tests/run/classdecorators_T336.pyx
+44
-0
No files found.
Cython/Compiler/DebugFlags.py
View file @
5f3824b8
...
...
@@ -10,7 +10,7 @@ debug_temp_code_comments = 0
debug_trace_code_generation
=
0
# Do not replace exceptions with user-friendly error messages
debug_no_exception_intercept
=
1
debug_no_exception_intercept
=
0
# Print a message each time a new stage in the pipeline is entered
debug_verbose_pipeline
=
0
Cython/Compiler/ExprNodes.py
View file @
5f3824b8
...
...
@@ -3177,7 +3177,7 @@ class SequenceNode(ExprNode):
arg
.
py_result
(),
target_list
,
target_list
))
# resize the list the hard way
code
.
putln
(
"((Py
List
Object*)%s)->ob_size--;"
%
target_list
)
code
.
putln
(
"((Py
Var
Object*)%s)->ob_size--;"
%
target_list
)
code
.
put_gotref
(
arg
.
py_result
())
coerced_arg
.
generate_evaluation_code
(
code
)
...
...
Cython/Compiler/Nodes.py
View file @
5f3824b8
...
...
@@ -2477,6 +2477,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:
#
...
...
@@ -2485,12 +2486,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
:
...
...
@@ -2536,6 +2539,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
)
...
...
@@ -2592,6 +2596,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
...
...
@@ -2606,6 +2611,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/Optimize.py
View file @
5f3824b8
...
...
@@ -148,13 +148,16 @@ class IterationTransform(Visitor.VisitorTransform):
# nothing we can do here, I guess
return
node
temp
=
UtilNodes
.
LetRefNode
(
ExprNodes
.
IntNode
(
enumerate_function
.
pos
,
value
=
'0'
,
type
=
counter_type
))
temp
=
UtilNodes
.
LetRefNode
(
ExprNodes
.
IntNode
(
enumerate_function
.
pos
,
value
=
'0'
,
type
=
counter_type
,
constant_result
=
0
))
inc_expression
=
ExprNodes
.
AddNode
(
enumerate_function
.
pos
,
operand1
=
temp
,
operand2
=
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
'1'
,
type
=
counter_type
),
type
=
counter_type
,
constant_result
=
1
),
operator
=
'+'
,
type
=
counter_type
,
is_temp
=
counter_type
.
is_pyobject
...
...
@@ -190,7 +193,8 @@ class IterationTransform(Visitor.VisitorTransform):
if
len
(
args
)
<
3
:
step_pos
=
range_function
.
pos
step_value
=
1
step
=
ExprNodes
.
IntNode
(
step_pos
,
value
=
1
)
step
=
ExprNodes
.
IntNode
(
step_pos
,
value
=
'1'
,
constant_result
=
1
)
else
:
step
=
args
[
2
]
step_pos
=
step
.
pos
...
...
@@ -202,7 +206,8 @@ class IterationTransform(Visitor.VisitorTransform):
# will lead to an error elsewhere
return
node
if
not
isinstance
(
step
,
ExprNodes
.
IntNode
):
step
=
ExprNodes
.
IntNode
(
step_pos
,
value
=
step_value
)
step
=
ExprNodes
.
IntNode
(
step_pos
,
value
=
str
(
step_value
),
constant_result
=
step_value
)
if
step_value
<
0
:
step
.
value
=
-
step_value
...
...
@@ -213,7 +218,8 @@ class IterationTransform(Visitor.VisitorTransform):
relation2
=
'<'
if
len
(
args
)
==
1
:
bound1
=
ExprNodes
.
IntNode
(
range_function
.
pos
,
value
=
0
)
bound1
=
ExprNodes
.
IntNode
(
range_function
.
pos
,
value
=
'0'
,
constant_result
=
0
)
bound2
=
args
[
0
].
coerce_to_integer
(
self
.
current_scope
)
else
:
bound1
=
args
[
0
].
coerce_to_integer
(
self
.
current_scope
)
...
...
@@ -350,7 +356,8 @@ class IterationTransform(Visitor.VisitorTransform):
Nodes
.
SingleAssignmentNode
(
pos
=
node
.
pos
,
lhs
=
pos_temp
,
rhs
=
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
0
)),
rhs
=
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
'0'
,
constant_result
=
0
)),
Nodes
.
WhileStatNode
(
pos
=
node
.
pos
,
condition
=
ExprNodes
.
SimpleCallNode
(
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
5f3824b8
...
...
@@ -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 @
5f3824b8
...
...
@@ -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 @
5f3824b8
...
...
@@ -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'
...
...
tests/run/classdecorators_T336.pyx
0 → 100644
View file @
5f3824b8
__doc__
=
u"""
>>> print('
\
\
n'.join(calls))
Py-Honk PyTestClass
PyTestClass
Py-Hello PyTestClass
PyTestClass
Py-Done PyTestClass
>>> c = PyTestClass()
Ho, Ho, Ho!
"""
calls
=
[]
class
print_msg
(
object
):
def
__init__
(
self
,
message
):
self
.
msg
=
message
def
__call__
(
self
,
c
):
calls
.
append
(
self
.
msg
+
c
.
__name__
)
return
c
def
print_name
(
c
):
calls
.
append
(
c
.
__name__
)
return
c
@
print_msg
(
u"Py-Done "
)
@
print_name
@
print_msg
(
u"Py-Hello "
)
@
print_name
@
print_msg
(
u"Py-Honk "
)
class
PyTestClass
(
object
):
def
__init__
(
self
):
print
u"Ho, Ho, Ho!"
# not currently working:
#
## @print_msg("Cy-Done ")
## @print_name
## @print_msg("Cy-Hello ")
## @print_name
## @print_msg("Cy-Honk ")
## cdef class CyTestClass(object):
## def __init__(self):
## print u"Ho, Ho, Ho!"
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