Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cython
Commits
6bb725cb
Commit
6bb725cb
authored
Nov 21, 2010
by
Mark Florisson
Browse files
Options
Browse Files
Download
Plain Diff
branch merge
parents
7ea63e29
17804df1
Changes
36
Hide whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1274 additions
and
426 deletions
+1274
-426
.hgtags
.hgtags
+8
-0
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+45
-11
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+318
-120
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+4
-2
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+80
-24
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+15
-18
Cython/Compiler/Options.py
Cython/Compiler/Options.py
+3
-2
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+30
-16
Cython/Compiler/Parsing.pxd
Cython/Compiler/Parsing.pxd
+126
-117
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+34
-16
Cython/Compiler/Scanning.pxd
Cython/Compiler/Scanning.pxd
+28
-7
Cython/Compiler/Scanning.py
Cython/Compiler/Scanning.py
+2
-2
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+0
-3
Cython/Compiler/Visitor.pxd
Cython/Compiler/Visitor.pxd
+3
-4
Cython/Compiler/Visitor.py
Cython/Compiler/Visitor.py
+36
-45
Cython/Plex/Actions.pxd
Cython/Plex/Actions.pxd
+25
-0
Cython/Plex/Actions.py
Cython/Plex/Actions.py
+5
-8
Cython/Plex/Scanners.pxd
Cython/Plex/Scanners.pxd
+8
-5
Cython/Plex/Scanners.py
Cython/Plex/Scanners.py
+5
-3
runtests.py
runtests.py
+75
-13
setup.py
setup.py
+1
-0
tests/bugs.txt
tests/bugs.txt
+6
-1
tests/compile/assert2.pyx
tests/compile/assert2.pyx
+0
-0
tests/compile/specialfloatvals.pyx
tests/compile/specialfloatvals.pyx
+2
-0
tests/errors/e_badexcvaltype.pyx
tests/errors/e_badexcvaltype.pyx
+1
-0
tests/errors/e_int_literals_py2.py
tests/errors/e_int_literals_py2.py
+15
-0
tests/errors/e_int_literals_py3.py
tests/errors/e_int_literals_py3.py
+17
-0
tests/run/closure_class_T596.pyx
tests/run/closure_class_T596.pyx
+58
-0
tests/run/closure_name_mangling_T537.pyx
tests/run/closure_name_mangling_T537.pyx
+23
-0
tests/run/cython3.pyx
tests/run/cython3.pyx
+26
-0
tests/run/exceptionpropagation.pyx
tests/run/exceptionpropagation.pyx
+14
-0
tests/run/inplace.pyx
tests/run/inplace.pyx
+10
-0
tests/run/listcomp.pyx
tests/run/listcomp.pyx
+13
-0
tests/run/metaclass.pyx
tests/run/metaclass.pyx
+97
-9
tests/run/py_unicode_type.pyx
tests/run/py_unicode_type.pyx
+33
-0
tests/run/tuple_constants.pyx
tests/run/tuple_constants.pyx
+108
-0
No files found.
.hgtags
View file @
6bb725cb
...
...
@@ -24,3 +24,11 @@ e90c522631ae06f2170a751fb256cdea0e50fb21 0.12.1
5ac2eaefcdc9c3a7a9c29a0bb8c3e4c6c016c64c 0.13.beta0
14957f635a379c97d9966097276313e43491ed96 0.13.beta1
32c957267b3ba3140fba4d1947fa98484d5e956b 0.13
ef9d2c680684d0df7d81f529cda29e9e1741f575 0.10.1
16a746d969e2654112fc0dc081690b891c496977 0.9.8
16a746d969e2654112fc0dc081690b891c496977 Version-0.9.8
0000000000000000000000000000000000000000 Version-0.9.8
ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1
0000000000000000000000000000000000000000 cython-0.10.1
59c67af0674bd93c5fd8958e08c76a9dab9aae37 sage-cythonizes
0000000000000000000000000000000000000000 sage-cythonizes
Cython/Compiler/Code.py
View file @
6bb725cb
...
...
@@ -421,6 +421,7 @@ class GlobalState(object):
'all_the_rest',
'pystring_table',
'cached_builtins',
'cached_constants',
'init_globals',
'init_module',
'cleanup_globals',
...
...
@@ -462,7 +463,12 @@ class GlobalState(object):
w.enter_cfunc_scope()
w.putln("
static
int
__Pyx_InitCachedBuiltins
(
void
)
{
")
w = self.parts['cached_constants']
w.enter_cfunc_scope()
w.putln("")
w.putln("
static
int
__Pyx_InitCachedConstants
(
void
)
{
")
w.put_setup_refcount_context("
__Pyx_InitCachedConstants
")
w = self.parts['init_globals']
w.enter_cfunc_scope()
w.putln("")
...
...
@@ -509,15 +515,27 @@ class GlobalState(object):
if Options.cache_builtins:
w = self.parts['cached_builtins']
w.putln("
return
0
;
")
w.put_label(w.error_label)
w.putln("
return
-
1
;
")
if w.label_used(w.error_label):
w.put_label(w.error_label)
w.putln("
return
-
1
;
")
w.putln("
}
")
w.exit_cfunc_scope()
w = self.parts['cached_constants']
w.put_finish_refcount_context()
w.putln("
return
0
;
")
if w.label_used(w.error_label):
w.put_label(w.error_label)
w.put_finish_refcount_context()
w.putln("
return
-
1
;
")
w.putln("
}
")
w.exit_cfunc_scope()
w = self.parts['init_globals']
w.putln("
return
0
;
")
w.put_label(w.error_label)
w.putln("
return
-
1
;
")
if w.label_used(w.error_label):
w.put_label(w.error_label)
w.putln("
return
-
1
;
")
w.putln("
}
")
w.exit_cfunc_scope()
...
...
@@ -536,6 +554,9 @@ class GlobalState(object):
# constant handling at code generation time
def get_cached_constants_writer(self):
return self.parts['cached_constants']
def get_int_const(self, str_value, longness=False):
longness = bool(longness)
try:
...
...
@@ -544,9 +565,14 @@ class GlobalState(object):
c = self.new_int_const(str_value, longness)
return c
def get_py_const(self, type):
def get_py_const(self, type
, prefix='', cleanup_level=None
):
# create a new Python object constant
return self.new_py_const(type)
const = self.new_py_const(type, prefix)
if cleanup_level is not None
\
and cleanup_level <= Options.generate_cleanup_code:
cleanup_writer = self.parts['cleanup_globals']
cleanup_writer.put_xdecref_clear(const.cname, type, nanny=False)
return const
def get_string_const(self, text):
# return a C string constant, creating a new one if necessary
...
...
@@ -581,8 +607,8 @@ class GlobalState(object):
self.int_const_index[(value, longness)] = c
return c
def new_py_const(self, type):
cname = self.new_const_cname()
def new_py_const(self, type
, prefix=''
):
cname = self.new_const_cname(
prefix
)
c = PyObjectConst(cname, type)
self.py_constants.append(c)
return c
...
...
@@ -946,6 +972,9 @@ class CCodeWriter(object):
def get_py_num(self, str_value, longness):
return self.globalstate.get_int_const(str_value, longness).cname
def get_py_const(self, type, prefix='', cleanup_level=None):
return self.globalstate.get_py_const(type, prefix, cleanup_level).cname
def get_string_const(self, text):
return self.globalstate.get_string_const(text).cname
...
...
@@ -961,6 +990,9 @@ class CCodeWriter(object):
def intern_identifier(self, text):
return self.get_py_string_const(text, identifier=True)
def get_cached_constants_writer(self):
return self.globalstate.get_cached_constants_writer()
# code generation
def putln(self, code = "", safe=False):
...
...
@@ -1247,11 +1279,13 @@ class CCodeWriter(object):
def
put_pymethoddef
(
self
,
entry
,
term
,
allow_skip
=
True
):
if
entry
.
is_special
or
entry
.
name
==
'__getattribute__'
:
if
entry
.
name
not
in
[
'__cinit__'
,
'__dealloc__'
,
'__richcmp__'
,
'__next__'
,
'__getreadbuffer__'
,
'__getwritebuffer__'
,
'__getsegcount__'
,
'__getcharbuffer__'
,
'__getbuffer__'
,
'__releasebuffer__'
,
'__getattr__'
]:
if
entry
.
name
not
in
[
'__cinit__'
,
'__dealloc__'
,
'__richcmp__'
,
'__next__'
,
'__getreadbuffer__'
,
'__getwritebuffer__'
,
'__getsegcount__'
,
'__getcharbuffer__'
,
'__getbuffer__'
,
'__releasebuffer__'
]:
if
entry
.
name
==
'__getattr__'
and
not
self
.
globalstate
.
directives
[
'fast_getattr'
]:
pass
# Python's typeobject.c will automatically fill in our slot
# in add_operators() (called by PyType_Ready) with a value
# that's better than ours.
if
allow_skip
:
el
if
allow_skip
:
return
from
TypeSlots
import
method_coexist
if
entry
.
doc
:
...
...
Cython/Compiler/ExprNodes.py
View file @
6bb725cb
...
...
@@ -800,9 +800,11 @@ class IntNode(ConstNode):
# unsigned "" or "U"
# longness "" or "L" or "LL"
# is_c_literal True/False/None creator considers this a C integer literal
unsigned
=
""
longness
=
""
is_c_literal
=
None
# unknown
def
__init__
(
self
,
pos
,
**
kwds
):
ExprNode
.
__init__
(
self
,
pos
,
**
kwds
)
...
...
@@ -815,7 +817,10 @@ class IntNode(ConstNode):
self
.
calculate_constant_result
()
except
ValueError
:
pass
if
self
.
constant_result
in
(
constant_value_not_set
,
not_a_constant
)
or
\
# we ignore 'is_c_literal = True' and instead map signed 32bit
# integers as C long values
if
self
.
is_c_literal
or
\
self
.
constant_result
in
(
constant_value_not_set
,
not_a_constant
)
or
\
self
.
unsigned
or
self
.
longness
==
'LL'
:
# clearly a C literal
rank
=
(
self
.
longness
==
'LL'
)
and
2
or
1
...
...
@@ -844,17 +849,18 @@ class IntNode(ConstNode):
else
:
return
FloatNode
(
self
.
pos
,
value
=
self
.
value
,
type
=
dst_type
,
constant_result
=
not_a_constant
)
node
=
IntNode
(
self
.
pos
,
value
=
self
.
value
,
constant_result
=
self
.
constant_result
,
type
=
dst_type
,
unsigned
=
self
.
unsigned
,
longness
=
self
.
longness
)
if
dst_type
.
is_numeric
and
not
dst_type
.
is_complex
:
node
=
IntNode
(
self
.
pos
,
value
=
self
.
value
,
constant_result
=
self
.
constant_result
,
type
=
dst_type
,
unsigned
=
self
.
unsigned
,
longness
=
self
.
longness
)
type
=
dst_type
,
is_c_literal
=
True
,
unsigned
=
self
.
unsigned
,
longness
=
self
.
longness
)
return
node
elif
dst_type
.
is_pyobject
:
node
=
IntNode
(
self
.
pos
,
value
=
self
.
value
,
constant_result
=
self
.
constant_result
,
type
=
PyrexTypes
.
py_object_type
,
unsigned
=
self
.
unsigned
,
longness
=
self
.
longness
)
type
=
PyrexTypes
.
py_object_type
,
is_c_literal
=
False
,
unsigned
=
self
.
unsigned
,
longness
=
self
.
longness
)
else
:
# not setting the type here!
# FIXME: not setting the type here to keep it working with
# complex numbers. Should they be special cased?
node
=
IntNode
(
self
.
pos
,
value
=
self
.
value
,
constant_result
=
self
.
constant_result
,
unsigned
=
self
.
unsigned
,
longness
=
self
.
longness
)
# We still need to perform normal coerce_to processing on the
...
...
@@ -1495,7 +1501,6 @@ class NameNode(AtomicExprNode):
namespace
=
Naming
.
builtins_cname
else
:
# entry.is_pyglobal
namespace
=
entry
.
scope
.
namespace_cname
code
.
globalstate
.
use_utility_code
(
getitem_dict_utility_code
)
code
.
putln
(
'%s = PyObject_GetItem(%s, %s); %s'
%
(
self
.
result
(),
...
...
@@ -3927,10 +3932,16 @@ class TupleNode(SequenceNode):
self
.
is_literal
=
1
else
:
SequenceNode
.
analyse_types
(
self
,
env
,
skip_children
)
for
child
in
self
.
args
:
if
not
child
.
is_literal
:
break
else
:
self
.
is_temp
=
0
self
.
is_literal
=
1
def
calculate_result_code
(
self
):
if
len
(
self
.
args
)
>
0
:
error
(
self
.
pos
,
"Positive length tuples must be constructed."
)
return
self
.
result_code
else
:
return
Naming
.
empty_tuple
...
...
@@ -3949,6 +3960,13 @@ class TupleNode(SequenceNode):
if
len
(
self
.
args
)
==
0
:
# result_code is Naming.empty_tuple
return
if
self
.
is_literal
:
# non-empty cached tuple => result is global constant,
# creation code goes into separate code writer
self
.
result_code
=
code
.
get_py_const
(
py_object_type
,
'tuple_'
,
cleanup_level
=
2
)
code
=
code
.
get_cached_constants_writer
()
code
.
mark_pos
(
self
.
pos
)
code
.
putln
(
"%s = PyTuple_New(%s); %s"
%
(
self
.
result
(),
...
...
@@ -3965,6 +3983,8 @@ class TupleNode(SequenceNode):
i
,
arg
.
py_result
()))
code
.
put_giveref
(
arg
.
py_result
())
if
self
.
is_literal
:
code
.
put_giveref
(
self
.
py_result
())
def
generate_subexpr_disposal_code
(
self
,
code
):
# We call generate_post_assignment_code here instead
...
...
@@ -4135,10 +4155,7 @@ class ComprehensionNode(ScopedExprNode):
def
analyse_declarations
(
self
,
env
):
self
.
append
.
target
=
self
# this is used in the PyList_Append of the inner loop
self
.
init_scope
(
env
)
if
self
.
expr_scope
is
not
None
:
self
.
loop
.
analyse_declarations
(
self
.
expr_scope
)
else
:
self
.
loop
.
analyse_declarations
(
env
)
self
.
loop
.
analyse_declarations
(
self
.
expr_scope
or
env
)
def
init_scope
(
self
,
outer_scope
,
expr_scope
=
None
):
if
expr_scope
is
not
None
:
...
...
@@ -4523,23 +4540,14 @@ class ClassNode(ExprNode, ModuleNameMixin):
# dict ExprNode Class dict (not owned by this node)
# doc ExprNode or None Doc string
# module_name EncodedString Name of defining module
# keyword_args ExprNode or None Py3 Dict of keyword arguments, passed to __new__
# starstar_arg ExprNode or None Py3 Dict of extra keyword args, same here
subexprs
=
[
'bases'
,
'
keyword_args'
,
'starstar_arg'
,
'
doc'
]
subexprs
=
[
'bases'
,
'doc'
]
def
analyse_types
(
self
,
env
):
self
.
bases
.
analyse_types
(
env
)
if
self
.
doc
:
self
.
doc
.
analyse_types
(
env
)
self
.
doc
=
self
.
doc
.
coerce_to_pyobject
(
env
)
if
self
.
keyword_args
:
self
.
keyword_args
.
analyse_types
(
env
)
if
self
.
starstar_arg
:
self
.
starstar_arg
.
analyse_types
(
env
)
# make sure we have a Python object as **kwargs mapping
self
.
starstar_arg
=
\
self
.
starstar_arg
.
coerce_to_pyobject
(
env
)
self
.
type
=
py_object_type
self
.
is_temp
=
1
env
.
use_utility_code
(
create_class_utility_code
);
...
...
@@ -4553,18 +4561,6 @@ class ClassNode(ExprNode, ModuleNameMixin):
def
generate_result_code
(
self
,
code
):
cname
=
code
.
intern_identifier
(
self
.
name
)
if
self
.
keyword_args
and
self
.
starstar_arg
:
code
.
put_error_if_neg
(
self
.
pos
,
"PyDict_Update(%s, %s)"
%
(
self
.
keyword_args
.
py_result
(),
self
.
starstar_arg
.
py_result
()))
keyword_code
=
self
.
keyword_args
.
py_result
()
elif
self
.
keyword_args
:
keyword_code
=
self
.
keyword_args
.
py_result
()
elif
self
.
starstar_arg
:
keyword_code
=
self
.
starstar_arg
.
py_result
()
else
:
keyword_code
=
'NULL'
if
self
.
doc
:
code
.
put_error_if_neg
(
self
.
pos
,
...
...
@@ -4573,17 +4569,161 @@ class ClassNode(ExprNode, ModuleNameMixin):
self
.
doc
.
py_result
()))
py_mod_name
=
self
.
get_py_mod_name
(
code
)
code
.
putln
(
'%s = __Pyx_CreateClass(%s, %s, %s, %s
, %s
); %s'
%
(
'%s = __Pyx_CreateClass(%s, %s, %s, %s); %s'
%
(
self
.
result
(),
self
.
bases
.
py_result
(),
self
.
dict
.
py_result
(),
cname
,
py_mod_name
,
keyword_code
,
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
class
Py3ClassNode
(
ExprNode
):
# Helper class used in the implementation of Python3+
# class definitions. Constructs a class object given
# a name, tuple of bases and class dictionary.
#
# name EncodedString Name of the class
# dict ExprNode Class dict (not owned by this node)
# module_name EncodedString Name of defining module
subexprs
=
[]
def
analyse_types
(
self
,
env
):
self
.
type
=
py_object_type
self
.
is_temp
=
1
def
may_be_none
(
self
):
return
True
gil_message
=
"Constructing Python class"
def
generate_result_code
(
self
,
code
):
code
.
globalstate
.
use_utility_code
(
create_py3class_utility_code
)
cname
=
code
.
intern_identifier
(
self
.
name
)
code
.
putln
(
'%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s'
%
(
self
.
result
(),
self
.
metaclass
.
result
(),
cname
,
self
.
bases
.
py_result
(),
self
.
dict
.
py_result
(),
self
.
mkw
.
py_result
(),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
class
KeywordArgsNode
(
ExprNode
):
# Helper class for keyword arguments
#
# keyword_args ExprNode or None Keyword arguments
# starstar_arg ExprNode or None Extra arguments
subexprs
=
[
'keyword_args'
,
'starstar_arg'
]
def
analyse_types
(
self
,
env
):
if
self
.
keyword_args
:
self
.
keyword_args
.
analyse_types
(
env
)
if
self
.
starstar_arg
:
self
.
starstar_arg
.
analyse_types
(
env
)
# make sure we have a Python object as **kwargs mapping
self
.
starstar_arg
=
\
self
.
starstar_arg
.
coerce_to_pyobject
(
env
)
self
.
type
=
py_object_type
self
.
is_temp
=
1
gil_message
=
"Constructing Keyword Args"
def
generate_result_code
(
self
,
code
):
if
self
.
keyword_args
and
self
.
starstar_arg
:
code
.
put_error_if_neg
(
self
.
pos
,
"PyDict_Update(%s, %s)"
%
(
self
.
keyword_args
.
py_result
(),
self
.
starstar_arg
.
py_result
()))
if
self
.
keyword_args
:
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
self
.
keyword_args
.
result
()))
code
.
put_incref
(
self
.
keyword_args
.
result
(),
self
.
keyword_args
.
ctype
())
elif
self
.
starstar_arg
:
code
.
putln
(
"%s = PyDict_Copy(%s); %s"
%
(
self
.
result
(),
self
.
starstar_arg
.
py_result
(),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
else
:
code
.
putln
(
"%s = PyDict_New(); %s"
%
(
self
.
result
(),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
class
PyClassMetaclassNode
(
ExprNode
):
# Helper class holds Python3 metaclass object
#
# bases ExprNode Base class tuple (not owned by this node)
# mkw ExprNode Class keyword arguments (not owned by this node)
subexprs
=
[]
def
analyse_types
(
self
,
env
):
self
.
type
=
py_object_type
self
.
is_temp
=
True
def
may_be_none
(
self
):
return
True
def
generate_result_code
(
self
,
code
):
code
.
putln
(
"%s = __Pyx_Py3MetaclassGet(%s, %s); %s"
%
(
self
.
result
(),
self
.
bases
.
result
(),
self
.
mkw
.
result
(),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
class
PyClassNamespaceNode
(
ExprNode
,
ModuleNameMixin
):
# Helper class holds Python3 namespace object
#
# All this are not owned by this node
# metaclass ExprNode Metaclass object
# bases ExprNode Base class tuple
# mkw ExprNode Class keyword arguments
# doc ExprNode or None Doc string (owned)
subexprs
=
[
'doc'
]
def
analyse_types
(
self
,
env
):
self
.
bases
.
analyse_types
(
env
)
if
self
.
doc
:
self
.
doc
.
analyse_types
(
env
)
self
.
doc
=
self
.
doc
.
coerce_to_pyobject
(
env
)
self
.
type
=
py_object_type
self
.
is_temp
=
1
#TODO(craig,haoyu) This should be moved to a better place
self
.
set_mod_name
(
env
)
def
may_be_none
(
self
):
return
True
def
generate_result_code
(
self
,
code
):
cname
=
code
.
intern_identifier
(
self
.
name
)
py_mod_name
=
self
.
get_py_mod_name
(
code
)
if
self
.
doc
:
doc_code
=
self
.
doc
.
result
()
else
:
doc_code
=
'(PyObject *) NULL'
code
.
putln
(
"%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s"
%
(
self
.
result
(),
self
.
metaclass
.
result
(),
self
.
bases
.
result
(),
cname
,
self
.
mkw
.
result
(),
py_mod_name
,
doc_code
,
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
class
BoundMethodNode
(
ExprNode
):
# Helper class used in the implementation of Python
# class definitions. Constructs an bound method
...
...
@@ -5359,6 +5499,9 @@ class BinopNode(ExprNode):
def
analyse_types
(
self
,
env
):
self
.
operand1
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
self
.
analyse_operation
(
env
)
def
analyse_operation
(
self
,
env
):
if
self
.
is_py_operation
():
self
.
coerce_operands_to_pyobjects
(
env
)
self
.
type
=
self
.
result_type
(
self
.
operand1
.
type
,
...
...
@@ -5653,12 +5796,12 @@ class DivNode(NumBinopNode):
except
Exception
,
e
:
self
.
compile_time_value_error
(
e
)
def
analyse_
types
(
self
,
env
):
def
analyse_
operation
(
self
,
env
):
if
self
.
cdivision
or
env
.
directives
[
'cdivision'
]:
self
.
ctruedivision
=
False
else
:
self
.
ctruedivision
=
self
.
truedivision
NumBinopNode
.
analyse_
types
(
self
,
env
)
NumBinopNode
.
analyse_
operation
(
self
,
env
)
if
self
.
is_cpp_operation
():
self
.
cdivision
=
True
if
not
self
.
type
.
is_pyobject
:
...
...
@@ -7296,120 +7439,176 @@ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
#------------------------------------------------------------------------------------
find_py2_metaclass_utility_code
=
UtilityCode
(
proto
=
'''
static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
'''
,
impl
=
'''
static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
PyObject *metaclass;
/* Default metaclass */
#if PY_MAJOR_VERSION < 3
if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
PyObject *base = PyTuple_GET_ITEM(bases, 0);
metaclass = PyObject_GetAttrString(base, "__class__");
if (!metaclass) {
PyErr_Clear();
metaclass = (PyObject*) Py_TYPE(base);
}
} else {
metaclass = (PyObject *) &PyClass_Type;
}
#else
if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
PyObject *base = PyTuple_GET_ITEM(bases, 0);
metaclass = (PyObject*) Py_TYPE(base);
} else {
metaclass = (PyObject *) &PyType_Type;
}
#endif
Py_INCREF(metaclass);
return metaclass;
}
'''
)
create_class_utility_code
=
UtilityCode
(
proto
=
"""
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
PyObject *modname, PyObject *kwargs); /*proto*/
static int __Pyx_PrepareClass(PyObject *metaclass, PyObject *bases, PyObject *name,
PyObject *mkw, PyObject *dict); /*proto*/
PyObject *modname); /*proto*/
"""
,
impl
=
"""
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
PyObject *modname) {
PyObject *result;
PyObject *metaclass;
if (PyDict_SetItemString(dict, "__module__", modname) < 0)
return NULL;
/* Python2 __metaclass__ */
metaclass = PyDict_GetItemString(dict, "__metaclass__");
if (metaclass) {
Py_INCREF(metaclass);
} else {
metaclass = __Pyx_FindPy2Metaclass(bases);
}
result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
Py_DECREF(metaclass);
return result;
}
"""
,
requires
=
[
find_py2_metaclass_utility_code
])
#------------------------------------------------------------------------------------
create_py3class_utility_code
=
UtilityCode
(
proto
=
"""
static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
"""
,
impl
=
"""
static int __Pyx_PrepareClass(PyObject *metaclass, PyObject *bases, PyObject *name,
PyObject *mkw, PyObject *dict) {
PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
if (metaclass) {
Py_INCREF(metaclass);
if (PyDict_DelItemString(mkw, "metaclass") < 0) {
Py_DECREF(metaclass);
return NULL;
}
return metaclass;
}
return __Pyx_FindPy2Metaclass(bases);
}
PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
PyObject *modname, PyObject *doc) {
PyObject *prep;
PyObject *pargs;
PyObject *ns;
PyObject *str;
prep = PyObject_GetAttrString(metaclass, "__prepare__");
if (
prep == NULL
) {
if (
!prep
) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return
-1
;
return
NULL
;
PyErr_Clear();
return
0
;
return
PyDict_New()
;
}
pargs = PyTuple_New(2);
if (!pargs) {
Py_DECREF(prep);
return
-1
;
return
NULL
;
}
Py_INCREF(name);
Py_INCREF(bases);
PyTuple_SET_ITEM(pargs, 0, name);
PyTuple_SET_ITEM(pargs, 1, bases);
ns = PyEval_CallObjectWithKeywords(prep, pargs, mkw);
Py_DECREF(pargs);
ns = PyObject_Call(prep, pargs, mkw);
Py_DECREF(prep);
Py_DECREF(pargs);
if (ns == NULL)
return -1;
/* XXX: This is hack, merge namespace back to dict,
__prepare__ should be ran before dict initialization */
if (PyDict_Merge(dict, ns, 0)) {
return NULL;
/* Required here to emulate assignment order */
/* XXX: use consts here */
#if PY_MAJOR_VERSION >= 3
str = PyUnicode_FromString("__module__");
#else
str = PyString_FromString("__module__");
#endif
if (!str) {
Py_DECREF(ns);
return
-1
;
return
NULL
;
}
Py_DECREF(ns);
return 0;
}
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
PyObject *modname, PyObject *kwargs) {
PyObject *result = NULL;
PyObject *metaclass = NULL;
PyObject *mkw = NULL;
if (PyDict_SetItemString(dict, "__module__", modname) < 0)
if (PyObject_SetItem(ns, str, modname) < 0) {
Py_DECREF(ns);
Py_DECREF(str);
return NULL;
/* Python3 metaclasses */
if (kwargs) {
mkw = PyDict_Copy(kwargs); /* Don't modify kwargs passed in! */
if (!mkw)
}
Py_DECREF(str);
if (doc) {
#if PY_MAJOR_VERSION >= 3
str = PyUnicode_FromString("__doc__");
#else
str = PyString_FromString("__doc__");
#endif
if (!str) {
Py_DECREF(ns);
return NULL;
metaclass = PyDict_GetItemString(mkw, "metaclass");
if (metaclass) {
Py_INCREF(metaclass);
if (PyDict_DelItemString(mkw, "metaclass") < 0)
goto bad;
if (__Pyx_PrepareClass(metaclass, bases, name, mkw, dict))
goto bad;
}
}
if (!metaclass) {
/* Python2 __metaclass__ */
metaclass = PyDict_GetItemString(dict, "__metaclass__");
if (!metaclass) {
/* Default metaclass */
#if PY_MAJOR_VERSION < 3
if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
PyObject *base = PyTuple_GET_ITEM(bases, 0);
metaclass = PyObject_GetAttrString(base, "__class__");
if (!metaclass) {
PyErr_Clear();
metaclass = (PyObject *)base->ob_type;
}
} else
metaclass = (PyObject *) &PyClass_Type;
#else
if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
PyObject *base = PyTuple_GET_ITEM(bases, 0);
metaclass = (PyObject *)base->ob_type;
} else
metaclass = (PyObject *) &PyType_Type;
#endif
if (PyObject_SetItem(ns, str, doc) < 0) {
Py_DECREF(ns);
Py_DECREF(str);
return NULL;
}
Py_
INCREF(metaclass
);
Py_
DECREF(str
);
}
if (mkw && PyDict_Size(mkw) > 0) {
PyObject *margs = PyTuple_New(3);
if (!margs)
goto bad;
Py_INCREF(name);
Py_INCREF(bases);
Py_INCREF(dict);
PyTuple_SET_ITEM(margs, 0, name);
PyTuple_SET_ITEM(margs, 1, bases);
PyTuple_SET_ITEM(margs, 2, dict);
result = PyEval_CallObjectWithKeywords(metaclass, margs, mkw);
Py_DECREF(margs);
} else {
result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
}
bad:
Py_DECREF(metaclass);
Py_XDECREF(mkw);
return ns;
}
PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
PyObject *result;
PyObject *margs = PyTuple_New(3);
if (!margs)
return NULL;
Py_INCREF(name);
Py_INCREF(bases);
Py_INCREF(dict);
PyTuple_SET_ITEM(margs, 0, name);
PyTuple_SET_ITEM(margs, 1, bases);
PyTuple_SET_ITEM(margs, 2, dict);
result = PyObject_Call(metaclass, margs, mkw);
Py_DECREF(margs);
return result;
}
"""
)
"""
,
requires
=
[
find_py2_metaclass_utility_code
])
#------------------------------------------------------------------------------------
...
...
@@ -7498,7 +7697,6 @@ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
getitem_dict_utility_code
=
UtilityCode
(
proto
=
"""
#if PY_MAJOR_VERSION >= 3
static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
PyObject *value;
...
...
Cython/Compiler/ModuleNode.py
View file @
6bb725cb
...
...
@@ -1768,8 +1768,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
Options
.
cache_builtins
:
code
.
putln
(
"/*--- Builtin init code ---*/"
)
code
.
putln
(
code
.
error_goto_if_neg
(
"__Pyx_InitCachedBuiltins()"
,
self
.
pos
))
code
.
putln
(
code
.
error_goto_if_neg
(
"__Pyx_InitCachedBuiltins()"
,
self
.
pos
))
code
.
putln
(
"/*--- Constants init code ---*/"
)
code
.
putln
(
code
.
error_goto_if_neg
(
"__Pyx_InitCachedConstants()"
,
self
.
pos
))
code
.
putln
(
"/*--- Global init code ---*/"
)
self
.
generate_global_init_code
(
env
,
code
)
...
...
Cython/Compiler/Nodes.py
View file @
6bb725cb
...
...
@@ -592,6 +592,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
"Exception value must be a Python exception or cdef function with no arguments."
)
exc_val
=
self
.
exception_value
else
:
self
.
exception_value
=
self
.
exception_value
.
coerce_to
(
return_type
,
env
)
if
self
.
exception_value
.
analyse_const_expression
(
env
):
exc_val
=
self
.
exception_value
.
get_constant_c_result_code
()
if
exc_val
is
None
:
...
...
@@ -1176,7 +1177,7 @@ class FuncDefNode(StatNode, BlockNode):
def
create_local_scope
(
self
,
env
):
genv
=
env
while
genv
.
is_py_class_scope
or
genv
.
is_c_class_scope
:
genv
=
env
.
outer_scope
genv
=
g
env
.
outer_scope
if
self
.
needs_closure
:
lenv
=
ClosureScope
(
name
=
self
.
entry
.
name
,
outer_scope
=
genv
,
...
...
@@ -1254,11 +1255,15 @@ class FuncDefNode(StatNode, BlockNode):
self
.
generate_function_header
(
code
,
with_pymethdef
=
with_pymethdef
)
# ----- Local variable declarations
# Find function scope
cenv
=
env
while
cenv
.
is_py_class_scope
or
cenv
.
is_c_class_scope
:
cenv
=
cenv
.
outer_scope
if
lenv
.
is_closure_scope
:
code
.
put
(
lenv
.
scope_class
.
type
.
declaration_code
(
Naming
.
cur_scope_cname
))
code
.
putln
(
";"
)
elif
env
.
is_closure_scope
:
code
.
put
(
env
.
scope_class
.
type
.
declaration_code
(
Naming
.
outer_scope_cname
))
elif
c
env
.
is_closure_scope
:
code
.
put
(
c
env
.
scope_class
.
type
.
declaration_code
(
Naming
.
outer_scope_cname
))
code
.
putln
(
";"
)
self
.
generate_argument_declarations
(
lenv
,
code
)
for
entry
in
lenv
.
var_entries
:
...
...
@@ -1309,14 +1314,14 @@ class FuncDefNode(StatNode, BlockNode):
code
.
putln
(
"}"
)
code
.
put_gotref
(
Naming
.
cur_scope_cname
)
# Note that it is unsafe to decref the scope at this point.
if
env
.
is_closure_scope
:
if
c
env
.
is_closure_scope
:
code
.
putln
(
"%s = (%s)%s;"
%
(
outer_scope_cname
,
env
.
scope_class
.
type
.
declaration_code
(
''
),
c
env
.
scope_class
.
type
.
declaration_code
(
''
),
Naming
.
self_cname
))
if
self
.
needs_closure
:
# inner closures own a reference to their outer parent
code
.
put_incref
(
outer_scope_cname
,
env
.
scope_class
.
type
)
code
.
put_incref
(
outer_scope_cname
,
c
env
.
scope_class
.
type
)
code
.
put_giveref
(
outer_scope_cname
)
# ----- Trace function call
if
profile
:
...
...
@@ -2136,7 +2141,7 @@ class DefNode(FuncDefNode):
entry
.
doc_cname
=
\
Naming
.
funcdoc_prefix
+
prefix
+
name
if
entry
.
is_special
:
if
entry
.
name
in
TypeSlots
.
invisible
or
not
entry
.
doc
:
if
entry
.
name
in
TypeSlots
.
invisible
or
not
entry
.
doc
or
(
entry
.
name
in
'__getattr__'
and
env
.
directives
[
'fast_getattr'
])
:
entry
.
wrapperbase_cname
=
None
else
:
entry
.
wrapperbase_cname
=
Naming
.
wrapperbase_prefix
+
prefix
+
name
...
...
@@ -2210,18 +2215,21 @@ class DefNode(FuncDefNode):
def
synthesize_assignment_node
(
self
,
env
):
import
ExprNodes
if
env
.
is_py_class_scope
:
rhs
=
ExprNodes
.
PyCFunctionNode
(
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
)
if
not
self
.
is_staticmethod
and
not
self
.
is_classmethod
:
rhs
.
binding
=
True
genv
=
env
while
genv
.
is_py_class_scope
or
genv
.
is_c_class_scope
:
genv
=
genv
.
outer_scope
elif
env
.
is_closure_scope
:
if
g
env
.
is_closure_scope
:
rhs
=
ExprNodes
.
InnerFunctionNode
(
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
)
else
:
rhs
=
ExprNodes
.
PyCFunctionNode
(
self
.
pos
,
pymethdef_cname
=
self
.
entry
.
pymethdef_cname
,
binding
=
env
.
directives
[
'binding'
])
if
env
.
is_py_class_scope
:
if
not
self
.
is_staticmethod
and
not
self
.
is_classmethod
:
rhs
.
binding
=
True
self
.
assmt
=
SingleAssignmentNode
(
self
.
pos
,
lhs
=
ExprNodes
.
NameNode
(
self
.
pos
,
name
=
self
.
name
),
rhs
=
rhs
)
...
...
@@ -2933,12 +2941,13 @@ class PyClassDefNode(ClassDefNode):
#
# The following subnodes are constructed internally:
#
# dict DictNode Class dictionary
# dict DictNode Class dictionary
or Py3 namespace
# classobj ClassNode Class object
# target NameNode Variable to assign class object to
child_attrs
=
[
"body"
,
"dict"
,
"classobj"
,
"target"
]
child_attrs
=
[
"body"
,
"dict"
,
"
metaclass"
,
"mkw"
,
"bases"
,
"
classobj"
,
"target"
]
decorators
=
None
py3_style_class
=
False
# Python3 style class (bases+kwargs)
def
__init__
(
self
,
pos
,
name
,
bases
,
doc
,
body
,
decorators
=
None
,
keyword_args
=
None
,
starstar_arg
=
None
):
...
...
@@ -2948,22 +2957,55 @@ class PyClassDefNode(ClassDefNode):
self
.
body
=
body
self
.
decorators
=
decorators
import
ExprNodes
self
.
dict
=
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
[])
if
self
.
doc
and
Options
.
docstrings
:
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
# FIXME: correct string node?
doc_node
=
ExprNodes
.
StringNode
(
pos
,
value
=
doc
)
else
:
doc_node
=
None
self
.
classobj
=
ExprNodes
.
ClassNode
(
pos
,
name
=
name
,
bases
=
bases
,
dict
=
self
.
dict
,
doc
=
doc_node
,
keyword_args
=
keyword_args
,
starstar_arg
=
starstar_arg
)
if
keyword_args
or
starstar_arg
:
self
.
py3_style_class
=
True
self
.
bases
=
bases
self
.
metaclass
=
None
if
keyword_args
and
not
starstar_arg
:
for
i
,
item
in
list
(
enumerate
(
keyword_args
.
key_value_pairs
))[::
-
1
]:
if
item
.
key
.
value
==
'metaclass'
:
if
self
.
metaclass
is
not
None
:
error
(
item
.
pos
,
"keyword argument 'metaclass' passed multiple times"
)
# special case: we already know the metaclass,
# so we don't need to do the "build kwargs,
# find metaclass" dance at runtime
self
.
metaclass
=
item
.
value
del
keyword_args
.
key_value_pairs
[
i
]
if
starstar_arg
or
(
keyword_args
and
keyword_args
.
key_value_pairs
):
self
.
mkw
=
ExprNodes
.
KeywordArgsNode
(
pos
,
keyword_args
=
keyword_args
,
starstar_arg
=
starstar_arg
)
else
:
self
.
mkw
=
ExprNodes
.
NullNode
(
pos
)
if
self
.
metaclass
is
None
:
self
.
metaclass
=
ExprNodes
.
PyClassMetaclassNode
(
pos
,
mkw
=
self
.
mkw
,
bases
=
self
.
bases
)
self
.
dict
=
ExprNodes
.
PyClassNamespaceNode
(
pos
,
name
=
name
,
doc
=
doc_node
,
metaclass
=
self
.
metaclass
,
bases
=
self
.
bases
,
mkw
=
self
.
mkw
)
self
.
classobj
=
ExprNodes
.
Py3ClassNode
(
pos
,
name
=
name
,
bases
=
self
.
bases
,
dict
=
self
.
dict
,
doc
=
doc_node
,
metaclass
=
self
.
metaclass
,
mkw
=
self
.
mkw
)
else
:
self
.
dict
=
ExprNodes
.
DictNode
(
pos
,
key_value_pairs
=
[])
self
.
metaclass
=
None
self
.
mkw
=
None
self
.
bases
=
None
self
.
classobj
=
ExprNodes
.
ClassNode
(
pos
,
name
=
name
,
bases
=
bases
,
dict
=
self
.
dict
,
doc
=
doc_node
)
self
.
target
=
ExprNodes
.
NameNode
(
pos
,
name
=
name
)
def
as_cclass
(
self
):
"""
Return this node as if it were declared as an extension class
"""
if
self
.
py3_style_class
:
error
(
self
.
classobj
.
pos
,
"Python3 style class could not be represented as C class"
)
return
bases
=
self
.
classobj
.
bases
.
args
if
len
(
bases
)
==
0
:
base_class_name
=
None
...
...
@@ -3001,8 +3043,8 @@ class PyClassDefNode(ClassDefNode):
def
create_scope
(
self
,
env
):
genv
=
env
while
env
.
is_py_class_scope
or
env
.
is_c_class_scope
:
env
=
env
.
outer_scope
while
genv
.
is_py_class_scope
or
g
env
.
is_c_class_scope
:
genv
=
g
env
.
outer_scope
cenv
=
self
.
scope
=
PyClassScope
(
name
=
self
.
name
,
outer_scope
=
genv
)
return
cenv
...
...
@@ -3014,6 +3056,10 @@ class PyClassDefNode(ClassDefNode):
self
.
body
.
analyse_declarations
(
cenv
)
def
analyse_expressions
(
self
,
env
):
if
self
.
py3_style_class
:
self
.
bases
.
analyse_expressions
(
env
)
self
.
metaclass
.
analyse_expressions
(
env
)
self
.
mkw
.
analyse_expressions
(
env
)
self
.
dict
.
analyse_expressions
(
env
)
self
.
classobj
.
analyse_expressions
(
env
)
genv
=
env
.
global_scope
()
...
...
@@ -3027,6 +3073,10 @@ class PyClassDefNode(ClassDefNode):
def
generate_execution_code
(
self
,
code
):
code
.
pyclass_stack
.
append
(
self
)
cenv
=
self
.
scope
if
self
.
py3_style_class
:
self
.
bases
.
generate_evaluation_code
(
code
)
self
.
mkw
.
generate_evaluation_code
(
code
)
self
.
metaclass
.
generate_evaluation_code
(
code
)
self
.
dict
.
generate_evaluation_code
(
code
)
cenv
.
namespace_cname
=
cenv
.
class_obj_cname
=
self
.
dict
.
result
()
self
.
body
.
generate_execution_code
(
code
)
...
...
@@ -3035,9 +3085,15 @@ class PyClassDefNode(ClassDefNode):
self
.
target
.
generate_assignment_code
(
self
.
classobj
,
code
)
self
.
dict
.
generate_disposal_code
(
code
)
self
.
dict
.
free_temps
(
code
)
if
self
.
py3_style_class
:
self
.
mkw
.
generate_disposal_code
(
code
)
self
.
mkw
.
free_temps
(
code
)
self
.
metaclass
.
generate_disposal_code
(
code
)
self
.
metaclass
.
free_temps
(
code
)
self
.
bases
.
generate_disposal_code
(
code
)
self
.
bases
.
free_temps
(
code
)
code
.
pyclass_stack
.
pop
()
class
CClassDefNode
(
ClassDefNode
):
# An extension type definition.
#
...
...
@@ -4034,7 +4090,6 @@ class IfClauseNode(Node):
self
.
body
.
analyse_control_flow
(
env
)
def
analyse_declarations
(
self
,
env
):
self
.
condition
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
def
analyse_expressions
(
self
,
env
):
...
...
@@ -4104,6 +4159,7 @@ class SwitchStatNode(StatNode):
child_attrs
=
[
'test'
,
'cases'
,
'else_clause'
]
def
generate_execution_code
(
self
,
code
):
self
.
test
.
generate_evaluation_code
(
code
)
code
.
putln
(
"switch (%s) {"
%
self
.
test
.
result
())
for
case
in
self
.
cases
:
case
.
generate_execution_code
(
code
)
...
...
Cython/Compiler/Optimize.py
View file @
6bb725cb
...
...
@@ -702,28 +702,25 @@ class SwitchTransform(Visitor.VisitorTransform):
break
if
isinstance
(
cond
,
ExprNodes
.
PrimaryCmpNode
):
if
cond
.
cascade
is
None
and
not
cond
.
is_python_comparison
():
if
cond
.
cascade
is
not
None
:
return
self
.
NO_MATCH
elif
cond
.
is_c_string_contains
()
and
\
isinstance
(
cond
.
operand2
,
(
ExprNodes
.
UnicodeNode
,
ExprNodes
.
BytesNode
)):
not_in
=
cond
.
operator
==
'not_in'
if
not_in
and
not
allow_not_in
:
return
self
.
NO_MATCH
if
isinstance
(
cond
.
operand2
,
ExprNodes
.
UnicodeNode
)
and
\
cond
.
operand2
.
contains_surrogates
():
# dealing with surrogates leads to different
# behaviour on wide and narrow Unicode
# platforms => refuse to optimise this case
return
self
.
NO_MATCH
return
not_in
,
cond
.
operand1
,
self
.
extract_in_string_conditions
(
cond
.
operand2
)
elif
not
cond
.
is_python_comparison
():
if
cond
.
operator
==
'=='
:
not_in
=
False
elif
allow_not_in
and
cond
.
operator
==
'!='
:
not_in
=
True
elif
cond
.
is_c_string_contains
()
and
\
isinstance
(
cond
.
operand2
,
(
ExprNodes
.
UnicodeNode
,
ExprNodes
.
BytesNode
)):
not_in
=
cond
.
operator
==
'not_in'
if
not_in
and
not
allow_not_in
:
return
self
.
NO_MATCH
if
isinstance
(
cond
.
operand2
,
ExprNodes
.
UnicodeNode
)
and
\
cond
.
operand2
.
contains_surrogates
():
# dealing with surrogates leads to different
# behaviour on wide and narrow Unicode
# platforms => refuse to optimise this case
return
self
.
NO_MATCH
# this looks somewhat silly, but it does the right
# checks for NameNode and AttributeNode
if
is_common_value
(
cond
.
operand1
,
cond
.
operand1
):
return
not_in
,
cond
.
operand1
,
self
.
extract_in_string_conditions
(
cond
.
operand2
)
else
:
return
self
.
NO_MATCH
else
:
return
self
.
NO_MATCH
# this looks somewhat silly, but it does the right
...
...
Cython/Compiler/Options.py
View file @
6bb725cb
...
...
@@ -71,6 +71,7 @@ directive_defaults = {
'autotestdict.cdef'
:
False
,
'autotestdict.all'
:
False
,
'language_level'
:
2
,
'fast_getattr'
:
False
,
# Undocumented until we come up with a better way to handle this everywhere.
'warn'
:
None
,
'warn.undeclared'
:
False
,
...
...
@@ -101,8 +102,8 @@ directive_scopes = { # defaults to available everywhere
'autotestdict'
:
(
'module'
,),
'autotestdict.all'
:
(
'module'
,),
'autotestdict.cdef'
:
(
'module'
,),
'test_assert_path_exists'
:
(
'function'
,),
'test_fail_if_path_exists'
:
(
'function'
,),
'test_assert_path_exists'
:
(
'function'
,
'class'
,
'cclass'
),
'test_fail_if_path_exists'
:
(
'function'
,
'class'
,
'cclass'
),
}
def
parse_directive_value
(
name
,
value
,
relaxed_bool
=
False
):
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
6bb725cb
...
...
@@ -787,6 +787,13 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
body
=
StatListNode
(
node
.
pos
,
stats
=
[
node
])
return
self
.
visit_with_directives
(
body
,
directives
)
def
visit_PyClassDefNode
(
self
,
node
):
directives
=
self
.
_extract_directives
(
node
,
'class'
)
if
not
directives
:
return
self
.
visit_Node
(
node
)
body
=
StatListNode
(
node
.
pos
,
stats
=
[
node
])
return
self
.
visit_with_directives
(
body
,
directives
)
def
_extract_directives
(
self
,
node
,
scope_name
):
if
not
node
.
decorators
:
return
{}
...
...
@@ -1060,21 +1067,17 @@ property NAME:
self
.
seen_vars_stack
.
pop
()
return
node
def
visit_ComprehensionNode
(
self
,
node
):
self
.
visitchildren
(
node
)
node
.
analyse_declarations
(
self
.
env_stack
[
-
1
])
return
node
def
visit_ScopedExprNode
(
self
,
node
):
node
.
analyse_declarations
(
self
.
env_stack
[
-
1
])
if
self
.
seen_vars_stack
:
# the node may or may not have a local scope
if
node
.
expr_scope
:
self
.
seen_vars_stack
.
append
(
set
(
self
.
seen_vars_stack
[
-
1
]))
self
.
env_stack
.
append
(
node
.
expr_scope
)
self
.
visitchildren
(
node
)
self
.
env_stack
.
pop
()
self
.
seen_vars_stack
.
pop
()
else
:
self
.
seen_vars_stack
.
append
(
set
())
self
.
env_stack
.
append
(
node
.
expr_scope
)
self
.
visitchildren
(
node
)
self
.
env_stack
.
pop
()
self
.
seen_vars_stack
.
pop
()
self
.
visitchildren
(
node
)
return
node
def
visit_TempResultFromStatNode
(
self
,
node
):
...
...
@@ -1187,6 +1190,7 @@ class ExpandInplaceOperators(EnvTransform):
# There is code to handle this case.
return
node
env
=
self
.
current_env
()
def
side_effect_free_reference
(
node
,
setting
=
False
):
if
isinstance
(
node
,
NameNode
):
return
node
,
[]
...
...
@@ -1215,12 +1219,18 @@ class ExpandInplaceOperators(EnvTransform):
operand1
=
dup
,
operand2
=
rhs
,
inplace
=
True
)
node
=
SingleAssignmentNode
(
node
.
pos
,
lhs
=
lhs
,
rhs
=
binop
)
# Manually analyse types for new node.
lhs
.
analyse_target_types
(
env
)
dup
.
analyse_types
(
env
)
binop
.
analyse_operation
(
env
)
node
=
SingleAssignmentNode
(
node
.
pos
,
lhs
=
lhs
,
rhs
=
binop
.
coerce_to
(
lhs
.
type
,
env
))
# Use LetRefNode to avoid side effects.
let_ref_nodes
.
reverse
()
for
t
in
let_ref_nodes
:
node
=
LetNode
(
t
,
node
)
node
.
analyse_expressions
(
self
.
current_env
())
return
node
def
visit_ExprNode
(
self
,
node
):
...
...
@@ -1318,7 +1328,7 @@ class CreateClosureClasses(CythonTransform):
return
node
def
create_class_from_scope
(
self
,
node
,
target_module_scope
):
as_name
=
"%s%s"
%
(
Naming
.
closure_class_prefix
,
node
.
entry
.
cname
)
as_name
=
'%s_%s'
%
(
target_module_scope
.
next_id
(
Naming
.
closure_class_prefix
)
,
node
.
entry
.
cname
)
func_scope
=
node
.
local_scope
entry
=
target_module_scope
.
declare_c_class
(
name
=
as_name
,
...
...
@@ -1327,11 +1337,15 @@ class CreateClosureClasses(CythonTransform):
class_scope
=
entry
.
type
.
scope
class_scope
.
is_internal
=
True
class_scope
.
directives
=
{
'final'
:
True
}
if
node
.
entry
.
scope
.
is_closure_scope
:
cscope
=
node
.
entry
.
scope
while
cscope
.
is_py_class_scope
or
cscope
.
is_c_class_scope
:
cscope
=
cscope
.
outer_scope
if
cscope
.
is_closure_scope
:
class_scope
.
declare_var
(
pos
=
node
.
pos
,
name
=
Naming
.
outer_scope_cname
,
# this could conflict?
cname
=
Naming
.
outer_scope_cname
,
type
=
node
.
entry
.
scope
.
scope_class
.
type
,
type
=
c
scope
.
scope_class
.
type
,
is_cdef
=
True
)
entries
=
func_scope
.
entries
.
items
()
entries
.
sort
()
...
...
Cython/Compiler/Parsing.pxd
View file @
6bb725cb
# We declare all of these here to type the first argument.
cimport
cython
from
Cython.Compiler.Scanning
cimport
PyrexScanner
# entry points
cpdef
p_ident
(
PyrexScanner
s
,
message
=*
)
cpdef
p_ident_list
(
PyrexScanner
s
)
cpdef
p_module
(
PyrexScanner
s
,
pxd
,
full_module_name
)
cpdef
p_code
(
PyrexScanner
s
,
level
=
*
)
# internal parser states
cpdef
p_binop_operator
(
PyrexScanner
s
)
cpdef
p_binop_expr
(
PyrexScanner
s
,
ops
,
p_sub_expr
)
cdef
p_ident
(
PyrexScanner
s
,
message
=*
)
cdef
p_ident_list
(
PyrexScanner
s
)
cdef
p_binop_operator
(
PyrexScanner
s
)
cdef
p_binop_expr
(
PyrexScanner
s
,
ops
,
p_sub_expr
)
cpdef
p_lambdef
(
PyrexScanner
s
,
bint
allow_conditional
=*
)
c
p
def
p_lambdef_nocond
(
PyrexScanner
s
)
c
p
def
p_test
(
PyrexScanner
s
)
c
p
def
p_test_nocond
(
PyrexScanner
s
)
c
p
def
p_or_test
(
PyrexScanner
s
)
c
p
def
p_rassoc_binop_expr
(
PyrexScanner
s
,
ops
,
p_subexpr
)
cdef
p_lambdef_nocond
(
PyrexScanner
s
)
cdef
p_test
(
PyrexScanner
s
)
cdef
p_test_nocond
(
PyrexScanner
s
)
cdef
p_or_test
(
PyrexScanner
s
)
cdef
p_rassoc_binop_expr
(
PyrexScanner
s
,
ops
,
p_subexpr
)
cpdef
p_and_test
(
PyrexScanner
s
)
cpdef
p_not_test
(
PyrexScanner
s
)
c
p
def
p_comparison
(
PyrexScanner
s
)
c
p
def
p_test_or_starred_expr
(
PyrexScanner
s
)
c
p
def
p_starred_expr
(
PyrexScanner
s
)
c
p
def
p_cascaded_cmp
(
PyrexScanner
s
)
c
p
def
p_cmp_op
(
PyrexScanner
s
)
c
p
def
p_bit_expr
(
PyrexScanner
s
)
cdef
p_comparison
(
PyrexScanner
s
)
cdef
p_test_or_starred_expr
(
PyrexScanner
s
)
cdef
p_starred_expr
(
PyrexScanner
s
)
cdef
p_cascaded_cmp
(
PyrexScanner
s
)
cdef
p_cmp_op
(
PyrexScanner
s
)
cdef
p_bit_expr
(
PyrexScanner
s
)
cpdef
p_xor_expr
(
PyrexScanner
s
)
cpdef
p_and_expr
(
PyrexScanner
s
)
cpdef
p_shift_expr
(
PyrexScanner
s
)
cpdef
p_arith_expr
(
PyrexScanner
s
)
cpdef
p_term
(
PyrexScanner
s
)
cpdef
p_factor
(
PyrexScanner
s
)
c
p
def
p_typecast
(
PyrexScanner
s
)
c
p
def
p_sizeof
(
PyrexScanner
s
)
c
p
def
p_yield_expression
(
PyrexScanner
s
)
c
p
def
p_yield_statement
(
PyrexScanner
s
)
c
p
def
p_power
(
PyrexScanner
s
)
c
p
def
p_new_expr
(
PyrexScanner
s
)
c
p
def
p_trailer
(
PyrexScanner
s
,
node1
)
cdef
p_typecast
(
PyrexScanner
s
)
cdef
p_sizeof
(
PyrexScanner
s
)
cdef
p_yield_expression
(
PyrexScanner
s
)
cdef
p_yield_statement
(
PyrexScanner
s
)
cdef
p_power
(
PyrexScanner
s
)
cdef
p_new_expr
(
PyrexScanner
s
)
cdef
p_trailer
(
PyrexScanner
s
,
node1
)
cpdef
p_call_parse_args
(
PyrexScanner
s
,
bint
allow_genexp
=
*
)
c
p
def
p_call_build_packed_args
(
pos
,
positional_args
,
keyword_args
,
star_arg
)
c
p
def
p_call
(
PyrexScanner
s
,
function
)
c
p
def
p_index
(
PyrexScanner
s
,
base
)
c
p
def
p_subscript_list
(
PyrexScanner
s
)
c
p
def
p_subscript
(
PyrexScanner
s
)
c
p
def
p_slice_element
(
PyrexScanner
s
,
follow_set
)
c
p
def
expect_ellipsis
(
PyrexScanner
s
)
c
p
def
make_slice_nodes
(
pos
,
subscripts
)
cdef
p_call_build_packed_args
(
pos
,
positional_args
,
keyword_args
,
star_arg
)
cdef
p_call
(
PyrexScanner
s
,
function
)
cdef
p_index
(
PyrexScanner
s
,
base
)
cdef
p_subscript_list
(
PyrexScanner
s
)
cdef
p_subscript
(
PyrexScanner
s
)
cdef
p_slice_element
(
PyrexScanner
s
,
follow_set
)
cdef
expect_ellipsis
(
PyrexScanner
s
)
cdef
make_slice_nodes
(
pos
,
subscripts
)
cpdef
make_slice_node
(
pos
,
start
,
stop
=
*
,
step
=
*
)
cpdef
p_atom
(
PyrexScanner
s
)
cpdef
p_name
(
PyrexScanner
s
,
name
)
cpdef
p_cat_string_literal
(
PyrexScanner
s
)
cpdef
p_opt_string_literal
(
PyrexScanner
s
,
required_type
=*
)
cpdef
bint
check_for_non_ascii_characters
(
unicode
string
)
cpdef
p_string_literal
(
PyrexScanner
s
,
kind_override
=*
)
cpdef
p_list_maker
(
PyrexScanner
s
)
cpdef
p_comp_iter
(
PyrexScanner
s
,
body
)
cpdef
p_comp_for
(
PyrexScanner
s
,
body
)
cpdef
p_comp_if
(
PyrexScanner
s
,
body
)
cpdef
p_dict_or_set_maker
(
PyrexScanner
s
)
cpdef
p_backquote_expr
(
PyrexScanner
s
)
cdef
p_atom
(
PyrexScanner
s
)
@
cython
.
locals
(
value
=
unicode
)
cdef
p_int_literal
(
PyrexScanner
s
)
cdef
p_name
(
PyrexScanner
s
,
name
)
cdef
p_cat_string_literal
(
PyrexScanner
s
)
cdef
p_opt_string_literal
(
PyrexScanner
s
,
required_type
=*
)
cdef
bint
check_for_non_ascii_characters
(
unicode
string
)
@
cython
.
locals
(
systr
=
unicode
,
is_python3_source
=
bint
)
cdef
p_string_literal
(
PyrexScanner
s
,
kind_override
=*
)
cdef
p_list_maker
(
PyrexScanner
s
)
cdef
p_comp_iter
(
PyrexScanner
s
,
body
)
cdef
p_comp_for
(
PyrexScanner
s
,
body
)
cdef
p_comp_if
(
PyrexScanner
s
,
body
)
cdef
p_dict_or_set_maker
(
PyrexScanner
s
)
cdef
p_backquote_expr
(
PyrexScanner
s
)
cpdef
p_simple_expr_list
(
PyrexScanner
s
,
expr
=*
)
c
pdef
p_test_or_starred_expr_list
(
s
,
expr
=*
)
c
p
def
p_testlist
(
PyrexScanner
s
)
c
p
def
p_testlist_star_expr
(
PyrexScanner
s
)
c
p
def
p_testlist_comp
(
PyrexScanner
s
)
c
p
def
p_genexp
(
PyrexScanner
s
,
expr
)
c
def
p_test_or_starred_expr_list
(
PyrexScanner
s
,
expr
=*
)
cdef
p_testlist
(
PyrexScanner
s
)
cdef
p_testlist_star_expr
(
PyrexScanner
s
)
cdef
p_testlist_comp
(
PyrexScanner
s
)
cdef
p_genexp
(
PyrexScanner
s
,
expr
)
#-------------------------------------------------------
#
...
...
@@ -70,94 +80,93 @@ cpdef p_genexp(PyrexScanner s, expr)
#
#-------------------------------------------------------
c
p
def
p_global_statement
(
PyrexScanner
s
)
c
p
def
p_expression_or_assignment
(
PyrexScanner
s
)
c
p
def
p_print_statement
(
PyrexScanner
s
)
c
p
def
p_exec_statement
(
PyrexScanner
s
)
c
p
def
p_del_statement
(
PyrexScanner
s
)
cdef
p_global_statement
(
PyrexScanner
s
)
cdef
p_expression_or_assignment
(
PyrexScanner
s
)
cdef
p_print_statement
(
PyrexScanner
s
)
cdef
p_exec_statement
(
PyrexScanner
s
)
cdef
p_del_statement
(
PyrexScanner
s
)
cpdef
p_pass_statement
(
PyrexScanner
s
,
bint
with_newline
=
*
)
c
p
def
p_break_statement
(
PyrexScanner
s
)
c
p
def
p_continue_statement
(
PyrexScanner
s
)
c
p
def
p_return_statement
(
PyrexScanner
s
)
c
p
def
p_raise_statement
(
PyrexScanner
s
)
c
p
def
p_import_statement
(
PyrexScanner
s
)
cdef
p_break_statement
(
PyrexScanner
s
)
cdef
p_continue_statement
(
PyrexScanner
s
)
cdef
p_return_statement
(
PyrexScanner
s
)
cdef
p_raise_statement
(
PyrexScanner
s
)
cdef
p_import_statement
(
PyrexScanner
s
)
cpdef
p_from_import_statement
(
PyrexScanner
s
,
bint
first_statement
=
*
)
c
p
def
p_imported_name
(
PyrexScanner
s
,
bint
is_cimport
)
cdef
p_imported_name
(
PyrexScanner
s
,
bint
is_cimport
)
cpdef
p_dotted_name
(
PyrexScanner
s
,
bint
as_allowed
)
c
p
def
p_as_name
(
PyrexScanner
s
)
c
p
def
p_assert_statement
(
PyrexScanner
s
)
c
p
def
p_if_statement
(
PyrexScanner
s
)
c
p
def
p_if_clause
(
PyrexScanner
s
)
c
p
def
p_else_clause
(
PyrexScanner
s
)
c
p
def
p_while_statement
(
PyrexScanner
s
)
c
p
def
p_for_statement
(
PyrexScanner
s
)
cdef
p_as_name
(
PyrexScanner
s
)
cdef
p_assert_statement
(
PyrexScanner
s
)
cdef
p_if_statement
(
PyrexScanner
s
)
cdef
p_if_clause
(
PyrexScanner
s
)
cdef
p_else_clause
(
PyrexScanner
s
)
cdef
p_while_statement
(
PyrexScanner
s
)
cdef
p_for_statement
(
PyrexScanner
s
)
cpdef
p_for_bounds
(
PyrexScanner
s
,
bint
allow_testlist
=
*
)
cpdef
p_for_from_relation
(
PyrexScanner
s
)
cpdef
p_for_from_step
(
PyrexScanner
s
)
cpdef
p_target
(
PyrexScanner
s
,
terminator
)
cpdef
p_for_target
(
PyrexScanner
s
)
cpdef
p_for_iterator
(
PyrexScanner
s
,
bint
allow_testlist
=
*
)
cpdef
p_try_statement
(
PyrexScanner
s
)
cpdef
p_except_clause
(
PyrexScanner
s
)
cpdef
p_include_statement
(
PyrexScanner
s
,
ctx
)
cpdef
p_with_statement
(
PyrexScanner
s
)
cdef
p_for_from_relation
(
PyrexScanner
s
)
cdef
p_for_from_step
(
PyrexScanner
s
)
cdef
p_target
(
PyrexScanner
s
,
terminator
)
cdef
p_for_target
(
PyrexScanner
s
)
cdef
p_for_iterator
(
PyrexScanner
s
,
bint
allow_testlist
=
*
)
cdef
p_try_statement
(
PyrexScanner
s
)
cdef
p_except_clause
(
PyrexScanner
s
)
cdef
p_include_statement
(
PyrexScanner
s
,
ctx
)
cdef
p_with_statement
(
PyrexScanner
s
)
cdef
p_with_items
(
PyrexScanner
s
)
cpdef
p_simple_statement
(
PyrexScanner
s
,
bint
first_statement
=
*
)
cpdef
p_simple_statement_list
(
PyrexScanner
s
,
ctx
,
bint
first_statement
=
*
)
c
p
def
p_compile_time_expr
(
PyrexScanner
s
)
c
p
def
p_DEF_statement
(
PyrexScanner
s
)
c
p
def
p_IF_statement
(
PyrexScanner
s
,
ctx
)
cdef
p_compile_time_expr
(
PyrexScanner
s
)
cdef
p_DEF_statement
(
PyrexScanner
s
)
cdef
p_IF_statement
(
PyrexScanner
s
,
ctx
)
cpdef
p_statement
(
PyrexScanner
s
,
ctx
,
bint
first_statement
=
*
)
cpdef
p_statement_list
(
PyrexScanner
s
,
ctx
,
bint
first_statement
=
*
)
cpdef
p_suite
(
PyrexScanner
s
,
ctx
=
*
,
bint
with_doc
=
*
,
bint
with_pseudo_doc
=
*
)
c
p
def
p_positional_and_keyword_args
(
PyrexScanner
s
,
end_sy_set
,
templates
=
*
)
cdef
p_positional_and_keyword_args
(
PyrexScanner
s
,
end_sy_set
,
templates
=
*
)
cpdef
p_c_base_type
(
PyrexScanner
s
,
bint
self_flag
=
*
,
bint
nonempty
=
*
,
templates
=
*
)
c
p
def
p_calling_convention
(
PyrexScanner
s
)
c
p
def
p_c_complex_base_type
(
PyrexScanner
s
)
cdef
p_calling_convention
(
PyrexScanner
s
)
cdef
p_c_complex_base_type
(
PyrexScanner
s
)
cpdef
p_c_simple_base_type
(
PyrexScanner
s
,
bint
self_flag
,
bint
nonempty
,
templates
=
*
)
c
p
def
p_buffer_or_template
(
PyrexScanner
s
,
base_type_node
,
templates
)
c
p
def
bint
looking_at_name
(
PyrexScanner
s
)
except
-
2
c
p
def
bint
looking_at_expr
(
PyrexScanner
s
)
except
-
2
c
p
def
bint
looking_at_base_type
(
PyrexScanner
s
)
except
-
2
c
p
def
bint
looking_at_dotted_name
(
PyrexScanner
s
)
except
-
2
c
p
def
p_sign_and_longness
(
PyrexScanner
s
)
c
p
def
p_opt_cname
(
PyrexScanner
s
)
cdef
p_buffer_or_template
(
PyrexScanner
s
,
base_type_node
,
templates
)
cdef
bint
looking_at_name
(
PyrexScanner
s
)
except
-
2
cdef
bint
looking_at_expr
(
PyrexScanner
s
)
except
-
2
cdef
bint
looking_at_base_type
(
PyrexScanner
s
)
except
-
2
cdef
bint
looking_at_dotted_name
(
PyrexScanner
s
)
except
-
2
cdef
p_sign_and_longness
(
PyrexScanner
s
)
cdef
p_opt_cname
(
PyrexScanner
s
)
cpdef
p_c_declarator
(
PyrexScanner
s
,
ctx
=
*
,
bint
empty
=
*
,
bint
is_type
=
*
,
bint
cmethod_flag
=
*
,
bint
assignable
=
*
,
bint
nonempty
=
*
,
bint
calling_convention_allowed
=
*
)
c
p
def
p_c_array_declarator
(
PyrexScanner
s
,
base
)
c
p
def
p_c_func_declarator
(
PyrexScanner
s
,
pos
,
ctx
,
base
,
bint
cmethod_flag
)
c
p
def
p_c_simple_declarator
(
PyrexScanner
s
,
ctx
,
bint
empty
,
bint
is_type
,
bint
cmethod_flag
,
cdef
p_c_array_declarator
(
PyrexScanner
s
,
base
)
cdef
p_c_func_declarator
(
PyrexScanner
s
,
pos
,
ctx
,
base
,
bint
cmethod_flag
)
cdef
p_c_simple_declarator
(
PyrexScanner
s
,
ctx
,
bint
empty
,
bint
is_type
,
bint
cmethod_flag
,
bint
assignable
,
bint
nonempty
)
c
p
def
p_nogil
(
PyrexScanner
s
)
c
p
def
p_with_gil
(
PyrexScanner
s
)
c
p
def
p_exception_value_clause
(
PyrexScanner
s
)
cdef
p_nogil
(
PyrexScanner
s
)
cdef
p_with_gil
(
PyrexScanner
s
)
cdef
p_exception_value_clause
(
PyrexScanner
s
)
cpdef
p_c_arg_list
(
PyrexScanner
s
,
ctx
=
*
,
bint
in_pyfunc
=
*
,
bint
cmethod_flag
=
*
,
bint
nonempty_declarators
=
*
,
bint
kw_only
=
*
,
bint
annotated
=
*
)
c
p
def
p_optional_ellipsis
(
PyrexScanner
s
)
cdef
p_optional_ellipsis
(
PyrexScanner
s
)
cpdef
p_c_arg_decl
(
PyrexScanner
s
,
ctx
,
in_pyfunc
,
bint
cmethod_flag
=
*
,
bint
nonempty
=
*
,
bint
kw_only
=
*
,
bint
annotated
=
*
)
c
p
def
p_api
(
PyrexScanner
s
)
c
p
def
p_cdef_statement
(
PyrexScanner
s
,
ctx
)
c
p
def
p_cdef_block
(
PyrexScanner
s
,
ctx
)
c
p
def
p_cdef_extern_block
(
PyrexScanner
s
,
pos
,
ctx
)
c
p
def
p_c_enum_definition
(
PyrexScanner
s
,
pos
,
ctx
)
c
p
def
p_c_enum_line
(
PyrexScanner
s
,
ctx
,
list
items
)
c
p
def
p_c_enum_item
(
PyrexScanner
s
,
ctx
,
list
items
)
c
p
def
p_c_struct_or_union_definition
(
PyrexScanner
s
,
pos
,
ctx
)
c
p
def
p_visibility
(
PyrexScanner
s
,
prev_visibility
)
c
p
def
p_c_modifiers
(
PyrexScanner
s
)
c
p
def
p_c_func_or_var_declaration
(
PyrexScanner
s
,
pos
,
ctx
)
c
p
def
p_ctypedef_statement
(
PyrexScanner
s
,
ctx
)
c
p
def
p_decorators
(
PyrexScanner
s
)
c
p
def
p_def_statement
(
PyrexScanner
s
,
list
decorators
=
*
)
cdef
p_api
(
PyrexScanner
s
)
cdef
p_cdef_statement
(
PyrexScanner
s
,
ctx
)
cdef
p_cdef_block
(
PyrexScanner
s
,
ctx
)
cdef
p_cdef_extern_block
(
PyrexScanner
s
,
pos
,
ctx
)
cdef
p_c_enum_definition
(
PyrexScanner
s
,
pos
,
ctx
)
cdef
p_c_enum_line
(
PyrexScanner
s
,
ctx
,
list
items
)
cdef
p_c_enum_item
(
PyrexScanner
s
,
ctx
,
list
items
)
cdef
p_c_struct_or_union_definition
(
PyrexScanner
s
,
pos
,
ctx
)
cdef
p_visibility
(
PyrexScanner
s
,
prev_visibility
)
cdef
p_c_modifiers
(
PyrexScanner
s
)
cdef
p_c_func_or_var_declaration
(
PyrexScanner
s
,
pos
,
ctx
)
cdef
p_ctypedef_statement
(
PyrexScanner
s
,
ctx
)
cdef
p_decorators
(
PyrexScanner
s
)
cdef
p_def_statement
(
PyrexScanner
s
,
list
decorators
=
*
)
cpdef
p_varargslist
(
PyrexScanner
s
,
terminator
=*
,
bint
annotated
=
*
)
cpdef
p_py_arg_decl
(
PyrexScanner
s
,
bint
annotated
=
*
)
cpdef
p_class_statement
(
PyrexScanner
s
,
decorators
)
cpdef
p_c_class_definition
(
PyrexScanner
s
,
pos
,
ctx
)
cpdef
p_c_class_options
(
PyrexScanner
s
)
cpdef
p_property_decl
(
PyrexScanner
s
)
cpdef
p_doc_string
(
PyrexScanner
s
)
cpdef
p_code
(
PyrexScanner
s
,
level
=
*
)
cpdef
p_compiler_directive_comments
(
PyrexScanner
s
)
cpdef
p_module
(
PyrexScanner
s
,
pxd
,
full_module_name
)
cpdef
p_cpp_class_definition
(
PyrexScanner
s
,
pos
,
ctx
)
cdef
p_class_statement
(
PyrexScanner
s
,
decorators
)
cdef
p_c_class_definition
(
PyrexScanner
s
,
pos
,
ctx
)
cdef
p_c_class_options
(
PyrexScanner
s
)
cdef
p_property_decl
(
PyrexScanner
s
)
cdef
p_doc_string
(
PyrexScanner
s
)
cdef
p_compiler_directive_comments
(
PyrexScanner
s
)
cdef
p_cpp_class_definition
(
PyrexScanner
s
,
pos
,
ctx
)
Cython/Compiler/Parsing.py
View file @
6bb725cb
...
...
@@ -583,20 +583,7 @@ def p_atom(s):
expect_ellipsis
(
s
)
return
ExprNodes
.
EllipsisNode
(
pos
)
elif
sy
==
'INT'
:
value
=
s
.
systring
s
.
next
()
unsigned
=
""
longness
=
""
while
value
[
-
1
]
in
"UuLl"
:
if
value
[
-
1
]
in
"Ll"
:
longness
+=
"L"
else
:
unsigned
+=
"U"
value
=
value
[:
-
1
]
return
ExprNodes
.
IntNode
(
pos
,
value
=
value
,
unsigned
=
unsigned
,
longness
=
longness
)
return
p_int_literal
(
s
)
elif
sy
==
'FLOAT'
:
value
=
s
.
systring
s
.
next
()
...
...
@@ -631,6 +618,37 @@ def p_atom(s):
else
:
s
.
error
(
"Expected an identifier or literal"
)
def
p_int_literal
(
s
):
pos
=
s
.
position
()
value
=
s
.
systring
s
.
next
()
unsigned
=
""
longness
=
""
while
value
[
-
1
]
in
u"UuLl"
:
if
value
[
-
1
]
in
u"Ll"
:
longness
+=
"L"
else
:
unsigned
+=
"U"
value
=
value
[:
-
1
]
# '3L' is ambiguous in Py2 but not in Py3. '3U' and '3LL' are
# illegal in Py2 Python files. All suffixes are illegal in Py3
# Python files.
is_c_literal
=
None
if
unsigned
:
is_c_literal
=
True
elif
longness
:
if
longness
==
'LL'
or
s
.
context
.
language_level
>=
3
:
is_c_literal
=
True
if
s
.
in_python_file
:
if
is_c_literal
:
error
(
pos
,
"illegal integer literal syntax in Python source file"
)
is_c_literal
=
False
return
ExprNodes
.
IntNode
(
pos
,
is_c_literal
=
is_c_literal
,
value
=
value
,
unsigned
=
unsigned
,
longness
=
longness
)
def
p_name
(
s
,
name
):
pos
=
s
.
position
()
if
not
s
.
compile_time_expr
and
name
in
s
.
compile_time_env
:
...
...
@@ -1722,7 +1740,7 @@ def p_statement(s, ctx, first_statement = 0):
s
.
level
=
ctx
.
level
return
p_def_statement
(
s
,
decorators
)
elif
s
.
sy
==
'class'
:
if
ctx
.
level
!=
'module'
:
if
ctx
.
level
not
in
(
'module'
,
'function'
,
'class'
,
'other'
)
:
s
.
error
(
"class definition not allowed here"
)
return
p_class_statement
(
s
,
decorators
)
elif
s
.
sy
==
'include'
:
...
...
@@ -2166,7 +2184,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
cname
=
ctx
.
namespace
+
"::"
+
name
if
name
==
'operator'
and
ctx
.
visibility
==
'extern'
and
nonempty
:
op
=
s
.
sy
if
[
c
in
'+-*/<=>!%&|([^~,'
for
c
in
op
]:
if
[
1
for
c
in
op
if
c
in
'+-*/<=>!%&|([^~,'
]:
s
.
next
()
# Handle diphthong operators.
if
op
==
'('
:
...
...
Cython/Compiler/Scanning.pxd
View file @
6bb725cb
...
...
@@ -2,14 +2,21 @@ import cython
from
Cython.Plex.Scanners
cimport
Scanner
cdef
class
Method
:
cdef
object
name
cdef
object
__name__
cdef
class
CompileTimeScope
:
cdef
public
entries
cdef
public
outer
cdef
public
dict
entries
cdef
public
CompileTimeScope
outer
cdef
declare
(
self
,
name
,
value
)
cdef
lookup_here
(
self
,
name
)
cpdef
lookup
(
self
,
name
)
cdef
class
PyrexScanner
(
Scanner
):
cdef
public
context
cdef
public
list
included_files
cdef
public
compile_time_env
cdef
public
CompileTimeScope
compile_time_env
cdef
public
bint
compile_time_eval
cdef
public
bint
compile_time_expr
cdef
public
bint
parse_comments
...
...
@@ -23,9 +30,23 @@ cdef class PyrexScanner(Scanner):
cdef
public
systring
cdef
long
current_level
(
self
)
cpdef
begin
(
self
,
state
)
cpdef
next
(
self
)
cpdef
bint
expect
(
self
,
what
,
message
=
*
)
except
-
2
#cpdef commentline(self, text)
#cpdef open_bracket_action(self, text)
#cpdef close_bracket_action(self, text)
#cpdef newline_action(self, text)
#cpdef begin_string_action(self, text)
#cpdef end_string_action(self, text)
#cpdef unclosed_string_action(self, text)
@
cython
.
locals
(
current_level
=
cython
.
long
,
new_level
=
cython
.
long
)
cpdef
indentation_action
(
self
,
text
)
#cpdef eof_action(self, text)
cdef
next
(
self
)
cdef
peek
(
self
)
#cpdef put_back(self, sy, systring)
#cdef unread(self, token, value)
cdef
bint
expect
(
self
,
what
,
message
=
*
)
except
-
2
cdef
expect_keyword
(
self
,
what
,
message
=
*
)
cdef
expected
(
self
,
what
,
message
=
*
)
cdef
expect_indent
(
self
)
cdef
expect_dedent
(
self
)
cdef
expect_newline
(
self
,
message
=
*
)
Cython/Compiler/Scanning.py
View file @
6bb725cb
...
...
@@ -358,10 +358,10 @@ class PyrexScanner(Scanner):
self
.
error
(
"Unrecognized character"
)
if
sy
==
IDENT
:
if
systring
in
self
.
keywords
:
if
systring
==
'print'
and
print_function
in
self
.
context
.
future_directives
:
if
systring
==
u
'print'
and
print_function
in
self
.
context
.
future_directives
:
self
.
keywords
.
remove
(
'print'
)
systring
=
EncodedString
(
systring
)
elif
systring
==
'exec'
and
self
.
context
.
language_level
>=
3
:
elif
systring
==
u
'exec'
and
self
.
context
.
language_level
>=
3
:
self
.
keywords
.
remove
(
'exec'
)
systring
=
EncodedString
(
systring
)
else
:
...
...
Cython/Compiler/Symtab.py
View file @
6bb725cb
...
...
@@ -1381,9 +1381,6 @@ class ClassScope(Scope):
self.class_name = name
self.doc = None
def add_string_const(self, value, identifier = False):
return self.outer_scope.add_string_const(value, identifier)
def lookup(self, name):
entry = Scope.lookup(self, name)
if entry:
...
...
Cython/Compiler/Visitor.pxd
View file @
6bb725cb
cimport
cython
cdef
class
BasicVisitor
:
cdef
class
TreeVisitor
:
cdef
public
list
access_path
cdef
dict
dispatch_table
cpdef
visit
(
self
,
obj
)
cdef
_visit
(
self
,
obj
)
cdef
find_handler
(
self
,
obj
)
cdef
class
TreeVisitor
(
BasicVisitor
):
cdef
public
list
access_path
cdef
_visitchild
(
self
,
child
,
parent
,
attrname
,
idx
)
@
cython
.
locals
(
idx
=
int
)
cdef
dict
_visitchildren
(
self
,
parent
,
attrs
)
...
...
Cython/Compiler/Visitor.py
View file @
6bb725cb
...
...
@@ -11,49 +11,7 @@ import Naming
import
Errors
import
DebugFlags
class
BasicVisitor
(
object
):
"""A generic visitor base class which can be used for visiting any kind of object."""
# Note: If needed, this can be replaced with a more efficient metaclass
# approach, resolving the jump table at module load time rather than per visitor
# instance.
def
__init__
(
self
):
self
.
dispatch_table
=
{}
def
visit
(
self
,
obj
):
return
self
.
_visit
(
obj
)
def
_visit
(
self
,
obj
):
try
:
handler_method
=
self
.
dispatch_table
[
type
(
obj
)]
except
KeyError
:
handler_method
=
self
.
find_handler
(
obj
)
self
.
dispatch_table
[
type
(
obj
)]
=
handler_method
return
handler_method
(
obj
)
def
find_handler
(
self
,
obj
):
cls
=
type
(
obj
)
#print "Cache miss for class %s in visitor %s" % (
# cls.__name__, type(self).__name__)
# Must resolve, try entire hierarchy
pattern
=
"visit_%s"
mro
=
inspect
.
getmro
(
cls
)
handler_method
=
None
for
mro_cls
in
mro
:
if
hasattr
(
self
,
pattern
%
mro_cls
.
__name__
):
handler_method
=
getattr
(
self
,
pattern
%
mro_cls
.
__name__
)
break
if
handler_method
is
None
:
print
type
(
self
),
cls
if
hasattr
(
self
,
'access_path'
)
and
self
.
access_path
:
print
self
.
access_path
if
self
.
access_path
:
print
self
.
access_path
[
-
1
][
0
].
pos
print
self
.
access_path
[
-
1
][
0
].
__dict__
raise
RuntimeError
(
"Visitor %r does not accept object: %s"
%
(
self
,
obj
))
#print "Caching " + cls.__name__
return
handler_method
class
TreeVisitor
(
BasicVisitor
):
class
TreeVisitor
(
object
):
"""
Base class for writing visitors for a Cython tree, contains utilities for
recursing such trees using visitors. Each node is
...
...
@@ -96,9 +54,9 @@ class TreeVisitor(BasicVisitor):
out 3
out 0
"""
def
__init__
(
self
):
super
(
TreeVisitor
,
self
).
__init__
()
self
.
dispatch_table
=
{}
self
.
access_path
=
[]
def
dump_node
(
self
,
node
,
indent
=
0
):
...
...
@@ -176,10 +134,43 @@ class TreeVisitor(BasicVisitor):
last_node
.
pos
,
self
.
__class__
.
__name__
,
u'
\
n
'
.
join
(
trace
),
e
,
stacktrace
)
def
find_handler
(
self
,
obj
):
# to resolve, try entire hierarchy
cls
=
type
(
obj
)
pattern
=
"visit_%s"
mro
=
inspect
.
getmro
(
cls
)
handler_method
=
None
for
mro_cls
in
mro
:
handler_method
=
getattr
(
self
,
pattern
%
mro_cls
.
__name__
,
None
)
if
handler_method
is
not
None
:
return
handler_method
print
type
(
self
),
cls
if
self
.
access_path
:
print
self
.
access_path
print
self
.
access_path
[
-
1
][
0
].
pos
print
self
.
access_path
[
-
1
][
0
].
__dict__
raise
RuntimeError
(
"Visitor %r does not accept object: %s"
%
(
self
,
obj
))
def
visit
(
self
,
obj
):
return
self
.
_visit
(
obj
)
def
_visit
(
self
,
obj
):
try
:
handler_method
=
self
.
dispatch_table
[
type
(
obj
)]
except
KeyError
:
handler_method
=
self
.
find_handler
(
obj
)
self
.
dispatch_table
[
type
(
obj
)]
=
handler_method
return
handler_method
(
obj
)
def
_visitchild
(
self
,
child
,
parent
,
attrname
,
idx
):
self
.
access_path
.
append
((
parent
,
attrname
,
idx
))
try
:
result
=
self
.
_visit
(
child
)
try
:
handler_method
=
self
.
dispatch_table
[
type
(
child
)]
except
KeyError
:
handler_method
=
self
.
find_handler
(
child
)
self
.
dispatch_table
[
type
(
child
)]
=
handler_method
result
=
handler_method
(
child
)
except
Errors
.
CompileError
:
raise
except
Exception
,
e
:
...
...
Cython/Plex/Actions.pxd
0 → 100644
View file @
6bb725cb
cdef
class
Action
:
cdef
perform
(
self
,
token_stream
,
text
)
cpdef
same_as
(
self
,
other
)
cdef
class
Return
(
Action
):
cdef
object
value
cdef
perform
(
self
,
token_stream
,
text
)
cpdef
same_as
(
self
,
other
)
cdef
class
Call
(
Action
):
cdef
object
function
cdef
perform
(
self
,
token_stream
,
text
)
cpdef
same_as
(
self
,
other
)
cdef
class
Begin
(
Action
):
cdef
object
state_name
cdef
perform
(
self
,
token_stream
,
text
)
cpdef
same_as
(
self
,
other
)
cdef
class
Ignore
(
Action
):
cdef
perform
(
self
,
token_stream
,
text
)
cdef
class
Text
(
Action
):
cdef
perform
(
self
,
token_stream
,
text
)
Cython/Plex/Actions.py
View file @
6bb725cb
...
...
@@ -8,6 +8,9 @@
class
Action
(
object
):
def
perform
(
self
,
token_stream
,
text
):
pass
# abstract
def
same_as
(
self
,
other
):
return
self
is
other
...
...
@@ -18,8 +21,6 @@ class Return(Action):
be returned as the value of the associated token
"""
value
=
None
def
__init__
(
self
,
value
):
self
.
value
=
value
...
...
@@ -38,8 +39,6 @@ class Call(Action):
Internal Plex action which causes a function to be called.
"""
function
=
None
def
__init__
(
self
,
function
):
self
.
function
=
function
...
...
@@ -60,8 +59,6 @@ class Begin(Action):
for more information.
"""
state_name
=
None
def
__init__
(
self
,
state_name
):
self
.
state_name
=
state_name
...
...
@@ -88,7 +85,7 @@ class Ignore(Action):
return
"IGNORE"
IGNORE
=
Ignore
()
IGNORE
.
__doc__
=
Ignore
.
__doc__
#
IGNORE.__doc__ = Ignore.__doc__
class
Text
(
Action
):
"""
...
...
@@ -104,6 +101,6 @@ class Text(Action):
return
"TEXT"
TEXT
=
Text
()
TEXT
.
__doc__
=
Text
.
__doc__
#
TEXT.__doc__ = Text.__doc__
Cython/Plex/Scanners.pxd
View file @
6bb725cb
import
cython
from
Cython.Plex.Actions
cimport
Action
cdef
class
Scanner
:
cdef
public
lexicon
...
...
@@ -25,10 +27,11 @@ cdef class Scanner:
cdef
public
level
@
cython
.
locals
(
input_state
=
long
)
cpdef
next_char
(
self
)
cpdef
tuple
read
(
self
)
cdef
next_char
(
self
)
@
cython
.
locals
(
action
=
Action
)
cdef
tuple
read
(
self
)
cdef
tuple
scan_a_token
(
self
)
c
p
def
tuple
position
(
self
)
cdef
tuple
position
(
self
)
@
cython
.
locals
(
cur_pos
=
long
,
cur_line
=
long
,
cur_line_start
=
long
,
input_state
=
long
,
next_pos
=
long
,
state
=
dict
,
...
...
@@ -36,5 +39,5 @@ cdef class Scanner:
trace
=
bint
,
discard
=
long
,
data
=
unicode
,
buffer
=
unicode
)
cdef
run_machine_inlined
(
self
)
c
p
def
begin
(
self
,
state
)
c
p
def
produce
(
self
,
value
,
text
=
*
)
cdef
begin
(
self
,
state
)
cdef
produce
(
self
,
value
,
text
=
*
)
Cython/Plex/Scanners.py
View file @
6bb725cb
...
...
@@ -8,11 +8,13 @@
#=======================================================================
import
cython
cython
.
declare
(
BOL
=
object
,
EOL
=
object
,
EOF
=
object
)
cython
.
declare
(
BOL
=
object
,
EOL
=
object
,
EOF
=
object
,
NOT_FOUND
=
object
)
import
Errors
from
Regexps
import
BOL
,
EOL
,
EOF
NOT_FOUND
=
object
()
class
Scanner
(
object
):
"""
A Scanner is used to read tokens from a stream of characters
...
...
@@ -179,8 +181,8 @@ class Scanner(object):
# End inlined self.save_for_backup()
c
=
cur_char
#new_state = state.new_state(c) #@slow
new_state
=
state
.
get
(
c
,
-
1
)
#@fast
if
new_state
==
-
1
:
#@fast
new_state
=
state
.
get
(
c
,
NOT_FOUND
)
#@fast
if
new_state
is
NOT_FOUND
:
#@fast
new_state
=
c
and
state
.
get
(
'else'
)
#@fast
if
new_state
:
if
trace
:
#TRACE#
...
...
runtests.py
View file @
6bb725cb
...
...
@@ -10,6 +10,7 @@ import unittest
import
doctest
import
operator
import
tempfile
import
traceback
try
:
from
StringIO
import
StringIO
except
ImportError
:
...
...
@@ -20,6 +21,11 @@ try:
except
ImportError
:
import
pickle
try
:
import
threading
except
ImportError
:
# No threads, no problems
threading
=
None
WITH_CYTHON
=
True
...
...
@@ -313,11 +319,10 @@ class CythonCompileTestCase(unittest.TestCase):
if
is_related
(
filename
)
and
os
.
path
.
isfile
(
os
.
path
.
join
(
workdir
,
filename
))
]
def
split_source_and_output
(
self
,
test_directory
,
module
,
workdir
):
source_file
=
os
.
path
.
join
(
test_directory
,
module
)
+
'.pyx'
source_and_output
=
codecs
.
open
(
self
.
find_module_source_file
(
source_file
),
'rU'
,
'ISO-8859-1'
)
source_file
=
self
.
find_module_source_file
(
os
.
path
.
join
(
test_directory
,
module
)
+
'.pyx'
)
source_and_output
=
codecs
.
open
(
source_file
,
'rU'
,
'ISO-8859-1'
)
try
:
out
=
codecs
.
open
(
os
.
path
.
join
(
workdir
,
module
+
'.pyx'
),
out
=
codecs
.
open
(
os
.
path
.
join
(
workdir
,
module
+
os
.
path
.
splitext
(
source_file
)[
1
]
),
'w'
,
'ISO-8859-1'
)
for
line
in
source_and_output
:
last_line
=
line
...
...
@@ -434,9 +439,12 @@ class CythonRunTestCase(CythonCompileTestCase):
result
.
startTest
(
self
)
try
:
self
.
setUp
()
self
.
runCompileTest
()
if
not
self
.
cython_only
:
self
.
run_doctests
(
self
.
module
,
result
)
try
:
self
.
runCompileTest
()
if
not
self
.
cython_only
:
self
.
run_doctests
(
self
.
module
,
result
)
finally
:
check_thread_termination
()
except
Exception
:
result
.
addError
(
self
,
sys
.
exc_info
())
result
.
stopTest
(
self
)
...
...
@@ -477,7 +485,6 @@ class CythonRunTestCase(CythonCompileTestCase):
output
=
open
(
result_file
,
'wb'
)
pickle
.
dump
(
partial_result
.
data
(),
output
)
except
:
import
traceback
traceback
.
print_exc
()
finally
:
try
:
output
.
close
()
...
...
@@ -531,6 +538,7 @@ class PureDoctestTestCase(unittest.TestCase):
del
m
if
loaded_module_name
in
sys
.
modules
:
del
sys
.
modules
[
loaded_module_name
]
check_thread_termination
()
except
Exception
:
result
.
addError
(
self
,
sys
.
exc_info
())
result
.
stopTest
(
self
)
...
...
@@ -602,8 +610,11 @@ class CythonUnitTestCase(CythonCompileTestCase):
result
.
startTest
(
self
)
try
:
self
.
setUp
()
self
.
runCompileTest
()
unittest
.
defaultTestLoader
.
loadTestsFromName
(
self
.
module
).
run
(
result
)
try
:
self
.
runCompileTest
()
unittest
.
defaultTestLoader
.
loadTestsFromName
(
self
.
module
).
run
(
result
)
finally
:
check_thread_termination
()
except
Exception
:
result
.
addError
(
self
,
sys
.
exc_info
())
result
.
stopTest
(
self
)
...
...
@@ -842,8 +853,38 @@ def refactor_for_py3(distdir, cy3_dir):
'''
)
sys
.
path
.
insert
(
0
,
cy3_dir
)
class
PendingThreadsError
(
RuntimeError
):
pass
if
__name__
==
'__main__'
:
threads_seen
=
[]
def
check_thread_termination
(
ignore_seen
=
True
):
if
threading
is
None
:
# no threading enabled in CPython
return
current
=
threading
.
currentThread
()
blocking_threads
=
[]
for
t
in
threading
.
enumerate
():
if
not
t
.
isAlive
()
or
t
==
current
:
continue
t
.
join
(
timeout
=
2
)
if
t
.
isAlive
():
if
not
ignore_seen
:
blocking_threads
.
append
(
t
)
continue
for
seen
in
threads_seen
:
if
t
is
seen
:
break
else
:
threads_seen
.
append
(
t
)
blocking_threads
.
append
(
t
)
if
not
blocking_threads
:
return
sys
.
stderr
.
write
(
"warning: left-over threads found after running test:
\
n
"
)
for
t
in
blocking_threads
:
sys
.
stderr
.
write
(
'...%s
\
n
'
%
repr
(
t
))
raise
PendingThreadsError
(
"left-over threads found after running test"
)
def
main
():
from
optparse
import
OptionParser
parser
=
OptionParser
()
parser
.
add_option
(
"--no-cleanup"
,
dest
=
"cleanup_workdir"
,
...
...
@@ -955,6 +996,7 @@ if __name__ == '__main__':
coverage
.
start
()
if
WITH_CYTHON
:
global
CompilationOptions
,
pyrex_default_options
,
cython_compile
from
Cython.Compiler.Main
import
\
CompilationOptions
,
\
default_options
as
pyrex_default_options
,
\
...
...
@@ -1097,7 +1139,27 @@ if __name__ == '__main__':
import
refnanny
sys
.
stderr
.
write
(
"
\
n
"
.
join
([
repr
(
x
)
for
x
in
refnanny
.
reflog
]))
print
(
"ALL DONE"
)
if
options
.
exit_ok
:
sys
.
exit
(
0
)
return_code
=
0
else
:
sys
.
exit
(
not
result
.
wasSuccessful
())
return_code
=
not
result
.
wasSuccessful
()
try
:
check_thread_termination
(
ignore_seen
=
False
)
sys
.
exit
(
return_code
)
except
PendingThreadsError
:
# normal program exit won't kill the threads, do it the hard way here
os
.
_exit
(
return_code
)
if
__name__
==
'__main__'
:
try
:
main
()
except
Exception
:
traceback
.
print_exc
()
try
:
check_thread_termination
(
ignore_seen
=
False
)
except
PendingThreadsError
:
# normal program exit won't kill the threads, do it the hard way here
os
.
_exit
(
1
)
setup.py
View file @
6bb725cb
...
...
@@ -87,6 +87,7 @@ else:
def
compile_cython_modules
(
profile
=
False
):
source_root
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
compiled_modules
=
[
"Cython.Plex.Scanners"
,
"Cython.Plex.Actions"
,
"Cython.Compiler.Scanning"
,
"Cython.Compiler.Parsing"
,
"Cython.Compiler.Visitor"
,
...
...
tests/bugs.txt
View file @
6bb725cb
...
...
@@ -17,11 +17,16 @@ function_as_method_T494
closure_inside_cdef_T554
ipow_crash_T562
pure_mode_cmethod_inheritance_T583
closure_class_T596
# CPython regression tests that don't current work:
pyregr.test_threadsignals
pyregr.test_module
pyregr.test_capi
pyregr.test_socket
pyregr.test_threading
pyregr.test_sys
# CPython regression tests that don't make sense
pyregr.test_gdb
pyregr.test_support
tests/
broken
/assert2.pyx
→
tests/
compile
/assert2.pyx
View file @
6bb725cb
File moved
tests/
broken
/specialfloatvals.pyx
→
tests/
compile
/specialfloatvals.pyx
View file @
6bb725cb
...
...
@@ -7,3 +7,5 @@ cdef int f() except -1:
x
=
nan
y
=
inf
z
=
minf
f
()
tests/errors/e_badexcvaltype.pyx
View file @
6bb725cb
...
...
@@ -2,5 +2,6 @@ cdef char *spam() except -1:
pass
_ERRORS
=
u"""
1:26: Cannot assign type 'long' to 'char *'
1:26: Exception value incompatible with function return type
"""
tests/errors/e_int_literals_py2.py
0 → 100644
View file @
6bb725cb
# cython: language_level=2
def
int_literals
():
a
=
1L
# ok
b
=
10000000000000L
# ok
c
=
1
UL
d
=
10000000000000
UL
e
=
10000000000000L
L
_ERRORS
=
"""
6:8: illegal integer literal syntax in Python source file
7:8: illegal integer literal syntax in Python source file
8:8: illegal integer literal syntax in Python source file
"""
tests/errors/e_int_literals_py3.py
0 → 100644
View file @
6bb725cb
# cython: language_level=3
def
int_literals
():
a
=
1L
b
=
10000000000000L
c
=
1
UL
d
=
10000000000000
UL
e
=
10000000000000L
L
_ERRORS
=
"""
4:8: illegal integer literal syntax in Python source file
5:8: illegal integer literal syntax in Python source file
6:8: illegal integer literal syntax in Python source file
7:8: illegal integer literal syntax in Python source file
8:8: illegal integer literal syntax in Python source file
"""
tests/run/closure_class_T596.pyx
0 → 100644
View file @
6bb725cb
def
simple
(
a
,
b
):
"""
>>> kls = simple(1, 2)
>>> kls().result()
3
"""
class
Foo
:
def
result
(
self
):
return
a
+
b
return
Foo
def
nested_classes
(
a
,
b
):
"""
>>> kls = nested_classes(1, 2)
>>> kls().result(-3)
0
"""
class
Foo
:
class
Bar
:
def
result
(
self
,
c
):
return
a
+
b
+
c
return
Foo
.
Bar
def
staff
(
a
,
b
):
"""
>>> kls = staff(1, 2)
>>> kls.static()
(1, 2)
>>> kls.klass()
('Foo', 1, 2)
>>> obj = kls()
>>> obj.member()
(1, 2)
"""
class
Foo
:
def
member
(
self
):
return
a
,
b
@
staticmethod
def
static
():
return
a
,
b
@
classmethod
def
klass
(
cls
):
return
cls
.
__name__
,
a
,
b
return
Foo
def
nested2
(
a
):
"""
>>> obj = nested2(1)
>>> f = obj.run(2)
>>> f()
3
"""
class
Foo
:
def
run
(
self
,
b
):
def
calc
():
return
a
+
b
return
calc
return
Foo
()
tests/run/closure_name_mangling_T537.pyx
0 → 100644
View file @
6bb725cb
__doc__
=
u"""
>>> f1 = nested1()
>>> f2 = nested2()
>>> f1 == f2 # inner functions (f)
False
>>> f1() == f2() # inner-inner functions (g)
False
"""
def
nested1
():
def
f
():
def
g
():
pass
return
g
return
f
def
nested2
():
def
f
():
def
g
():
pass
return
g
return
f
tests/run/cython3.pyx
View file @
6bb725cb
...
...
@@ -64,6 +64,19 @@ def list_comp_unknown_type(l):
"""
return
[
x
*
2
for
x
in
l
if
x
%
2
==
0
]
def
listcomp_as_condition
(
sequence
):
"""
>>> listcomp_as_condition(['a', 'b', '+'])
True
>>> listcomp_as_condition('ab+')
True
>>> listcomp_as_condition('abc')
False
"""
if
[
1
for
c
in
sequence
if
c
in
'+-*/<=>!%&|([^~,'
]:
return
True
return
False
def
set_comp
():
"""
>>> sorted(set_comp())
...
...
@@ -106,3 +119,16 @@ def dict_iter(dict d):
values
=
[
value
for
value
in
d
.
values
()
]
items
=
[
item
for
item
in
d
.
items
()
]
return
keys
,
values
,
items
def
int_literals
():
"""
>>> int_literals()
long
long
unsigned long
unsigned long
"""
print
(
cython
.
typeof
(
1L
))
print
(
cython
.
typeof
(
10000000000000L
))
print
(
cython
.
typeof
(
1
UL
))
print
(
cython
.
typeof
(
10000000000000
UL
))
tests/run/exceptionpropagation.pyx
View file @
6bb725cb
...
...
@@ -28,3 +28,17 @@ def test_except_expr(bint fire):
RuntimeError
"""
except_expr
(
fire
)
cdef
double
except_big_result
(
bint
fire
)
except
100000000000000000000000000000000
:
if
fire
:
raise
RuntimeError
def
test_except_big_result
(
bint
fire
):
"""
>>> test_except_big_result(False)
>>> test_except_big_result(True)
Traceback (most recent call last):
...
RuntimeError
"""
except_big_result
(
fire
)
tests/run/inplace.pyx
View file @
6bb725cb
...
...
@@ -244,3 +244,13 @@ def double_deref_and_increment(o, key1, key2):
v __setitem__ a 11
"""
o
[
side_effect
(
key1
)][
side_effect
(
key2
)]
+=
1
def
conditional_inplace
(
value
,
a
,
condition
,
b
):
"""
>>> conditional_inplace([1, 2, 3], [100], True, [200])
[1, 2, 3, 100]
>>> conditional_inplace([1, 2, 3], [100], False, [200])
[1, 2, 3, 200]
"""
value
+=
a
if
condition
else
b
return
value
tests/run/listcomp.pyx
View file @
6bb725cb
...
...
@@ -63,3 +63,16 @@ def nested_result():
"""
result
=
[[
a
-
1
for
a
in
range
(
b
)]
for
b
in
range
(
4
)]
return
result
def
listcomp_as_condition
(
sequence
):
"""
>>> listcomp_as_condition(['a', 'b', '+'])
True
>>> listcomp_as_condition('ab+')
True
>>> listcomp_as_condition('abc')
False
"""
if
[
1
for
c
in
sequence
if
c
in
'+-*/<=>!%&|([^~,'
]:
return
True
return
False
tests/run/metaclass.pyx
View file @
6bb725cb
cimport
cython
class
Base
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
):
attrs
[
'metaclass_was_here'
]
=
True
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
@
cython
.
test_fail_if_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Foo
(
object
):
"""
>>> obj = Foo()
...
...
@@ -12,26 +15,111 @@ class Foo(object):
"""
__metaclass__
=
Base
class
ODict
(
dict
):
def
__init__
(
self
):
dict
.
__init__
(
self
)
self
.
_order
=
[]
dict
.
__setitem__
(
self
,
'_order'
,
self
.
_order
)
def
__setitem__
(
self
,
key
,
value
):
dict
.
__setitem__
(
self
,
key
,
value
)
self
.
_order
.
append
(
key
)
class
Py3MetaclassPlusAttr
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
,
**
kwargs
):
for
key
,
value
in
kwargs
.
items
():
attrs
[
key
]
=
value
attrs
[
'metaclass_was_here'
]
=
True
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
def
__init__
(
self
,
cls
,
attrs
,
obj
,
**
kwargs
):
pass
@
staticmethod
def
__prepare__
(
*
args
,
**
kwargs
):
return
ODict
()
@
cython
.
test_fail_if_path_exists
(
"//PyClassMetaclassNode"
)
@
cython
.
test_assert_path_exists
(
"//Py3ClassNode"
)
class
Py3ClassMCOnly
(
object
,
metaclass
=
Py3MetaclassPlusAttr
):
"""
>>> obj = Py3ClassMCOnly()
>>> obj.bar
321
>>> obj.metaclass_was_here
True
>>> obj._order
['__module__', '__doc__', 'bar', 'metaclass_was_here']
"""
bar
=
321
class
Py3Base
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
,
foo
=
None
):
attrs
[
'foo'
]
=
foo
def
__new__
(
cls
,
name
,
bases
,
attrs
,
**
kwargs
):
for
key
,
value
in
kwargs
.
items
():
attrs
[
key
]
=
value
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
def
__init__
(
self
,
cls
,
attrs
,
obj
,
foo
=
None
):
def
__init__
(
self
,
cls
,
attrs
,
obj
,
**
kwargs
):
pass
@
staticmethod
def
__prepare__
(
name
,
base
s
,
**
kwargs
):
return
{
'bar'
:
666
,
'dirty'
:
True
}
def
__prepare__
(
*
arg
s
,
**
kwargs
):
return
ODict
()
@
cython
.
test_fail_if_path_exists
(
"//PyClassMetaclassNode"
)
@
cython
.
test_assert_path_exists
(
"//Py3ClassNode"
)
class
Py3Foo
(
object
,
metaclass
=
Py3Base
,
foo
=
123
):
"""
>>> obj = Py3Foo()
>>> obj.foo
123
>>> obj.bar
666
>>> obj.dirty
False
321
>>> obj._order
['__module__', '__doc__', 'bar', 'foo']
"""
bar
=
321
kwargs
=
{
'foo'
:
123
,
'bar'
:
456
}
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Py3Mixed
(
metaclass
=
Py3Base
,
**
kwargs
):
"""
>>> Py3Mixed.foo
123
>>> Py3Mixed.bar
456
"""
kwargs
[
'metaclass'
]
=
Py3Base
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
)
class
Py3Kwargs
(
**
kwargs
):
"""
>>> Py3Kwargs.foo
123
>>> Py3Kwargs.bar
456
"""
class
Base3
(
type
):
def
__new__
(
cls
,
name
,
bases
,
attrs
,
**
kwargs
):
kwargs
[
'b'
]
=
2
return
type
.
__new__
(
cls
,
name
,
bases
,
attrs
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
kwargs
=
kwargs
@
staticmethod
def
__prepare__
(
*
args
,
**
kwargs
):
kwargs
[
'a'
]
=
1
return
{}
kwargs
=
{
'c'
:
0
}
@
cython
.
test_assert_path_exists
(
"//PyClassMetaclassNode"
,
"//Py3ClassNode"
)
class
Foo3
(
metaclass
=
Base3
,
a
=
0
,
b
=
0
,
**
kwargs
):
"""
>>> Foo3.kwargs
{'a': 0, 'c': 0, 'b': 0}
"""
dirty
=
False
tests/run/py_unicode_type.pyx
View file @
6bb725cb
...
...
@@ -162,3 +162,36 @@ def count_lower_case_characters(unicode ustring):
if
uchar
.
islower
():
count
+=
1
return
count
@
cython
.
test_assert_path_exists
(
'//SwitchStatNode'
,
'//ForFromStatNode'
)
@
cython
.
test_fail_if_path_exists
(
'//ForInStatNode'
)
def
iter_and_in
():
"""
>>> iter_and_in()
a
b
e
f
h
"""
for
c
in
u'abcdefgh'
:
if
c
in
u'abCDefGh'
:
print
c
@
cython
.
test_assert_path_exists
(
'//SwitchStatNode'
,
'//ForFromStatNode'
)
@
cython
.
test_fail_if_path_exists
(
'//ForInStatNode'
)
def
index_and_in
():
"""
>>> index_and_in()
1
3
4
7
8
"""
cdef
int
i
for
i
in
range
(
1
,
9
):
if
u'abcdefgh'
[
-
i
]
in
u'abCDefGh'
:
print
i
tests/run/tuple_constants.pyx
0 → 100644
View file @
6bb725cb
cimport
cython
module_level_tuple
=
(
1
,
2
,
3
)
def
return_module_level_tuple
():
"""
>>> return_module_level_tuple()
(1, 2, 3)
"""
return
module_level_tuple
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_empty_tuple
():
"""
>>> return_empty_tuple()
()
"""
return
()
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_constant_tuple1
():
"""
>>> return_constant_tuple1()
(1,)
"""
return
(
1
,)
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_folded_tuple
():
"""
>>> return_folded_tuple()
(1, 2, 3)
"""
return
(
1
,
1
+
1
,
1
+
1
+
1
)
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_nested_tuple
():
"""
>>> return_nested_tuple()
(1, (2, 3), (3, (4, 5)))
"""
return
(
1
,
(
2
,
3
),
(
3
,
(
4
,
5
)))
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
constant_tuple1
():
"""
>>> constant_tuple1()
(1,)
"""
tuple1
=
(
1
,)
return
tuple1
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_constant_tuple2
():
"""
>>> return_constant_tuple2()
(1, 2)
"""
return
(
1
,
2
)
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_constant_tuple_strings
():
"""
>>> return_constant_tuple_strings()
('tuple_1', 'bc', 'tuple_2')
"""
return
(
'tuple_1'
,
'bc'
,
'tuple_2'
)
@
cython
.
test_assert_path_exists
(
"//TupleNode"
,
"//TupleNode[@is_literal = true]"
)
@
cython
.
test_fail_if_path_exists
(
"//TupleNode[@is_literal = false]"
)
def
return_constant_tuples_string_types
():
"""
>>> a,b,c = return_constant_tuples_string_types()
>>> a is b
False
>>> a is c
False
>>> b is c
False
"""
return
(
'a'
,
'bc'
),
(
u'a'
,
u'bc'
),
(
b'a'
,
b'bc'
)
@
cython
.
test_assert_path_exists
(
"//ReturnStatNode//TupleNode"
,
"//ReturnStatNode//TupleNode[@is_literal = false]"
)
@
cython
.
test_fail_if_path_exists
(
"//ReturnStatNode//TupleNode[@is_literal = true]"
)
def
return_nonconstant_tuple
():
"""
>>> return_nonconstant_tuple()
('a', 1, 'd')
"""
a
=
eval
(
"1"
)
return
(
'a'
,
a
,
'd'
)
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