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
fde67796
Commit
fde67796
authored
Feb 14, 2009
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
c84a953c
3bbefcb4
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
543 additions
and
219 deletions
+543
-219
Cython/Compiler/AutoDocTransforms.py
Cython/Compiler/AutoDocTransforms.py
+20
-61
Cython/Compiler/Builtin.py
Cython/Compiler/Builtin.py
+19
-7
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+19
-30
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+74
-13
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+3
-2
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+55
-10
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+3
-1
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+110
-5
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+61
-36
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+19
-2
Cython/Compiler/Scanning.py
Cython/Compiler/Scanning.py
+2
-11
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+12
-9
Cython/Compiler/TreeFragment.py
Cython/Compiler/TreeFragment.py
+6
-6
Cython/Plex/Scanners.py
Cython/Plex/Scanners.py
+3
-1
Cython/Shadow.py
Cython/Shadow.py
+22
-0
Cython/__init__.py
Cython/__init__.py
+2
-0
cython.py
cython.py
+8
-2
setup.py
setup.py
+3
-1
tests/compile/types_and_names.pxd
tests/compile/types_and_names.pxd
+9
-0
tests/compile/types_and_names.pyx
tests/compile/types_and_names.pyx
+23
-0
tests/errors/e_argdefault.pyx
tests/errors/e_argdefault.pyx
+1
-1
tests/errors/e_bufaccess2.pyx
tests/errors/e_bufaccess2.pyx
+1
-3
tests/errors/e_modop.pyx
tests/errors/e_modop.pyx
+0
-6
tests/errors/invalid_cast.pyx
tests/errors/invalid_cast.pyx
+2
-2
tests/run/embedsignatures.pyx
tests/run/embedsignatures.pyx
+10
-10
tests/run/fmod.pyx
tests/run/fmod.pyx
+7
-0
tests/run/isinstance.pyx
tests/run/isinstance.pyx
+35
-0
tests/run/locals.pyx
tests/run/locals.pyx
+9
-0
tests/run/sizeof.pyx
tests/run/sizeof.pyx
+5
-0
No files found.
Cython/Compiler/AutoDocTransforms.py
View file @
fde67796
import
re
from
Cython.Compiler.Visitor
import
CythonTransform
from
Cython.Compiler.Nodes
import
DefNode
,
CFuncDefNode
from
Cython.Compiler.Errors
import
CompileError
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler
import
Options
from
Cython.Compiler
import
PyrexTypes
class
EmbedSignature
(
CythonTransform
):
SPECIAL_METHOD_RE
=
re
.
compile
(
r'__\
w+__
')
class
EmbedSignature
(
CythonTransform
):
def
__init__
(
self
,
context
):
super
(
EmbedSignature
,
self
).
__init__
(
context
)
self
.
denv
=
None
# XXX
self.is_in_class = False
self
.
class_name
=
None
def _fmt_basic_c_type_modifiers(self, ctype):
longness = ctype.longness
modifiers = ''
if longness < 0:
modifiers = '
short
'
elif longness > 0:
modifiers = '
long
' * longness
signed = ctype.signed
if signed == 0:
modifiers = '
unsigned
' + modifiers
elif signed == 2:
modifiers = '
signed
' + modifiers
return modifiers[:-1] # strip final space
def _fmt_arg_type(self, arg):
try:
base_type = arg.base_type
arg_type = base_type.name
except AttributeError:
return ''
if base_type.is_basic_c_type:
modifiers = self._fmt_basic_c_type_modifiers(base_type)
if modifiers:
arg_type = '
%
s
%
s
' % (modifiers, arg_type)
return arg_type
def _fmt_arg_name(self, arg):
try:
return arg.declarator.name
except AttributeError:
return arg.declarator.base.name
def
_fmt_arg_defv
(
self
,
arg
):
if
not
arg
.
default
:
return
None
...
...
@@ -63,14 +28,14 @@ class EmbedSignature(CythonTransform):
return
'<???>'
def
_fmt_arg
(
self
,
arg
):
arg_type = self._fmt_arg_type(arg)
arg_name = self._fmt_arg_name(arg)
arg_defv = self._fmt_arg_defv(arg)
doc = arg_name
if arg
_type
:
doc = ('
%
s
' % arg_type) + doc
if arg_defv:
doc = doc + ('
=%
s
' % arg_defv)
if
arg
.
type
is
PyrexTypes
.
py_object_type
or
arg
.
is_self_arg
:
doc
=
arg
.
name
else
:
doc
=
arg
.
type
.
declaration_code
(
arg
.
name
,
for_display
=
1
)
if
arg
.
default
:
arg_defv
=
self
.
_fmt_arg_defv
(
arg
)
if
arg_defv
:
doc
=
doc
+
(
'=%s'
%
arg_defv
)
return
doc
def
_fmt_arglist
(
self
,
args
,
...
...
@@ -89,13 +54,10 @@ class EmbedSignature(CythonTransform):
return
arglist
def
_fmt_ret_type
(
self
,
ret
):
ret_type = ret.name
if ret_type is None:
return ''
modifiers = self._fmt_basic_c_type_modifiers(ret)
if modifiers:
ret_type = '
%
s
%
s
' % (modifiers, ret_type)
return ret_type
if
ret
is
PyrexTypes
.
py_object_type
:
return
None
else
:
return
ret
.
declaration_code
(
""
,
for_display
=
1
)
def
_fmt_signature
(
self
,
cls_name
,
func_name
,
args
,
npargs
=
0
,
pargs
=
None
,
...
...
@@ -128,9 +90,7 @@ class EmbedSignature(CythonTransform):
return
super
(
EmbedSignature
,
self
).
__call__
(
node
)
def
visit_ClassDefNode
(
self
,
node
):
oldincls = self.is_in_class
oldname
=
self
.
class_name
self.is_in_class = True
try
:
# PyClassDefNode
self
.
class_name
=
node
.
name
...
...
@@ -138,7 +98,6 @@ class EmbedSignature(CythonTransform):
# CClassDefNode
self
.
class_name
=
node
.
class_name
self
.
visitchildren
(
node
)
self.is_in_class = oldincls
self
.
class_name
=
oldname
return
node
...
...
@@ -148,9 +107,7 @@ class EmbedSignature(CythonTransform):
signature
=
None
if
type
(
node
)
is
DefNode
:
# def FOO(...):
special_method = (self.is_in_class and
\
self.SPECIAL_METHOD_RE.match(node.name))
if not special_method:
if
not
node
.
entry
.
is_special
:
nkargs
=
getattr
(
node
,
'num_kwonly_args'
,
0
)
npargs
=
len
(
node
.
args
)
-
nkargs
signature
=
self
.
_fmt_signature
(
...
...
@@ -163,10 +120,12 @@ class EmbedSignature(CythonTransform):
signature
=
self
.
_fmt_signature
(
self
.
class_name
,
node
.
declarator
.
base
.
name
,
node
.
declarator
.
args
,
return_type=node.
base
_type)
return_type
=
node
.
return
_type
)
else
:
# should not fall here ...
assert
False
if
signature
:
new_doc = self._embed_signature(signature, node.doc)
node.doc = EncodedString(new_doc) # XXX
new_doc
=
self
.
_embed_signature
(
signature
,
node
.
entry
.
doc
)
node
.
entry
.
doc
=
EncodedString
(
new_doc
)
if
hasattr
(
node
,
'py_func'
)
and
node
.
py_func
is
not
None
:
node
.
py_func
.
entry
.
doc
=
EncodedString
(
new_doc
)
return
node
Cython/Compiler/Builtin.py
View file @
fde67796
...
...
@@ -30,6 +30,7 @@ builtin_function_table = [
(
'issubclass'
,
"OO"
,
"b"
,
"PyObject_IsSubclass"
),
(
'iter'
,
"O"
,
"O"
,
"PyObject_GetIter"
),
(
'len'
,
"O"
,
"Z"
,
"PyObject_Length"
),
(
'locals'
,
""
,
"O"
,
"__pyx_locals"
),
#('map', "", "", ""),
#('max', "", "", ""),
#('min', "", "", ""),
...
...
@@ -82,23 +83,34 @@ builtin_function_table = [
builtin_types_table
=
[
(
"type"
,
"PyType_Type"
,
[]),
# ("str", "PyBytes_Type", []),
(
"bool"
,
"PyBool_Type"
,
[]),
(
"int"
,
"PyInt_Type"
,
[]),
(
"long"
,
"PyLong_Type"
,
[]),
(
"float"
,
"PyFloat_Type"
,
[]),
(
"complex"
,
"PyComplex_Type"
,
[]),
(
"bytes"
,
"PyBytes_Type"
,
[]),
(
"str"
,
"PyString_Type"
,
[]),
(
"unicode"
,
"PyUnicode_Type"
,
[]),
(
"file"
,
"PyFile_Type"
,
[]),
# ("slice", "PySlice_Type", []),
# ("set", "PySet_Type", []),
(
"frozenset"
,
"PyFrozenSet_Type"
,
[]),
(
"tuple"
,
"PyTuple_Type"
,
[]),
(
"list"
,
"PyList_Type"
,
[(
"append"
,
"OO"
,
"i"
,
"PyList_Append"
),
(
"insert"
,
"OiO"
,
"i"
,
"PyList_Insert"
),
(
"sort"
,
"O"
,
"i"
,
"PyList_Sort"
),
(
"reverse"
,
"O"
,
"i"
,
"PyList_Reverse"
)]),
(
"dict"
,
"PyDict_Type"
,
[(
"items"
,
"O"
,
"O"
,
"PyDict_Items"
),
(
"keys"
,
"O"
,
"O"
,
"PyDict_Keys"
),
(
"values"
,
"O"
,
"O"
,
"PyDict_Values"
)]),
(
"set"
,
"PySet_Type"
,
[]),
(
"frozenset"
,
"PyFrozenSet_Type"
,
[]),
(
"slice"
,
"PySlice_Type"
,
[]),
(
"file"
,
"PyFile_Type"
,
[]),
]
builtin_structs_table
=
[
...
...
Cython/Compiler/Code.py
View file @
fde67796
...
...
@@ -190,13 +190,12 @@ class GlobalState(object):
self
.
init_cached_builtins_writer
.
putln
(
"static int __Pyx_InitCachedBuiltins(void) {"
)
self
.
initwriter
.
enter_cfunc_scope
()
self
.
initwriter
.
putln
(
""
).
putln
(
"static int __Pyx_InitGlobals(void) {"
)
self
.
initwriter
.
putln
(
""
)
self
.
initwriter
.
putln
(
"static int __Pyx_InitGlobals(void) {"
)
(
self
.
pystring_table
.
putln
(
""
)
.
putln
(
"static __Pyx_StringTabEntry %s[] = {"
%
self
.
pystring_table
.
putln
(
""
)
self
.
pystring_table
.
putln
(
"static __Pyx_StringTabEntry %s[] = {"
%
Naming
.
stringtab_cname
)
)
#
# Global constants, interned objects, etc.
...
...
@@ -208,7 +207,8 @@ class GlobalState(object):
# This is called when it is known that no more global declarations will
# declared (but can be called before or after insert_XXX).
if
self
.
pystring_table_needed
:
self
.
pystring_table
.
putln
(
"{0, 0, 0, 0, 0, 0}"
).
putln
(
"};"
)
self
.
pystring_table
.
putln
(
"{0, 0, 0, 0, 0, 0}"
)
self
.
pystring_table
.
putln
(
"};"
)
import
Nodes
self
.
use_utility_code
(
Nodes
.
init_string_tab_utility_code
)
self
.
initwriter
.
putln
(
...
...
@@ -217,21 +217,19 @@ class GlobalState(object):
self
.
initwriter
.
error_goto
(
self
.
module_pos
)))
if
Options
.
cache_builtins
:
(
self
.
init_cached_builtins_writer
.
putln
(
"return 0;"
)
.
put_label
(
self
.
init_cached_builtins_writer
.
error_label
)
.
putln
(
"return -1;"
)
.
putln
(
"}"
)
.
exit_cfunc_scope
()
)
(
self
.
initwriter
.
putln
(
"return 0;"
)
.
put_label
(
self
.
initwriter
.
error_label
)
.
putln
(
"return -1;"
)
.
putln
(
"}"
)
.
exit_cfunc_scope
()
)
w
=
self
.
init_cached_builtins_writer
w
.
putln
(
"return 0;"
)
w
.
put_label
(
w
.
error_label
)
w
.
putln
(
"return -1;"
)
w
.
putln
(
"}"
)
w
.
exit_cfunc_scope
()
w
=
self
.
initwriter
w
.
putln
(
"return 0;"
)
w
.
put_label
(
w
.
error_label
)
w
.
putln
(
"return -1;"
)
w
.
putln
(
"}"
)
w
.
exit_cfunc_scope
()
def
insert_initcode_into
(
self
,
code
):
if
self
.
pystring_table_needed
:
...
...
@@ -526,7 +524,6 @@ class CCodeWriter(object):
self
.
put
(
code
)
self
.
write
(
"
\
n
"
);
self
.
bol
=
1
return
self
def
emit_marker
(
self
):
self
.
write
(
"
\
n
"
);
...
...
@@ -534,7 +531,6 @@ class CCodeWriter(object):
self
.
write
(
"/* %s */
\
n
"
%
self
.
marker
[
1
])
self
.
last_marker_line
=
self
.
marker
[
0
]
self
.
marker
=
None
return
self
def
put_safe
(
self
,
code
):
# put code, but ignore {}
...
...
@@ -557,25 +553,20 @@ class CCodeWriter(object):
self
.
level
+=
dl
elif
fix_indent
:
self
.
level
+=
1
return
self
def
increase_indent
(
self
):
self
.
level
=
self
.
level
+
1
return
self
def
decrease_indent
(
self
):
self
.
level
=
self
.
level
-
1
return
self
def
begin_block
(
self
):
self
.
putln
(
"{"
)
self
.
increase_indent
()
return
self
def
end_block
(
self
):
self
.
decrease_indent
()
self
.
putln
(
"}"
)
return
self
def
indent
(
self
):
self
.
write
(
" "
*
self
.
level
)
...
...
@@ -604,12 +595,10 @@ class CCodeWriter(object):
def
put_label
(
self
,
lbl
):
if
lbl
in
self
.
funcstate
.
labels_used
:
self
.
putln
(
"%s:;"
%
lbl
)
return
self
def
put_goto
(
self
,
lbl
):
self
.
funcstate
.
use_label
(
lbl
)
self
.
putln
(
"goto %s;"
%
lbl
)
return
self
def
put_var_declarations
(
self
,
entries
,
static
=
0
,
dll_linkage
=
None
,
definition
=
True
):
...
...
Cython/Compiler/ExprNodes.py
View file @
fde67796
...
...
@@ -290,6 +290,11 @@ class ExprNode(Node):
# If this node can be interpreted as a reference to a
# cimported module, return its scope, else None.
return
None
def
analyse_as_type
(
self
,
env
):
# If this node can be interpreted as a reference to a
# type, return that type, else None.
return
None
def
analyse_as_extension_type
(
self
,
env
):
# If this node can be interpreted as a reference to an
...
...
@@ -773,6 +778,15 @@ class StringNode(ConstNode):
def
analyse_types
(
self
,
env
):
self
.
entry
=
env
.
add_string_const
(
self
.
value
)
def
analyse_as_type
(
self
,
env
):
from
TreeFragment
import
TreeFragment
pos
=
(
self
.
pos
[
0
],
self
.
pos
[
1
],
self
.
pos
[
2
]
-
7
)
declaration
=
TreeFragment
(
u"sizeof(%s)"
%
self
.
value
,
name
=
pos
[
0
].
filename
,
initial_pos
=
pos
)
sizeof_node
=
declaration
.
root
.
stats
[
0
].
expr
sizeof_node
.
analyse_types
(
env
)
if
isinstance
(
sizeof_node
,
SizeofTypeNode
):
return
sizeof_node
.
arg_type
def
coerce_to
(
self
,
dst_type
,
env
):
if
dst_type
.
is_int
:
...
...
@@ -944,6 +958,17 @@ class NameNode(AtomicExprNode):
if
entry
and
entry
.
as_module
:
return
entry
.
as_module
return
None
def
analyse_as_type
(
self
,
env
):
if
self
.
name
in
PyrexTypes
.
rank_to_type_name
:
return
PyrexTypes
.
simple_c_type
(
1
,
0
,
self
.
name
)
entry
=
self
.
entry
if
not
entry
:
entry
=
env
.
lookup
(
self
.
name
)
if
entry
and
entry
.
is_type
:
return
entry
.
type
else
:
return
None
def
analyse_as_extension_type
(
self
,
env
):
# Try to interpret this as a reference to an extension type.
...
...
@@ -1427,6 +1452,12 @@ class IndexNode(ExprNode):
def
analyse_target_declaration
(
self
,
env
):
pass
def
analyse_as_type
(
self
,
env
):
base_type
=
self
.
base
.
analyse_as_type
(
env
)
if
base_type
and
not
base_type
.
is_pyobject
:
return
PyrexTypes
.
CArrayType
(
base_type
,
int
(
self
.
index
.
compile_time_value
(
env
)))
return
None
def
analyse_types
(
self
,
env
):
self
.
analyse_base_and_index_types
(
env
,
getting
=
1
)
...
...
@@ -2243,6 +2274,14 @@ class AttributeNode(ExprNode):
self
.
mutate_into_name_node
(
env
,
ubcm_entry
,
None
)
return
1
return
0
def
analyse_as_type
(
self
,
env
):
module_scope
=
self
.
obj
.
analyse_as_module
(
env
)
if
module_scope
:
entry
=
module_scope
.
lookup_here
(
self
.
attribute
)
if
entry
and
entry
.
is_type
:
return
entry
.
type
return
None
def
analyse_as_extension_type
(
self
,
env
):
# Try to interpret this as a reference to an extension type
...
...
@@ -2800,6 +2839,9 @@ class DictItemNode(ExprNode):
def
generate_disposal_code
(
self
,
code
):
self
.
key
.
generate_disposal_code
(
code
)
self
.
value
.
generate_disposal_code
(
code
)
def
__iter__
(
self
):
return
iter
([
self
.
key
,
self
.
value
])
class
ClassNode
(
ExprNode
):
...
...
@@ -3168,6 +3210,8 @@ class TypecastNode(ExprNode):
class
SizeofNode
(
ExprNode
):
# Abstract base class for sizeof(x) expression nodes.
type
=
PyrexTypes
.
c_int_type
def
check_const
(
self
):
pass
...
...
@@ -3183,11 +3227,12 @@ class SizeofTypeNode(SizeofNode):
# declarator CDeclaratorNode
subexprs
=
[]
arg_type
=
None
def
analyse_types
(
self
,
env
):
# we may have incorrectly interpreted a dotted name as a type rather than an attribute
# this could be better handled by more uniformly treating types as runtime-available objects
if
self
.
base_type
.
module_path
:
if
0
and
self
.
base_type
.
module_path
:
path
=
self
.
base_type
.
module_path
obj
=
env
.
lookup
(
path
[
0
])
if
obj
.
as_module
is
None
:
...
...
@@ -3199,16 +3244,20 @@ class SizeofTypeNode(SizeofNode):
self
.
__class__
=
SizeofVarNode
self
.
analyse_types
(
env
)
return
base_type
=
self
.
base_type
.
analyse
(
env
)
_
,
arg_type
=
self
.
declarator
.
analyse
(
base_type
,
env
)
self
.
arg_type
=
arg_type
if
self
.
arg_type
is
None
:
base_type
=
self
.
base_type
.
analyse
(
env
)
_
,
arg_type
=
self
.
declarator
.
analyse
(
base_type
,
env
)
self
.
arg_type
=
arg_type
self
.
check_type
()
def
check_type
(
self
):
arg_type
=
self
.
arg_type
if
arg_type
.
is_pyobject
and
not
arg_type
.
is_extension_type
:
error
(
self
.
pos
,
"Cannot take sizeof Python object"
)
elif
arg_type
.
is_void
:
error
(
self
.
pos
,
"Cannot take sizeof void"
)
elif
not
arg_type
.
is_complete
():
error
(
self
.
pos
,
"Cannot take sizeof incomplete type '%s'"
%
arg_type
)
self
.
type
=
PyrexTypes
.
c_int_type
def
calculate_result_code
(
self
):
if
self
.
arg_type
.
is_extension_type
:
...
...
@@ -3228,8 +3277,15 @@ class SizeofVarNode(SizeofNode):
subexprs
=
[
'operand'
]
def
analyse_types
(
self
,
env
):
self
.
operand
.
analyse_types
(
env
)
self
.
type
=
PyrexTypes
.
c_int_type
# We may actually be looking at a type rather than a variable...
# If we are, traditional analysis would fail...
operand_as_type
=
self
.
operand
.
analyse_as_type
(
env
)
if
operand_as_type
:
self
.
arg_type
=
operand_as_type
self
.
__class__
=
SizeofTypeNode
self
.
check_type
()
else
:
self
.
operand
.
analyse_types
(
env
)
def
calculate_result_code
(
self
):
return
"(sizeof(%s))"
%
self
.
operand
.
result
()
...
...
@@ -3475,22 +3531,27 @@ class FloorDivNode(NumBinopNode):
self
.
operand2
.
result
())
class
ModNode
(
Int
BinopNode
):
class
ModNode
(
Num
BinopNode
):
# '%' operator.
def
is_py_operation
(
self
):
return
(
self
.
operand1
.
type
.
is_string
or
self
.
operand2
.
type
.
is_string
or
Int
BinopNode
.
is_py_operation
(
self
))
or
Num
BinopNode
.
is_py_operation
(
self
))
def
calculate_result_code
(
self
):
if
self
.
operand1
.
type
.
is_float
or
self
.
operand2
.
type
.
is_float
:
return
"fmod(%s, %s)"
%
(
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
else
:
return
"(%s %% %s)"
%
(
self
.
operand1
.
result
(),
self
.
operand2
.
result
())
class
PowNode
(
NumBinopNode
):
# '**' operator.
def
analyse_types
(
self
,
env
):
env
.
pow_function_used
=
1
NumBinopNode
.
analyse_types
(
self
,
env
)
def
compute_c_result_type
(
self
,
type1
,
type2
):
if
self
.
c_types_okay
(
type1
,
type2
):
return
PyrexTypes
.
c_double_type
...
...
Cython/Compiler/Main.py
View file @
fde67796
...
...
@@ -79,7 +79,7 @@ class Context:
from
ParseTreeTransforms
import
WithTransform
,
NormalizeTree
,
PostParse
,
PxdPostParse
from
ParseTreeTransforms
import
AnalyseDeclarationsTransform
,
AnalyseExpressionsTransform
from
ParseTreeTransforms
import
CreateClosureClasses
,
MarkClosureVisitor
,
DecoratorTransform
from
ParseTreeTransforms
import
InterpretCompilerDirectives
from
ParseTreeTransforms
import
InterpretCompilerDirectives
,
TransformBuiltinMethods
from
AutoDocTransforms
import
EmbedSignature
from
Optimize
import
FlattenInListTransform
,
SwitchTransform
,
FinalOptimizePhase
from
Buffer
import
IntroduceBufferAuxiliaryVars
...
...
@@ -97,11 +97,12 @@ class Context:
PostParse
(
self
),
_specific_post_parse
,
InterpretCompilerDirectives
(
self
,
self
.
pragma_overrides
),
EmbedSignature
(
self
),
FlattenInListTransform
(),
WithTransform
(
self
),
DecoratorTransform
(
self
),
AnalyseDeclarationsTransform
(
self
),
EmbedSignature
(
self
),
TransformBuiltinMethods
(
self
),
IntroduceBufferAuxiliaryVars
(
self
),
_check_c_classes
,
AnalyseExpressionsTransform
(
self
),
...
...
Cython/Compiler/Nodes.py
View file @
fde67796
...
...
@@ -411,8 +411,10 @@ class CNameDeclaratorNode(CDeclaratorNode):
error
(
self
.
pos
,
"Missing argument name"
)
elif
base_type
.
is_void
:
error
(
self
.
pos
,
"Use spam() rather than spam(void) to declare a function with no arguments."
)
self
.
name
=
base_type
.
declaration_code
(
""
,
for_display
=
1
,
pyrex
=
1
)
base_type
=
py_object_type
else
:
print
"here"
self
.
name
=
base_type
.
declaration_code
(
""
,
for_display
=
1
,
pyrex
=
1
)
base_type
=
py_object_type
self
.
type
=
base_type
return
self
,
base_type
...
...
@@ -570,7 +572,19 @@ class CArgDeclNode(Node):
def
analyse
(
self
,
env
,
nonempty
=
0
):
#print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
base_type
=
self
.
base_type
.
analyse
(
env
)
# The parser may missinterpret names as types...
# We fix that here.
if
isinstance
(
self
.
declarator
,
CNameDeclaratorNode
)
and
self
.
declarator
.
name
==
''
:
if
nonempty
:
self
.
declarator
.
name
=
self
.
base_type
.
name
self
.
base_type
.
name
=
None
self
.
base_type
.
is_basic_c_type
=
False
could_be_name
=
True
else
:
could_be_name
=
False
base_type
=
self
.
base_type
.
analyse
(
env
,
could_be_name
=
could_be_name
)
if
self
.
base_type
.
arg_name
:
self
.
declarator
.
name
=
self
.
base_type
.
arg_name
return
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
nonempty
)
def
annotate
(
self
,
code
):
...
...
@@ -597,8 +611,9 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
# is_self_arg boolean Is self argument of C method
child_attrs
=
[]
arg_name
=
None
# in case the argument name was interpreted as a type
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
# Return type descriptor.
#print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
type
=
None
...
...
@@ -615,13 +630,22 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
else
:
type
=
py_object_type
else
:
scope
=
env
.
find_imported_module
(
self
.
module_path
,
self
.
pos
)
if
self
.
module_path
:
scope
=
env
.
find_imported_module
(
self
.
module_path
,
self
.
pos
)
else
:
scope
=
env
if
scope
:
if
scope
.
is_c_class_scope
:
scope
=
scope
.
global_scope
()
entry
=
scope
.
find
(
self
.
name
,
self
.
pos
)
entry
=
scope
.
lookup
(
self
.
name
)
if
entry
and
entry
.
is_type
:
type
=
entry
.
type
elif
could_be_name
:
if
self
.
is_self_arg
and
env
.
is_c_class_scope
:
type
=
env
.
parent_type
else
:
type
=
py_object_type
self
.
arg_name
=
self
.
name
else
:
error
(
self
.
pos
,
"'%s' is not a type identifier"
%
self
.
name
)
if
type
:
...
...
@@ -644,7 +668,7 @@ class CBufferAccessTypeNode(CBaseTypeNode):
dtype_node
=
None
def
analyse
(
self
,
env
):
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base_type
=
self
.
base_type_node
.
analyse
(
env
)
if
base_type
.
is_error
:
return
base_type
import
Buffer
...
...
@@ -665,8 +689,8 @@ class CComplexBaseTypeNode(CBaseTypeNode):
child_attrs
=
[
"base_type"
,
"declarator"
]
def
analyse
(
self
,
env
):
base
=
self
.
base_type
.
analyse
(
env
)
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
_
,
type
=
self
.
declarator
.
analyse
(
base
,
env
)
return
type
...
...
@@ -1142,11 +1166,16 @@ class CFuncDefNode(FuncDefNode):
# overridable whether or not this is a cpdef function
child_attrs
=
[
"base_type"
,
"declarator"
,
"body"
,
"py_func"
]
def
unqualified_name
(
self
):
return
self
.
entry
.
name
def
analyse_declarations
(
self
,
env
):
if
'locals'
in
env
.
directives
:
directive_locals
=
env
.
directives
[
'locals'
]
else
:
directive_locals
=
{}
self
.
directive_locals
=
directive_locals
base_type
=
self
.
base_type
.
analyse
(
env
)
# The 2 here is because we need both function and argument names.
name_declarator
,
type
=
self
.
declarator
.
analyse
(
base_type
,
env
,
nonempty
=
2
*
(
self
.
body
is
not
None
))
...
...
@@ -1418,11 +1447,27 @@ class DefNode(FuncDefNode):
entry
=
None
def
analyse_declarations
(
self
,
env
):
if
'locals'
in
env
.
directives
:
directive_locals
=
env
.
directives
[
'locals'
]
else
:
directive_locals
=
{}
self
.
directive_locals
=
directive_locals
for
arg
in
self
.
args
:
base_type
=
arg
.
base_type
.
analyse
(
env
)
name_declarator
,
type
=
\
arg
.
declarator
.
analyse
(
base_type
,
env
)
arg
.
name
=
name_declarator
.
name
if
arg
.
name
in
directive_locals
:
type_node
=
directive_locals
[
arg
.
name
]
other_type
=
type_node
.
analyse_as_type
(
env
)
if
other_type
is
None
:
error
(
type_node
.
pos
,
"Not a type"
)
elif
(
type
is
not
PyrexTypes
.
py_object_type
and
not
type
.
same_as
(
other_type
)):
error
(
arg
.
base_type
.
pos
,
"Signature does not agree with previous declaration"
)
error
(
type_node
.
pos
,
"Previous declaration here"
)
else
:
type
=
other_type
if
name_declarator
.
cname
:
error
(
self
.
pos
,
"Python function argument cannot have C name specification"
)
...
...
Cython/Compiler/Options.py
View file @
fde67796
...
...
@@ -58,13 +58,15 @@ c_line_in_traceback = 1
option_types
=
{
'boundscheck'
:
bool
,
'nonecheck'
:
bool
,
'embedsignature'
:
bool
'embedsignature'
:
bool
,
'locals'
:
dict
,
}
option_defaults
=
{
'boundscheck'
:
True
,
'nonecheck'
:
False
,
'embedsignature'
:
False
,
'locals'
:
{}
}
def
parse_option_value
(
name
,
value
):
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
fde67796
...
...
@@ -282,6 +282,7 @@ class InterpretCompilerDirectives(CythonTransform):
self
.
options
=
options
node
.
directives
=
options
self
.
visitchildren
(
node
)
node
.
cython_module_names
=
self
.
cython_module_names
return
node
# Track cimports of the cython module.
...
...
@@ -308,6 +309,14 @@ class InterpretCompilerDirectives(CythonTransform):
newimp
.
append
((
pos
,
name
,
as_name
,
kind
))
node
.
imported_names
=
newimpo
return
node
def
visit_SingleAssignmentNode
(
self
,
node
):
if
(
isinstance
(
node
.
rhs
,
ImportNode
)
and
node
.
rhs
.
module_name
.
value
==
u'cython'
):
self
.
cython_module_names
.
add
(
node
.
lhs
.
name
)
else
:
self
.
visitchildren
(
node
)
return
node
def
visit_Node
(
self
,
node
):
self
.
visitchildren
(
node
)
...
...
@@ -318,7 +327,7 @@ class InterpretCompilerDirectives(CythonTransform):
# decorator), returns (optionname, value).
# Otherwise, returns None
optname
=
None
if
isinstance
(
node
,
Simple
CallNode
):
if
isinstance
(
node
,
CallNode
):
if
(
isinstance
(
node
.
function
,
AttributeNode
)
and
isinstance
(
node
.
function
.
obj
,
NameNode
)
and
node
.
function
.
obj
.
name
in
self
.
cython_module_names
):
...
...
@@ -330,12 +339,25 @@ class InterpretCompilerDirectives(CythonTransform):
if
optname
:
optiontype
=
Options
.
option_types
.
get
(
optname
)
if
optiontype
:
args
=
node
.
args
if
isinstance
(
node
,
SimpleCallNode
):
args
=
node
.
args
kwds
=
None
else
:
if
node
.
starstar_arg
or
not
isinstance
(
node
.
positional_args
,
TupleNode
):
raise
PostParseError
(
dec
.
function
.
pos
,
'Compile-time keyword arguments must be explicit.'
%
optname
)
args
=
node
.
positional_args
.
args
kwds
=
node
.
keyword_args
if
optiontype
is
bool
:
if
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
BoolNode
):
if
kwds
is
not
None
or
len
(
args
)
!=
1
or
not
isinstance
(
args
[
0
],
BoolNode
):
raise
PostParseError
(
dec
.
function
.
pos
,
'The %s option takes one compile-time boolean argument'
%
optname
)
return
(
optname
,
args
[
0
].
value
)
elif
optiontype
is
dict
:
if
len
(
args
)
!=
0
:
raise
PostParseError
(
dec
.
function
.
pos
,
'The %s option takes no prepositional arguments'
%
optname
)
return
optname
,
dict
([(
key
.
value
,
value
)
for
key
,
value
in
kwds
.
key_value_pairs
])
else
:
assert
False
...
...
@@ -367,7 +389,7 @@ class InterpretCompilerDirectives(CythonTransform):
else
:
realdecs
.
append
(
dec
)
node
.
decorators
=
realdecs
if
options
:
optdict
=
{}
options
.
reverse
()
# Decorators coming first take precedence
...
...
@@ -499,12 +521,19 @@ property NAME:
lenv
=
node
.
create_local_scope
(
self
.
env_stack
[
-
1
])
node
.
body
.
analyse_control_flow
(
lenv
)
# this will be totally refactored
node
.
declare_arguments
(
lenv
)
for
var
,
type_node
in
node
.
directive_locals
.
items
():
if
not
lenv
.
lookup_here
(
var
):
# don't redeclare args
type
=
type_node
.
analyse_as_type
(
lenv
)
if
type
:
lenv
.
declare_var
(
var
,
type
,
type_node
.
pos
)
else
:
error
(
type_node
.
pos
,
"Not a type"
)
node
.
body
.
analyse_declarations
(
lenv
)
self
.
env_stack
.
append
(
lenv
)
self
.
visitchildren
(
node
)
self
.
env_stack
.
pop
()
return
node
# Some nodes are no longer needed after declaration
# analysis and can be dropped. The analysis was performed
# on these nodes in a seperate recursive process from the
...
...
@@ -534,6 +563,7 @@ property NAME:
return
property
class
AnalyseExpressionsTransform
(
CythonTransform
):
def
visit_ModuleNode
(
self
,
node
):
node
.
body
.
analyse_expressions
(
node
.
scope
)
self
.
visitchildren
(
node
)
...
...
@@ -591,3 +621,78 @@ class CreateClosureClasses(CythonTransform):
return
node
class
EnvTransform
(
CythonTransform
):
"""
This transformation keeps a stack of the environments.
"""
def
__call__
(
self
,
root
):
self
.
env_stack
=
[
root
.
scope
]
return
super
(
EnvTransform
,
self
).
__call__
(
root
)
def
visit_FuncDefNode
(
self
,
node
):
self
.
env_stack
.
append
(
node
.
local_scope
)
self
.
visitchildren
(
node
)
self
.
env_stack
.
pop
()
return
node
class
TransformBuiltinMethods
(
EnvTransform
):
def
cython_attribute
(
self
,
node
):
if
(
isinstance
(
node
,
AttributeNode
)
and
isinstance
(
node
.
obj
,
NameNode
)
and
node
.
obj
.
name
in
self
.
cython_module_names
):
return
node
.
attribute
def
visit_ModuleNode
(
self
,
node
):
self
.
cython_module_names
=
node
.
cython_module_names
self
.
visitchildren
(
node
)
return
node
def
visit_AttributeNode
(
self
,
node
):
attribute
=
self
.
cython_attribute
(
node
)
if
attribute
:
if
attribute
==
u'compiled'
:
node
=
BoolNode
(
node
.
pos
,
value
=
True
)
else
:
error
(
node
.
function
.
pos
,
u"'%s' not a valid cython attribute"
%
function
)
return
node
def
visit_SimpleCallNode
(
self
,
node
):
# locals
if
isinstance
(
node
.
function
,
ExprNodes
.
NameNode
):
if
node
.
function
.
name
==
'locals'
:
pos
=
node
.
pos
lenv
=
self
.
env_stack
[
-
1
]
items
=
[
ExprNodes
.
DictItemNode
(
pos
,
key
=
ExprNodes
.
IdentifierStringNode
(
pos
,
value
=
var
),
value
=
ExprNodes
.
NameNode
(
pos
,
name
=
var
))
for
var
in
lenv
.
entries
]
return
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
items
)
# cython.foo
function
=
self
.
cython_attribute
(
node
.
function
)
if
function
:
if
function
==
u'cast'
:
if
len
(
node
.
args
)
!=
2
:
error
(
node
.
function
.
pos
,
u"cast takes exactly two arguments"
%
function
)
else
:
type
=
node
.
args
[
0
].
analyse_as_type
(
self
.
env_stack
[
-
1
])
if
type
:
node
=
TypecastNode
(
node
.
function
.
pos
,
type
=
type
,
operand
=
node
.
args
[
1
])
else
:
error
(
node
.
args
[
0
].
pos
,
"Not a type"
)
elif
function
==
u'sizeof'
:
if
len
(
node
.
args
)
!=
1
:
error
(
node
.
function
.
pos
,
u"sizeof takes exactly one argument"
%
function
)
else
:
type
=
node
.
args
[
0
].
analyse_as_type
(
self
.
env_stack
[
-
1
])
if
type
:
node
=
SizeofTypeNode
(
node
.
function
.
pos
,
arg_type
=
type
)
else
:
node
=
SizeofVarNode
(
node
.
function
.
pos
,
operand
=
node
.
args
[
0
])
else
:
error
(
node
.
function
.
pos
,
u"'%s' not a valid cython language construct"
%
function
)
self
.
visitchildren
(
node
)
return
node
Cython/Compiler/Parsing.py
View file @
fde67796
...
...
@@ -250,14 +250,17 @@ def p_sizeof(s):
pos
=
s
.
position
()
s
.
next
()
s
.
expect
(
'('
)
if
looking_at_type
(
s
)
or
looking_at_dotted_name
(
s
):
# Here we decide if we are looking at an expression or type
# If it is actually a type, but parsable as an expression,
# we treat it as an expression here.
if
looking_at_expr
(
s
):
operand
=
p_simple_expr
(
s
)
node
=
ExprNodes
.
SizeofVarNode
(
pos
,
operand
=
operand
)
else
:
base_type
=
p_c_base_type
(
s
)
declarator
=
p_c_declarator
(
s
,
empty
=
1
)
node
=
ExprNodes
.
SizeofTypeNode
(
pos
,
base_type
=
base_type
,
declarator
=
declarator
)
else
:
operand
=
p_simple_expr
(
s
)
node
=
ExprNodes
.
SizeofVarNode
(
pos
,
operand
=
operand
)
s
.
expect
(
')'
)
return
node
...
...
@@ -1028,9 +1031,6 @@ def p_from_import_statement(s, first_statement = 0):
s
.
context
.
future_directives
.
add
(
directive
)
return
Nodes
.
PassStatNode
(
pos
)
elif
kind
==
'cimport'
:
for
(
name_pos
,
name
,
as_name
,
kind
)
in
imported_names
:
local_name
=
as_name
or
name
s
.
add_type_name
(
local_name
)
return
Nodes
.
FromCImportStatNode
(
pos
,
module_name
=
dotted_name
,
imported_names
=
imported_names
)
...
...
@@ -1604,7 +1604,7 @@ def p_c_complex_base_type(s):
base_type
=
base_type
,
declarator
=
declarator
)
def
p_c_simple_base_type
(
s
,
self_flag
,
nonempty
):
#print "p_c_simple_base_type: self_flag =", self_flag
#print "p_c_simple_base_type: self_flag =", self_flag
, nonempty
is_basic
=
0
signed
=
1
longness
=
0
...
...
@@ -1619,12 +1619,19 @@ def p_c_simple_base_type(s, self_flag, nonempty):
s
.
next
()
else
:
name
=
'int'
elif
s
.
looking_at_type_name
():
elif
looking_at_dotted_name
(
s
):
#print "p_c_simple_base_type: looking_at_type_name at", s.position()
name
=
s
.
systring
s
.
next
()
while
s
.
sy
==
'.'
:
module_path
.
append
(
name
)
s
.
next
()
name
=
p_ident
(
s
)
else
:
name
=
s
.
systring
s
.
next
()
if
nonempty
and
s
.
sy
!=
'IDENT'
:
# Make sure this is not a declaration of a variable or
# function with the same name as a type.
# Make sure this is not a declaration of a variable or function.
if
s
.
sy
==
'('
:
s
.
next
()
if
s
.
sy
==
'*'
or
s
.
sy
==
'**'
:
...
...
@@ -1636,18 +1643,7 @@ def p_c_simple_base_type(s, self_flag, nonempty):
elif
s
.
sy
not
in
(
'*'
,
'**'
,
'['
):
s
.
put_back
(
'IDENT'
,
name
)
name
=
None
elif
looking_at_dotted_name
(
s
):
#print "p_c_simple_base_type: looking_at_type_name at", s.position()
name
=
s
.
systring
s
.
next
()
while
s
.
sy
==
'.'
:
module_path
.
append
(
name
)
s
.
next
()
name
=
p_ident
(
s
)
else
:
#print "p_c_simple_base_type: not looking at type at", s.position()
name
=
None
type_node
=
Nodes
.
CSimpleBaseTypeNode
(
pos
,
name
=
name
,
module_path
=
module_path
,
is_basic_c_type
=
is_basic
,
signed
=
signed
,
...
...
@@ -1687,8 +1683,44 @@ def p_buffer_access(s, base_type_node):
return
result
def
looking_at_type
(
s
):
return
looking_at_base_type
(
s
)
or
s
.
looking_at_type_name
()
def
looking_at_name
(
s
):
return
s
.
sy
==
'IDENT'
and
not
s
.
systring
in
calling_convention_words
def
looking_at_expr
(
s
):
if
s
.
systring
in
base_type_start_words
:
return
False
elif
s
.
sy
==
'IDENT'
:
is_type
=
False
name
=
s
.
systring
dotted_path
=
[]
s
.
next
()
while
s
.
sy
==
'.'
:
s
.
next
()
dotted_path
.
append
(
s
.
systring
)
s
.
expect
(
'IDENT'
)
saved
=
s
.
sy
,
s
.
systring
if
s
.
sy
==
'IDENT'
:
is_type
=
True
elif
s
.
sy
==
'*'
or
s
.
sy
==
'**'
:
s
.
next
()
is_type
=
s
.
sy
==
')'
s
.
put_back
(
*
saved
)
elif
s
.
sy
==
'('
:
s
.
next
()
is_type
=
s
.
sy
==
'*'
s
.
put_back
(
*
saved
)
elif
s
.
sy
==
'['
:
s
.
next
()
is_type
=
s
.
sy
==
']'
s
.
put_back
(
*
saved
)
dotted_path
.
reverse
()
for
p
in
dotted_path
:
s
.
put_back
(
'IDENT'
,
p
)
s
.
put_back
(
'.'
,
'.'
)
s
.
put_back
(
'IDENT'
,
name
)
return
not
is_type
else
:
return
True
def
looking_at_base_type
(
s
):
#print "looking_at_base_type?", s.sy, s.systring, s.position()
...
...
@@ -1703,7 +1735,7 @@ def looking_at_dotted_name(s):
return
result
else
:
return
0
basic_c_type_names
=
(
"void"
,
"char"
,
"int"
,
"float"
,
"double"
,
"Py_ssize_t"
,
"bint"
)
sign_and_longness_words
=
(
"short"
,
"long"
,
"signed"
,
"unsigned"
)
...
...
@@ -1744,7 +1776,7 @@ def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0,
pos
=
s
.
position
()
if
s
.
sy
==
'('
:
s
.
next
()
if
s
.
sy
==
')'
or
looking_at_
typ
e
(
s
):
if
s
.
sy
==
')'
or
looking_at_
nam
e
(
s
):
base
=
Nodes
.
CNameDeclaratorNode
(
pos
,
name
=
EncodedString
(
u""
),
cname
=
None
)
result
=
p_c_func_declarator
(
s
,
pos
,
ctx
,
base
,
cmethod_flag
)
else
:
...
...
@@ -1816,8 +1848,6 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
rhs
=
None
if
s
.
sy
==
'IDENT'
:
name
=
EncodedString
(
s
.
systring
)
if
is_type
:
s
.
add_type_name
(
name
)
if
empty
:
error
(
s
.
position
(),
"Declarator should be empty"
)
s
.
next
()
...
...
@@ -2002,7 +2032,6 @@ def p_c_enum_definition(s, pos, ctx):
if
s
.
sy
==
'IDENT'
:
name
=
s
.
systring
s
.
next
()
s
.
add_type_name
(
name
)
cname
=
p_opt_cname
(
s
)
else
:
name
=
None
...
...
@@ -2052,7 +2081,6 @@ def p_c_struct_or_union_definition(s, pos, ctx):
s
.
next
()
name
=
p_ident
(
s
)
cname
=
p_opt_cname
(
s
)
s
.
add_type_name
(
name
)
attributes
=
None
if
s
.
sy
==
':'
:
s
.
next
()
...
...
@@ -2149,6 +2177,8 @@ def p_ctypedef_statement(s, ctx):
return
p_c_struct_or_union_definition
(
s
,
pos
,
ctx
)
else
:
base_type
=
p_c_base_type
(
s
,
nonempty
=
1
)
if
base_type
.
name
is
None
:
s
.
error
(
"Syntax error in ctypedef statement"
)
declarator
=
p_c_declarator
(
s
,
ctx
,
is_type
=
1
,
nonempty
=
1
)
s
.
expect_newline
(
"Syntax error in ctypedef statement"
)
return
Nodes
.
CTypeDefNode
(
...
...
@@ -2244,7 +2274,6 @@ def p_c_class_definition(s, pos, ctx):
as_name
=
p_ident
(
s
)
else
:
as_name
=
class_name
s
.
add_type_name
(
as_name
)
objstruct_name
=
None
typeobj_name
=
None
base_class_module
=
None
...
...
@@ -2345,8 +2374,6 @@ def p_doc_string(s):
return
None
def
p_code
(
s
,
level
=
None
):
s
.
add_type_name
(
"object"
)
s
.
add_type_name
(
"Py_buffer"
)
body
=
p_statement_list
(
s
,
Ctx
(
level
=
level
),
first_statement
=
1
)
if
s
.
sy
!=
'EOF'
:
s
.
error
(
"Syntax error in statement [%s,%s]"
%
(
...
...
@@ -2371,8 +2398,6 @@ def p_compiler_directive_comments(s):
return result
def p_module(s, pxd, full_module_name):
s.add_type_name("
object
")
s.add_type_name("
Py_buffer
")
pos = s.position()
doc = p_doc_string(s)
if pxd:
...
...
Cython/Compiler/PyrexTypes.py
View file @
fde67796
...
...
@@ -280,7 +280,6 @@ class BuiltinObjectType(PyObjectType):
return
"<%s>"
%
self
.
cname
def
assignable_from
(
self
,
src_type
):
if
isinstance
(
src_type
,
BuiltinObjectType
):
return
src_type
.
name
==
self
.
name
else
:
...
...
@@ -473,6 +472,8 @@ class CNumericType(CType):
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
):
base
=
public_decl
(
self
.
sign_and_name
(),
dll_linkage
)
if
for_display
and
self
.
is_longlong
:
base
=
base
.
replace
(
'PY_LONG_LONG'
,
'long long'
)
return
self
.
base_declaration_code
(
base
,
entity_code
)
...
...
@@ -557,7 +558,7 @@ class CULongType(CUIntType):
from_py_function
=
"PyInt_AsUnsignedLongMask"
class
CLongLongType
(
C
U
IntType
):
class
CLongLongType
(
CIntType
):
is_longlong
=
1
to_py_function
=
"PyLong_FromLongLong"
...
...
@@ -1184,6 +1185,9 @@ modifiers_and_name_to_type = {
(
2
,
1
,
"int"
):
c_slong_type
,
(
2
,
2
,
"int"
):
c_slonglong_type
,
(
2
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
(
1
,
0
,
"long"
):
c_long_type
,
(
1
,
0
,
"bint"
):
c_bint_type
,
}
def
widest_numeric_type
(
type1
,
type2
):
...
...
@@ -1220,6 +1224,19 @@ def c_ptr_type(base_type):
return
c_char_ptr_type
else
:
return
CPtrType
(
base_type
)
def
Node_to_type
(
node
,
env
):
from
ExprNodes
import
NameNode
,
AttributeNode
,
StringNode
,
error
if
isinstance
(
node
,
StringNode
):
node
=
NameNode
(
node
.
pos
,
name
=
node
.
value
)
if
isinstance
(
node
,
NameNode
)
and
node
.
name
in
rank_to_type_name
:
return
simple_c_type
(
1
,
0
,
node
.
name
)
elif
isinstance
(
node
,
(
AttributeNode
,
NameNode
)):
node
.
analyze_types
(
env
)
if
not
node
.
entry
.
is_type
:
pass
else
:
error
(
node
.
pos
,
"Bad type"
)
def
public_decl
(
base
,
dll_linkage
):
if
dll_linkage
:
...
...
Cython/Compiler/Scanning.py
View file @
fde67796
...
...
@@ -282,7 +282,6 @@ class StringSourceDescriptor(SourceDescriptor):
class
PyrexScanner
(
Scanner
):
# context Context Compilation context
# type_names set Identifiers to be treated as type names
# included_files [string] Files included with 'include' statement
# compile_time_env dict Environment for conditional compilation
# compile_time_eval boolean In a true conditional compilation context
...
...
@@ -290,18 +289,16 @@ class PyrexScanner(Scanner):
resword_dict
=
build_resword_dict
()
def
__init__
(
self
,
file
,
filename
,
parent_scanner
=
None
,
scope
=
None
,
context
=
None
,
source_encoding
=
None
,
parse_comments
=
True
):
Scanner
.
__init__
(
self
,
get_lexicon
(),
file
,
filename
)
scope
=
None
,
context
=
None
,
source_encoding
=
None
,
parse_comments
=
True
,
initial_pos
=
None
):
Scanner
.
__init__
(
self
,
get_lexicon
(),
file
,
filename
,
initial_pos
)
if
parent_scanner
:
self
.
context
=
parent_scanner
.
context
self
.
type_names
=
parent_scanner
.
type_names
self
.
included_files
=
parent_scanner
.
included_files
self
.
compile_time_env
=
parent_scanner
.
compile_time_env
self
.
compile_time_eval
=
parent_scanner
.
compile_time_eval
self
.
compile_time_expr
=
parent_scanner
.
compile_time_expr
else
:
self
.
context
=
context
self
.
type_names
=
scope
.
type_names
self
.
included_files
=
scope
.
included_files
self
.
compile_time_env
=
initial_compile_time_env
()
self
.
compile_time_eval
=
1
...
...
@@ -431,12 +428,6 @@ class PyrexScanner(Scanner):
# This method should be added to Plex
self
.
queue
.
insert
(
0
,
(
token
,
value
))
def
add_type_name
(
self
,
name
):
self
.
type_names
[
name
]
=
1
def
looking_at_type_name
(
self
):
return
self
.
sy
==
'IDENT'
and
self
.
systring
in
self
.
type_names
def
error
(
self
,
message
,
pos
=
None
,
fatal
=
True
):
if
pos
is
None
:
pos
=
self
.
position
()
...
...
Cython/Compiler/Symtab.py
View file @
fde67796
...
...
@@ -167,7 +167,6 @@ class Scope:
# temp_counter integer Counter for naming temp vars
# cname_to_entry {string : Entry} Temp cname to entry mapping
# int_to_entry {int : Entry} Temp cname to entry mapping
# pow_function_used boolean The C pow() function is used
# return_type PyrexType or None Return type of function owning scope
# is_py_class_scope boolean Is a Python class scope
# is_c_class_scope boolean Is an extension type scope
...
...
@@ -221,7 +220,6 @@ class Scope:
#self.pending_temp_entries = [] # TEMPORARY
self.temp_counter = 1
self.cname_to_entry = {}
self.pow_function_used = 0
self.string_to_entry = {}
self.identifier_to_entry = {}
self.num_to_entry = {}
...
...
@@ -315,6 +313,7 @@ class Scope:
entry.is_type = 1
if defining:
self.type_entries.append(entry)
# here we would set as_variable to an object representing this type
return entry
def declare_typedef(self, name, base_type, pos, cname = None,
...
...
@@ -637,8 +636,6 @@ class Scope:
def generate_library_function_declarations(self, code):
# Generate extern decls for C library funcs used.
#if self.pow_function_used:
# code.putln("
%
s
double
pow
(
double
,
double
);
" % Naming.extern_c_macro)
pass
def defines_any(self, names):
...
...
@@ -722,21 +719,27 @@ class BuiltinScope(Scope):
def builtin_scope(self):
return self
builtin_entries = {
"
type
": ["
((
PyObject
*
)
&
PyType_Type
)
", py_object_type],
"
bool
": ["
((
PyObject
*
)
&
PyBool_Type
)
", py_object_type],
"
int
": ["
((
PyObject
*
)
&
PyInt_Type
)
", py_object_type],
"
long
": ["
((
PyObject
*
)
&
PyLong_Type
)
", py_object_type],
"
float
": ["
((
PyObject
*
)
&
PyFloat_Type
)
", py_object_type],
"
str
": ["
((
PyObject
*
)
&
PyBytes_Type
)
", py_object_type],
"
complex
":["
((
PyObject
*
)
&
PyComplex_Type
)
", py_object_type],
"
bytes
": ["
((
PyObject
*
)
&
PyBytes_Type
)
", py_object_type],
"
str
": ["
((
PyObject
*
)
&
PyString_Type
)
", py_object_type],
"
unicode
":["
((
PyObject
*
)
&
PyUnicode_Type
)
", py_object_type],
"
tuple
": ["
((
PyObject
*
)
&
PyTuple_Type
)
", py_object_type],
"
list
": ["
((
PyObject
*
)
&
PyList_Type
)
", py_object_type],
"
dict
": ["
((
PyObject
*
)
&
PyDict_Type
)
", py_object_type],
"
set
": ["
((
PyObject
*
)
&
PySet_Type
)
", py_object_type],
"
frozenset
": ["
((
PyObject
*
)
&
PyFrozenSet_Type
)
", py_object_type],
"
type
": ["
((
PyObject
*
)
&
PyType_Type
)
", py_object_type],
"
slice
": ["
((
PyObject
*
)
&
PySlice_Type
)
", py_object_type],
"
file
": ["
((
PyObject
*
)
&
PyFile_Type
)
", py_object_type],
...
...
Cython/Compiler/TreeFragment.py
View file @
fde67796
...
...
@@ -29,7 +29,7 @@ class StringParseContext(Main.Context):
raise
AssertionError
(
"Not yet supporting any cimports/includes from string code snippets"
)
return
ModuleScope
(
module_name
,
parent_module
=
None
,
context
=
self
)
def
parse_from_strings
(
name
,
code
,
pxds
=
{},
level
=
None
):
def
parse_from_strings
(
name
,
code
,
pxds
=
{},
level
=
None
,
initial_pos
=
None
):
"""
Utility method to parse a (unicode) string of code. This is mostly
used for internal Cython compiler purposes (creating code snippets
...
...
@@ -47,7 +47,8 @@ def parse_from_strings(name, code, pxds={}, level=None):
encoding
=
"UTF-8"
module_name
=
name
initial_pos
=
(
name
,
1
,
0
)
if
initial_pos
is
None
:
initial_pos
=
(
name
,
1
,
0
)
code_source
=
StringSourceDescriptor
(
name
,
code
)
context
=
StringParseContext
([],
name
)
...
...
@@ -56,7 +57,7 @@ def parse_from_strings(name, code, pxds={}, level=None):
buf
=
StringIO
(
code
.
encode
(
encoding
))
scanner
=
PyrexScanner
(
buf
,
code_source
,
source_encoding
=
encoding
,
scope
=
scope
,
context
=
context
)
scope
=
scope
,
context
=
context
,
initial_pos
=
initial_pos
)
if
level
is
None
:
tree
=
Parsing
.
p_module
(
scanner
,
0
,
module_name
)
else
:
...
...
@@ -181,7 +182,7 @@ def strip_common_indent(lines):
return
lines
class
TreeFragment
(
object
):
def
__init__
(
self
,
code
,
name
=
"(tree fragment)"
,
pxds
=
{},
temps
=
[],
pipeline
=
[],
level
=
None
):
def
__init__
(
self
,
code
,
name
=
"(tree fragment)"
,
pxds
=
{},
temps
=
[],
pipeline
=
[],
level
=
None
,
initial_pos
=
None
):
if
isinstance
(
code
,
unicode
):
def
fmt
(
x
):
return
u"
\
n
"
.
join
(
strip_common_indent
(
x
.
split
(
u"
\
n
"
)))
...
...
@@ -189,8 +190,7 @@ class TreeFragment(object):
fmt_pxds
=
{}
for
key
,
value
in
pxds
.
iteritems
():
fmt_pxds
[
key
]
=
fmt
(
value
)
mod
=
t
=
parse_from_strings
(
name
,
fmt_code
,
fmt_pxds
,
level
=
level
)
mod
=
t
=
parse_from_strings
(
name
,
fmt_code
,
fmt_pxds
,
level
=
level
,
initial_pos
=
initial_pos
)
if
level
is
None
:
t
=
t
.
body
# Make sure a StatListNode is at the top
if
not
isinstance
(
t
,
StatListNode
):
...
...
Cython/Plex/Scanners.py
View file @
fde67796
...
...
@@ -60,7 +60,7 @@ class Scanner:
queue
=
None
# list of tokens to be returned
trace
=
0
def
__init__
(
self
,
lexicon
,
stream
,
name
=
''
):
def
__init__
(
self
,
lexicon
,
stream
,
name
=
''
,
initial_pos
=
None
):
"""
Scanner(lexicon, stream, name = '')
...
...
@@ -84,6 +84,8 @@ class Scanner:
self
.
cur_line_start
=
0
self
.
cur_char
=
BOL
self
.
input_state
=
1
if
initial_pos
is
not
None
:
self
.
cur_line
,
self
.
cur_line_start
=
initial_pos
[
1
],
-
initial_pos
[
2
]
def
read
(
self
):
"""
...
...
Cython/Shadow.py
0 → 100644
View file @
fde67796
compiled
=
False
def
empty_decorator
(
x
):
return
x
def
locals
(
**
arg_types
):
return
empty_decorator
def
cast
(
type
,
arg
):
# can/should we emulate anything here?
return
arg
def
sizeof
(
arg
):
# can/should we emulate anything here?
return
1
py_int
=
int
py_long
=
long
py_float
=
float
# They just have to exist...
int
=
long
=
char
=
bint
=
uint
=
ulong
=
longlong
=
ulonglong
=
Py_ssize_t
=
float
=
double
=
None
Cython/__init__.py
View file @
fde67796
# Void cython.* directives (for case insensitive operating systems).
from
Shadow
import
*
cython.py
View file @
fde67796
...
...
@@ -2,5 +2,11 @@
# Cython -- Main Program, generic
#
from
Cython.Compiler.Main
import
main
main
(
command_line
=
1
)
if
__name__
==
'__main__'
:
from
Cython.Compiler.Main
import
main
main
(
command_line
=
1
)
else
:
# Void cython.* directives.
from
Cython.Shadow
import
*
setup.py
View file @
fde67796
...
...
@@ -100,7 +100,9 @@ setup(
],
# pyximport
py_modules
=
[
"pyximport/pyximport"
,
"pyximport/pyxbuild"
],
py_modules
=
[
"pyximport/__init__"
,
"pyximport/pyximport"
,
"pyximport/pyxbuild"
],
**
setup_args
)
tests/compile/types_and_names.pxd
0 → 100644
View file @
fde67796
cdef
struct
point
:
double
x
double
y
double
z
cdef
foo
(
int
,
int
i
,
list
,
list
L
,
point
,
point
p
,
point
*
ps
)
tests/compile/types_and_names.pyx
0 → 100644
View file @
fde67796
print
sizeof
(
point
*
)
cdef
foo
(
int
i0
,
int
i
,
list
L0
,
list
L
,
point
p0
,
point
p
,
point
*
ps
):
pass
cdef
class
A
:
cdef
list
cdef
list
L
# Possibly empty declarators
cdef
point
(
self
,
int
,
int
i
,
list
,
list
L
,
point
,
point
p
,
point
*
ps
):
pass
cdef
class
B
(
A
):
cdef
point
(
self
,
o
,
int
i
,
oo
,
list
L
,
ooo
,
point
p
,
point
*
ps
):
pass
cdef
point
P
cdef
point
*
Ps
cdef
A
a
foo
(
2
,
3
,
[],
[],
P
,
P
,
&
P
)
a
.
point
(
"something"
,
3
,
"anything"
,
[],
"an object"
,
P
,
&
P
)
tests/errors/e_argdefault.pyx
View file @
fde67796
...
...
@@ -10,7 +10,7 @@ cdef class Grail:
pass
_ERRORS
=
u"""
1:
9
: Non-default argument follows default argument
1:
10
: Non-default argument follows default argument
9:16: This argument cannot have a default value
4:23: Non-default argument following default argument
"""
tests/errors/e_bufaccess2.pyx
View file @
fde67796
...
...
@@ -4,7 +4,5 @@ def f():
cdef
object
[
e_bufaccess_pxd
.
T
]
buf
_ERRORS
=
u"""
3:17: Syntax error in ctypedef statement
4:31: 'T' is not a type identifier
4:31: 'T' is not declared
3:9: 'nothing' is not a type identifier
"""
tests/errors/e_modop.pyx
deleted
100644 → 0
View file @
c84a953c
def
f
():
cdef
float
flt1
,
flt2
,
flt3
flt1
=
flt2
%
flt3
# error
_ERRORS
=
u"""
/Local/Projects/D/Pyrex/Source/Tests/Errors2/e_modop.pyx:3:13: Invalid operand types for '%' (float; float)
"""
tests/errors/invalid_cast.pyx
View file @
fde67796
def
f
():
a
=
<
foao
>
x
a
=
<
foao
>
True
_ERRORS
=
"""
2:
13: Unknown type
2:
9: 'foao' is not a type identifier
"""
\ No newline at end of file
tests/run/embedsignatures.pyx
View file @
fde67796
...
...
@@ -48,7 +48,7 @@ __doc__ = ur"""
'with_doc_2(a, b, c)\n\n Existing string\n '
>>> types.__doc__
'types(Ext a, int b, unsigned short
int
c, float d, e)'
'types(Ext a, int b, unsigned short c, float d, e)'
>>> print (f_c.__doc__)
f_c(char c) -> char
...
...
@@ -61,13 +61,13 @@ __doc__ = ur"""
>>> print (f_s.__doc__)
f_s(short
int s) -> short in
t
f_s(short
s) -> shor
t
>>> print (f_us.__doc__)
f_us(unsigned short
int s) -> unsigned short in
t
f_us(unsigned short
s) -> unsigned shor
t
>>> print (f_ss.__doc__)
f_ss(signed short
int s) -> signed short in
t
f_ss(signed short
s) -> signed shor
t
>>> print (f_i.__doc__)
...
...
@@ -81,23 +81,23 @@ __doc__ = ur"""
>>> print (f_l.__doc__)
f_l(long
int l) -> long int
f_l(long
l) -> long
>>> print (f_ul.__doc__)
f_ul(unsigned long
int l) -> unsigned long int
f_ul(unsigned long
l) -> unsigned long
>>> print (f_sl.__doc__)
f_sl(signed long
int l) -> signed long int
f_sl(signed long
l) -> signed long
>>> print (f_L.__doc__)
f_L(long long
int L) -> long long int
f_L(long long
L) -> long long
>>> print (f_uL.__doc__)
f_uL(unsigned long long
int L) -> unsigned long long int
f_uL(unsigned long long
L) -> unsigned long long
>>> print (f_sL.__doc__)
f_sL(signed long long
int L) -> signed long long int
f_sL(signed long long
L) -> signed long long
>>> print (f_f.__doc__)
...
...
tests/run/fmod.pyx
0 → 100644
View file @
fde67796
__doc__
=
"""
>>> fmod(7, 1.25)
0.75
"""
def
fmod
(
double
a
,
double
b
):
return
a
%
b
tests/run/isinstance.pyx
0 → 100644
View file @
fde67796
__doc__
=
u"""
>>> test_all()
True
"""
cdef
class
A
:
pass
def
test_all
():
# Optimized tests.
assert
isinstance
(
type
(
'a'
,(),{}),
type
)
assert
isinstance
(
bool
(),
bool
)
assert
isinstance
(
int
(),
int
)
assert
isinstance
(
long
(),
long
)
assert
isinstance
(
float
(),
float
)
assert
isinstance
(
complex
(),
complex
)
assert
isinstance
(
bytes
(),
bytes
)
assert
isinstance
(
str
(),
str
)
assert
isinstance
(
unicode
(),
unicode
)
assert
isinstance
(
tuple
(),
tuple
)
assert
isinstance
(
list
(),
list
)
assert
isinstance
(
dict
(),
dict
)
# if py_ver > (2, 3):
# assert isinstance(set(), set)
assert
isinstance
(
slice
(
0
),
slice
)
assert
isinstance
(
A
,
type
)
assert
isinstance
(
A
(),
A
)
assert
not
isinstance
(
"foo"
,
int
)
# Non-optimized
foo
=
A
assert
isinstance
(
A
(),
foo
)
assert
isinstance
(
0
,
(
int
,
long
))
assert
not
isinstance
(
"xyz"
,
(
int
,
long
))
return
True
tests/run/locals.pyx
0 → 100644
View file @
fde67796
__doc__
=
"""
sage: get_locals(1,2,3)
{'args': (2, 3), 'kwds': {}, 'x': 1, 'y': 'hi', 'z': 5}
"""
def
get_locals
(
x
,
*
args
,
**
kwds
):
y
=
"hi"
cdef
int
z
=
5
return
locals
()
tests/run/sizeof.pyx
View file @
fde67796
...
...
@@ -11,4 +11,9 @@ def f():
i
=
sizeof
(
p
)
i
=
sizeof
(
j
+
k
)
i
=
sizeof
(
int
)
i
=
sizeof
(
long
int
)
i
=
sizeof
(
void
*
)
i
=
sizeof
(
Spam
)
i
=
sizeof
(
Spam
*
)
i
=
sizeof
(
Spam
[
5
])
i
=
sizeof
(
Spam
(
*
)())
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