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
Kirill Smelkov
cython
Commits
cf61552b
Commit
cf61552b
authored
Sep 29, 2008
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
bbba7ca8
364dfc77
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
275 additions
and
83 deletions
+275
-83
Cython/CodeWriter.py
Cython/CodeWriter.py
+18
-8
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+1
-2
Cython/Compiler/CodeGeneration.py
Cython/Compiler/CodeGeneration.py
+1
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+88
-7
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+1
-0
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+13
-12
Cython/Compiler/Tests/TestParseTreeTransforms.py
Cython/Compiler/Tests/TestParseTreeTransforms.py
+18
-18
Cython/Compiler/Tests/TestTreeFragment.py
Cython/Compiler/Tests/TestTreeFragment.py
+5
-4
Cython/Compiler/TreeFragment.py
Cython/Compiler/TreeFragment.py
+18
-11
Cython/Compiler/UtilNodes.py
Cython/Compiler/UtilNodes.py
+85
-0
Cython/Compiler/Visitor.py
Cython/Compiler/Visitor.py
+0
-17
Cython/TestUtils.py
Cython/TestUtils.py
+9
-3
tests/run/nonecheck.pyx
tests/run/nonecheck.pyx
+18
-0
No files found.
Cython/CodeWriter.py
View file @
cf61552b
from
Cython.Compiler.Visitor
import
TreeVisitor
,
get_temp_name_handle_desc
from
Cython.Compiler.Visitor
import
TreeVisitor
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.ExprNodes
import
*
from
Cython.Compiler.ExprNodes
import
*
...
@@ -37,6 +37,7 @@ class CodeWriter(TreeVisitor):
...
@@ -37,6 +37,7 @@ class CodeWriter(TreeVisitor):
self
.
result
=
result
self
.
result
=
result
self
.
numindents
=
0
self
.
numindents
=
0
self
.
tempnames
=
{}
self
.
tempnames
=
{}
self
.
tempblockindex
=
0
def
write
(
self
,
tree
):
def
write
(
self
,
tree
):
self
.
visit
(
tree
)
self
.
visit
(
tree
)
...
@@ -60,12 +61,6 @@ class CodeWriter(TreeVisitor):
...
@@ -60,12 +61,6 @@ class CodeWriter(TreeVisitor):
self
.
startline
(
s
)
self
.
startline
(
s
)
self
.
endline
()
self
.
endline
()
def
putname
(
self
,
name
):
tmpdesc
=
get_temp_name_handle_desc
(
name
)
if
tmpdesc
is
not
None
:
name
=
self
.
tempnames
.
setdefault
(
tmpdesc
,
u"$"
+
tmpdesc
)
self
.
put
(
name
)
def
comma_seperated_list
(
self
,
items
,
output_rhs
=
False
):
def
comma_seperated_list
(
self
,
items
,
output_rhs
=
False
):
if
len
(
items
)
>
0
:
if
len
(
items
)
>
0
:
for
item
in
items
[:
-
1
]:
for
item
in
items
[:
-
1
]:
...
@@ -132,7 +127,7 @@ class CodeWriter(TreeVisitor):
...
@@ -132,7 +127,7 @@ class CodeWriter(TreeVisitor):
self
.
endline
()
self
.
endline
()
def
visit_NameNode
(
self
,
node
):
def
visit_NameNode
(
self
,
node
):
self
.
put
name
(
node
.
name
)
self
.
put
(
node
.
name
)
def
visit_IntNode
(
self
,
node
):
def
visit_IntNode
(
self
,
node
):
self
.
put
(
node
.
value
)
self
.
put
(
node
.
value
)
...
@@ -312,3 +307,18 @@ class CodeWriter(TreeVisitor):
...
@@ -312,3 +307,18 @@ class CodeWriter(TreeVisitor):
self
.
visit
(
node
.
operand
)
self
.
visit
(
node
.
operand
)
self
.
put
(
u")"
)
self
.
put
(
u")"
)
def
visit_TempsBlockNode
(
self
,
node
):
"""
Temporaries are output like $1_1', where the first number is
an index of the TempsBlockNode and the second number is an index
of the temporary which that block allocates.
"""
idx
=
0
for
handle
in
node
.
temps
:
self
.
tempnames
[
handle
]
=
"$%d_%d"
%
(
self
.
tempblockindex
,
idx
)
idx
+=
1
self
.
tempblockindex
+=
1
self
.
visit
(
node
.
body
)
def
visit_TempRefNode
(
self
,
node
):
self
.
put
(
self
.
tempnames
[
node
.
handle
])
Cython/Compiler/Buffer.py
View file @
cf61552b
from
Cython.Compiler.Visitor
import
VisitorTransform
,
temp_name_handle
,
CythonTransform
from
Cython.Compiler.Visitor
import
VisitorTransform
,
CythonTransform
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.ExprNodes
import
*
from
Cython.Compiler.ExprNodes
import
*
from
Cython.Compiler.TreeFragment
import
TreeFragment
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.Errors
import
CompileError
from
Cython.Compiler.Errors
import
CompileError
import
Interpreter
import
Interpreter
...
...
Cython/Compiler/CodeGeneration.py
View file @
cf61552b
from
Cython.Compiler.Visitor
import
VisitorTransform
,
temp_name_handle
,
CythonTransform
from
Cython.Compiler.Visitor
import
VisitorTransform
,
CythonTransform
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.ExprNodes
import
*
from
Cython.Compiler.ExprNodes
import
*
...
...
Cython/Compiler/ExprNodes.py
View file @
cf61552b
...
@@ -168,6 +168,7 @@ class ExprNode(Node):
...
@@ -168,6 +168,7 @@ class ExprNode(Node):
saved_subexpr_nodes
=
None
saved_subexpr_nodes
=
None
is_temp
=
0
is_temp
=
0
is_target
=
0
def
get_child_attrs
(
self
):
def
get_child_attrs
(
self
):
return
self
.
subexprs
return
self
.
subexprs
...
@@ -206,10 +207,10 @@ class ExprNode(Node):
...
@@ -206,10 +207,10 @@ class ExprNode(Node):
return
self
.
saved_subexpr_nodes
return
self
.
saved_subexpr_nodes
def
result
(
self
):
def
result
(
self
):
if
self
.
is_temp
:
if
not
self
.
is_temp
or
self
.
is_target
:
return
self
.
result_code
else
:
return
self
.
calculate_result_code
()
return
self
.
calculate_result_code
()
else
:
# i.e. self.is_temp:
return
self
.
result_code
def
result_as
(
self
,
type
=
None
):
def
result_as
(
self
,
type
=
None
):
# Return the result code cast to the specified C type.
# Return the result code cast to the specified C type.
...
@@ -335,7 +336,7 @@ class ExprNode(Node):
...
@@ -335,7 +336,7 @@ class ExprNode(Node):
if
debug_temp_alloc
:
if
debug_temp_alloc
:
print
(
"%s Allocating target temps"
%
self
)
print
(
"%s Allocating target temps"
%
self
)
self
.
allocate_subexpr_temps
(
env
)
self
.
allocate_subexpr_temps
(
env
)
self
.
result_code
=
self
.
target_code
()
self
.
is_target
=
True
if
rhs
:
if
rhs
:
rhs
.
release_temp
(
env
)
rhs
.
release_temp
(
env
)
self
.
release_subexpr_temps
(
env
)
self
.
release_subexpr_temps
(
env
)
...
@@ -560,6 +561,66 @@ class ExprNode(Node):
...
@@ -560,6 +561,66 @@ class ExprNode(Node):
return
self
.
result_in_temp
()
return
self
.
result_in_temp
()
class
NewTempExprNode
(
ExprNode
):
backwards_compatible_result
=
None
def
result
(
self
):
if
self
.
is_temp
:
return
self
.
temp_code
else
:
return
self
.
calculate_result_code
()
def
allocate_target_temps
(
self
,
env
,
rhs
):
self
.
allocate_subexpr_temps
(
env
)
rhs
.
release_temp
(
rhs
)
self
.
releasesubexpr_temps
(
env
)
def
allocate_temps
(
self
,
env
,
result
=
None
):
self
.
allocate_subexpr_temps
(
env
)
self
.
backwards_compatible_result
=
result
if
self
.
is_temp
:
self
.
release_subexpr_temps
(
env
)
def
allocate_temp
(
self
,
env
,
result
=
None
):
assert
result
is
None
def
release_temp
(
self
,
env
):
pass
def
generate_result_code
(
self
,
code
):
if
self
.
is_temp
:
type
=
self
.
type
if
not
type
.
is_void
:
if
type
.
is_pyobject
:
type
=
PyrexTypes
.
py_object_type
if
self
.
backwards_compatible_result
:
self
.
temp_code
=
self
.
backwards_compatible_result
else
:
self
.
temp_code
=
code
.
funcstate
.
allocate_temp
(
type
)
else
:
self
.
temp_code
=
None
def
generate_disposal_code
(
self
,
code
):
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
())
if
not
self
.
backwards_compatible_result
:
code
.
funcstate
.
release_temp
(
self
.
temp_code
)
else
:
self
.
generate_subexpr_disposal_code
(
code
)
def
generate_post_assignment_code
(
self
,
code
):
if
self
.
is_temp
:
if
self
.
type
.
is_pyobject
:
code
.
putln
(
"%s = 0;"
%
self
.
temp_code
)
if
not
self
.
backwards_compatible_result
:
code
.
funcstate
.
release_temp
(
self
.
temp_code
)
else
:
self
.
generate_subexpr_disposal_code
(
code
)
class
AtomicExprNode
(
ExprNode
):
class
AtomicExprNode
(
ExprNode
):
# Abstract base class for expression nodes which have
# Abstract base class for expression nodes which have
# no sub-expressions.
# no sub-expressions.
...
@@ -1499,7 +1560,8 @@ class IndexNode(ExprNode):
...
@@ -1499,7 +1560,8 @@ class IndexNode(ExprNode):
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
if
self
.
is_buffer_access
:
if
self
.
is_buffer_access
:
# buffer_pointer_code is returned by result()
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
self
.
put_nonecheck
(
code
)
ptrcode
=
self
.
buffer_lookup_code
(
code
)
ptrcode
=
self
.
buffer_lookup_code
(
code
)
code
.
putln
(
"%s = *%s;"
%
(
code
.
putln
(
"%s = *%s;"
%
(
self
.
result
(),
self
.
result
(),
...
@@ -1543,6 +1605,8 @@ class IndexNode(ExprNode):
...
@@ -1543,6 +1605,8 @@ class IndexNode(ExprNode):
def
generate_buffer_setitem_code
(
self
,
rhs
,
code
,
op
=
""
):
def
generate_buffer_setitem_code
(
self
,
rhs
,
code
,
op
=
""
):
# Used from generate_assignment_code and InPlaceAssignmentNode
# Used from generate_assignment_code and InPlaceAssignmentNode
if
code
.
globalstate
.
directives
[
'nonecheck'
]:
self
.
put_nonecheck
(
code
)
ptrexpr
=
self
.
buffer_lookup_code
(
code
)
ptrexpr
=
self
.
buffer_lookup_code
(
code
)
if
self
.
buffer_type
.
dtype
.
is_pyobject
:
if
self
.
buffer_type
.
dtype
.
is_pyobject
:
# Must manage refcounts. Decref what is already there
# Must manage refcounts. Decref what is already there
...
@@ -1609,6 +1673,13 @@ class IndexNode(ExprNode):
...
@@ -1609,6 +1673,13 @@ class IndexNode(ExprNode):
options
=
code
.
globalstate
.
directives
,
options
=
code
.
globalstate
.
directives
,
pos
=
self
.
pos
,
code
=
code
)
pos
=
self
.
pos
,
code
=
code
)
def
put_nonecheck
(
self
,
code
):
code
.
globalstate
.
use_utility_code
(
raise_noneindex_error_utility_code
)
code
.
putln
(
"if (%s) {"
%
code
.
unlikely
(
"%s == Py_None"
)
%
self
.
base
.
result_as
(
PyrexTypes
.
py_object_type
))
code
.
putln
(
"__Pyx_RaiseNoneIndexingError();"
)
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
code
.
putln
(
"}"
)
class
SliceIndexNode
(
ExprNode
):
class
SliceIndexNode
(
ExprNode
):
# 2-element slice indexing
# 2-element slice indexing
#
#
...
@@ -3211,7 +3282,7 @@ def get_compile_time_binop(node):
...
@@ -3211,7 +3282,7 @@ def get_compile_time_binop(node):
%
node
.
operator
)
%
node
.
operator
)
return
func
return
func
class
BinopNode
(
ExprNode
):
class
BinopNode
(
NewTemp
ExprNode
):
# operator string
# operator string
# operand1 ExprNode
# operand1 ExprNode
# operand2 ExprNode
# operand2 ExprNode
...
@@ -3261,6 +3332,7 @@ class BinopNode(ExprNode):
...
@@ -3261,6 +3332,7 @@ class BinopNode(ExprNode):
self
.
operand2
.
check_const
()
self
.
operand2
.
check_const
()
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
NewTempExprNode
.
generate_result_code
(
self
,
code
)
#print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
#print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
if
self
.
operand1
.
type
.
is_pyobject
:
if
self
.
operand1
.
type
.
is_pyobject
:
function
=
self
.
py_operation_function
()
function
=
self
.
py_operation_function
()
...
@@ -4589,3 +4661,12 @@ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) {
...
@@ -4589,3 +4661,12 @@ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) {
PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
}
}
"""
]
"""
]
raise_noneindex_error_utility_code
=
[
"""
static INLINE void __Pyx_RaiseNoneIndexingError();
"""
,
"""
static INLINE void __Pyx_RaiseNoneIndexingError() {
PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
}
"""
]
Cython/Compiler/Nodes.py
View file @
cf61552b
...
@@ -4188,6 +4188,7 @@ class FromImportStatNode(StatNode):
...
@@ -4188,6 +4188,7 @@ class FromImportStatNode(StatNode):
self
.
module
.
generate_disposal_code
(
code
)
self
.
module
.
generate_disposal_code
(
code
)
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
#
#
# Runtime support code
# Runtime support code
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
cf61552b
from
Cython.Compiler.Visitor
import
VisitorTransform
,
temp_name_handle
,
CythonTransform
from
Cython.Compiler.Visitor
import
VisitorTransform
,
CythonTransform
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.ExprNodes
import
*
from
Cython.Compiler.ExprNodes
import
*
from
Cython.Compiler.UtilNodes
import
*
from
Cython.Compiler.TreeFragment
import
TreeFragment
from
Cython.Compiler.TreeFragment
import
TreeFragment
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.Errors
import
CompileError
from
Cython.Compiler.Errors
import
CompileError
...
@@ -409,7 +410,7 @@ class WithTransform(CythonTransform):
...
@@ -409,7 +410,7 @@ class WithTransform(CythonTransform):
finally:
finally:
if EXC:
if EXC:
EXIT(None, None, None)
EXIT(None, None, None)
"""
,
temps
=
[
u'MGR'
,
u'EXC'
,
u"EXIT"
,
u"SYS)"
],
"""
,
temps
=
[
u'MGR'
,
u'EXC'
,
u"EXIT"
],
pipeline
=
[
NormalizeTree
(
None
)])
pipeline
=
[
NormalizeTree
(
None
)])
template_with_target
=
TreeFragment
(
u"""
template_with_target
=
TreeFragment
(
u"""
...
@@ -428,32 +429,32 @@ class WithTransform(CythonTransform):
...
@@ -428,32 +429,32 @@ class WithTransform(CythonTransform):
finally:
finally:
if EXC:
if EXC:
EXIT(None, None, None)
EXIT(None, None, None)
"""
,
temps
=
[
u'MGR'
,
u'EXC'
,
u"EXIT"
,
u"VALUE"
,
u"SYS"
],
"""
,
temps
=
[
u'MGR'
,
u'EXC'
,
u"EXIT"
,
u"VALUE"
],
pipeline
=
[
NormalizeTree
(
None
)])
pipeline
=
[
NormalizeTree
(
None
)])
def
visit_WithStatNode
(
self
,
node
):
def
visit_WithStatNode
(
self
,
node
):
excinfo_name
=
temp_name_handle
(
'EXCINFO'
)
excinfo_temp
=
TempHandle
(
PyrexTypes
.
py_object_type
)
excinfo_namenode
=
NameNode
(
pos
=
node
.
pos
,
name
=
excinfo_name
)
excinfo_target
=
NameNode
(
pos
=
node
.
pos
,
name
=
excinfo_name
)
if
node
.
target
is
not
None
:
if
node
.
target
is
not
None
:
result
=
self
.
template_with_target
.
substitute
({
result
=
self
.
template_with_target
.
substitute
({
u'EXPR'
:
node
.
manager
,
u'EXPR'
:
node
.
manager
,
u'BODY'
:
node
.
body
,
u'BODY'
:
node
.
body
,
u'TARGET'
:
node
.
target
,
u'TARGET'
:
node
.
target
,
u'EXCINFO'
:
excinfo_
namenode
u'EXCINFO'
:
excinfo_
temp
.
ref
(
node
.
pos
)
},
pos
=
node
.
pos
)
},
pos
=
node
.
pos
)
# Set except excinfo target to EXCINFO
# Set except excinfo target to EXCINFO
result
.
stats
[
4
].
body
.
stats
[
0
].
except_clauses
[
0
].
excinfo_target
=
excinfo_target
result
.
body
.
stats
[
4
].
body
.
stats
[
0
].
except_clauses
[
0
].
excinfo_target
=
(
excinfo_temp
.
ref
(
node
.
pos
))
else
:
else
:
result
=
self
.
template_without_target
.
substitute
({
result
=
self
.
template_without_target
.
substitute
({
u'EXPR'
:
node
.
manager
,
u'EXPR'
:
node
.
manager
,
u'BODY'
:
node
.
body
,
u'BODY'
:
node
.
body
,
u'EXCINFO'
:
excinfo_
namenode
u'EXCINFO'
:
excinfo_
temp
.
ref
(
node
.
pos
)
},
pos
=
node
.
pos
)
},
pos
=
node
.
pos
)
# Set except excinfo target to EXCINFO
# Set except excinfo target to EXCINFO
result
.
stats
[
4
].
body
.
stats
[
0
].
except_clauses
[
0
].
excinfo_target
=
excinfo_target
result
.
body
.
stats
[
4
].
body
.
stats
[
0
].
except_clauses
[
0
].
excinfo_target
=
(
excinfo_temp
.
ref
(
node
.
pos
))
return
result
.
stats
return
TempsBlockNode
(
node
.
pos
,
temps
=
[
excinfo_temp
],
body
=
result
)
class
DecoratorTransform
(
CythonTransform
):
class
DecoratorTransform
(
CythonTransform
):
...
...
Cython/Compiler/Tests/TestParseTreeTransforms.py
View file @
cf61552b
...
@@ -95,20 +95,20 @@ class TestWithTransform(TransformTest):
...
@@ -95,20 +95,20 @@ class TestWithTransform(TransformTest):
self
.
assertCode
(
u"""
self
.
assertCode
(
u"""
$
MGR
= x
$
1_0
= x
$
EXIT = $MGR
.__exit__
$
1_2 = $1_0
.__exit__
$
MGR
.__enter__()
$
1_0
.__enter__()
$
EXC
= True
$
1_1
= True
try:
try:
try:
try:
y = z ** 3
y = z ** 3
except:
except:
$
EXC
= False
$
1_1
= False
if (not $
EXIT($EXCINFO
)):
if (not $
1_2($0_0
)):
raise
raise
finally:
finally:
if $
EXC
:
if $
1_1
:
$
EXIT
(None, None, None)
$
1_2
(None, None, None)
"""
,
t
)
"""
,
t
)
...
@@ -119,21 +119,21 @@ class TestWithTransform(TransformTest):
...
@@ -119,21 +119,21 @@ class TestWithTransform(TransformTest):
"""
)
"""
)
self
.
assertCode
(
u"""
self
.
assertCode
(
u"""
$
MGR
= x
$
1_0
= x
$
EXIT = $MGR
.__exit__
$
1_2 = $1_0
.__exit__
$
VALUE = $MGR
.__enter__()
$
1_3 = $1_0
.__enter__()
$
EXC
= True
$
1_1
= True
try:
try:
try:
try:
y = $
VALUE
y = $
1_3
y = z ** 3
y = z ** 3
except:
except:
$
EXC
= False
$
1_1
= False
if (not $
EXIT($EXCINFO
)):
if (not $
1_2($0_0
)):
raise
raise
finally:
finally:
if $
EXC
:
if $
1_1
:
$
EXIT
(None, None, None)
$
1_2
(None, None, None)
"""
,
t
)
"""
,
t
)
...
...
Cython/Compiler/Tests/TestTreeFragment.py
View file @
cf61552b
from
Cython.TestUtils
import
CythonTest
from
Cython.TestUtils
import
CythonTest
from
Cython.Compiler.TreeFragment
import
*
from
Cython.Compiler.TreeFragment
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.Nodes
import
*
from
Cython.Compiler.UtilNodes
import
*
import
Cython.Compiler.Naming
as
Naming
import
Cython.Compiler.Naming
as
Naming
class
TestTreeFragments
(
CythonTest
):
class
TestTreeFragments
(
CythonTest
):
...
@@ -54,10 +55,10 @@ class TestTreeFragments(CythonTest):
...
@@ -54,10 +55,10 @@ class TestTreeFragments(CythonTest):
x = TMP
x = TMP
"""
)
"""
)
T
=
F
.
substitute
(
temps
=
[
u"TMP"
])
T
=
F
.
substitute
(
temps
=
[
u"TMP"
])
s
=
T
.
stats
s
=
T
.
body
.
stats
self
.
assert_
(
s
[
0
].
expr
.
name
==
Naming
.
temp_prefix
+
u"1_TMP"
,
s
[
0
].
expr
.
name
)
self
.
assert_
(
isinstance
(
s
[
0
].
expr
,
TempRefNode
)
)
self
.
assert_
(
s
[
1
].
rhs
.
name
==
Naming
.
temp_prefix
+
u"1_TMP"
)
self
.
assert_
(
isinstance
(
s
[
1
].
rhs
,
TempRefNode
)
)
self
.
assert_
(
s
[
0
].
expr
.
name
!=
u"TMP"
)
self
.
assert_
(
s
[
0
].
expr
.
handle
is
s
[
1
].
rhs
.
handle
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
import
unittest
import
unittest
...
...
Cython/Compiler/TreeFragment.py
View file @
cf61552b
...
@@ -8,11 +8,12 @@ from Scanning import PyrexScanner, StringSourceDescriptor
...
@@ -8,11 +8,12 @@ from Scanning import PyrexScanner, StringSourceDescriptor
from
Symtab
import
BuiltinScope
,
ModuleScope
from
Symtab
import
BuiltinScope
,
ModuleScope
import
Symtab
import
Symtab
import
PyrexTypes
import
PyrexTypes
from
Visitor
import
VisitorTransform
,
temp_name_handle
from
Visitor
import
VisitorTransform
from
Nodes
import
Node
,
StatListNode
from
Nodes
import
Node
,
StatListNode
from
ExprNodes
import
NameNode
from
ExprNodes
import
NameNode
import
Parsing
import
Parsing
import
Main
import
Main
import
UtilNodes
"""
"""
Support for parsing strings into code trees.
Support for parsing strings into code trees.
...
@@ -111,12 +112,20 @@ class TemplateTransform(VisitorTransform):
...
@@ -111,12 +112,20 @@ class TemplateTransform(VisitorTransform):
def
__call__
(
self
,
node
,
substitutions
,
temps
,
pos
):
def
__call__
(
self
,
node
,
substitutions
,
temps
,
pos
):
self
.
substitutions
=
substitutions
self
.
substitutions
=
substitutions
tempdict
=
{}
for
key
in
temps
:
tempdict
[
key
]
=
temp_name_handle
(
key
)
# pending result_code refactor: Symtab.new_temp(PyrexTypes.py_object_type, key)
self
.
temp_key_to_entries
=
tempdict
self
.
pos
=
pos
self
.
pos
=
pos
return
super
(
TemplateTransform
,
self
).
__call__
(
node
)
tempmap
=
{}
temphandles
=
[]
for
temp
in
temps
:
handle
=
UtilNodes
.
TempHandle
(
PyrexTypes
.
py_object_type
)
tempmap
[
temp
]
=
handle
temphandles
.
append
(
handle
)
self
.
tempmap
=
tempmap
result
=
super
(
TemplateTransform
,
self
).
__call__
(
node
)
if
temps
:
result
=
UtilNodes
.
TempsBlockNode
(
self
.
get_pos
(
node
),
temps
=
temphandles
,
body
=
result
)
return
result
def
get_pos
(
self
,
node
):
def
get_pos
(
self
,
node
):
if
self
.
pos
:
if
self
.
pos
:
...
@@ -143,13 +152,11 @@ class TemplateTransform(VisitorTransform):
...
@@ -143,13 +152,11 @@ class TemplateTransform(VisitorTransform):
else
:
else
:
return
self
.
visit_Node
(
node
)
# make copy as usual
return
self
.
visit_Node
(
node
)
# make copy as usual
def
visit_NameNode
(
self
,
node
):
def
visit_NameNode
(
self
,
node
):
temp
entry
=
self
.
temp_key_to_entries
.
get
(
node
.
name
)
temp
handle
=
self
.
tempmap
.
get
(
node
.
name
)
if
temp
entry
is
not
Non
e
:
if
temp
handl
e
:
# Replace name with temporary
# Replace name with temporary
return
NameNode
(
self
.
get_pos
(
node
),
name
=
tempentry
)
return
temphandle
.
ref
(
self
.
get_pos
(
node
))
# Pending result_code refactor: return NameNode(self.get_pos(node), entry=tempentry)
else
:
else
:
return
self
.
try_substitution
(
node
,
node
.
name
)
return
self
.
try_substitution
(
node
,
node
.
name
)
...
...
Cython/Compiler/UtilNodes.py
0 → 100644
View file @
cf61552b
#
# Nodes used as utilities and support for transforms etc.
# These often make up sets including both Nodes and ExprNodes
# so it is convenient to have them in a seperate module.
#
import
Nodes
import
ExprNodes
from
Nodes
import
Node
from
ExprNodes
import
ExprNode
class
TempHandle
(
object
):
temp
=
None
def
__init__
(
self
,
type
):
self
.
type
=
type
def
ref
(
self
,
pos
):
return
TempRefNode
(
pos
,
handle
=
self
,
type
=
self
.
type
)
class
TempRefNode
(
ExprNode
):
# handle TempHandle
subexprs
=
[]
def
analyse_types
(
self
,
env
):
assert
self
.
type
==
self
.
handle
.
type
def
analyse_target_types
(
self
,
env
):
assert
self
.
type
==
self
.
handle
.
type
def
analyse_target_declaration
(
self
,
env
):
pass
def
calculate_result_code
(
self
):
result
=
self
.
handle
.
temp
if
result
is
None
:
result
=
"<error>"
# might be called and overwritten
return
result
def
generate_result_code
(
self
,
code
):
pass
def
generate_assignment_code
(
self
,
rhs
,
code
):
if
self
.
type
.
is_pyobject
:
rhs
.
make_owned_reference
(
code
)
code
.
put_xdecref
(
self
.
result
(),
self
.
ctype
())
code
.
putln
(
'%s = %s;'
%
(
self
.
result
(),
rhs
.
result_as
(
self
.
ctype
())))
rhs
.
generate_post_assignment_code
(
code
)
class
TempsBlockNode
(
Node
):
"""
Creates a block which allocates temporary variables.
This is used by transforms to output constructs that need
to make use of a temporary variable. Simply pass the types
of the needed temporaries to the constructor.
The variables can be referred to using a TempRefNode
(which can be constructed by calling get_ref_node).
"""
# temps [TempHandle]
# body StatNode
child_attrs
=
[
"body"
]
def
generate_execution_code
(
self
,
code
):
for
handle
in
self
.
temps
:
handle
.
temp
=
code
.
funcstate
.
allocate_temp
(
handle
.
type
)
self
.
body
.
generate_execution_code
(
code
)
for
handle
in
self
.
temps
:
code
.
funcstate
.
release_temp
(
handle
.
temp
)
def
analyse_control_flow
(
self
,
env
):
self
.
body
.
analyse_control_flow
(
env
)
def
analyse_declarations
(
self
,
env
):
self
.
body
.
analyse_declarations
(
env
)
def
analyse_expressions
(
self
,
env
):
self
.
body
.
analyse_expressions
(
env
)
def
generate_function_definitions
(
self
,
env
,
code
):
self
.
body
.
generate_function_definitions
(
env
,
code
)
def
annotate
(
self
,
code
):
self
.
body
.
annotate
(
code
)
Cython/Compiler/Visitor.py
View file @
cf61552b
...
@@ -199,23 +199,6 @@ def replace_node(ptr, value):
...
@@ -199,23 +199,6 @@ def replace_node(ptr, value):
else
:
else
:
getattr
(
parent
,
attrname
)[
listidx
]
=
value
getattr
(
parent
,
attrname
)[
listidx
]
=
value
tmpnamectr
=
0
def
temp_name_handle
(
description
=
None
):
global
tmpnamectr
tmpnamectr
+=
1
if
description
is
not
None
:
name
=
u"%d_%s"
%
(
tmpnamectr
,
description
)
else
:
name
=
u"%d"
%
tmpnamectr
return
EncodedString
(
Naming
.
temp_prefix
+
name
)
def
get_temp_name_handle_desc
(
handle
):
if
not
handle
.
startswith
(
u"__cyt_"
):
return
None
else
:
idx
=
handle
.
find
(
u"_"
,
6
)
return
handle
[
idx
+
1
:]
class
PrintTree
(
TreeVisitor
):
class
PrintTree
(
TreeVisitor
):
"""Prints a representation of the tree to standard output.
"""Prints a representation of the tree to standard output.
Subclass and override repr_of to provide more information
Subclass and override repr_of to provide more information
...
...
Cython/TestUtils.py
View file @
cf61552b
...
@@ -47,10 +47,16 @@ class CythonTest(unittest.TestCase):
...
@@ -47,10 +47,16 @@ class CythonTest(unittest.TestCase):
self
.
assertEqual
(
len
(
expected
),
len
(
result
),
self
.
assertEqual
(
len
(
expected
),
len
(
result
),
"Unmatched lines. Got:
\
n
%s
\
n
Expected:
\
n
%s"
%
(
"
\
n
"
.
join
(
expected
),
u"
\
n
"
.
join
(
result
)))
"Unmatched lines. Got:
\
n
%s
\
n
Expected:
\
n
%s"
%
(
"
\
n
"
.
join
(
expected
),
u"
\
n
"
.
join
(
result
)))
def
assertCode
(
self
,
expected
,
result_
tree
):
def
codeToLines
(
self
,
tree
):
writer
=
CodeWriter
()
writer
=
CodeWriter
()
writer
.
write
(
result_tree
)
writer
.
write
(
tree
)
result_lines
=
writer
.
result
.
lines
return
writer
.
result
.
lines
def
codeToString
(
self
,
tree
):
return
"
\
n
"
.
join
(
self
.
codeToLines
(
tree
))
def
assertCode
(
self
,
expected
,
result_tree
):
result_lines
=
self
.
codeToLines
(
result_tree
)
expected_lines
=
strip_common_indent
(
expected
.
split
(
"
\
n
"
))
expected_lines
=
strip_common_indent
(
expected
.
split
(
"
\
n
"
))
...
...
tests/run/nonecheck.pyx
View file @
cf61552b
...
@@ -32,6 +32,16 @@ Traceback (most recent call last):
...
@@ -32,6 +32,16 @@ Traceback (most recent call last):
...
...
AttributeError: 'NoneType' object has no attribute 'a'
AttributeError: 'NoneType' object has no attribute 'a'
>>> check_buffer_get(None)
Traceback (most recent call last):
...
TypeError: 'NoneType' object is unsubscriptable
>>> check_buffer_set(None)
Traceback (most recent call last):
...
TypeError: 'NoneType' object is unsubscriptable
"""
"""
cimport
cython
cimport
cython
...
@@ -70,3 +80,11 @@ def check_and_assign(MyClass var):
...
@@ -70,3 +80,11 @@ def check_and_assign(MyClass var):
var
=
None
var
=
None
print
var
.
a
print
var
.
a
@
cython
.
nonecheck
(
True
)
def
check_buffer_get
(
object
[
int
]
buf
):
return
buf
[
0
]
@
cython
.
nonecheck
(
True
)
def
check_buffer_set
(
object
[
int
]
buf
):
buf
[
0
]
=
1
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