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
6a57acd5
Commit
6a57acd5
authored
Apr 01, 2011
by
Vitja Makarov
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote branch 'upstream/master' into ticket_668
parents
0b25d4b9
0a56c99d
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1096 additions
and
296 deletions
+1096
-296
Cython/Build/Dependencies.py
Cython/Build/Dependencies.py
+4
-1
Cython/CodeWriter.py
Cython/CodeWriter.py
+267
-79
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+11
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+7
-4
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+215
-81
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+23
-24
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+0
-1
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+12
-8
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+2
-2
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+52
-42
Cython/Debugger/Tests/test_libcython_in_gdb.py
Cython/Debugger/Tests/test_libcython_in_gdb.py
+26
-0
Cython/Debugger/Tests/test_libpython_in_gdb.py
Cython/Debugger/Tests/test_libpython_in_gdb.py
+1
-3
Cython/Debugger/libcython.py
Cython/Debugger/libcython.py
+84
-17
Cython/Debugger/libpython.py
Cython/Debugger/libpython.py
+58
-31
runtests.py
runtests.py
+1
-1
tests/bugs.txt
tests/bugs.txt
+1
-0
tests/compile/a_capi.pyx
tests/compile/a_capi.pyx
+9
-0
tests/compile/publicapi_api.pyx
tests/compile/publicapi_api.pyx
+65
-0
tests/compile/publicapi_mix.pyx
tests/compile/publicapi_mix.pyx
+77
-0
tests/compile/publicapi_pub.pyx
tests/compile/publicapi_pub.pyx
+65
-0
tests/compile/publicapi_pxd_mix.pxd
tests/compile/publicapi_pxd_mix.pxd
+68
-0
tests/compile/publicapi_pxd_mix.pyx
tests/compile/publicapi_pxd_mix.pyx
+15
-0
tests/run/builtinnames.pyx
tests/run/builtinnames.pyx
+11
-0
tests/run/capiimpl.pyx
tests/run/capiimpl.pyx
+22
-1
No files found.
Cython/Build/Dependencies.py
View file @
6a57acd5
...
@@ -434,9 +434,12 @@ def create_extension_list(patterns, exclude=[], ctx=None, aliases=None):
...
@@ -434,9 +434,12 @@ def create_extension_list(patterns, exclude=[], ctx=None, aliases=None):
for
key
,
value
in
base
.
values
.
items
():
for
key
,
value
in
base
.
values
.
items
():
if
key
not
in
kwds
:
if
key
not
in
kwds
:
kwds
[
key
]
=
value
kwds
[
key
]
=
value
sources
=
[
file
]
if
template
is
not
None
:
sources
+=
template
.
sources
[
1
:]
module_list
.
append
(
exn_type
(
module_list
.
append
(
exn_type
(
name
=
module_name
,
name
=
module_name
,
sources
=
[
file
]
,
sources
=
sources
,
**
kwds
))
**
kwds
))
m
=
module_list
[
-
1
]
m
=
module_list
[
-
1
]
seen
.
add
(
name
)
seen
.
add
(
name
)
...
...
Cython/CodeWriter.py
View file @
6a57acd5
...
@@ -26,12 +26,12 @@ class LinesResult(object):
...
@@ -26,12 +26,12 @@ class LinesResult(object):
self
.
put
(
s
)
self
.
put
(
s
)
self
.
newline
()
self
.
newline
()
class
Code
Writer
(
TreeVisitor
):
class
Declaration
Writer
(
TreeVisitor
):
indent_string
=
u" "
indent_string
=
u" "
def
__init__
(
self
,
result
=
None
):
def
__init__
(
self
,
result
=
None
):
super
(
Code
Writer
,
self
).
__init__
()
super
(
Declaration
Writer
,
self
).
__init__
()
if
result
is
None
:
if
result
is
None
:
result
=
LinesResult
()
result
=
LinesResult
()
self
.
result
=
result
self
.
result
=
result
...
@@ -41,6 +41,7 @@ class CodeWriter(TreeVisitor):
...
@@ -41,6 +41,7 @@ class CodeWriter(TreeVisitor):
def
write
(
self
,
tree
):
def
write
(
self
,
tree
):
self
.
visit
(
tree
)
self
.
visit
(
tree
)
return
self
.
result
def
indent
(
self
):
def
indent
(
self
):
self
.
numindents
+=
1
self
.
numindents
+=
1
...
@@ -54,6 +55,9 @@ class CodeWriter(TreeVisitor):
...
@@ -54,6 +55,9 @@ class CodeWriter(TreeVisitor):
def
put
(
self
,
s
):
def
put
(
self
,
s
):
self
.
result
.
put
(
s
)
self
.
result
.
put
(
s
)
def
putline
(
self
,
s
):
self
.
result
.
putline
(
self
.
indent_string
*
self
.
numindents
+
s
)
def
endline
(
self
,
s
=
u""
):
def
endline
(
self
,
s
=
u""
):
self
.
result
.
putline
(
s
)
self
.
result
.
putline
(
s
)
...
@@ -79,23 +83,45 @@ class CodeWriter(TreeVisitor):
...
@@ -79,23 +83,45 @@ class CodeWriter(TreeVisitor):
def
visit_StatListNode
(
self
,
node
):
def
visit_StatListNode
(
self
,
node
):
self
.
visitchildren
(
node
)
self
.
visitchildren
(
node
)
def
visit_FuncDefNode
(
self
,
node
):
def
visit_CDefExternNode
(
self
,
node
):
self
.
startline
(
u"def %s("
%
node
.
name
)
if
node
.
include_file
is
None
:
self
.
comma_separated_list
(
node
.
args
)
file
=
u'*'
self
.
endline
(
u"):"
)
else
:
file
=
u'"%s"'
%
node
.
include_file
self
.
putline
(
u"cdef extern from %s:"
%
file
)
self
.
indent
()
self
.
indent
()
self
.
visit
(
node
.
body
)
self
.
visit
(
node
.
body
)
self
.
dedent
()
self
.
dedent
()
def
visit_CArgDeclNode
(
self
,
node
):
def
visit_CPtrDeclaratorNode
(
self
,
node
):
if
node
.
base_type
.
name
is
not
None
:
self
.
put
(
'*'
)
self
.
visit
(
node
.
base_type
)
self
.
visit
(
node
.
base
)
self
.
put
(
u" "
)
self
.
visit
(
node
.
declarator
)
def
visit_CReferenceDeclaratorNode
(
self
,
node
):
if
node
.
default
is
not
None
:
self
.
put
(
'&'
)
self
.
put
(
u" = "
)
self
.
visit
(
node
.
base
)
self
.
visit
(
node
.
default
)
def
visit_CArrayDeclaratorNode
(
self
,
node
):
self
.
visit
(
node
.
base
)
self
.
put
(
u'['
)
if
node
.
dimension
is
not
None
:
self
.
visit
(
node
.
dimension
)
self
.
put
(
u']'
)
def
visit_CArrayDeclaratorNode
(
self
,
node
):
self
.
visit
(
node
.
base
)
self
.
put
(
u'['
)
if
node
.
dimension
is
not
None
:
self
.
visit
(
node
.
dimension
)
self
.
put
(
u']'
)
def
visit_CFuncDeclaratorNode
(
self
,
node
):
# TODO: except, gil, etc.
self
.
visit
(
node
.
base
)
self
.
put
(
u'('
)
self
.
comma_separated_list
(
node
.
args
)
self
.
endline
(
u')'
)
def
visit_CNameDeclaratorNode
(
self
,
node
):
def
visit_CNameDeclaratorNode
(
self
,
node
):
self
.
put
(
node
.
name
)
self
.
put
(
node
.
name
)
...
@@ -108,22 +134,149 @@ class CodeWriter(TreeVisitor):
...
@@ -108,22 +134,149 @@ class CodeWriter(TreeVisitor):
self
.
put
(
"short "
*
-
node
.
longness
)
self
.
put
(
"short "
*
-
node
.
longness
)
elif
node
.
longness
>
0
:
elif
node
.
longness
>
0
:
self
.
put
(
"long "
*
node
.
longness
)
self
.
put
(
"long "
*
node
.
longness
)
self
.
put
(
node
.
name
)
def
visit_CComplexBaseTypeNode
(
self
,
node
):
self
.
put
(
u'('
)
self
.
visit
(
node
.
base_type
)
self
.
visit
(
node
.
declarator
)
self
.
put
(
u')'
)
def
visit_CNestedBaseTypeNode
(
self
,
node
):
self
.
visit
(
node
.
base_type
)
self
.
put
(
u'.'
)
self
.
put
(
node
.
name
)
self
.
put
(
node
.
name
)
def
visit_SingleAssignmentNode
(
self
,
node
):
def
visit_TemplatedTypeNode
(
self
,
node
):
self
.
startline
()
self
.
visit
(
node
.
base_type_node
)
self
.
visit
(
node
.
lhs
)
self
.
put
(
u'['
)
self
.
put
(
u" = "
)
self
.
comma_separated_list
(
node
.
positional_args
+
node
.
keyword_args
.
key_value_pairs
)
self
.
visit
(
node
.
rhs
)
self
.
put
(
u']'
)
def
visit_CVarDefNode
(
self
,
node
):
self
.
startline
(
u"cdef "
)
self
.
visit
(
node
.
base_type
)
self
.
put
(
u" "
)
self
.
comma_separated_list
(
node
.
declarators
,
output_rhs
=
True
)
self
.
endline
()
self
.
endline
()
def
visit_CascadedAssignmentNode
(
self
,
node
):
def
visit_container_node
(
self
,
node
,
decl
,
extras
,
attributes
):
self
.
startline
()
# TODO: visibility
for
lhs
in
node
.
lhs_list
:
self
.
startline
(
decl
)
self
.
visit
(
lhs
)
if
node
.
name
:
self
.
put
(
u' '
)
self
.
put
(
node
.
name
)
if
node
.
cname
is
not
None
:
self
.
put
(
u' "%s"'
%
node
.
cname
)
if
extras
:
self
.
put
(
extras
)
self
.
endline
(
':'
)
self
.
indent
()
if
not
attributes
:
self
.
putline
(
'pass'
)
else
:
for
attribute
in
attributes
:
self
.
visit
(
attribute
)
self
.
dedent
()
def
visit_CStructOrUnionDefNode
(
self
,
node
):
if
node
.
typedef_flag
:
decl
=
u'ctypedef '
else
:
decl
=
u'cdef '
if
node
.
visibility
==
'public'
:
decl
+=
u'public '
if
node
.
packed
:
decl
+=
u'packed '
decl
+=
node
.
kind
self
.
visit_container_node
(
node
,
decl
,
None
,
node
.
attributes
)
def
visit_CppClassNode
(
self
,
node
):
extras
=
""
if
node
.
templates
:
extras
=
u"[%s]"
%
", "
.
join
(
node
.
templates
)
if
node
.
base_classes
:
extras
+=
"(%s)"
%
", "
.
join
(
node
.
base_classes
)
self
.
visit_container_node
(
node
,
u"cdef cppclass"
,
extras
,
node
.
attributes
)
def
visit_CEnumDefNode
(
self
,
node
):
self
.
visit_container_node
(
node
,
u"cdef enum"
,
None
,
node
.
items
)
def
visit_CEnumDefItemNode
(
self
,
node
):
self
.
startline
(
node
.
name
)
if
node
.
cname
:
self
.
put
(
u' "%s"'
%
node
.
cname
)
if
node
.
value
:
self
.
put
(
u" = "
)
self
.
put
(
u" = "
)
self
.
visit
(
node
.
rhs
)
self
.
visit
(
node
.
value
)
self
.
endline
()
def
visit_CClassDefNode
(
self
,
node
):
assert
not
node
.
module_name
if
node
.
decorators
:
for
decorator
in
node
.
decorators
:
self
.
visit
(
decorator
)
self
.
startline
(
u"cdef class "
)
self
.
put
(
node
.
class_name
)
if
node
.
base_class_name
:
self
.
put
(
u"("
)
if
node
.
base_class_module
:
self
.
put
(
node
.
base_class_module
)
self
.
put
(
u"."
)
self
.
put
(
node
.
base_class_name
)
self
.
put
(
u")"
)
self
.
endline
(
u":"
)
self
.
indent
()
self
.
visit
(
node
.
body
)
self
.
dedent
()
def
visit_CTypeDefNode
(
self
,
node
):
self
.
startline
(
u"ctypedef "
)
self
.
visit
(
node
.
base_type
)
self
.
put
(
u" "
)
self
.
visit
(
node
.
declarator
)
self
.
endline
()
def
visit_FuncDefNode
(
self
,
node
):
self
.
startline
(
u"def %s("
%
node
.
name
)
self
.
comma_separated_list
(
node
.
args
)
self
.
endline
(
u"):"
)
self
.
indent
()
self
.
visit
(
node
.
body
)
self
.
dedent
()
def
visit_CArgDeclNode
(
self
,
node
):
if
node
.
base_type
.
name
is
not
None
:
self
.
visit
(
node
.
base_type
)
self
.
put
(
u" "
)
self
.
visit
(
node
.
declarator
)
if
node
.
default
is
not
None
:
self
.
put
(
u" = "
)
self
.
visit
(
node
.
default
)
def
visit_CImportStatNode
(
self
,
node
):
self
.
startline
(
u"cimport "
)
self
.
put
(
node
.
module_name
)
if
node
.
as_name
:
self
.
put
(
u" as "
)
self
.
put
(
node
.
as_name
)
self
.
endline
()
def
visit_FromCImportStatNode
(
self
,
node
):
self
.
startline
(
u"from "
)
self
.
put
(
node
.
module_name
)
self
.
put
(
u" cimport "
)
first
=
True
for
pos
,
name
,
as_name
,
kind
in
node
.
imported_names
:
assert
kind
is
None
if
first
:
first
=
False
else
:
self
.
put
(
u", "
)
self
.
put
(
name
)
if
as_name
:
self
.
put
(
u" as "
)
self
.
put
(
as_name
)
self
.
endline
()
self
.
endline
()
def
visit_NameNode
(
self
,
node
):
def
visit_NameNode
(
self
,
node
):
...
@@ -132,6 +285,31 @@ class CodeWriter(TreeVisitor):
...
@@ -132,6 +285,31 @@ class CodeWriter(TreeVisitor):
def
visit_IntNode
(
self
,
node
):
def
visit_IntNode
(
self
,
node
):
self
.
put
(
node
.
value
)
self
.
put
(
node
.
value
)
def
visit_NoneNode
(
self
,
node
):
self
.
put
(
u"None"
)
def
visit_NotNode
(
self
,
node
):
self
.
put
(
u"(not "
)
self
.
visit
(
node
.
operand
)
self
.
put
(
u")"
)
def
visit_DecoratorNode
(
self
,
node
):
self
.
startline
(
"@"
)
self
.
visit
(
node
.
decorator
)
self
.
endline
()
def
visit_BinopNode
(
self
,
node
):
self
.
visit
(
node
.
operand1
)
self
.
put
(
u" %s "
%
node
.
operator
)
self
.
visit
(
node
.
operand2
)
def
visit_AttributeNode
(
self
,
node
):
self
.
visit
(
node
.
obj
)
self
.
put
(
u".%s"
%
node
.
attribute
)
def
visit_BoolNode
(
self
,
node
):
self
.
put
(
str
(
node
.
value
))
# FIXME: represent string nodes correctly
# FIXME: represent string nodes correctly
def
visit_StringNode
(
self
,
node
):
def
visit_StringNode
(
self
,
node
):
value
=
node
.
value
value
=
node
.
value
...
@@ -139,32 +317,27 @@ class CodeWriter(TreeVisitor):
...
@@ -139,32 +317,27 @@ class CodeWriter(TreeVisitor):
value
=
value
.
encode
(
value
.
encoding
)
value
=
value
.
encode
(
value
.
encoding
)
self
.
put
(
repr
(
value
))
self
.
put
(
repr
(
value
))
def
visit_IfStatNode
(
self
,
node
):
# The IfClauseNode is handled directly without a seperate match
# for clariy.
self
.
startline
(
u"if "
)
self
.
visit
(
node
.
if_clauses
[
0
].
condition
)
self
.
endline
(
":"
)
self
.
indent
()
self
.
visit
(
node
.
if_clauses
[
0
].
body
)
self
.
dedent
()
for
clause
in
node
.
if_clauses
[
1
:]:
self
.
startline
(
"elif "
)
self
.
visit
(
clause
.
condition
)
self
.
endline
(
":"
)
self
.
indent
()
self
.
visit
(
clause
.
body
)
self
.
dedent
()
if
node
.
else_clause
is
not
None
:
self
.
line
(
"else:"
)
self
.
indent
()
self
.
visit
(
node
.
else_clause
)
self
.
dedent
()
def
visit_PassStatNode
(
self
,
node
):
def
visit_PassStatNode
(
self
,
node
):
self
.
startline
(
u"pass"
)
self
.
startline
(
u"pass"
)
self
.
endline
()
self
.
endline
()
class
CodeWriter
(
DeclarationWriter
):
def
visit_SingleAssignmentNode
(
self
,
node
):
self
.
startline
()
self
.
visit
(
node
.
lhs
)
self
.
put
(
u" = "
)
self
.
visit
(
node
.
rhs
)
self
.
endline
()
def
visit_CascadedAssignmentNode
(
self
,
node
):
self
.
startline
()
for
lhs
in
node
.
lhs_list
:
self
.
visit
(
lhs
)
self
.
put
(
u" = "
)
self
.
visit
(
node
.
rhs
)
self
.
endline
()
def
visit_PrintStatNode
(
self
,
node
):
def
visit_PrintStatNode
(
self
,
node
):
self
.
startline
(
u"print "
)
self
.
startline
(
u"print "
)
self
.
comma_separated_list
(
node
.
arg_tuple
.
args
)
self
.
comma_separated_list
(
node
.
arg_tuple
.
args
)
...
@@ -172,18 +345,6 @@ class CodeWriter(TreeVisitor):
...
@@ -172,18 +345,6 @@ class CodeWriter(TreeVisitor):
self
.
put
(
u","
)
self
.
put
(
u","
)
self
.
endline
()
self
.
endline
()
def
visit_BinopNode
(
self
,
node
):
self
.
visit
(
node
.
operand1
)
self
.
put
(
u" %s "
%
node
.
operator
)
self
.
visit
(
node
.
operand2
)
def
visit_CVarDefNode
(
self
,
node
):
self
.
startline
(
u"cdef "
)
self
.
visit
(
node
.
base_type
)
self
.
put
(
u" "
)
self
.
comma_separated_list
(
node
.
declarators
,
output_rhs
=
True
)
self
.
endline
()
def
visit_ForInStatNode
(
self
,
node
):
def
visit_ForInStatNode
(
self
,
node
):
self
.
startline
(
u"for "
)
self
.
startline
(
u"for "
)
self
.
visit
(
node
.
target
)
self
.
visit
(
node
.
target
)
...
@@ -199,6 +360,28 @@ class CodeWriter(TreeVisitor):
...
@@ -199,6 +360,28 @@ class CodeWriter(TreeVisitor):
self
.
visit
(
node
.
else_clause
)
self
.
visit
(
node
.
else_clause
)
self
.
dedent
()
self
.
dedent
()
def
visit_IfStatNode
(
self
,
node
):
# The IfClauseNode is handled directly without a seperate match
# for clariy.
self
.
startline
(
u"if "
)
self
.
visit
(
node
.
if_clauses
[
0
].
condition
)
self
.
endline
(
":"
)
self
.
indent
()
self
.
visit
(
node
.
if_clauses
[
0
].
body
)
self
.
dedent
()
for
clause
in
node
.
if_clauses
[
1
:]:
self
.
startline
(
"elif "
)
self
.
visit
(
clause
.
condition
)
self
.
endline
(
":"
)
self
.
indent
()
self
.
visit
(
clause
.
body
)
self
.
dedent
()
if
node
.
else_clause
is
not
None
:
self
.
line
(
"else:"
)
self
.
indent
()
self
.
visit
(
node
.
else_clause
)
self
.
dedent
()
def
visit_SequenceNode
(
self
,
node
):
def
visit_SequenceNode
(
self
,
node
):
self
.
comma_separated_list
(
node
.
args
)
# Might need to discover whether we need () around tuples...hmm...
self
.
comma_separated_list
(
node
.
args
)
# Might need to discover whether we need () around tuples...hmm...
...
@@ -244,13 +427,6 @@ class CodeWriter(TreeVisitor):
...
@@ -244,13 +427,6 @@ class CodeWriter(TreeVisitor):
self
.
visit
(
node
.
body
)
self
.
visit
(
node
.
body
)
self
.
dedent
()
self
.
dedent
()
def
visit_AttributeNode
(
self
,
node
):
self
.
visit
(
node
.
obj
)
self
.
put
(
u".%s"
%
node
.
attribute
)
def
visit_BoolNode
(
self
,
node
):
self
.
put
(
str
(
node
.
value
))
def
visit_TryFinallyStatNode
(
self
,
node
):
def
visit_TryFinallyStatNode
(
self
,
node
):
self
.
line
(
u"try:"
)
self
.
line
(
u"try:"
)
self
.
indent
()
self
.
indent
()
...
@@ -289,25 +465,12 @@ class CodeWriter(TreeVisitor):
...
@@ -289,25 +465,12 @@ class CodeWriter(TreeVisitor):
self
.
visit
(
node
.
value
)
self
.
visit
(
node
.
value
)
self
.
endline
()
self
.
endline
()
def
visit_DecoratorNode
(
self
,
node
):
self
.
startline
(
"@"
)
self
.
visit
(
node
.
decorator
)
self
.
endline
()
def
visit_ReraiseStatNode
(
self
,
node
):
def
visit_ReraiseStatNode
(
self
,
node
):
self
.
line
(
"raise"
)
self
.
line
(
"raise"
)
def
visit_NoneNode
(
self
,
node
):
self
.
put
(
u"None"
)
def
visit_ImportNode
(
self
,
node
):
def
visit_ImportNode
(
self
,
node
):
self
.
put
(
u"(import %s)"
%
node
.
module_name
.
value
)
self
.
put
(
u"(import %s)"
%
node
.
module_name
.
value
)
def
visit_NotNode
(
self
,
node
):
self
.
put
(
u"(not "
)
self
.
visit
(
node
.
operand
)
self
.
put
(
u")"
)
def
visit_TempsBlockNode
(
self
,
node
):
def
visit_TempsBlockNode
(
self
,
node
):
"""
"""
Temporaries are output like $1_1', where the first number is
Temporaries are output like $1_1', where the first number is
...
@@ -323,3 +486,28 @@ class CodeWriter(TreeVisitor):
...
@@ -323,3 +486,28 @@ class CodeWriter(TreeVisitor):
def
visit_TempRefNode
(
self
,
node
):
def
visit_TempRefNode
(
self
,
node
):
self
.
put
(
self
.
tempnames
[
node
.
handle
])
self
.
put
(
self
.
tempnames
[
node
.
handle
])
class
PxdWriter
(
DeclarationWriter
):
def
__call__
(
self
,
node
):
print
u'
\
n
'
.
join
(
self
.
write
(
node
).
lines
)
return
node
def
visit_CFuncDefNode
(
self
,
node
):
if
'inline'
in
node
.
modifiers
:
return
if
node
.
overridable
:
self
.
startline
(
u'cpdef '
)
else
:
self
.
startline
(
u'cdef '
)
if
node
.
visibility
!=
'private'
:
self
.
put
(
node
.
visibility
)
self
.
put
(
u' '
)
if
node
.
api
:
self
.
put
(
u'api '
)
self
.
visit
(
node
.
declarator
)
def
visit_StatNode
(
self
,
node
):
pass
\ No newline at end of file
Cython/Compiler/Code.py
View file @
6a57acd5
...
@@ -650,17 +650,27 @@ class GlobalState(object):
...
@@ -650,17 +650,27 @@ class GlobalState(object):
if self.should_declare(entry.cname, entry):
if self.should_declare(entry.cname, entry):
self.put_pyobject_decl(entry)
self.put_pyobject_decl(entry)
w = self.parts['cached_builtins']
w = self.parts['cached_builtins']
conditional_name = False
if entry.name == 'xrange':
if entry.name == 'xrange':
# replaced by range() in Py3
# replaced by range() in Py3
conditional_name = True
w.putln('#if PY_MAJOR_VERSION >= 3')
w.putln('#if PY_MAJOR_VERSION >= 3')
self.put_cached_builtin_init(
self.put_cached_builtin_init(
entry.pos, StringEncoding.EncodedString('range'),
entry.pos, StringEncoding.EncodedString('range'),
entry.cname)
entry.cname)
elif entry.name == 'BaseException':
# replace BaseException by Exception in Py<2.5
conditional_name = True
w.putln('#if PY_VERSION_HEX < 0x02050000')
self.put_cached_builtin_init(
entry.pos, StringEncoding.EncodedString('Exception'),
entry.cname)
if conditional_name:
w.putln('#else')
w.putln('#else')
self.put_cached_builtin_init(
self.put_cached_builtin_init(
entry.pos, StringEncoding.EncodedString(entry.name),
entry.pos, StringEncoding.EncodedString(entry.name),
entry.cname)
entry.cname)
if
entry.name == 'xrange'
:
if
conditional_name
:
w.putln('#endif')
w.putln('#endif')
def put_cached_builtin_init(self, pos, name, cname):
def put_cached_builtin_init(self, pos, name, cname):
...
...
Cython/Compiler/ExprNodes.py
View file @
6a57acd5
...
@@ -861,9 +861,8 @@ class IntNode(ConstNode):
...
@@ -861,9 +861,8 @@ class IntNode(ConstNode):
return
self
return
self
elif
dst_type
.
is_float
:
elif
dst_type
.
is_float
:
if
self
.
constant_result
is
not
not_a_constant
:
if
self
.
constant_result
is
not
not_a_constant
:
float_value
=
float
(
self
.
constant_result
)
return
FloatNode
(
self
.
pos
,
value
=
'%d.0'
%
int
(
self
.
constant_result
),
type
=
dst_type
,
return
FloatNode
(
self
.
pos
,
value
=
repr
(
float_value
),
type
=
dst_type
,
constant_result
=
float
(
self
.
constant_result
))
constant_result
=
float_value
)
else
:
else
:
return
FloatNode
(
self
.
pos
,
value
=
self
.
value
,
type
=
dst_type
,
return
FloatNode
(
self
.
pos
,
value
=
self
.
value
,
type
=
dst_type
,
constant_result
=
not_a_constant
)
constant_result
=
not_a_constant
)
...
@@ -3054,7 +3053,11 @@ class SimpleCallNode(CallNode):
...
@@ -3054,7 +3053,11 @@ class SimpleCallNode(CallNode):
# nogil anyway)
# nogil anyway)
pass
pass
else
:
else
:
self
.
args
[
i
]
=
arg
.
coerce_to_temp
(
env
)
#self.args[i] = arg.coerce_to_temp(env)
# instead: issue a warning
if
i
>
0
or
i
==
1
and
self
.
self
is
not
None
:
# skip first arg
warning
(
arg
.
pos
,
"Argument evaluation order in C function call is undefined and may not be as expected"
,
0
)
break
# Calc result type and code fragment
# Calc result type and code fragment
if
isinstance
(
self
.
function
,
NewExprNode
):
if
isinstance
(
self
.
function
,
NewExprNode
):
self
.
type
=
PyrexTypes
.
CPtrType
(
self
.
function
.
class_type
)
self
.
type
=
PyrexTypes
.
CPtrType
(
self
.
function
.
class_type
)
...
...
Cython/Compiler/ModuleNode.py
View file @
6a57acd5
...
@@ -73,7 +73,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -73,7 +73,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_c_code
(
env
,
options
,
result
)
self
.
generate_c_code
(
env
,
options
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
self
.
generate_h_code
(
env
,
options
,
result
)
self
.
generate_api_code
(
env
,
result
)
self
.
generate_api_code
(
env
,
result
)
def
has_imported_c_functions
(
self
):
def
has_imported_c_functions
(
self
):
for
module
in
self
.
referenced_modules
:
for
module
in
self
.
referenced_modules
:
for
entry
in
module
.
cfunc_entries
:
for
entry
in
module
.
cfunc_entries
:
...
@@ -96,14 +96,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -96,14 +96,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
f
.
close
()
f
.
close
()
def
generate_h_code
(
self
,
env
,
options
,
result
):
def
generate_h_code
(
self
,
env
,
options
,
result
):
def
h_entries
(
entries
,
pxd
=
0
):
def
h_entries
(
entries
,
api
=
0
,
pxd
=
0
):
return
[
entry
for
entry
in
entries
return
[
entry
for
entry
in
entries
if
entry
.
visibility
==
'public'
or
pxd
and
entry
.
defined_in_pxd
]
if
((
entry
.
visibility
==
'public'
)
or
h_types
=
h_entries
(
env
.
type_entries
)
(
api
and
entry
.
api
)
or
(
pxd
and
entry
.
defined_in_pxd
))]
h_types
=
h_entries
(
env
.
type_entries
,
api
=
1
)
h_vars
=
h_entries
(
env
.
var_entries
)
h_vars
=
h_entries
(
env
.
var_entries
)
h_funcs
=
h_entries
(
env
.
cfunc_entries
)
h_funcs
=
h_entries
(
env
.
cfunc_entries
)
h_extension_types
=
h_entries
(
env
.
c_class_entries
)
h_extension_types
=
h_entries
(
env
.
c_class_entries
)
if
h_types
or
h_vars
or
h_funcs
or
h_extension_types
:
if
(
h_types
or
h_vars
or
h_funcs
or
h_extension_types
)
:
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
h_code
=
Code
.
CCodeWriter
()
h_code
=
Code
.
CCodeWriter
()
Code
.
GlobalState
(
h_code
)
Code
.
GlobalState
(
h_code
)
...
@@ -112,32 +114,40 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -112,32 +114,40 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
i_code
=
Code
.
PyrexCodeWriter
(
result
.
i_file
)
i_code
=
Code
.
PyrexCodeWriter
(
result
.
i_file
)
else
:
else
:
i_code
=
None
i_code
=
None
guard
=
Naming
.
h_guard_prefix
+
env
.
qualified_name
.
replace
(
"."
,
"__"
)
h_code
.
put_h_guard
(
guard
)
h_guard
=
Naming
.
h_guard_prefix
+
self
.
api_name
(
env
)
self
.
generate_extern_c_macro_definition
(
h_code
)
h_code
.
put_h_guard
(
h_guard
)
h_code
.
putln
(
""
)
self
.
generate_type_header_code
(
h_types
,
h_code
)
self
.
generate_type_header_code
(
h_types
,
h_code
)
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#ifndef %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
api_guard
=
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
)
if
h_vars
:
h_code
.
putln
(
"#ifndef %s"
%
api_guard
)
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
for
entry
in
h_vars
:
self
.
generate_extern_c_macro_definition
(
h_code
)
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
if
h_funcs
:
h_code
.
putln
(
""
)
for
entry
in
h_funcs
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
if
h_extension_types
:
if
h_extension_types
:
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
for
entry
in
h_extension_types
:
for
entry
in
h_extension_types
:
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
if
i_code
:
if
i_code
:
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
if
h_funcs
:
h_code
.
putln
(
""
)
for
entry
in
h_funcs
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
if
h_vars
:
h_code
.
putln
(
""
)
for
entry
in
h_vars
:
self
.
generate_public_declaration
(
entry
,
h_code
,
i_code
)
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif
"
)
h_code
.
putln
(
"#endif
/* !%s */"
%
api_guard
)
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#if PY_MAJOR_VERSION < 3"
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#else"
)
h_code
.
putln
(
"PyMODINIT_FUNC PyInit_%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"#endif"
)
h_code
.
putln
(
"#endif"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif /* !%s */"
%
h_guard
)
f
=
open_new_file
(
result
.
h_file
)
f
=
open_new_file
(
result
.
h_file
)
try
:
try
:
...
@@ -156,65 +166,70 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -156,65 +166,70 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
api_name
(
self
,
env
):
def
api_name
(
self
,
env
):
return
env
.
qualified_name
.
replace
(
"."
,
"__"
)
return
env
.
qualified_name
.
replace
(
"."
,
"__"
)
def
generate_api_code
(
self
,
env
,
result
):
def
generate_api_code
(
self
,
env
,
result
):
api_funcs
=
[]
def
api_entries
(
entries
,
pxd
=
1
):
public_extension_types
=
[]
return
[
entry
for
entry
in
entries
has_api_extension_types
=
0
if
entry
.
api
or
(
pxd
and
entry
.
defined_in_pxd
)]
for
entry
in
env
.
cfunc_entries
:
api_vars
=
api_entries
(
env
.
var_entries
)
if
entry
.
api
:
api_funcs
=
api_entries
(
env
.
cfunc_entries
)
api_funcs
.
append
(
entry
)
api_extension_types
=
api_entries
(
env
.
c_class_entries
)
for
entry
in
env
.
c_class_entries
:
if
api_vars
or
api_funcs
or
api_extension_types
:
if
entry
.
visibility
==
'public'
:
public_extension_types
.
append
(
entry
)
if
entry
.
api
:
has_api_extension_types
=
1
if
api_funcs
or
has_api_extension_types
:
result
.
api_file
=
replace_suffix
(
result
.
c_file
,
"_api.h"
)
result
.
api_file
=
replace_suffix
(
result
.
c_file
,
"_api.h"
)
h_code
=
Code
.
CCodeWriter
()
h_code
=
Code
.
CCodeWriter
()
Code
.
GlobalState
(
h_code
)
Code
.
GlobalState
(
h_code
)
name
=
self
.
api_name
(
env
)
api_guard
=
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
)
guard
=
Naming
.
api_guard_prefix
+
name
h_code
.
put_h_guard
(
api_guard
)
h_code
.
put_h_guard
(
guard
)
h_code
.
putln
(
'#include "Python.h"'
)
h_code
.
putln
(
'#include "Python.h"'
)
if
result
.
h_file
:
if
result
.
h_file
:
h_code
.
putln
(
'#include "%s"'
%
os
.
path
.
basename
(
result
.
h_file
))
h_code
.
putln
(
'#include "%s"'
%
os
.
path
.
basename
(
result
.
h_file
))
for
entry
in
public_extension_types
:
if
api_extension_types
:
type
=
entry
.
type
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"static PyTypeObject *%s;"
%
type
.
typeptr_cname
)
for
entry
in
api_extension_types
:
h_code
.
putln
(
"#define %s (*%s)"
%
(
type
=
entry
.
type
type
.
typeobj_cname
,
type
.
typeptr_cname
))
h_code
.
putln
(
"static PyTypeObject *%s = 0;"
%
type
.
typeptr_cname
)
h_code
.
putln
(
"#define %s (*%s)"
%
(
type
.
typeobj_cname
,
type
.
typeptr_cname
))
if
api_funcs
:
if
api_funcs
:
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
for
entry
in
api_funcs
:
for
entry
in
api_funcs
:
type
=
CPtrType
(
entry
.
type
)
type
=
CPtrType
(
entry
.
type
)
h_code
.
putln
(
"static %s;"
%
type
.
declaration_code
(
entry
.
cname
))
cname
=
env
.
mangle
(
Naming
.
func_prefix
,
entry
.
name
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"static %s = 0;"
%
type
.
declaration_code
(
cname
))
h_code
.
put_h_guard
(
Naming
.
api_func_guard
+
"import_module"
)
h_code
.
putln
(
"#define %s %s"
%
(
entry
.
name
,
cname
))
if
api_vars
:
h_code
.
putln
(
""
)
for
entry
in
api_vars
:
type
=
CPtrType
(
entry
.
type
)
cname
=
env
.
mangle
(
Naming
.
var_prefix
,
entry
.
name
)
h_code
.
putln
(
"static %s = 0;"
%
type
.
declaration_code
(
cname
))
h_code
.
putln
(
"#define %s (*%s)"
%
(
entry
.
name
,
cname
))
h_code
.
put
(
import_module_utility_code
.
impl
)
h_code
.
put
(
import_module_utility_code
.
impl
)
h_code
.
putln
(
""
)
if
api_vars
:
h_code
.
putln
(
"#endif"
)
h_code
.
put
(
voidptr_import_utility_code
.
impl
)
if
api_funcs
:
if
api_funcs
:
h_code
.
putln
(
""
)
h_code
.
put
(
function_import_utility_code
.
impl
)
h_code
.
put
(
function_import_utility_code
.
impl
)
if
public_extension_types
:
if
api_extension_types
:
h_code
.
putln
(
""
)
h_code
.
put
(
type_import_utility_code
.
impl
)
h_code
.
put
(
type_import_utility_code
.
impl
)
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"static int import_%s(void) {"
%
name
)
h_code
.
putln
(
"static int import_%s(void) {"
%
self
.
api_name
(
env
)
)
h_code
.
putln
(
"PyObject *module = 0;"
)
h_code
.
putln
(
"PyObject *module = 0;"
)
h_code
.
putln
(
'module = __Pyx_ImportModule("%s");'
%
env
.
qualified_name
)
h_code
.
putln
(
'module = __Pyx_ImportModule("%s");'
%
env
.
qualified_name
)
h_code
.
putln
(
"if (!module) goto bad;"
)
h_code
.
putln
(
"if (!module) goto bad;"
)
for
entry
in
api_funcs
:
for
entry
in
api_funcs
:
cname
=
env
.
mangle
(
Naming
.
func_prefix
,
entry
.
name
)
sig
=
entry
.
type
.
signature_string
()
sig
=
entry
.
type
.
signature_string
()
h_code
.
putln
(
h_code
.
putln
(
'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
%
(
'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
entry
.
name
,
%
(
entry
.
name
,
cname
,
sig
))
entry
.
cname
,
for
entry
in
api_vars
:
sig
))
cname
=
env
.
mangle
(
Naming
.
var_prefix
,
entry
.
name
)
sig
=
entry
.
type
.
declaration_code
(
""
)
h_code
.
putln
(
'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
%
(
entry
.
name
,
cname
,
sig
))
h_code
.
putln
(
"Py_DECREF(module); module = 0;"
)
h_code
.
putln
(
"Py_DECREF(module); module = 0;"
)
for
entry
in
public
_extension_types
:
for
entry
in
api
_extension_types
:
self
.
generate_type_import_call
(
self
.
generate_type_import_call
(
entry
.
type
,
h_code
,
entry
.
type
,
h_code
,
"if (!%s) goto bad;"
%
entry
.
type
.
typeptr_cname
)
"if (!%s) goto bad;"
%
entry
.
type
.
typeptr_cname
)
...
@@ -224,7 +239,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -224,7 +239,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
h_code
.
putln
(
"return -1;"
)
h_code
.
putln
(
"return -1;"
)
h_code
.
putln
(
"}"
)
h_code
.
putln
(
"}"
)
h_code
.
putln
(
""
)
h_code
.
putln
(
""
)
h_code
.
putln
(
"#endif
"
)
h_code
.
putln
(
"#endif
/* !%s */"
%
api_guard
)
f
=
open_new_file
(
result
.
api_file
)
f
=
open_new_file
(
result
.
api_file
)
try
:
try
:
...
@@ -233,8 +248,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -233,8 +248,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
f
.
close
()
f
.
close
()
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
h_code
.
putln
(
"%s DL_IMPORT(PyTypeObject) %s;"
%
(
h_code
.
putln
(
"%s %s %s;"
%
(
Naming
.
extern_c_macro
,
Naming
.
extern_c_macro
,
PyrexTypes
.
public_decl
(
"PyTypeObject"
,
"DL_IMPORT"
),
type
.
typeobj_cname
))
type
.
typeobj_cname
))
def
generate_cclass_include_code
(
self
,
type
,
i_code
):
def
generate_cclass_include_code
(
self
,
type
,
i_code
):
...
@@ -424,8 +440,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -424,8 +440,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_objstruct_definition
(
type
,
code
)
self
.
generate_objstruct_definition
(
type
,
code
)
for
entry
in
vtabslot_list
:
for
entry
in
vtabslot_list
:
self
.
generate_objstruct_definition
(
entry
.
type
,
code
)
self
.
generate_objstruct_definition
(
entry
.
type
,
code
)
self
.
generate_typeobj_predeclaration
(
entry
,
code
)
for
entry
in
vtab_list
:
for
entry
in
vtab_list
:
self
.
generate_typeobj
ect
_predeclaration
(
entry
,
code
)
self
.
generate_typeobj_predeclaration
(
entry
,
code
)
self
.
generate_exttype_vtable_struct
(
entry
,
code
)
self
.
generate_exttype_vtable_struct
(
entry
,
code
)
self
.
generate_exttype_vtabptr_declaration
(
entry
,
code
)
self
.
generate_exttype_vtabptr_declaration
(
entry
,
code
)
...
@@ -685,6 +702,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -685,6 +702,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"#define _USE_MATH_DEFINES"
)
code
.
putln
(
"#define _USE_MATH_DEFINES"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"#include <math.h>"
)
code
.
putln
(
"#define %s"
%
Naming
.
h_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
code
.
putln
(
"#define %s"
%
Naming
.
api_guard_prefix
+
self
.
api_name
(
env
))
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
self
.
generate_includes
(
env
,
cimported_modules
,
code
)
code
.
putln
(
""
)
code
.
putln
(
""
)
...
@@ -721,10 +739,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -721,10 +739,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_extern_c_macro_definition
(
self
,
code
):
def
generate_extern_c_macro_definition
(
self
,
code
):
name
=
Naming
.
extern_c_macro
name
=
Naming
.
extern_c_macro
code
.
putln
(
"#ifdef __cplusplus"
)
code
.
putln
(
"#ifndef %s"
%
name
)
code
.
putln
(
'#define %s extern "C"'
%
name
)
code
.
putln
(
" #ifdef __cplusplus"
)
code
.
putln
(
"#else"
)
code
.
putln
(
' #define %s extern "C"'
%
name
)
code
.
putln
(
"#define %s extern"
%
name
)
code
.
putln
(
" #else"
)
code
.
putln
(
" #define %s extern"
%
name
)
code
.
putln
(
" #endif"
)
code
.
putln
(
"#endif"
)
code
.
putln
(
"#endif"
)
def
generate_includes
(
self
,
env
,
cimported_modules
,
code
):
def
generate_includes
(
self
,
env
,
cimported_modules
,
code
):
...
@@ -786,10 +806,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -786,10 +806,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_typedef
(
self
,
entry
,
code
):
def
generate_typedef
(
self
,
entry
,
code
):
base_type
=
entry
.
type
.
typedef_base_type
base_type
=
entry
.
type
.
typedef_base_type
if
base_type
.
is_numeric
:
if
base_type
.
is_numeric
:
writer
=
code
.
globalstate
[
'numeric_typedefs'
]
try
:
writer
=
code
.
globalstate
[
'numeric_typedefs'
]
except
KeyError
:
writer
=
code
else
:
else
:
writer
=
code
writer
=
code
writer
.
putln
(
""
)
writer
.
mark_pos
(
entry
.
pos
)
writer
.
putln
(
"typedef %s;"
%
base_type
.
declaration_code
(
entry
.
cname
))
writer
.
putln
(
"typedef %s;"
%
base_type
.
declaration_code
(
entry
.
cname
))
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
def
sue_header_footer
(
self
,
type
,
kind
,
name
):
...
@@ -813,7 +836,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -813,7 +836,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
globalstate
.
use_utility_code
(
packed_struct_utility_code
)
code
.
globalstate
.
use_utility_code
(
packed_struct_utility_code
)
header
,
footer
=
\
header
,
footer
=
\
self
.
sue_header_footer
(
type
,
kind
,
type
.
cname
)
self
.
sue_header_footer
(
type
,
kind
,
type
.
cname
)
code
.
putln
(
""
)
if
packed
:
if
packed
:
code
.
putln
(
"#if defined(__SUNPRO_C)"
)
code
.
putln
(
"#if defined(__SUNPRO_C)"
)
code
.
putln
(
" #pragma pack(1)"
)
code
.
putln
(
" #pragma pack(1)"
)
...
@@ -844,7 +866,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -844,7 +866,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
name
=
entry
.
cname
or
entry
.
name
or
""
name
=
entry
.
cname
or
entry
.
name
or
""
header
,
footer
=
\
header
,
footer
=
\
self
.
sue_header_footer
(
type
,
"enum"
,
name
)
self
.
sue_header_footer
(
type
,
"enum"
,
name
)
code
.
putln
(
""
)
code
.
putln
(
header
)
code
.
putln
(
header
)
enum_values
=
entry
.
enum_values
enum_values
=
entry
.
enum_values
if
not
enum_values
:
if
not
enum_values
:
...
@@ -870,21 +891,23 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -870,21 +891,23 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
value_code
)
code
.
putln
(
value_code
)
code
.
putln
(
footer
)
code
.
putln
(
footer
)
def
generate_typeobj
ect
_predeclaration
(
self
,
entry
,
code
):
def
generate_typeobj_predeclaration
(
self
,
entry
,
code
):
code
.
putln
(
""
)
code
.
putln
(
""
)
name
=
entry
.
type
.
typeobj_cname
name
=
entry
.
type
.
typeobj_cname
if
name
:
if
name
:
if
entry
.
visibility
==
'extern'
and
not
entry
.
in_cinclude
:
if
entry
.
visibility
==
'extern'
and
not
entry
.
in_cinclude
:
code
.
putln
(
"%s
DL_IMPORT(PyTypeObject)
%s;"
%
(
code
.
putln
(
"%s
%s
%s;"
%
(
Naming
.
extern_c_macro
,
Naming
.
extern_c_macro
,
PyrexTypes
.
public_decl
(
"PyTypeObject"
,
"DL_IMPORT"
),
name
))
name
))
elif
entry
.
visibility
==
'public'
:
elif
entry
.
visibility
==
'public'
:
code
.
putln
(
"%s
DL_EXPORT(PyTypeObject)
%s;"
%
(
code
.
putln
(
"%s
%s
%s;"
%
(
Naming
.
extern_c_macro
,
Naming
.
extern_c_macro
,
PyrexTypes
.
public_decl
(
"PyTypeObject"
,
"DL_EXPORT"
),
name
))
name
))
# ??? Do we really need the rest of this? ???
# ??? Do we really need the rest of this? ???
#else:
#else:
# code.putln("static
forward
PyTypeObject %s;" % name)
# code.putln("static PyTypeObject %s;" % name)
def
generate_exttype_vtable_struct
(
self
,
entry
,
code
):
def
generate_exttype_vtable_struct
(
self
,
entry
,
code
):
code
.
mark_pos
(
entry
.
pos
)
code
.
mark_pos
(
entry
.
pos
)
...
@@ -924,7 +947,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -924,7 +947,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
return
# Forward declared but never defined
return
# Forward declared but never defined
header
,
footer
=
\
header
,
footer
=
\
self
.
sue_header_footer
(
type
,
"struct"
,
type
.
objstruct_cname
)
self
.
sue_header_footer
(
type
,
"struct"
,
type
.
objstruct_cname
)
code
.
putln
(
""
)
code
.
putln
(
header
)
code
.
putln
(
header
)
base_type
=
type
.
base_type
base_type
=
type
.
base_type
if
base_type
:
if
base_type
:
...
@@ -963,24 +985,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -963,24 +985,26 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
entry
in
env
.
cfunc_entries
:
for
entry
in
env
.
cfunc_entries
:
if
entry
.
inline_func_in_pxd
or
(
not
entry
.
in_cinclude
and
(
definition
if
entry
.
inline_func_in_pxd
or
(
not
entry
.
in_cinclude
and
(
definition
or
entry
.
defined_in_pxd
or
entry
.
visibility
==
'extern'
)):
or
entry
.
defined_in_pxd
or
entry
.
visibility
==
'extern'
)):
if
entry
.
visibility
in
(
'public'
,
'extern'
):
if
entry
.
visibility
==
'public'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_EXPORT"
dll_linkage
=
"DL_EXPORT"
elif
entry
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
dll_linkage
=
"DL_IMPORT"
elif
entry
.
visibility
==
'private'
:
storage_class
=
"static "
dll_linkage
=
None
else
:
else
:
storage_class
=
"static "
dll_linkage
=
None
dll_linkage
=
None
type
=
entry
.
type
type
=
entry
.
type
if
not
definition
and
entry
.
defined_in_pxd
:
if
not
definition
and
entry
.
defined_in_pxd
:
type
=
CPtrType
(
type
)
type
=
CPtrType
(
type
)
header
=
type
.
declaration_code
(
entry
.
cname
,
header
=
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
)
dll_linkage
=
dll_linkage
)
if
entry
.
visibility
==
'private'
:
storage_class
=
"static "
elif
entry
.
visibility
==
'public'
:
storage_class
=
""
else
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
if
entry
.
func_modifiers
:
if
entry
.
func_modifiers
:
modifiers
=
'%s '
%
' '
.
join
([
modifiers
=
"%s "
%
' '
.
join
(
entry
.
func_modifiers
).
upper
()
modifier
.
upper
()
for
modifier
in
entry
.
func_modifiers
])
else
:
else
:
modifiers
=
''
modifiers
=
''
code
.
putln
(
"%s%s%s; /*proto*/"
%
(
code
.
putln
(
"%s%s%s; /*proto*/"
%
(
...
@@ -1803,6 +1827,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1803,6 +1827,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"/*--- Global init code ---*/"
)
code
.
putln
(
"/*--- Global init code ---*/"
)
self
.
generate_global_init_code
(
env
,
code
)
self
.
generate_global_init_code
(
env
,
code
)
code
.
putln
(
"/*--- Variable export code ---*/"
)
self
.
generate_c_variable_export_code
(
env
,
code
)
code
.
putln
(
"/*--- Function export code ---*/"
)
code
.
putln
(
"/*--- Function export code ---*/"
)
self
.
generate_c_function_export_code
(
env
,
code
)
self
.
generate_c_function_export_code
(
env
,
code
)
...
@@ -1990,6 +2017,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1990,6 +2017,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
entry
.
type
.
is_pyobject
and
entry
.
used
:
if
entry
.
type
.
is_pyobject
and
entry
.
used
:
code
.
put_init_var_to_py_none
(
entry
,
nanny
=
False
)
code
.
put_init_var_to_py_none
(
entry
,
nanny
=
False
)
def
generate_c_variable_export_code
(
self
,
env
,
code
):
# Generate code to create PyCFunction wrappers for exported C functions.
for
entry
in
env
.
var_entries
:
if
entry
.
api
or
entry
.
defined_in_pxd
:
env
.
use_utility_code
(
voidptr_export_utility_code
)
signature
=
entry
.
type
.
declaration_code
(
""
)
code
.
putln
(
'if (__Pyx_ExportVoidPtr("%s", (void *)&%s, "%s") < 0) %s'
%
(
entry
.
name
,
entry
.
cname
,
signature
,
code
.
error_goto
(
self
.
pos
)))
def
generate_c_function_export_code
(
self
,
env
,
code
):
def
generate_c_function_export_code
(
self
,
env
,
code
):
# Generate code to create PyCFunction wrappers for exported C functions.
# Generate code to create PyCFunction wrappers for exported C functions.
for
entry
in
env
.
cfunc_entries
:
for
entry
in
env
.
cfunc_entries
:
...
@@ -2333,6 +2372,45 @@ bad:
...
@@ -2333,6 +2372,45 @@ bad:
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
voidptr_export_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ExportVoidPtr(const char *name, void *p, const char *sig); /*proto*/
"""
,
impl
=
r"""
static int __Pyx_ExportVoidPtr(const char *name, void *p, const char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
if (!d) {
PyErr_Clear();
d = PyDict_New();
if (!d)
goto bad;
Py_INCREF(d);
if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
cobj = PyCapsule_New(p, sig, 0);
#else
cobj = PyCObject_FromVoidPtrAndDesc(p, (void *)sig, 0);
#endif
if (!cobj)
goto bad;
if (PyDict_SetItemString(d, name, cobj) < 0)
goto bad;
Py_DECREF(cobj);
Py_DECREF(d);
return 0;
bad:
Py_XDECREF(cobj);
Py_XDECREF(d);
return -1;
}
"""
%
{
'MODULE'
:
Naming
.
module_cname
,
'API'
:
Naming
.
api_name
}
)
function_export_utility_code
=
UtilityCode
(
function_export_utility_code
=
UtilityCode
(
proto
=
"""
proto
=
"""
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
...
@@ -2377,6 +2455,62 @@ bad:
...
@@ -2377,6 +2455,62 @@ bad:
"""
%
{
'MODULE'
:
Naming
.
module_cname
,
'API'
:
Naming
.
api_name
}
"""
%
{
'MODULE'
:
Naming
.
module_cname
,
'API'
:
Naming
.
api_name
}
)
)
voidptr_import_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig); /*proto*/
"""
,
impl
=
"""
#ifndef __PYX_HAVE_RT_ImportVoidPtr
#define __PYX_HAVE_RT_ImportVoidPtr
static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
d = PyObject_GetAttrString(module, (char *)"%(API)s");
if (!d)
goto bad;
cobj = PyDict_GetItemString(d, name);
if (!cobj) {
PyErr_Format(PyExc_ImportError,
"%%s does not export expected C variable %%s",
PyModule_GetName(module), name);
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
if (!PyCapsule_IsValid(cobj, sig)) {
PyErr_Format(PyExc_TypeError,
"C variable %%s.%%s has wrong signature (expected %%s, got %%s)",
PyModule_GetName(module), name, sig, PyCapsule_GetName(cobj));
goto bad;
}
*p = PyCapsule_GetPointer(cobj, sig);
#else
{const char *desc, *s1, *s2;
desc = (const char *)PyCObject_GetDesc(cobj);
if (!desc)
goto bad;
s1 = desc; s2 = sig;
while (*s1 != '
\
\
0' && *s1 == *s2) { s1++; s2++; }
if (*s1 != *s2) {
PyErr_Format(PyExc_TypeError,
"C variable %%s.%%s has wrong signature (expected %%s, got %%s)",
PyModule_GetName(module), name, sig, desc);
goto bad;
}
*p = PyCObject_AsVoidPtr(cobj);}
#endif
if (!(*p))
goto bad;
Py_DECREF(d);
return 0;
bad:
Py_XDECREF(d);
return -1;
}
#endif
"""
%
dict
(
API
=
Naming
.
api_name
)
)
function_import_utility_code
=
UtilityCode
(
function_import_utility_code
=
UtilityCode
(
proto
=
"""
proto
=
"""
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
...
...
Cython/Compiler/Nodes.py
View file @
6a57acd5
...
@@ -970,7 +970,7 @@ class CVarDefNode(StatNode):
...
@@ -970,7 +970,7 @@ class CVarDefNode(StatNode):
error
(
self
.
pos
,
error
(
self
.
pos
,
"Only 'extern' C variable declaration allowed in .pxd file"
)
"Only 'extern' C variable declaration allowed in .pxd file"
)
entry
=
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
entry
=
dest_scope
.
declare_var
(
name
,
type
,
declarator
.
pos
,
cname
=
cname
,
visibility
=
visibility
,
is_cdef
=
1
)
cname
=
cname
,
visibility
=
visibility
,
api
=
self
.
api
,
is_cdef
=
1
)
entry
.
needs_property
=
need_property
entry
.
needs_property
=
need_property
...
@@ -980,6 +980,7 @@ class CStructOrUnionDefNode(StatNode):
...
@@ -980,6 +980,7 @@ class CStructOrUnionDefNode(StatNode):
# kind "struct" or "union"
# kind "struct" or "union"
# typedef_flag boolean
# typedef_flag boolean
# visibility "public" or "private"
# visibility "public" or "private"
# api boolean
# in_pxd boolean
# in_pxd boolean
# attributes [CVarDefNode] or None
# attributes [CVarDefNode] or None
# entry Entry
# entry Entry
...
@@ -995,7 +996,8 @@ class CStructOrUnionDefNode(StatNode):
...
@@ -995,7 +996,8 @@ class CStructOrUnionDefNode(StatNode):
scope
=
StructOrUnionScope
(
self
.
name
)
scope
=
StructOrUnionScope
(
self
.
name
)
self
.
entry
=
env
.
declare_struct_or_union
(
self
.
entry
=
env
.
declare_struct_or_union
(
self
.
name
,
self
.
kind
,
scope
,
self
.
typedef_flag
,
self
.
pos
,
self
.
name
,
self
.
kind
,
scope
,
self
.
typedef_flag
,
self
.
pos
,
self
.
cname
,
visibility
=
self
.
visibility
,
packed
=
self
.
packed
)
self
.
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
packed
=
self
.
packed
)
if
self
.
attributes
is
not
None
:
if
self
.
attributes
is
not
None
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
self
.
entry
.
defined_in_pxd
=
1
self
.
entry
.
defined_in_pxd
=
1
...
@@ -1078,15 +1080,16 @@ class CEnumDefNode(StatNode):
...
@@ -1078,15 +1080,16 @@ class CEnumDefNode(StatNode):
# items [CEnumDefItemNode]
# items [CEnumDefItemNode]
# typedef_flag boolean
# typedef_flag boolean
# visibility "public" or "private"
# visibility "public" or "private"
# api boolean
# in_pxd boolean
# in_pxd boolean
# entry Entry
# entry Entry
child_attrs
=
[
"items"
]
child_attrs
=
[
"items"
]
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
self
.
entry
=
env
.
declare_enum
(
self
.
name
,
self
.
pos
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
cname
=
self
.
cname
,
typedef_flag
=
self
.
typedef_flag
,
visibility
=
self
.
visibility
)
visibility
=
self
.
visibility
,
api
=
self
.
api
)
if
self
.
items
is
not
None
:
if
self
.
items
is
not
None
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
self
.
entry
.
defined_in_pxd
=
1
self
.
entry
.
defined_in_pxd
=
1
...
@@ -1097,7 +1100,7 @@ class CEnumDefNode(StatNode):
...
@@ -1097,7 +1100,7 @@ class CEnumDefNode(StatNode):
pass
pass
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
if
self
.
visibility
==
'public'
:
if
self
.
visibility
==
'public'
or
self
.
api
:
temp
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
py_object_type
,
manage_ref
=
True
)
temp
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
py_object_type
,
manage_ref
=
True
)
for
item
in
self
.
entry
.
enum_values
:
for
item
in
self
.
entry
.
enum_values
:
code
.
putln
(
"%s = PyInt_FromLong(%s); %s"
%
(
code
.
putln
(
"%s = PyInt_FromLong(%s); %s"
%
(
...
@@ -1127,9 +1130,9 @@ class CEnumDefItemNode(StatNode):
...
@@ -1127,9 +1130,9 @@ class CEnumDefItemNode(StatNode):
if
not
self
.
value
.
type
.
is_int
:
if
not
self
.
value
.
type
.
is_int
:
self
.
value
=
self
.
value
.
coerce_to
(
PyrexTypes
.
c_int_type
,
env
)
self
.
value
=
self
.
value
.
coerce_to
(
PyrexTypes
.
c_int_type
,
env
)
self
.
value
.
analyse_const_expression
(
env
)
self
.
value
.
analyse_const_expression
(
env
)
entry
=
env
.
declare_const
(
self
.
name
,
enum_entry
.
type
,
entry
=
env
.
declare_const
(
self
.
name
,
enum_entry
.
type
,
self
.
value
,
self
.
pos
,
cname
=
self
.
cname
,
self
.
value
,
self
.
pos
,
cname
=
self
.
cname
,
visibility
=
enum_entry
.
visibility
)
visibility
=
enum_entry
.
visibility
,
api
=
enum_entry
.
api
)
enum_entry
.
enum_values
.
append
(
entry
)
enum_entry
.
enum_values
.
append
(
entry
)
...
@@ -1137,6 +1140,7 @@ class CTypeDefNode(StatNode):
...
@@ -1137,6 +1140,7 @@ class CTypeDefNode(StatNode):
# base_type CBaseTypeNode
# base_type CBaseTypeNode
# declarator CDeclaratorNode
# declarator CDeclaratorNode
# visibility "public" or "private"
# visibility "public" or "private"
# api boolean
# in_pxd boolean
# in_pxd boolean
child_attrs
=
[
"base_type"
,
"declarator"
]
child_attrs
=
[
"base_type"
,
"declarator"
]
...
@@ -1147,10 +1151,10 @@ class CTypeDefNode(StatNode):
...
@@ -1147,10 +1151,10 @@ class CTypeDefNode(StatNode):
name
=
name_declarator
.
name
name
=
name_declarator
.
name
cname
=
name_declarator
.
cname
cname
=
name_declarator
.
cname
entry
=
env
.
declare_typedef
(
name
,
type
,
self
.
pos
,
entry
=
env
.
declare_typedef
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
)
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
)
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
if
self
.
in_pxd
and
not
env
.
in_cinclude
:
entry
.
defined_in_pxd
=
1
entry
.
defined_in_pxd
=
1
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
pass
pass
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
...
@@ -1740,7 +1744,6 @@ class CFuncDefNode(FuncDefNode):
...
@@ -1740,7 +1744,6 @@ class CFuncDefNode(FuncDefNode):
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
with_opt_args
=
1
,
with_dispatch
=
1
,
cname
=
None
):
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
with_opt_args
=
1
,
with_dispatch
=
1
,
cname
=
None
):
arg_decls
=
[]
arg_decls
=
[]
type
=
self
.
type
type
=
self
.
type
visibility
=
self
.
entry
.
visibility
for
arg
in
type
.
args
[:
len
(
type
.
args
)
-
type
.
optional_arg_count
]:
for
arg
in
type
.
args
[:
len
(
type
.
args
)
-
type
.
optional_arg_count
]:
arg_decls
.
append
(
arg
.
declaration_code
())
arg_decls
.
append
(
arg
.
declaration_code
())
if
with_dispatch
and
self
.
overridable
:
if
with_dispatch
and
self
.
overridable
:
...
@@ -1754,24 +1757,20 @@ class CFuncDefNode(FuncDefNode):
...
@@ -1754,24 +1757,20 @@ class CFuncDefNode(FuncDefNode):
if
cname
is
None
:
if
cname
is
None
:
cname
=
self
.
entry
.
func_cname
cname
=
self
.
entry
.
func_cname
entity
=
type
.
function_header_code
(
cname
,
', '
.
join
(
arg_decls
))
entity
=
type
.
function_header_code
(
cname
,
', '
.
join
(
arg_decls
))
if
visibility
==
'public
'
:
if
self
.
entry
.
visibility
==
'private
'
:
dll_linkage
=
"DL_EXPORT
"
storage_class
=
"static
"
else
:
else
:
dll_linkage
=
None
header
=
self
.
return_type
.
declaration_code
(
entity
,
dll_linkage
=
dll_linkage
)
if
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
elif
visibility
==
'public'
:
storage_class
=
""
storage_class
=
""
else
:
dll_linkage
=
None
storage_class
=
"static
"
modifiers
=
"
"
if
'inline'
in
self
.
modifiers
:
if
'inline'
in
self
.
modifiers
:
self
.
modifiers
[
self
.
modifiers
.
index
(
'inline'
)]
=
'cython_inline'
self
.
modifiers
[
self
.
modifiers
.
index
(
'inline'
)]
=
'cython_inline'
code
.
putln
(
"%s%s %s {"
%
(
if
self
.
modifiers
:
storage_class
,
modifiers
=
"%s "
%
' '
.
join
(
self
.
modifiers
).
upper
()
' '
.
join
(
self
.
modifiers
).
upper
(),
# macro forms
header
))
header
=
self
.
return_type
.
declaration_code
(
entity
,
dll_linkage
=
dll_linkage
)
#print (storage_class, modifiers, header)
code
.
putln
(
"%s%s%s {"
%
(
storage_class
,
modifiers
,
header
))
def
generate_argument_declarations
(
self
,
env
,
code
):
def
generate_argument_declarations
(
self
,
env
,
code
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
6a57acd5
...
@@ -64,7 +64,6 @@ class SkipDeclarations(object):
...
@@ -64,7 +64,6 @@ class SkipDeclarations(object):
def
visit_CStructOrUnionDefNode
(
self
,
node
):
def
visit_CStructOrUnionDefNode
(
self
,
node
):
return
node
return
node
class
NormalizeTree
(
CythonTransform
):
class
NormalizeTree
(
CythonTransform
):
"""
"""
This transform fixes up a few things after parsing
This transform fixes up a few things after parsing
...
...
Cython/Compiler/Parsing.py
View file @
6a57acd5
...
@@ -2003,7 +2003,7 @@ def looking_at_expr(s):
...
@@ -2003,7 +2003,7 @@ def looking_at_expr(s):
is_type
=
True
is_type
=
True
elif
s
.
sy
==
'*'
or
s
.
sy
==
'**'
:
elif
s
.
sy
==
'*'
or
s
.
sy
==
'**'
:
s
.
next
()
s
.
next
()
is_type
=
s
.
sy
==
')'
is_type
=
s
.
sy
in
(
')'
,
']'
)
s
.
put_back
(
*
saved
)
s
.
put_back
(
*
saved
)
elif
s
.
sy
==
'('
:
elif
s
.
sy
==
'('
:
s
.
next
()
s
.
next
()
...
@@ -2420,7 +2420,7 @@ def p_c_enum_definition(s, pos, ctx):
...
@@ -2420,7 +2420,7 @@ def p_c_enum_definition(s, pos, ctx):
return
Nodes
.
CEnumDefNode
(
return
Nodes
.
CEnumDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
items
=
items
,
pos
,
name
=
name
,
cname
=
cname
,
items
=
items
,
typedef_flag
=
ctx
.
typedef_flag
,
visibility
=
ctx
.
visibility
,
typedef_flag
=
ctx
.
typedef_flag
,
visibility
=
ctx
.
visibility
,
in_pxd
=
ctx
.
level
==
'module_pxd'
)
api
=
ctx
.
api
,
in_pxd
=
ctx
.
level
==
'module_pxd'
)
def
p_c_enum_line
(
s
,
ctx
,
items
):
def
p_c_enum_line
(
s
,
ctx
,
items
):
if
s
.
sy
!=
'pass'
:
if
s
.
sy
!=
'pass'
:
...
@@ -2478,10 +2478,10 @@ def p_c_struct_or_union_definition(s, pos, ctx):
...
@@ -2478,10 +2478,10 @@ def p_c_struct_or_union_definition(s, pos, ctx):
s
.
expect_dedent
()
s
.
expect_dedent
()
else
:
else
:
s
.
expect_newline
(
"Syntax error in struct or union definition"
)
s
.
expect_newline
(
"Syntax error in struct or union definition"
)
return
Nodes
.
CStructOrUnionDefNode
(
pos
,
return
Nodes
.
CStructOrUnionDefNode
(
pos
,
name
=
name
,
cname
=
cname
,
kind
=
kind
,
attributes
=
attributes
,
name
=
name
,
cname
=
cname
,
kind
=
kind
,
attributes
=
attributes
,
typedef_flag
=
ctx
.
typedef_flag
,
visibility
=
ctx
.
visibility
,
typedef_flag
=
ctx
.
typedef_flag
,
visibility
=
ctx
.
visibility
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
packed
=
packed
)
api
=
ctx
.
api
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
packed
=
packed
)
def
p_visibility
(
s
,
prev_visibility
):
def
p_visibility
(
s
,
prev_visibility
):
pos
=
s
.
position
()
pos
=
s
.
position
()
...
@@ -2566,7 +2566,8 @@ def p_ctypedef_statement(s, ctx):
...
@@ -2566,7 +2566,8 @@ def p_ctypedef_statement(s, ctx):
s
.
expect_newline
(
"Syntax error in ctypedef statement"
)
s
.
expect_newline
(
"Syntax error in ctypedef statement"
)
return
Nodes
.
CTypeDefNode
(
return
Nodes
.
CTypeDefNode
(
pos
,
base_type
=
base_type
,
pos
,
base_type
=
base_type
,
declarator
=
declarator
,
visibility
=
visibility
,
declarator
=
declarator
,
visibility
=
visibility
,
api
=
api
,
in_pxd
=
ctx
.
level
==
'module_pxd'
)
in_pxd
=
ctx
.
level
==
'module_pxd'
)
def
p_decorators
(
s
):
def
p_decorators
(
s
):
...
@@ -2693,8 +2694,8 @@ def p_c_class_definition(s, pos, ctx):
...
@@ -2693,8 +2694,8 @@ def p_c_class_definition(s, pos, ctx):
base_class_module
=
"."
.
join
(
base_class_path
[:
-
1
])
base_class_module
=
"."
.
join
(
base_class_path
[:
-
1
])
base_class_name
=
base_class_path
[
-
1
]
base_class_name
=
base_class_path
[
-
1
]
if
s
.
sy
==
'['
:
if
s
.
sy
==
'['
:
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
):
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
)
and
not
ctx
.
api
:
error
(
s
.
position
(),
"Name options only allowed for 'public' or 'extern' C class"
)
error
(
s
.
position
(),
"Name options only allowed for 'public'
, 'api',
or 'extern' C class"
)
objstruct_name
,
typeobj_name
=
p_c_class_options
(
s
)
objstruct_name
,
typeobj_name
=
p_c_class_options
(
s
)
if
s
.
sy
==
':'
:
if
s
.
sy
==
':'
:
if
ctx
.
level
==
'module_pxd'
:
if
ctx
.
level
==
'module_pxd'
:
...
@@ -2718,7 +2719,10 @@ def p_c_class_definition(s, pos, ctx):
...
@@ -2718,7 +2719,10 @@ def p_c_class_definition(s, pos, ctx):
error
(
pos
,
"Type object name specification required for 'public' C class"
)
error
(
pos
,
"Type object name specification required for 'public' C class"
)
elif
ctx
.
visibility
==
'private'
:
elif
ctx
.
visibility
==
'private'
:
if
ctx
.
api
:
if
ctx
.
api
:
error
(
pos
,
"Only 'public' C class can be declared 'api'"
)
if
not
objstruct_name
:
error
(
pos
,
"Object struct name specification required for 'api' C class"
)
if
not
typeobj_name
:
error
(
pos
,
"Type object name specification required for 'api' C class"
)
else
:
else
:
error
(
pos
,
"Invalid class visibility '%s'"
%
ctx
.
visibility
)
error
(
pos
,
"Invalid class visibility '%s'"
%
ctx
.
visibility
)
return
Nodes
.
CClassDefNode
(
pos
,
return
Nodes
.
CClassDefNode
(
pos
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
6a57acd5
...
@@ -1190,8 +1190,8 @@ class CComplexType(CNumericType):
...
@@ -1190,8 +1190,8 @@ class CComplexType(CNumericType):
visibility
=
"extern"
)
visibility
=
"extern"
)
scope
.
parent_type
=
self
scope
.
parent_type
=
self
scope
.
directives
=
{}
scope
.
directives
=
{}
scope
.
declare_var
(
"real"
,
self
.
real_type
,
None
,
"real"
,
is_cdef
=
True
)
scope
.
declare_var
(
"real"
,
self
.
real_type
,
None
,
cname
=
"real"
,
is_cdef
=
True
)
scope
.
declare_var
(
"imag"
,
self
.
real_type
,
None
,
"imag"
,
is_cdef
=
True
)
scope
.
declare_var
(
"imag"
,
self
.
real_type
,
None
,
cname
=
"imag"
,
is_cdef
=
True
)
entry
=
scope
.
declare_cfunction
(
entry
=
scope
.
declare_cfunction
(
"conjugate"
,
"conjugate"
,
CFuncType
(
self
,
[
CFuncTypeArg
(
"self"
,
self
,
None
)],
nogil
=
True
),
CFuncType
(
self
,
[
CFuncTypeArg
(
"self"
,
self
,
None
)],
nogil
=
True
),
...
...
Cython/Compiler/Symtab.py
View file @
6a57acd5
...
@@ -361,10 +361,10 @@ class Scope(object):
...
@@ -361,10 +361,10 @@ class Scope(object):
def qualify_name(self, name):
def qualify_name(self, name):
return EncodedString("
%
s
.
%
s
" % (self.qualified_name, name))
return EncodedString("
%
s
.
%
s
" % (self.qualified_name, name))
def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'):
def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'
, api = 0
):
# Add an entry for a named constant.
# Add an entry for a named constant.
if not cname:
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
cname = name
else:
else:
cname = self.mangle(Naming.enum_prefix, name)
cname = self.mangle(Naming.enum_prefix, name)
...
@@ -374,21 +374,22 @@ class Scope(object):
...
@@ -374,21 +374,22 @@ class Scope(object):
return entry
return entry
def declare_type(self, name, type, pos,
def declare_type(self, name, type, pos,
cname = None, visibility = 'private', defining = 1, shadow = 0):
cname = None, visibility = 'private',
api = 0,
defining = 1, shadow = 0):
# Add an entry for a type definition.
# Add an entry for a type definition.
if not cname:
if not cname:
cname = name
cname = name
entry = self.declare(name, cname, type, pos, visibility, shadow)
entry = self.declare(name, cname, type, pos, visibility, shadow)
entry.is_type = 1
entry.is_type = 1
entry.api = api
if defining:
if defining:
self.type_entries.append(entry)
self.type_entries.append(entry)
# here we would set as_variable to an object representing this type
# here we would set as_variable to an object representing this type
return entry
return entry
def declare_typedef(self, name, base_type, pos, cname = None,
def declare_typedef(self, name, base_type, pos, cname = None,
visibility = 'private'
):
visibility = 'private', api = 0
):
if not cname:
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
cname = name
else:
else:
cname = self.mangle(Naming.type_prefix, name)
cname = self.mangle(Naming.type_prefix, name)
...
@@ -398,16 +399,18 @@ class Scope(object):
...
@@ -398,16 +399,18 @@ class Scope(object):
except ValueError, e:
except ValueError, e:
error(pos, e.args[0])
error(pos, e.args[0])
type = PyrexTypes.error_type
type = PyrexTypes.error_type
entry = self.declare_type(name, type, pos, cname, visibility)
entry = self.declare_type(name, type, pos, cname,
visibility = visibility, api = api)
type.qualified_name = entry.qualified_name
type.qualified_name = entry.qualified_name
return entry
return entry
def declare_struct_or_union(self, name, kind, scope,
def declare_struct_or_union(self, name, kind, scope,
typedef_flag, pos, cname = None, visibility = 'private',
typedef_flag, pos, cname = None,
packed = False):
visibility = 'private', api = 0,
packed = False):
# Add an entry for a struct or union definition.
# Add an entry for a struct or union definition.
if not cname:
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
cname = name
else:
else:
cname = self.mangle(Naming.type_prefix, name)
cname = self.mangle(Naming.type_prefix, name)
...
@@ -416,7 +419,8 @@ class Scope(object):
...
@@ -416,7 +419,8 @@ class Scope(object):
type = PyrexTypes.CStructOrUnionType(
type = PyrexTypes.CStructOrUnionType(
name, kind, scope, typedef_flag, cname, packed)
name, kind, scope, typedef_flag, cname, packed)
entry = self.declare_type(name, type, pos, cname,
entry = self.declare_type(name, type, pos, cname,
visibility = visibility, defining = scope is not None)
visibility = visibility, api = api,
defining = scope is not None)
self.sue_entries.append(entry)
self.sue_entries.append(entry)
type.entry = entry
type.entry = entry
else:
else:
...
@@ -482,12 +486,12 @@ class Scope(object):
...
@@ -482,12 +486,12 @@ class Scope(object):
if entry.visibility != visibility:
if entry.visibility != visibility:
error(pos, "'%s'
previously
declared
as
'%s'" % (
error(pos, "'%s'
previously
declared
as
'%s'" % (
entry.name, entry.visibility))
entry.name, entry.visibility))
def declare_enum(self, name, pos, cname, typedef_flag,
def declare_enum(self, name, pos, cname, typedef_flag,
visibility = 'private'):
visibility = 'private'
, api = 0
):
if name:
if name:
if not cname:
if not cname:
if self.in_cinclude or
visibility == 'public'
:
if self.in_cinclude or
(visibility == 'public' or api)
:
cname = name
cname = name
else:
else:
cname = self.mangle(Naming.type_prefix, name)
cname = self.mangle(Naming.type_prefix, name)
...
@@ -495,13 +499,13 @@ class Scope(object):
...
@@ -495,13 +499,13 @@ class Scope(object):
else:
else:
type = PyrexTypes.c_anon_enum_type
type = PyrexTypes.c_anon_enum_type
entry = self.declare_type(name, type, pos, cname = cname,
entry = self.declare_type(name, type, pos, cname = cname,
visibility = visibility)
visibility = visibility
, api = api
)
entry.enum_values = []
entry.enum_values = []
self.sue_entries.append(entry)
self.sue_entries.append(entry)
return entry
return entry
def declare_var(self, name, type, pos,
def declare_var(self, name, type, pos,
cname = None, visibility = 'private'
, is_cdef = 0):
cname = None, visibility = 'private', api = 0
, is_cdef = 0):
# Add an entry for a variable.
# Add an entry for a variable.
if not cname:
if not cname:
if visibility != 'private':
if visibility != 'private':
...
@@ -514,6 +518,7 @@ class Scope(object):
...
@@ -514,6 +518,7 @@ class Scope(object):
error(pos, "
C
++
class
must
have
a
default
constructor
to
be
stack
allocated
")
error(pos, "
C
++
class
must
have
a
default
constructor
to
be
stack
allocated
")
entry = self.declare(name, cname, type, pos, visibility)
entry = self.declare(name, cname, type, pos, visibility)
entry.is_variable = 1
entry.is_variable = 1
entry.api = api
self.control_flow.set_state((), (name, 'initialized'), False)
self.control_flow.set_state((), (name, 'initialized'), False)
return entry
return entry
...
@@ -902,8 +907,8 @@ class ModuleScope(Scope):
...
@@ -902,8 +907,8 @@ class ModuleScope(Scope):
return self.outer_scope.lookup(name, language_level = self.context.language_level)
return self.outer_scope.lookup(name, language_level = self.context.language_level)
def declare_builtin(self, name, pos):
def declare_builtin(self, name, pos):
if not hasattr(builtins, name) and name
!= 'xrange'
:
if not hasattr(builtins, name) and name
not in ('xrange', 'BaseException')
:
# 'xrange'
is
special cased in Code.py
# 'xrange'
and 'BaseException' are
special cased in Code.py
if self.has_import_star:
if self.has_import_star:
entry = self.declare_var(name, py_object_type, pos)
entry = self.declare_var(name, py_object_type, pos)
return entry
return entry
...
@@ -995,13 +1000,13 @@ class ModuleScope(Scope):
...
@@ -995,13 +1000,13 @@ class ModuleScope(Scope):
return entry
return entry
def declare_var(self, name, type, pos,
def declare_var(self, name, type, pos,
cname = None, visibility = 'private'
, is_cdef = 0):
cname = None, visibility = 'private', api = 0
, is_cdef = 0):
# Add an entry for a global variable. If it is a Python
# Add an entry for a global variable. If it is a Python
# object type, and not declared with cdef, it will live
# object type, and not declared with cdef, it will live
# in the module dictionary, otherwise it will be a C
# in the module dictionary, otherwise it will be a C
# global variable.
# global variable.
entry = Scope.declare_var(self, name, type, pos,
entry = Scope.declare_var(self, name, type, pos,
cname, visibility,
is_cdef)
cname=cname, visibility=visibility, api=api, is_cdef=
is_cdef)
if not visibility in ('private', 'public', 'extern'):
if not visibility in ('private', 'public', 'extern'):
error(pos, "
Module
-
level
variable
cannot
be
declared
%
s
" % visibility)
error(pos, "
Module
-
level
variable
cannot
be
declared
%
s
" % visibility)
if not is_cdef:
if not is_cdef:
...
@@ -1033,10 +1038,10 @@ class ModuleScope(Scope):
...
@@ -1033,10 +1038,10 @@ class ModuleScope(Scope):
buffer_defaults = None, shadow = 0):
buffer_defaults = None, shadow = 0):
# If this is a non-extern typedef class, expose the typedef, but use
# If this is a non-extern typedef class, expose the typedef, but use
# the non-typedef struct internally to avoid needing forward
# the non-typedef struct internally to avoid needing forward
# declarations for anonymous structs.
# declarations for anonymous structs.
if typedef_flag and visibility != 'extern':
if typedef_flag and visibility != 'extern':
if
visibility != 'public'
:
if
not (visibility == 'public' or api)
:
warning(pos, "
ctypedef
only
valid
for
public
and
extern
classes
", 2)
warning(pos, "
ctypedef
only
valid
for
'extern'
,
'public'
,
and
'api'
", 2)
objtypedef_cname = objstruct_cname
objtypedef_cname = objstruct_cname
typedef_flag = 0
typedef_flag = 0
else:
else:
...
@@ -1283,12 +1288,12 @@ class LocalScope(Scope):
...
@@ -1283,12 +1288,12 @@ class LocalScope(Scope):
return
entry
return
entry
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
# Add an entry for a local variable.
# Add an entry for a local variable.
if
visibility
in
(
'public'
,
'readonly'
):
if
visibility
in
(
'public'
,
'readonly'
):
error
(
pos
,
"Local variable cannot be declared %s"
%
visibility
)
error
(
pos
,
"Local variable cannot be declared %s"
%
visibility
)
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
if
type
.
is_pyobject
and
not
Options
.
init_local_none
:
if
type
.
is_pyobject
and
not
Options
.
init_local_none
:
entry
.
init
=
"0"
entry
.
init
=
"0"
entry
.
init_to_none
=
(
type
.
is_pyobject
or
type
.
is_unspecified
)
and
Options
.
init_local_none
entry
.
init_to_none
=
(
type
.
is_pyobject
or
type
.
is_unspecified
)
and
Options
.
init_local_none
...
@@ -1354,7 +1359,7 @@ class GeneratorExpressionScope(Scope):
...
@@ -1354,7 +1359,7 @@ class GeneratorExpressionScope(Scope):
return
'%s%s'
%
(
self
.
genexp_prefix
,
self
.
parent_scope
.
mangle
(
prefix
,
name
))
return
'%s%s'
%
(
self
.
genexp_prefix
,
self
.
parent_scope
.
mangle
(
prefix
,
name
))
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
True
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
True
):
if
type
is
unspecified_type
:
if
type
is
unspecified_type
:
# if the outer scope defines a type for this variable, inherit it
# if the outer scope defines a type for this variable, inherit it
outer_entry
=
self
.
outer_scope
.
lookup
(
name
)
outer_entry
=
self
.
outer_scope
.
lookup
(
name
)
...
@@ -1397,7 +1402,7 @@ class StructOrUnionScope(Scope):
...
@@ -1397,7 +1402,7 @@ class StructOrUnionScope(Scope):
Scope
.
__init__
(
self
,
name
,
None
,
None
)
Scope
.
__init__
(
self
,
name
,
None
,
None
)
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
,
allow_pyobject
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
# Add an entry for an attribute.
# Add an entry for an attribute.
if
not
cname
:
if
not
cname
:
cname
=
name
cname
=
name
...
@@ -1419,7 +1424,8 @@ class StructOrUnionScope(Scope):
...
@@ -1419,7 +1424,8 @@ class StructOrUnionScope(Scope):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
cname
=
None
,
visibility
=
'private'
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
,
modifiers
=
()):
# currently no utility code ...
api
=
0
,
in_pxd
=
0
,
modifiers
=
()):
# currently no utility code ...
return
self
.
declare_var
(
name
,
type
,
pos
,
cname
,
visibility
)
return
self
.
declare_var
(
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
)
class
ClassScope
(
Scope
):
class
ClassScope
(
Scope
):
# Abstract base class for namespace of
# Abstract base class for namespace of
...
@@ -1463,12 +1469,12 @@ class PyClassScope(ClassScope):
...
@@ -1463,12 +1469,12 @@ class PyClassScope(ClassScope):
is_py_class_scope
=
1
is_py_class_scope
=
1
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
if
type
is
unspecified_type
:
if
type
is
unspecified_type
:
type
=
py_object_type
type
=
py_object_type
# Add an entry for a class attribute.
# Add an entry for a class attribute.
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
entry
.
is_pyglobal
=
1
entry
.
is_pyglobal
=
1
entry
.
is_pyclass_attr
=
1
entry
.
is_pyclass_attr
=
1
return
entry
return
entry
...
@@ -1513,7 +1519,7 @@ class CClassScope(ClassScope):
...
@@ -1513,7 +1519,7 @@ class CClassScope(ClassScope):
self
.
parent_type
.
base_type
.
scope
.
needs_gc
())
self
.
parent_type
.
base_type
.
scope
.
needs_gc
())
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
is_cdef
=
0
):
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
is_cdef
=
0
):
if
is_cdef
:
if
is_cdef
:
# Add an entry for an attribute.
# Add an entry for an attribute.
if
self
.
defined
:
if
self
.
defined
:
...
@@ -1553,7 +1559,7 @@ class CClassScope(ClassScope):
...
@@ -1553,7 +1559,7 @@ class CClassScope(ClassScope):
type
=
py_object_type
type
=
py_object_type
# Add an entry for a class attribute.
# Add an entry for a class attribute.
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
entry
=
Scope
.
declare_var
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
is_cdef
)
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
is_cdef
=
is_cdef
)
entry
.
is_member
=
1
entry
.
is_member
=
1
entry
.
is_pyglobal
=
1
# xxx: is_pyglobal changes behaviour in so many places that
entry
.
is_pyglobal
=
1
# xxx: is_pyglobal changes behaviour in so many places that
# I keep it in for now. is_member should be enough
# I keep it in for now. is_member should be enough
...
@@ -1569,7 +1575,8 @@ class CClassScope(ClassScope):
...
@@ -1569,7 +1575,8 @@ class CClassScope(ClassScope):
if
name
==
"__new__"
:
if
name
==
"__new__"
:
error
(
pos
,
"__new__ method of extension type will change semantics "
error
(
pos
,
"__new__ method of extension type will change semantics "
"in a future version of Pyrex and Cython. Use __cinit__ instead."
)
"in a future version of Pyrex and Cython. Use __cinit__ instead."
)
entry
=
self
.
declare_var
(
name
,
py_object_type
,
pos
,
visibility
=
'extern'
)
entry
=
self
.
declare_var
(
name
,
py_object_type
,
pos
,
visibility
=
'extern'
)
special_sig
=
get_special_method_signature
(
name
)
special_sig
=
get_special_method_signature
(
name
)
if
special_sig
:
if
special_sig
:
# Special methods get put in the method table with a particular
# Special methods get put in the method table with a particular
...
@@ -1694,7 +1701,8 @@ class CppClassScope(Scope):
...
@@ -1694,7 +1701,8 @@ class CppClassScope(Scope):
self
.
inherited_var_entries
=
[]
self
.
inherited_var_entries
=
[]
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'extern'
,
is_cdef
=
0
,
allow_pyobject
=
0
):
cname
=
None
,
visibility
=
'extern'
,
api
=
0
,
is_cdef
=
0
,
allow_pyobject
=
0
):
# Add an entry for an attribute.
# Add an entry for an attribute.
if
not
cname
:
if
not
cname
:
cname
=
name
cname
=
name
...
@@ -1735,15 +1743,16 @@ class CppClassScope(Scope):
...
@@ -1735,15 +1743,16 @@ class CppClassScope(Scope):
error
(
pos
,
"no matching function for call to %s::%s()"
%
error
(
pos
,
"no matching function for call to %s::%s()"
%
(
self
.
default_constructor
,
self
.
default_constructor
))
(
self
.
default_constructor
,
self
.
default_constructor
))
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
cname
=
None
,
visibility
=
'extern'
,
defining
=
0
,
visibility
=
'extern'
,
api
=
0
,
defining
=
0
,
api
=
0
,
in_pxd
=
0
,
modifiers
=
(),
utility_code
=
None
):
in_pxd
=
0
,
modifiers
=
(),
utility_code
=
None
):
if
name
==
self
.
name
.
split
(
'::'
)[
-
1
]
and
cname
is
None
:
if
name
==
self
.
name
.
split
(
'::'
)[
-
1
]
and
cname
is
None
:
self
.
check_base_default_constructor
(
pos
)
self
.
check_base_default_constructor
(
pos
)
name
=
'<init>'
name
=
'<init>'
type
.
return_type
=
self
.
lookup
(
self
.
name
).
type
type
.
return_type
=
self
.
lookup
(
self
.
name
).
type
prev_entry
=
self
.
lookup_here
(
name
)
prev_entry
=
self
.
lookup_here
(
name
)
entry
=
self
.
declare_var
(
name
,
type
,
pos
,
cname
,
visibility
)
entry
=
self
.
declare_var
(
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
)
if
prev_entry
:
if
prev_entry
:
entry
.
overloaded_alternatives
=
prev_entry
.
all_alternatives
()
entry
.
overloaded_alternatives
=
prev_entry
.
all_alternatives
()
entry
.
utility_code
=
utility_code
entry
.
utility_code
=
utility_code
...
@@ -1767,8 +1776,9 @@ class CppClassScope(Scope):
...
@@ -1767,8 +1776,9 @@ class CppClassScope(Scope):
self
.
inherited_var_entries
.
append
(
entry
)
self
.
inherited_var_entries
.
append
(
entry
)
for
base_entry
in
base_scope
.
cfunc_entries
:
for
base_entry
in
base_scope
.
cfunc_entries
:
entry
=
self
.
declare_cfunction
(
base_entry
.
name
,
base_entry
.
type
,
entry
=
self
.
declare_cfunction
(
base_entry
.
name
,
base_entry
.
type
,
base_entry
.
pos
,
base_entry
.
cname
,
base_entry
.
pos
,
base_entry
.
cname
,
base_entry
.
visibility
,
base_entry
.
func_modifiers
,
base_entry
.
visibility
,
0
,
modifiers
=
base_entry
.
func_modifiers
,
utility_code
=
base_entry
.
utility_code
)
utility_code
=
base_entry
.
utility_code
)
entry
.
is_inherited
=
1
entry
.
is_inherited
=
1
...
...
Cython/Debugger/Tests/test_libcython_in_gdb.py
View file @
6a57acd5
...
@@ -378,6 +378,32 @@ class TestExec(DebugTestCase):
...
@@ -378,6 +378,32 @@ class TestExec(DebugTestCase):
gdb
.
execute
(
'cy exec some_random_var = 14'
)
gdb
.
execute
(
'cy exec some_random_var = 14'
)
self
.
assertEqual
(
'14'
,
self
.
eval_command
(
'some_random_var'
))
self
.
assertEqual
(
'14'
,
self
.
eval_command
(
'some_random_var'
))
class
CySet
(
DebugTestCase
):
def
test_cyset
(
self
):
self
.
break_and_run
(
'os.path.join("foo", "bar")'
)
gdb
.
execute
(
'cy set a = $cy_eval("{None: []}")'
)
stringvalue
=
self
.
read_var
(
"a"
,
cast_to
=
str
)
self
.
assertEqual
(
stringvalue
,
"{None: []}"
)
class
TestCyEval
(
DebugTestCase
):
"Test the $cy_eval() gdb function."
def
test_cy_eval
(
self
):
# This function leaks a few objects in the GDB python process. This
# is no biggie
self
.
break_and_run
(
'os.path.join("foo", "bar")'
)
result
=
gdb
.
execute
(
'print $cy_eval("None")'
,
to_string
=
True
)
assert
re
.
match
(
r'\
$
\d+ = None\n'
,
result
),
result
result
=
gdb
.
execute
(
'print $cy_eval("[a]")'
,
to_string
=
True
)
assert
re
.
match
(
r'\
$
\d+ = \
[
0\
]
', result), result
class TestClosure(DebugTestCase):
class TestClosure(DebugTestCase):
def break_and_run_func(self, funcname):
def break_and_run_func(self, funcname):
...
...
Cython/Debugger/Tests/test_libpython_in_gdb.py
View file @
6a57acd5
...
@@ -112,6 +112,4 @@ class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase):
...
@@ -112,6 +112,4 @@ class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase):
def
test_frame_type
(
self
):
def
test_frame_type
(
self
):
frame
=
self
.
pyobject_fromcode
(
'PyEval_GetFrame()'
)
frame
=
self
.
pyobject_fromcode
(
'PyEval_GetFrame()'
)
self
.
assertEqual
(
type
(
frame
),
libpython
.
PyFrameObjectPtr
)
self
.
assertEqual
(
type
(
frame
),
libpython
.
PyFrameObjectPtr
)
\ No newline at end of file
Cython/Debugger/libcython.py
View file @
6a57acd5
...
@@ -592,6 +592,7 @@ class CyCy(CythonCommand):
...
@@ -592,6 +592,7 @@ class CyCy(CythonCommand):
cy bt / cy backtrace
cy bt / cy backtrace
cy list
cy list
cy print
cy print
cy set
cy locals
cy locals
cy globals
cy globals
cy exec
cy exec
...
@@ -607,6 +608,7 @@ class CyCy(CythonCommand):
...
@@ -607,6 +608,7 @@ class CyCy(CythonCommand):
completer_class
,
prefix
=
True
)
completer_class
,
prefix
=
True
)
commands
=
dict
(
commands
=
dict
(
# GDB commands
import_
=
CyImport
.
register
(),
import_
=
CyImport
.
register
(),
break_
=
CyBreak
.
register
(),
break_
=
CyBreak
.
register
(),
step
=
CyStep
.
register
(),
step
=
CyStep
.
register
(),
...
@@ -624,9 +626,13 @@ class CyCy(CythonCommand):
...
@@ -624,9 +626,13 @@ class CyCy(CythonCommand):
globals
=
CyGlobals
.
register
(),
globals
=
CyGlobals
.
register
(),
exec_
=
libpython
.
FixGdbCommand
(
'cy exec'
,
'-cy-exec'
),
exec_
=
libpython
.
FixGdbCommand
(
'cy exec'
,
'-cy-exec'
),
_exec
=
CyExec
.
register
(),
_exec
=
CyExec
.
register
(),
set
=
CySet
.
register
(),
# GDB functions
cy_cname
=
CyCName
(
'cy_cname'
),
cy_cname
=
CyCName
(
'cy_cname'
),
cy_cvalue
=
CyCValue
(
'cy_cvalue'
),
cy_cvalue
=
CyCValue
(
'cy_cvalue'
),
cy_lineno
=
CyLine
(
'cy_lineno'
),
cy_lineno
=
CyLine
(
'cy_lineno'
),
cy_eval
=
CyEval
(
'cy_eval'
),
)
)
for
command_name
,
command
in
commands
.
iteritems
():
for
command_name
,
command
in
commands
.
iteritems
():
...
@@ -1169,15 +1175,14 @@ class CyGlobals(CyLocals):
...
@@ -1169,15 +1175,14 @@ class CyGlobals(CyLocals):
max_name_length
,
' '
)
max_name_length
,
' '
)
class
CyExec
(
CythonCommand
,
libpython
.
PyExec
):
class
EvaluateOrExecuteCodeMixin
(
object
):
"""
"""
Execute Python code in the nearest Python or Cython frame.
Evaluate or execute Python code in a Cython or Python frame. The 'evalcode'
method evaluations Python code, prints a traceback if an exception went
uncaught, and returns any return value as a gdb.Value (NULL on exception).
"""
"""
name
=
'-cy-exec'
command_class
=
gdb
.
COMMAND_STACK
completer_class
=
gdb
.
COMPLETE_NONE
def
_fill_locals_dict
(
self
,
executor
,
local_dict_pointer
):
def
_fill_locals_dict
(
self
,
executor
,
local_dict_pointer
):
"Fill a remotely allocated dict with values from the Cython C stack"
"Fill a remotely allocated dict with values from the Cython C stack"
cython_func
=
self
.
get_cython_function
()
cython_func
=
self
.
get_cython_function
()
...
@@ -1208,28 +1213,22 @@ class CyExec(CythonCommand, libpython.PyExec):
...
@@ -1208,28 +1213,22 @@ class CyExec(CythonCommand, libpython.PyExec):
raise
gdb
.
GdbError
(
"Unable to execute Python code."
)
raise
gdb
.
GdbError
(
"Unable to execute Python code."
)
finally
:
finally
:
# PyDict_SetItem doesn't steal our reference
# PyDict_SetItem doesn't steal our reference
executor
.
decref
(
pystringp
)
executor
.
x
decref
(
pystringp
)
def
_find_first_cython_or_python_frame
(
self
):
def
_find_first_cython_or_python_frame
(
self
):
frame
=
gdb
.
selected_frame
()
frame
=
gdb
.
selected_frame
()
while
frame
:
while
frame
:
if
(
self
.
is_cython_function
(
frame
)
or
if
(
self
.
is_cython_function
(
frame
)
or
self
.
is_python_function
(
frame
)):
self
.
is_python_function
(
frame
)):
frame
.
select
()
return
frame
return
frame
frame
=
frame
.
older
()
frame
=
frame
.
older
()
raise
gdb
.
GdbError
(
"There is no Cython or Python frame on the stack."
)
raise
gdb
.
GdbError
(
"There is no Cython or Python frame on the stack."
)
def
invoke
(
self
,
expr
,
from_tty
):
frame
=
self
.
_find_first_cython_or_python_frame
()
if
self
.
is_python_function
(
frame
):
libpython
.
py_exec
.
invoke
(
expr
,
from_tty
)
return
expr
,
input_type
=
self
.
readcode
(
expr
)
executor
=
libpython
.
PythonCodeExecutor
()
def
_evalcode_cython
(
self
,
executor
,
code
,
input_type
):
with
libpython
.
FetchAndRestoreError
():
with
libpython
.
FetchAndRestoreError
():
# get the dict of Cython globals and construct a dict in the
# get the dict of Cython globals and construct a dict in the
# inferior with Cython locals
# inferior with Cython locals
...
@@ -1240,9 +1239,65 @@ class CyExec(CythonCommand, libpython.PyExec):
...
@@ -1240,9 +1239,65 @@ class CyExec(CythonCommand, libpython.PyExec):
try
:
try
:
self
.
_fill_locals_dict
(
executor
,
self
.
_fill_locals_dict
(
executor
,
libpython
.
pointervalue
(
local_dict
))
libpython
.
pointervalue
(
local_dict
))
executor
.
evalcode
(
expr
,
input_type
,
global_dict
,
local_dict
)
result
=
executor
.
evalcode
(
code
,
input_type
,
global_dict
,
local_dict
)
finally
:
finally
:
executor
.
decref
(
libpython
.
pointervalue
(
local_dict
))
executor
.
xdecref
(
libpython
.
pointervalue
(
local_dict
))
return
result
def
evalcode
(
self
,
code
,
input_type
):
"""
Evaluate `code` in a Python or Cython stack frame using the given
`input_type`.
"""
frame
=
self
.
_find_first_cython_or_python_frame
()
executor
=
libpython
.
PythonCodeExecutor
()
if
self
.
is_python_function
(
frame
):
return
libpython
.
_evalcode_python
(
executor
,
code
,
input_type
)
return
self
.
_evalcode_cython
(
executor
,
code
,
input_type
)
class
CyExec
(
CythonCommand
,
libpython
.
PyExec
,
EvaluateOrExecuteCodeMixin
):
"""
Execute Python code in the nearest Python or Cython frame.
"""
name
=
'-cy-exec'
command_class
=
gdb
.
COMMAND_STACK
completer_class
=
gdb
.
COMPLETE_NONE
def
invoke
(
self
,
expr
,
from_tty
):
expr
,
input_type
=
self
.
readcode
(
expr
)
executor
=
libpython
.
PythonCodeExecutor
()
executor
.
xdecref
(
self
.
evalcode
(
expr
,
executor
.
Py_single_input
))
class
CySet
(
CythonCommand
):
"""
Set a Cython variable to a certain value
cy set my_cython_c_variable = 10
cy set my_cython_py_variable = $cy_eval("{'doner': 'kebab'}")
This is equivalent to
set $cy_value("my_cython_variable") = 10
"""
name
=
'cy set'
command_class
=
gdb
.
COMMAND_DATA
completer_class
=
gdb
.
COMPLETE_NONE
@
require_cython_frame
def
invoke
(
self
,
expr
,
from_tty
):
name_and_expr
=
expr
.
split
(
'='
,
1
)
if
len
(
name_and_expr
)
!=
2
:
raise
gdb
.
GdbError
(
"Invalid expression. Use 'cy set var = expr'."
)
varname
,
expr
=
name_and_expr
cname
=
self
.
cy
.
cy_cname
.
invoke
(
varname
.
strip
())
gdb
.
execute
(
"set %s = %s"
%
(
cname
,
expr
))
# Functions
# Functions
...
@@ -1312,6 +1367,18 @@ class CyLine(gdb.Function, CythonBase):
...
@@ -1312,6 +1367,18 @@ class CyLine(gdb.Function, CythonBase):
def
invoke
(
self
):
def
invoke
(
self
):
return
self
.
get_cython_lineno
()
return
self
.
get_cython_lineno
()
class
CyEval
(
gdb
.
Function
,
CythonBase
,
EvaluateOrExecuteCodeMixin
):
"""
Evaluate Python code in the nearest Python or Cython frame and return
"""
@
gdb_function_value_to_unicode
def
invoke
(
self
,
python_expression
):
input_type
=
libpython
.
PythonCodeExecutor
.
Py_eval_input
return
self
.
evalcode
(
python_expression
,
input_type
)
cython_info
=
CythonInfo
()
cython_info
=
CythonInfo
()
cy
=
CyCy
.
register
()
cy
=
CyCy
.
register
()
cython_info
.
cy
=
cy
cython_info
.
cy
=
cy
...
...
Cython/Debugger/libpython.py
View file @
6a57acd5
...
@@ -1949,26 +1949,40 @@ class ExecutionControlCommandBase(gdb.Command):
...
@@ -1949,26 +1949,40 @@ class ExecutionControlCommandBase(gdb.Command):
gdb.execute("
delete
%
s
" % bp)
gdb.execute("
delete
%
s
" % bp)
def filter_output(self, result):
def filter_output(self, result):
output = []
match_finish = re.search(r'^Value returned is
\
$
\
d+ = (.*)', result,
re.MULTILINE)
if match_finish:
output.append('Value returned: %s' % match_finish.group(1))
reflags = re.MULTILINE
reflags = re.MULTILINE
regexes = [
output_on_halt = [
(r'^Program received signal .*', reflags|re.DOTALL),
(r'^Program received signal .*', reflags|re.DOTALL),
(r'.*[Ww]arning.*', 0),
(r'.*[Ww]arning.*', 0),
(r'^Program exited .*', reflags),
(r'^Program exited .*', reflags),
]
]
for regex, flags in regexes:
output_always = [
match = re.search(regex, result, flags)
# output when halting on a watchpoint
if match:
(r'^(Old|New) value = .*', reflags),
output.append(match.group(0))
# output from the 'display' command
(r'^
\
d+:
\
w+ = .*', reflags),
]
def filter_output(regexes):
output = []
for regex, flags in regexes:
for match in re.finditer(regex, result, flags):
output.append(match.group(0))
return '
\
n
'.join(output)
# Filter the return value output of the 'finish' command
match_finish = re.search(r'^Value returned is
\
$
\
d+ = (.*)', result,
re.MULTILINE)
if match_finish:
finish_output = 'Value returned: %s
\
n
' % match_finish.group(1)
else:
finish_output = ''
return (filter_output(output_on_halt),
finish_output + filter_output(output_always))
return '
\
n
'.join(output)
def stopped(self):
def stopped(self):
return get_selected_inferior().pid == 0
return get_selected_inferior().pid == 0
...
@@ -1979,17 +1993,23 @@ class ExecutionControlCommandBase(gdb.Command):
...
@@ -1979,17 +1993,23 @@ class ExecutionControlCommandBase(gdb.Command):
of source code or the result of the last executed gdb command (passed
of source code or the result of the last executed gdb command (passed
in as the `result` argument).
in as the `result` argument).
"""
"""
result
= self.filter_output(result)
output_on_halt, output_always
= self.filter_output(result)
if self.stopped():
if self.stopped():
print result.strip()
print output_always
print output_on_halt
else:
else:
frame = gdb.selected_frame()
frame = gdb.selected_frame()
source_line = self.lang_info.get_source_line(frame)
if self.lang_info.is_relevant_function(frame):
if self.lang_info.is_relevant_function(frame):
raised_exception = self.lang_info.exc_info(frame)
raised_exception = self.lang_info.exc_info(frame)
if raised_exception:
if raised_exception:
print raised_exception
print raised_exception
print self.lang_info.get_source_line(frame) or result
if source_line:
if output_always.rstrip():
print output_always.rstrip()
print source_line
else:
else:
print result
print result
...
@@ -2190,12 +2210,12 @@ class PythonInfo(LanguageInfo):
...
@@ -2190,12 +2210,12 @@ class PythonInfo(LanguageInfo):
try:
try:
tstate = frame.read_var('
tstate
').dereference()
tstate = frame.read_var('
tstate
').dereference()
if gdb.parse_and_eval('
tstate
->
frame
==
f'):
if gdb.parse_and_eval('
tstate
->
frame
==
f'):
# tstate local variable initialized
# tstate local variable initialized
, check for an exception
inf_type = tstate['
curexc_type
']
inf_type = tstate['
curexc_type
']
inf_value = tstate['
curexc_value
']
inf_value = tstate['
curexc_value
']
if inf_type:
if inf_type:
return '
An
exception
was
raised
:
%
s
(
%
s
)
' % (inf_type,
return '
An
exception
was
raised
:
%
s
' % (inf_value,)
inf_value)
except (ValueError, RuntimeError), e:
except (ValueError, RuntimeError), e:
# Could not read the variable tstate or it'
s
memory
,
it
's ok
# Could not read the variable tstate or it'
s
memory
,
it
's ok
pass
pass
...
@@ -2342,7 +2362,7 @@ class PythonCodeExecutor(object):
...
@@ -2342,7 +2362,7 @@ class PythonCodeExecutor(object):
"Increment the reference count of a Python object in the inferior."
"Increment the reference count of a Python object in the inferior."
gdb
.
parse_and_eval
(
'Py_IncRef((PyObject *) %d)'
%
pointer
)
gdb
.
parse_and_eval
(
'Py_IncRef((PyObject *) %d)'
%
pointer
)
def
decref
(
self
,
pointer
):
def
x
decref
(
self
,
pointer
):
"Decrement the reference count of a Python object in the inferior."
"Decrement the reference count of a Python object in the inferior."
# Py_DecRef is like Py_XDECREF, but a function. So we don't have
# Py_DecRef is like Py_XDECREF, but a function. So we don't have
# to check for NULL. This should also decref all our allocated
# to check for NULL. This should also decref all our allocated
...
@@ -2382,10 +2402,11 @@ class PythonCodeExecutor(object):
...
@@ -2382,10 +2402,11 @@ class PythonCodeExecutor(object):
with
FetchAndRestoreError
():
with
FetchAndRestoreError
():
try
:
try
:
self
.
decref
(
gdb
.
parse_and_eval
(
code
)
)
pyobject_return_value
=
gdb
.
parse_and_eval
(
code
)
finally
:
finally
:
self
.
free
(
pointer
)
self
.
free
(
pointer
)
return
pyobject_return_value
class
FetchAndRestoreError
(
PythonCodeExecutor
):
class
FetchAndRestoreError
(
PythonCodeExecutor
):
"""
"""
...
@@ -2462,6 +2483,20 @@ class FixGdbCommand(gdb.Command):
...
@@ -2462,6 +2483,20 @@ class FixGdbCommand(gdb.Command):
self
.
fix_gdb
()
self
.
fix_gdb
()
def
_evalcode_python
(
executor
,
code
,
input_type
):
"""
Execute Python code in the most recent stack frame.
"""
global_dict
=
gdb
.
parse_and_eval
(
'PyEval_GetGlobals()'
)
local_dict
=
gdb
.
parse_and_eval
(
'PyEval_GetLocals()'
)
if
(
pointervalue
(
global_dict
)
==
0
or
pointervalue
(
local_dict
)
==
0
):
raise
gdb
.
GdbError
(
"Unable to find the locals or globals of the "
"most recent Python function (relative to the "
"selected frame)."
)
return
executor
.
evalcode
(
code
,
input_type
,
global_dict
,
local_dict
)
class
PyExec
(
gdb
.
Command
):
class
PyExec
(
gdb
.
Command
):
def
readcode
(
self
,
expr
):
def
readcode
(
self
,
expr
):
...
@@ -2484,17 +2519,9 @@ class PyExec(gdb.Command):
...
@@ -2484,17 +2519,9 @@ class PyExec(gdb.Command):
def
invoke
(
self
,
expr
,
from_tty
):
def
invoke
(
self
,
expr
,
from_tty
):
expr
,
input_type
=
self
.
readcode
(
expr
)
expr
,
input_type
=
self
.
readcode
(
expr
)
executor
=
PythonCodeExecutor
()
executor
=
PythonCodeExecutor
()
global_dict
=
gdb
.
parse_and_eval
(
'PyEval_GetGlobals()'
)
executor
.
xdecref
(
_evalcode_python
(
executor
,
input_type
,
global_dict
,
local_dict
=
gdb
.
parse_and_eval
(
'PyEval_GetLocals()'
)
local_dict
))
if
pointervalue
(
global_dict
)
==
0
or
pointervalue
(
local_dict
)
==
0
:
raise
gdb
.
GdbError
(
"Unable to find the locals or globals of the "
"most recent Python function (relative to the "
"selected frame)."
)
executor
.
evalcode
(
expr
,
input_type
,
global_dict
,
local_dict
)
gdb
.
execute
(
'set breakpoint pending on'
)
gdb
.
execute
(
'set breakpoint pending on'
)
...
...
runtests.py
View file @
6a57acd5
...
@@ -894,7 +894,7 @@ class EmbedTest(unittest.TestCase):
...
@@ -894,7 +894,7 @@ class EmbedTest(unittest.TestCase):
# report the error for the original directory
# report the error for the original directory
libdir
=
sysconfig
.
get_config_var
(
'LIBDIR'
)
libdir
=
sysconfig
.
get_config_var
(
'LIBDIR'
)
cython
=
'cython.py'
cython
=
'cython.py'
if
sys
.
version_info
[
0
]
>=
3
:
if
sys
.
version_info
[
0
]
>=
3
and
CY3_DIR
:
cython
=
os
.
path
.
join
(
CY3_DIR
,
cython
)
cython
=
os
.
path
.
join
(
CY3_DIR
,
cython
)
cython
=
os
.
path
.
abspath
(
os
.
path
.
join
(
'..'
,
'..'
,
cython
))
cython
=
os
.
path
.
abspath
(
os
.
path
.
join
(
'..'
,
'..'
,
cython
))
self
.
assert_
(
os
.
system
(
self
.
assert_
(
os
.
system
(
...
...
tests/bugs.txt
View file @
6a57acd5
...
@@ -18,6 +18,7 @@ pure_mode_cmethod_inheritance_T583
...
@@ -18,6 +18,7 @@ pure_mode_cmethod_inheritance_T583
genexpr_iterable_lookup_T600
genexpr_iterable_lookup_T600
for_from_pyvar_loop_T601
for_from_pyvar_loop_T601
decorators_T593
decorators_T593
temp_sideeffects_T654
# CPython regression tests that don't current work:
# CPython regression tests that don't current work:
pyregr.test_threadsignals
pyregr.test_threadsignals
...
...
tests/compile/a_capi.pyx
View file @
6a57acd5
...
@@ -11,6 +11,12 @@ cdef public class C[type C_Type, object C_Obj]:
...
@@ -11,6 +11,12 @@ cdef public class C[type C_Type, object C_Obj]:
cdef
public
Zax
*
blarg
cdef
public
Zax
*
blarg
cdef
public
C
c_pub
=
C
()
cdef
api
C
c_api
=
C
()
cdef
public
dict
o_pub
=
C
()
cdef
api
list
o_api
=
C
()
cdef
api
float
f
(
Foo
*
x
):
cdef
api
float
f
(
Foo
*
x
):
pass
pass
...
@@ -19,3 +25,6 @@ cdef public void g(Blarg *x):
...
@@ -19,3 +25,6 @@ cdef public void g(Blarg *x):
cdef
public
api
void
h
(
Zax
*
x
):
cdef
public
api
void
h
(
Zax
*
x
):
pass
pass
cdef
extern
from
"a_capi.h"
:
pass
tests/compile/publicapi_api.pyx
0 → 100644
View file @
6a57acd5
# --
ctypedef
int
Int0
ctypedef
api
int
Int1
ctypedef
enum
EnumA0
:
EA0
ctypedef
api
enum
EnumA1
:
EA1
cdef
enum
EnumB0
:
EB0
=
0
cdef
api
enum
EnumB1
:
EB1
=
1
cdef
Int0
i0
=
0
cdef
EnumA0
ea0
=
EA0
cdef
EnumB0
eb0
=
EB0
cdef
api
Int1
i1
=
0
cdef
api
EnumA1
ea1
=
EA1
cdef
api
EnumB1
eb1
=
EB1
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
api
struct
StructA1
:
int
SA1
cdef
struct
StructB0
:
int
SB0
cdef
api
struct
StructB1
:
int
SB1
cdef
StructA0
sa0
=
{
'SA0'
:
0
}
cdef
StructB0
sb0
=
{
'SB0'
:
2
}
cdef
api
StructA1
sa1
=
{
'SA1'
:
1
}
cdef
api
StructB1
sb1
=
{
'SB1'
:
3
}
# --
ctypedef
class
Foo0
:
pass
ctypedef
api
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
api
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
Foo0
f0
=
None
cdef
Bar0
b0
=
None
cdef
api
Foo1
f1
=
None
cdef
api
Bar1
b1
=
None
# --
cdef
void
bar0
():
pass
cdef
api
void
bar1
():
pass
cdef
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
api
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
bar0
()
bar1
()
spam0
(
None
)
spam1
(
None
)
# --
tests/compile/publicapi_mix.pyx
0 → 100644
View file @
6a57acd5
# --
ctypedef
int
Int0
ctypedef
public
int
Int1
ctypedef
api
int
Int2
ctypedef
public
api
int
Int3
ctypedef
enum
EnumA0
:
EA0
ctypedef
public
enum
EnumA1
:
EA1
ctypedef
api
enum
EnumA2
:
EA2
ctypedef
public
api
enum
EnumA3
:
EA3
cdef
enum
EnumB0
:
EB0
=
0
cdef
public
enum
EnumB1
:
EB1
=
1
cdef
api
enum
EnumB2
:
EB2
=
2
cdef
public
api
enum
EnumB3
:
EB3
=
3
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
public
struct
StructA1
:
int
SA1
ctypedef
api
struct
StructA2
:
int
SA2
ctypedef
public
api
struct
StructA3
:
int
SA3
cdef
struct
StructB0
:
int
SB0
cdef
public
struct
StructB1
:
int
SB1
cdef
api
struct
StructB2
:
int
SB2
cdef
public
api
struct
StructB3
:
int
SB3
# --
ctypedef
class
Foo0
:
pass
ctypedef
public
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
ctypedef
api
class
Foo2
[
type
PyFoo2_Type
,
object
PyFoo2_Object
]:
pass
ctypedef
public
api
class
Foo3
[
type
PyFoo3_Type
,
object
PyFoo3_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
public
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
api
class
Bar2
[
type
PyBar2_Type
,
object
PyBar2_Object
]:
pass
cdef
public
api
class
Bar3
[
type
PyBar3_Type
,
object
PyBar3_Object
]:
pass
# --
cdef
void
bar0
():
pass
cdef
public
void
bar1
():
pass
cdef
api
void
bar2
():
pass
cdef
public
api
void
bar3
():
pass
cdef
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
public
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
cdef
api
void
*
spam2
(
object
o
)
except
NULL
:
return
NULL
cdef
public
api
void
*
spam3
(
object
o
)
except
NULL
:
return
NULL
bar0
()
spam0
(
None
)
# --
cdef
double
d0
=
0
cdef
public
double
d1
=
1
cdef
api
double
d2
=
2
cdef
public
api
double
d3
=
3
cdef
object
o0
=
None
cdef
public
object
o1
=
None
cdef
api
object
o2
=
None
cdef
public
api
object
o3
=
None
# --
tests/compile/publicapi_pub.pyx
0 → 100644
View file @
6a57acd5
# --
ctypedef
int
Int0
ctypedef
public
int
Int1
ctypedef
enum
EnumA0
:
EA0
ctypedef
public
enum
EnumA1
:
EA1
cdef
enum
EnumB0
:
EB0
=
0
cdef
public
enum
EnumB1
:
EB1
=
1
cdef
Int0
i0
=
0
cdef
EnumA0
ea0
=
EA0
cdef
EnumB0
eb0
=
EB0
cdef
public
Int1
i1
=
0
cdef
public
EnumA1
ea1
=
EA1
cdef
public
EnumB1
eb1
=
EB1
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
public
struct
StructA1
:
int
SA1
cdef
struct
StructB0
:
int
SB0
cdef
public
struct
StructB1
:
int
SB1
cdef
StructA0
sa0
=
{
'SA0'
:
0
}
cdef
StructB0
sb0
=
{
'SB0'
:
2
}
cdef
public
StructA1
sa1
=
{
'SA1'
:
1
}
cdef
public
StructB1
sb1
=
{
'SB1'
:
3
}
# --
ctypedef
class
Foo0
:
pass
ctypedef
public
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
public
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
Foo0
f0
=
None
cdef
Bar0
b0
=
None
cdef
public
Foo1
f1
=
None
cdef
public
Bar1
b1
=
None
# --
cdef
void
bar0
():
pass
cdef
public
void
bar1
():
pass
cdef
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
public
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
bar0
()
bar1
()
spam0
(
None
)
spam1
(
None
)
# --
tests/compile/publicapi_pxd_mix.pxd
0 → 100644
View file @
6a57acd5
# --
ctypedef
int
Int0
ctypedef
public
int
Int1
ctypedef
api
int
Int2
ctypedef
public
api
int
Int3
ctypedef
enum
EnumA0
:
EA0
ctypedef
public
enum
EnumA1
:
EA1
ctypedef
api
enum
EnumA2
:
EA2
ctypedef
public
api
enum
EnumA3
:
EA3
cdef
enum
EnumB0
:
EB0
=
0
cdef
public
enum
EnumB1
:
EB1
=
1
cdef
api
enum
EnumB2
:
EB2
=
2
cdef
public
api
enum
EnumB3
:
EB3
=
3
# --
ctypedef
struct
StructA0
:
int
SA0
ctypedef
public
struct
StructA1
:
int
SA1
ctypedef
api
struct
StructA2
:
int
SA2
ctypedef
public
api
struct
StructA3
:
int
SA3
cdef
struct
StructB0
:
int
SB0
cdef
public
struct
StructB1
:
int
SB1
cdef
api
struct
StructB2
:
int
SB2
cdef
public
api
struct
StructB3
:
int
SB3
# --
ctypedef
class
Foo0
:
pass
ctypedef
public
class
Foo1
[
type
PyFoo1_Type
,
object
PyFoo1_Object
]:
pass
ctypedef
api
class
Foo2
[
type
PyFoo2_Type
,
object
PyFoo2_Object
]:
pass
ctypedef
public
api
class
Foo3
[
type
PyFoo3_Type
,
object
PyFoo3_Object
]:
pass
cdef
class
Bar0
:
pass
cdef
public
class
Bar1
[
type
PyBar1_Type
,
object
PyBar1_Object
]:
pass
cdef
api
class
Bar2
[
type
PyBar2_Type
,
object
PyBar2_Object
]:
pass
cdef
public
api
class
Bar3
[
type
PyBar3_Type
,
object
PyBar3_Object
]:
pass
# --
cdef
inline
void
bar0
():
pass
cdef
public
void
bar1
()
cdef
api
void
bar2
()
cdef
public
api
void
bar3
()
cdef
inline
void
*
spam0
(
object
o
)
except
NULL
:
return
NULL
cdef
public
void
*
spam1
(
object
o
)
except
NULL
cdef
api
void
*
spam2
(
object
o
)
nogil
except
NULL
cdef
public
api
void
*
spam3
(
object
o
)
except
NULL
with
gil
# --
#cdef public int i1
#cdef api int i2
#cdef public api int i3
# --
tests/compile/publicapi_pxd_mix.pyx
0 → 100644
View file @
6a57acd5
cdef
class
Foo1
:
pass
cdef
class
Foo2
:
pass
cdef
class
Foo3
:
pass
cdef
class
Bar1
:
pass
cdef
class
Bar2
:
pass
cdef
class
Bar3
:
pass
cdef
public
void
bar1
():
pass
cdef
api
void
bar2
():
pass
cdef
public
api
void
bar3
():
pass
cdef
public
void
*
spam1
(
object
o
)
except
NULL
:
return
NULL
cdef
api
void
*
spam2
(
object
o
)
nogil
except
NULL
:
return
NULL
cdef
public
api
void
*
spam3
(
object
o
)
except
NULL
with
gil
:
return
NULL
tests/run/builtinnames.pyx
View file @
6a57acd5
...
@@ -56,3 +56,14 @@ def test_for_in_range(arg):
...
@@ -56,3 +56,14 @@ def test_for_in_range(arg):
for
c
in
range
(
arg
):
for
c
in
range
(
arg
):
l
.
append
(
c
)
l
.
append
(
c
)
return
l
return
l
def
raise_and_catch_BaseException
():
"""
>>> raise_and_catch_BaseException()
1
"""
try
:
raise
BaseException
except
BaseException
:
return
1
return
2
tests/run/capiimpl.pyx
View file @
6a57acd5
...
@@ -2,8 +2,20 @@ __doc__ = u"""
...
@@ -2,8 +2,20 @@ __doc__ = u"""
>>> import sys
>>> import sys
>>> sys.getrefcount(Foo.__pyx_vtable__)
>>> sys.getrefcount(Foo.__pyx_vtable__)
2
2
>>> sys.getrefcount(__pyx_capi__['
spam
'])
>>> sys.getrefcount(__pyx_capi__['
ten
'])
2
2
>>> sys.getrefcount(__pyx_capi__['pi'])
2
>>> sys.getrefcount(__pyx_capi__['obj'])
2
>>> sys.getrefcount(__pyx_capi__['dct'])
2
>>> sys.getrefcount(__pyx_capi__['one'])
2
>>> sys.getrefcount(__pyx_capi__['two'])
Traceback (most recent call last):
...
KeyError: 'two'
"""
"""
cdef
public
api
class
Foo
[
type
FooType
,
object
FooObject
]:
cdef
public
api
class
Foo
[
type
FooType
,
object
FooObject
]:
...
@@ -12,3 +24,12 @@ cdef public api class Foo [type FooType, object FooObject]:
...
@@ -12,3 +24,12 @@ cdef public api class Foo [type FooType, object FooObject]:
cdef
api
void
spam
():
cdef
api
void
spam
():
pass
pass
cdef
api
int
ten
=
10
cdef
api
double
pi
=
3.14
cdef
api
object
obj
=
object
()
cdef
api
dict
dct
=
{}
cdef
public
api
int
one
=
1
cdef
public
int
two
=
2
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