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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
a17fac09
Commit
a17fac09
authored
May 01, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
fe2191ac
fd236aa1
Changes
42
Show whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
2007 additions
and
709 deletions
+2007
-709
Cython/Build/BuildExecutable.py
Cython/Build/BuildExecutable.py
+30
-14
Cython/Compiler/Builtin.py
Cython/Compiler/Builtin.py
+50
-0
Cython/Compiler/CmdLine.py
Cython/Compiler/CmdLine.py
+1
-9
Cython/Compiler/Code.pxd
Cython/Compiler/Code.pxd
+2
-1
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+85
-34
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+145
-35
Cython/Compiler/Main.py
Cython/Compiler/Main.py
+2
-2
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+93
-93
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+220
-34
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+18
-1
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+58
-77
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+36
-14
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+179
-178
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+33
-24
Cython/Compiler/Tests/TestTreeFragment.py
Cython/Compiler/Tests/TestTreeFragment.py
+4
-5
Cython/Compiler/TreeFragment.py
Cython/Compiler/TreeFragment.py
+7
-9
Cython/Compiler/UtilNodes.py
Cython/Compiler/UtilNodes.py
+4
-0
Cython/Includes/libcpp/string.pxd
Cython/Includes/libcpp/string.pxd
+114
-0
Cython/Plex/Errors.py
Cython/Plex/Errors.py
+1
-1
Cython/Plex/Scanners.py
Cython/Plex/Scanners.py
+5
-0
pyximport/pyximport.py
pyximport/pyximport.py
+2
-1
runtests.py
runtests.py
+148
-111
setup.py
setup.py
+4
-0
tests/bugs.txt
tests/bugs.txt
+9
-2
tests/compile/future_imports.pyx
tests/compile/future_imports.pyx
+9
-0
tests/errors/w_cdef_override.pyx
tests/errors/w_cdef_override.pyx
+1
-1
tests/run/arithmetic_analyse_types.pyx
tests/run/arithmetic_analyse_types.pyx
+12
-12
tests/run/arithmetic_analyse_types_helper.h
tests/run/arithmetic_analyse_types_helper.h
+6
-6
tests/run/cpp_stl_string.pyx
tests/run/cpp_stl_string.pyx
+177
-0
tests/run/cython3.pyx
tests/run/cython3.pyx
+12
-0
tests/run/flatin.pyx
tests/run/flatin.pyx
+1
-1
tests/run/funcexceptraisefrom.pyx
tests/run/funcexceptraisefrom.pyx
+51
-0
tests/run/generator_expressions.pyx
tests/run/generator_expressions.pyx
+39
-0
tests/run/generators_py.py
tests/run/generators_py.py
+34
-0
tests/run/ifelseexpr_T267.pyx
tests/run/ifelseexpr_T267.pyx
+39
-16
tests/run/relativeimport_T542.pyx
tests/run/relativeimport_T542.pyx
+2
-3
tests/run/strliterals.pyx
tests/run/strliterals.pyx
+13
-0
tests/run/test_raisefrom.pyx
tests/run/test_raisefrom.pyx
+39
-0
tests/run/trybreak.pyx
tests/run/trybreak.pyx
+29
-8
tests/run/with_statement_module_level_T536.pyx
tests/run/with_statement_module_level_T536.pyx
+21
-6
tests/run/withstat.pyx
tests/run/withstat.pyx
+0
-11
tests/run/withstat_py.py
tests/run/withstat_py.py
+272
-0
No files found.
Cython/Build/BuildExecutable.py
View file @
a17fac09
...
...
@@ -13,17 +13,27 @@ import sys
import
os
from
distutils
import
sysconfig
INCDIR
=
sysconfig
.
get_python_inc
()
LIBDIR1
=
sysconfig
.
get_config_var
(
'LIBDIR'
)
LIBDIR2
=
sysconfig
.
get_config_var
(
'LIBPL'
)
PYLIB
=
sysconfig
.
get_config_var
(
'LIBRARY'
)[
3
:
-
2
]
def
get_config_var
(
name
):
return
sysconfig
.
get_config_var
(
name
)
or
''
CC
=
sysconfig
.
get_config_var
(
'CC'
)
CFLAGS
=
sysconfig
.
get_config_var
(
'CFLAGS'
)
+
' '
+
os
.
environ
.
get
(
'CFLAGS'
,
''
)
LINKCC
=
sysconfig
.
get_config_var
(
'LINKCC'
)
LINKFORSHARED
=
sysconfig
.
get_config_var
(
'LINKFORSHARED'
)
LIBS
=
sysconfig
.
get_config_var
(
'LIBS'
)
SYSLIBS
=
sysconfig
.
get_config_var
(
'SYSLIBS'
)
INCDIR
=
sysconfig
.
get_python_inc
()
LIBDIR1
=
get_config_var
(
'LIBDIR'
)
LIBDIR2
=
get_config_var
(
'LIBPL'
)
PYLIB
=
get_config_var
(
'LIBRARY'
)
PYLIB_DYN
=
get_config_var
(
'LDLIBRARY'
)
if
PYLIB_DYN
==
PYLIB
:
# no shared library
PYLIB_DYN
=
''
else
:
PYLIB_DYN
=
os
.
path
.
splitext
(
PYLIB_DYN
[
3
:])[
0
]
# 'lib(XYZ).so' -> XYZ
CC
=
get_config_var
(
'CC'
)
CFLAGS
=
get_config_var
(
'CFLAGS'
)
+
' '
+
os
.
environ
.
get
(
'CFLAGS'
,
''
)
LINKCC
=
get_config_var
(
'LINKCC'
)
LINKFORSHARED
=
get_config_var
(
'LINKFORSHARED'
)
LIBS
=
get_config_var
(
'LIBS'
)
SYSLIBS
=
get_config_var
(
'SYSLIBS'
)
EXE_EXT
=
sysconfig
.
get_config_var
(
'EXE'
)
def
_debug
(
msg
,
*
args
):
if
DEBUG
:
...
...
@@ -36,12 +46,14 @@ def dump_config():
_debug
(
'LIBDIR1: %s'
,
LIBDIR1
)
_debug
(
'LIBDIR2: %s'
,
LIBDIR2
)
_debug
(
'PYLIB: %s'
,
PYLIB
)
_debug
(
'PYLIB_DYN: %s'
,
PYLIB_DYN
)
_debug
(
'CC: %s'
,
CC
)
_debug
(
'CFLAGS: %s'
,
CFLAGS
)
_debug
(
'LINKCC: %s'
,
LINKCC
)
_debug
(
'LINKFORSHARED: %s'
,
LINKFORSHARED
)
_debug
(
'LIBS: %s'
,
LIBS
)
_debug
(
'SYSLIBS: %s'
,
SYSLIBS
)
_debug
(
'EXE_EXT: %s'
,
EXE_EXT
)
def
runcmd
(
cmd
,
shell
=
True
):
if
shell
:
...
...
@@ -61,7 +73,8 @@ def runcmd(cmd, shell=True):
sys
.
exit
(
returncode
)
def
clink
(
basename
):
runcmd
([
LINKCC
,
'-o'
,
basename
,
basename
+
'.o'
,
'-L'
+
LIBDIR1
,
'-L'
+
LIBDIR2
,
'-l'
+
PYLIB
]
runcmd
([
LINKCC
,
'-o'
,
basename
+
EXE_EXT
,
basename
+
'.o'
,
'-L'
+
LIBDIR1
,
'-L'
+
LIBDIR2
]
+
[
PYLIB_DYN
and
(
'-l'
+
PYLIB_DYN
)
or
os
.
path
.
join
(
LIBDIR1
,
PYLIB
)]
+
LIBS
.
split
()
+
SYSLIBS
.
split
()
+
LINKFORSHARED
.
split
())
def
ccompile
(
basename
):
...
...
@@ -75,8 +88,8 @@ def cycompile(input_file, options=()):
if
result
.
num_errors
>
0
:
sys
.
exit
(
1
)
def
exec_file
(
base
name
,
args
=
()):
runcmd
([
os
.
path
.
abspath
(
base
name
)]
+
list
(
args
),
shell
=
False
)
def
exec_file
(
program_
name
,
args
=
()):
runcmd
([
os
.
path
.
abspath
(
program_
name
)]
+
list
(
args
),
shell
=
False
)
def
build
(
input_file
,
compiler_args
=
()):
"""
...
...
@@ -88,7 +101,7 @@ def build(input_file, compiler_args=()):
cycompile
(
input_file
,
compiler_args
)
ccompile
(
basename
)
clink
(
basename
)
return
basename
return
basename
+
EXE_EXT
def
build_and_run
(
args
):
"""
...
...
@@ -114,3 +127,6 @@ def build_and_run(args):
program_name
=
build
(
input_file
,
cy_args
)
exec_file
(
program_name
,
args
)
if
__name__
==
'__main__'
:
build_and_run
(
sys
.
argv
[
1
:])
Cython/Compiler/Builtin.py
View file @
a17fac09
...
...
@@ -95,6 +95,54 @@ static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) {
}
"""
)
globals_utility_code
=
UtilityCode
(
# This is a stub implementation until we have something more complete.
# Currently, we only handle the most common case of a read-only dict
# of Python names. Supporting cdef names in the module and write
# access requires a rewrite as a dedicated class.
proto
=
"""
static PyObject* __Pyx_Globals(); /*proto*/
"""
,
impl
=
'''
static PyObject* __Pyx_Globals() {
Py_ssize_t i;
/*PyObject *d;*/
PyObject *names = NULL;
PyObject *globals = PyObject_GetAttrString(%(MODULE)s, "__dict__");
if (!globals) {
PyErr_SetString(PyExc_TypeError,
"current module must have __dict__ attribute");
goto bad;
}
names = PyObject_Dir(%(MODULE)s);
if (!names)
goto bad;
for (i = 0; i < PyList_GET_SIZE(names); i++) {
PyObject* name = PyList_GET_ITEM(names, i);
if (!PyDict_Contains(globals, name)) {
PyObject* value = PyObject_GetAttr(%(MODULE)s, PyList_GET_ITEM(names, i));
if (!value)
goto bad;
if (PyDict_SetItem(globals, name, value) < 0) {
Py_DECREF(value);
goto bad;
}
}
}
Py_DECREF(names);
return globals;
/*
d = PyDictProxy_New(globals);
Py_DECREF(globals);
return d;
*/
bad:
Py_XDECREF(names);
Py_XDECREF(globals);
return NULL;
}
'''
%
{
'MODULE'
:
Naming
.
module_cname
})
pyexec_utility_code
=
UtilityCode
(
proto
=
"""
#if PY_VERSION_HEX < 0x02040000
...
...
@@ -384,6 +432,8 @@ builtin_function_table = [
utility_code
=
getattr3_utility_code
),
BuiltinFunction
(
'getattr3'
,
"OOO"
,
"O"
,
"__Pyx_GetAttr3"
,
"getattr"
,
utility_code
=
getattr3_utility_code
),
# Pyrex compatibility
BuiltinFunction
(
'globals'
,
""
,
"O"
,
"__Pyx_Globals"
,
utility_code
=
globals_utility_code
),
BuiltinFunction
(
'hasattr'
,
"OO"
,
"b"
,
"__Pyx_HasAttr"
,
utility_code
=
hasattr_utility_code
),
BuiltinFunction
(
'hash'
,
"O"
,
"h"
,
"PyObject_Hash"
),
...
...
Cython/Compiler/CmdLine.py
View file @
a17fac09
...
...
@@ -163,15 +163,7 @@ def parse_command_line(args):
sys
.
stderr
.
write
(
"Unknown compiler flag: %s
\
n
"
%
option
)
sys
.
exit
(
1
)
else
:
arg
=
pop_arg
()
if
arg
.
endswith
(
".pyx"
):
sources
.
append
(
arg
)
elif
arg
.
endswith
(
".py"
):
# maybe do some other stuff, but this should work for now
sources
.
append
(
arg
)
else
:
sys
.
stderr
.
write
(
"cython: %s: Unknown filename suffix
\
n
"
%
arg
)
sources
.
append
(
pop_arg
())
if
options
.
use_listing_file
and
len
(
sources
)
>
1
:
sys
.
stderr
.
write
(
"cython: Only one source file allowed when using -o
\
n
"
)
...
...
Cython/Compiler/Code.pxd
View file @
a17fac09
...
...
@@ -59,9 +59,10 @@ cdef class StringConst:
cdef
public
object
text
cdef
public
object
escaped_value
cdef
public
dict
py_strings
cdef
public
list
py_versions
@
cython
.
locals
(
intern
=
bint
,
is_str
=
bint
,
is_unicode
=
bint
)
cpdef
get_py_string_const
(
self
,
encoding
,
identifier
=*
,
is_str
=*
)
cpdef
get_py_string_const
(
self
,
encoding
,
identifier
=*
,
is_str
=*
,
py3str_cstring
=*
)
## cdef class PyStringConst:
## cdef public object cname
...
...
Cython/Compiler/Code.py
View file @
a17fac09
...
...
@@ -25,12 +25,19 @@ except ImportError:
non_portable_builtins_map
=
{
# builtins that have different names in different Python versions
'bytes'
:
(
'PY_MAJOR_VERSION < 3'
,
'str'
),
'unicode'
:
(
'PY_MAJOR_VERSION >= 3'
,
'str'
),
'xrange'
:
(
'PY_MAJOR_VERSION >= 3'
,
'range'
),
'BaseException'
:
(
'PY_VERSION_HEX < 0x02050000'
,
'Exception'
),
}
uncachable_builtins
=
[
# builtin names that cannot be cached because they may or may not
# be available at import time
'WindowsError'
,
]
class
UtilityCode
(
object
):
# Stores utility code to add during code generation.
#
...
...
@@ -324,8 +331,16 @@ class StringConst(object):
self.text = text
self.escaped_value = StringEncoding.escape_byte_string(byte_string)
self.py_strings = None
self.py_versions = []
def get_py_string_const(self, encoding, identifier=None, is_str=False):
def add_py_version(self, version):
if not version:
self.py_versions = [2,3]
elif version not in self.py_versions:
self.py_versions.append(version)
def get_py_string_const(self, encoding, identifier=None,
is_str=False, py3str_cstring=None):
py_strings = self.py_strings
text = self.text
...
...
@@ -344,12 +359,15 @@ class StringConst(object):
else:
encoding_key = ''.join(find_alphanums(encoding))
key = (is_str, is_unicode, encoding_key)
if py_strings is not None and key in py_strings:
py_string = py_strings[key]
key = (is_str, is_unicode, encoding_key, py3str_cstring)
if py_strings is not None:
try:
return py_strings[key]
except KeyError:
pass
else:
if py_strings is None:
self.py_strings = {}
if identifier:
intern = True
elif identifier is None:
...
...
@@ -369,22 +387,24 @@ class StringConst(object):
self.cname[len(Naming.const_prefix):])
py_string = PyStringConst(
pystring_cname, encoding, is_unicode, is_str
, intern)
pystring_cname, encoding, is_unicode, is_str, py3str_cstring
, intern)
self.py_strings[key] = py_string
return py_string
class PyStringConst(object):
"""Global info about a Python string constant held by GlobalState.
"""
# cname string
# py3str_cstring string
# encoding string
# intern boolean
# is_unicode boolean
# is_str boolean
def __init__(self, cname, encoding, is_unicode, is_str=False, intern=False):
def __init__(self, cname, encoding, is_unicode, is_str=False,
py3str_cstring=None, intern=False):
self.cname = cname
self.py3str_cstring = py3str_cstring
self.encoding = encoding
self.is_str = is_str
self.is_unicode = is_unicode
...
...
@@ -595,7 +615,7 @@ class GlobalState(object):
cleanup_writer.put_xdecref_clear(const.cname, type, nanny=False)
return const
def get_string_const(self, text):
def get_string_const(self, text
, py_version=None
):
# return a C string constant, creating a new one if necessary
if text.is_unicode:
byte_string = text.utf8encode()
...
...
@@ -605,12 +625,21 @@ class GlobalState(object):
c = self.string_const_index[byte_string]
except KeyError:
c = self.new_string_const(text, byte_string)
c.add_py_version(py_version)
return c
def get_py_string_const(self, text, identifier=None, is_str=False):
def get_py_string_const(self, text, identifier=None,
is_str=False, unicode_value=None):
# return a Python string constant, creating a new one if necessary
py3str_cstring = None
if is_str and unicode_value is not None
\
and unicode_value.utf8encode() != text.byteencode():
py3str_cstring = self.get_string_const(unicode_value, py_version=3)
c_string = self.get_string_const(text, py_version=2)
else:
c_string = self.get_string_const(text)
py_string = c_string.get_py_string_const(text.encoding, identifier, is_str)
py_string = c_string.get_py_string_const(
text.encoding, identifier, is_str, py3str_cstring)
return py_string
def get_interned_identifier(self, text):
...
...
@@ -711,8 +740,15 @@ class GlobalState(object):
decls_writer = self.parts['decls']
for _, cname, c in c_consts:
conditional = False
if c.py_versions and (2 not in c.py_versions or 3 not in c.py_versions):
conditional = True
decls_writer.putln("
#if PY_MAJOR_VERSION %s 3" % (
(
2
in
c
.
py_versions
)
and
'<'
or
'>='
))
decls_writer
.
putln
(
'static char %s[] = "%s";'
%
(
cname
,
StringEncoding
.
split_string_literal
(
c
.
escaped_value
)))
if
conditional
:
decls_writer
.
putln
(
"#endif"
)
if
c
.
py_strings
is
not
None
:
for
py_string
in
c
.
py_strings
.
values
():
py_strings
.
append
((
c
.
cname
,
len
(
py_string
.
cname
),
py_string
))
...
...
@@ -736,6 +772,17 @@ class GlobalState(object):
decls_writer
.
putln
(
"static PyObject *%s;"
%
py_string
.
cname
)
if
py_string
.
py3str_cstring
:
w
.
putln
(
"#if PY_MAJOR_VERSION >= 3"
)
w
.
putln
(
"{&%s, %s, sizeof(%s), %s, %d, %d, %d},"
%
(
py_string
.
cname
,
py_string
.
py3str_cstring
.
cname
,
py_string
.
py3str_cstring
.
cname
,
'0'
,
1
,
0
,
py_string
.
intern
))
w
.
putln
(
"#else"
)
w
.
putln
(
"{&%s, %s, sizeof(%s), %s, %d, %d, %d},"
%
(
py_string
.
cname
,
...
...
@@ -746,6 +793,8 @@ class GlobalState(object):
py_string
.
is_str
,
py_string
.
intern
))
if
py_string
.
py3str_cstring
:
w
.
putln
(
"#endif"
)
w
.
putln
(
"{0, 0, 0, 0, 0, 0, 0}"
)
w
.
putln
(
"};"
)
...
...
@@ -1003,8 +1052,10 @@ class CCodeWriter(object):
def
get_string_const
(
self
,
text
):
return
self
.
globalstate
.
get_string_const
(
text
).
cname
def get_py_string_const(self, text, identifier=None, is_str=False):
return self.globalstate.get_py_string_const(text, identifier, is_str).cname
def
get_py_string_const
(
self
,
text
,
identifier
=
None
,
is_str
=
False
,
unicode_value
=
None
):
return
self
.
globalstate
.
get_py_string_const
(
text
,
identifier
,
is_str
,
unicode_value
).
cname
def
get_argument_default_const
(
self
,
type
):
return
self
.
globalstate
.
get_py_const
(
type
).
cname
...
...
Cython/Compiler/ExprNodes.py
View file @
a17fac09
...
...
@@ -1122,16 +1122,6 @@ class StringNode(PyConstNode):
if
not
dst_type
.
is_pyobject
:
return
BytesNode
(
self
.
pos
,
value
=
self
.
value
).
coerce_to
(
dst_type
,
env
)
self
.
check_for_coercion_error
(
dst_type
,
fail
=
True
)
# this will be a unicode string in Py3, so make sure we can decode it
if
self
.
value
.
encoding
and
isinstance
(
self
.
value
,
StringEncoding
.
BytesLiteral
):
try
:
self
.
value
.
decode
(
self
.
value
.
encoding
)
except
UnicodeDecodeError
:
error
(
self
.
pos
,
(
"Decoding unprefixed string literal from '%s' failed. Consider using"
"a byte string or unicode string explicitly, "
"or adjust the source code encoding."
)
%
self
.
value
.
encoding
)
return
self
def
can_coerce_to_char_literal
(
self
):
...
...
@@ -1139,7 +1129,8 @@ class StringNode(PyConstNode):
def
generate_evaluation_code
(
self
,
code
):
self
.
result_code
=
code
.
get_py_string_const
(
self
.
value
,
identifier
=
self
.
is_identifier
,
is_str
=
True
)
self
.
value
,
identifier
=
self
.
is_identifier
,
is_str
=
True
,
unicode_value
=
self
.
unicode_value
)
def
get_constant_c_result_code
(
self
):
return
None
...
...
@@ -1926,6 +1917,40 @@ class NextNode(AtomicExprNode):
code
.
putln
(
"}"
)
class
WithExitCallNode
(
ExprNode
):
# The __exit__() call of a 'with' statement. Used in both the
# except and finally clauses.
# with_stat WithStatNode the surrounding 'with' statement
# args TupleNode or ResultStatNode the exception info tuple
subexprs
=
[
'args'
]
def
analyse_types
(
self
,
env
):
self
.
args
.
analyse_types
(
env
)
self
.
type
=
PyrexTypes
.
c_bint_type
self
.
is_temp
=
True
def
generate_result_code
(
self
,
code
):
if
isinstance
(
self
.
args
,
TupleNode
):
# call only if it was not already called (and decref-cleared)
code
.
putln
(
"if (%s) {"
%
self
.
with_stat
.
exit_var
)
result_var
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
manage_ref
=
False
)
code
.
putln
(
"%s = PyObject_Call(%s, %s, NULL);"
%
(
result_var
,
self
.
with_stat
.
exit_var
,
self
.
args
.
result
()))
code
.
put_decref_clear
(
self
.
with_stat
.
exit_var
,
type
=
py_object_type
)
code
.
putln
(
code
.
error_goto_if_null
(
result_var
,
self
.
pos
))
code
.
put_gotref
(
result_var
)
code
.
putln
(
"%s = __Pyx_PyObject_IsTrue(%s);"
%
(
self
.
result
(),
result_var
))
code
.
put_decref_clear
(
result_var
,
type
=
py_object_type
)
code
.
putln
(
code
.
error_goto_if_neg
(
self
.
result
(),
self
.
pos
))
code
.
funcstate
.
release_temp
(
result_var
)
if
isinstance
(
self
.
args
,
TupleNode
):
code
.
putln
(
"}"
)
class
ExcValueNode
(
AtomicExprNode
):
# Node created during analyse_types phase
# of an ExceptClauseNode to fetch the current
...
...
@@ -1960,7 +1985,7 @@ class TempNode(ExprNode):
subexprs
=
[]
def
__init__
(
self
,
pos
,
type
,
env
):
def
__init__
(
self
,
pos
,
type
,
env
=
None
):
ExprNode
.
__init__
(
self
,
pos
)
self
.
type
=
type
if
type
.
is_pyobject
:
...
...
@@ -1970,6 +1995,9 @@ class TempNode(ExprNode):
def
analyse_types
(
self
,
env
):
return
self
.
type
def
analyse_target_declaration
(
self
,
env
):
pass
def
generate_result_code
(
self
,
code
):
pass
...
...
@@ -6665,6 +6693,14 @@ class CmpNode(object):
env
.
use_utility_code
(
pyunicode_equals_utility_code
)
self
.
special_bool_cmp_function
=
"__Pyx_PyUnicode_Equals"
return
True
elif
type1
is
Builtin
.
bytes_type
or
type2
is
Builtin
.
bytes_type
:
env
.
use_utility_code
(
pybytes_equals_utility_code
)
self
.
special_bool_cmp_function
=
"__Pyx_PyBytes_Equals"
return
True
elif
type1
is
Builtin
.
str_type
or
type2
is
Builtin
.
str_type
:
env
.
use_utility_code
(
pystr_equals_utility_code
)
self
.
special_bool_cmp_function
=
"__Pyx_PyString_Equals"
return
True
return
False
def
generate_operation_code
(
self
,
code
,
result_code
,
...
...
@@ -6861,8 +6897,6 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int
return -1;
return (equals == Py_EQ) ? (result == 0) : (result != 0);
}
} else if ((s1 == Py_None) & (s2 == Py_None)) {
return (equals == Py_EQ);
} else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
return (equals == Py_NE);
} else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
...
...
@@ -6879,6 +6913,53 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int
}
"""
)
pybytes_equals_utility_code
=
UtilityCode
(
proto
=
"""
static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
"""
,
impl
=
"""
static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
return (equals == Py_EQ);
} else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
if (PyBytes_GET_SIZE(s1) != PyBytes_GET_SIZE(s2)) {
return (equals == Py_NE);
} else if (PyBytes_GET_SIZE(s1) == 1) {
if (equals == Py_EQ)
return (PyBytes_AS_STRING(s1)[0] == PyBytes_AS_STRING(s2)[0]);
else
return (PyBytes_AS_STRING(s1)[0] != PyBytes_AS_STRING(s2)[0]);
} else {
int result = memcmp(PyBytes_AS_STRING(s1), PyBytes_AS_STRING(s2), PyBytes_GET_SIZE(s1));
return (equals == Py_EQ) ? (result == 0) : (result != 0);
}
} else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
return (equals == Py_NE);
} else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
return (equals == Py_NE);
} else {
int result;
PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
if (!py_result)
return -1;
result = __Pyx_PyObject_IsTrue(py_result);
Py_DECREF(py_result);
return result;
}
}
"""
,
requires
=
[
Builtin
.
include_string_h_utility_code
])
pystr_equals_utility_code
=
UtilityCode
(
proto
=
"""
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
#else
#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
#endif
"""
,
requires
=
[
pybytes_equals_utility_code
,
pyunicode_equals_utility_code
])
class
PrimaryCmpNode
(
ExprNode
,
CmpNode
):
# Non-cascaded comparison or first comparison of
...
...
@@ -7684,11 +7765,18 @@ impl = """
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyObject *result;
result = PyObject_GetAttr(dict, name);
if (!result)
if (!result) {
if (dict != %(BUILTINS)s) {
PyErr_Clear();
result = PyObject_GetAttr(%(BUILTINS)s, name);
}
if (!result) {
PyErr_SetObject(PyExc_NameError, name);
}
}
return result;
}
"""
)
"""
%
{
'BUILTINS'
:
Naming
.
builtins_cname
}
)
#------------------------------------------------------------------------------------
...
...
@@ -8532,6 +8620,17 @@ static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args, CYTHON_UNU
typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
"""
,
impl
=
"""
static CYTHON_INLINE void __Pyx_Generator_ExceptionClear(struct __pyx_Generator_object *self)
{
Py_XDECREF(self->exc_type);
Py_XDECREF(self->exc_value);
Py_XDECREF(self->exc_traceback);
self->exc_type = NULL;
self->exc_value = NULL;
self->exc_traceback = NULL;
}
static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_object *self, PyObject *value)
{
PyObject *retval;
...
...
@@ -8556,10 +8655,21 @@ static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_obj
return NULL;
}
if (value)
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
else
__Pyx_Generator_ExceptionClear(self);
self->is_running = 1;
retval = self->body((PyObject *) self, value);
self->is_running = 0;
if (retval)
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
else
__Pyx_Generator_ExceptionClear(self);
return retval;
}
...
...
@@ -8612,10 +8722,10 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args, CYTHON_UN
if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
return NULL;
__Pyx_Raise(typ, val, tb);
__Pyx_Raise(typ, val, tb
, NULL
);
return __Pyx_Generator_SendEx(generator, NULL);
}
"""
,
proto_block
=
'utility_code_proto_before_types'
,
requires
=
[
Nodes
.
raise_utility_code
],
requires
=
[
Nodes
.
raise_utility_code
,
Nodes
.
swap_exception_utility_code
],
)
Cython/Compiler/Main.py
View file @
a17fac09
...
...
@@ -619,7 +619,7 @@ def run_pipeline(source, options, full_module_name = None):
options
.
annotate
=
True
# Get pipeline
if
source_ext
.
lower
()
==
'.py'
:
if
source_ext
.
lower
()
==
'.py'
or
not
source_ext
:
pipeline
=
context
.
create_py_pipeline
(
options
,
result
)
else
:
pipeline
=
context
.
create_pyx_pipeline
(
options
,
result
)
...
...
Cython/Compiler/ModuleNode.py
View file @
a17fac09
Cython/Compiler/Nodes.py
View file @
a17fac09
...
...
@@ -2406,14 +2406,7 @@ class DefNode(FuncDefNode):
entry
.
doc
=
None
def
declare_lambda_function
(
self
,
env
):
name
=
self
.
name
prefix
=
env
.
scope_prefix
func_cname
=
\
Naming
.
lambda_func_prefix
+
u'funcdef'
+
prefix
+
self
.
lambda_name
entry
=
env
.
declare_lambda_function
(
func_cname
,
self
.
pos
)
entry
.
pymethdef_cname
=
\
Naming
.
lambda_func_prefix
+
u'methdef'
+
prefix
+
self
.
lambda_name
entry
.
qualified_name
=
env
.
qualify_name
(
self
.
lambda_name
)
entry
=
env
.
declare_lambda_function
(
self
.
lambda_name
,
self
.
pos
)
entry
.
doc
=
None
self
.
entry
=
entry
...
...
@@ -4349,8 +4342,9 @@ class RaiseStatNode(StatNode):
# exc_type ExprNode or None
# exc_value ExprNode or None
# exc_tb ExprNode or None
# cause ExprNode or None
child_attrs
=
[
"exc_type"
,
"exc_value"
,
"exc_tb"
]
child_attrs
=
[
"exc_type"
,
"exc_value"
,
"exc_tb"
,
"cause"
]
def
analyse_expressions
(
self
,
env
):
if
self
.
exc_type
:
...
...
@@ -4362,6 +4356,9 @@ class RaiseStatNode(StatNode):
if
self
.
exc_tb
:
self
.
exc_tb
.
analyse_types
(
env
)
self
.
exc_tb
=
self
.
exc_tb
.
coerce_to_pyobject
(
env
)
if
self
.
cause
:
self
.
cause
.
analyse_types
(
env
)
self
.
cause
=
self
.
cause
.
coerce_to_pyobject
(
env
)
# special cases for builtin exceptions
self
.
builtin_exc_name
=
None
if
self
.
exc_type
and
not
self
.
exc_value
and
not
self
.
exc_tb
:
...
...
@@ -4399,13 +4396,19 @@ class RaiseStatNode(StatNode):
tb_code
=
self
.
exc_tb
.
py_result
()
else
:
tb_code
=
"0"
if
self
.
cause
:
self
.
cause
.
generate_evaluation_code
(
code
)
cause_code
=
self
.
cause
.
py_result
()
else
:
cause_code
=
"0"
code
.
globalstate
.
use_utility_code
(
raise_utility_code
)
code
.
putln
(
"__Pyx_Raise(%s, %s, %s);"
%
(
"__Pyx_Raise(%s, %s, %s
, %s
);"
%
(
type_code
,
value_code
,
tb_code
))
for
obj
in
(
self
.
exc_type
,
self
.
exc_value
,
self
.
exc_tb
):
tb_code
,
cause_code
))
for
obj
in
(
self
.
exc_type
,
self
.
exc_value
,
self
.
exc_tb
,
self
.
cause
):
if
obj
:
obj
.
generate_disposal_code
(
code
)
obj
.
free_temps
(
code
)
...
...
@@ -4419,6 +4422,8 @@ class RaiseStatNode(StatNode):
self
.
exc_value
.
generate_function_definitions
(
env
,
code
)
if
self
.
exc_tb
is
not
None
:
self
.
exc_tb
.
generate_function_definitions
(
env
,
code
)
if
self
.
cause
is
not
None
:
self
.
cause
.
generate_function_definitions
(
env
,
code
)
def
annotate
(
self
,
code
):
if
self
.
exc_type
:
...
...
@@ -4427,6 +4432,8 @@ class RaiseStatNode(StatNode):
self
.
exc_value
.
annotate
(
code
)
if
self
.
exc_tb
:
self
.
exc_tb
.
annotate
(
code
)
if
self
.
cause
:
self
.
cause
.
annotate
(
code
)
class
ReraiseStatNode
(
StatNode
):
...
...
@@ -5030,14 +5037,134 @@ class WithStatNode(StatNode):
"""
Represents a Python with statement.
This is only used at parse tree level; and is not present in
analysis or generation phases.
Implemented by the WithTransform as follows:
MGR = EXPR
EXIT = MGR.__exit__
VALUE = MGR.__enter__()
EXC = True
try:
try:
TARGET = VALUE # optional
BODY
except:
EXC = False
if not EXIT(*EXCINFO):
raise
finally:
if EXC:
EXIT(None, None, None)
MGR = EXIT = VALUE = None
"""
# manager The with statement manager object
# target
Node (lhs expression)
# target
ExprNode the target lhs of the __enter__() call
# body StatNode
child_attrs
=
[
"manager"
,
"target"
,
"body"
]
has_target
=
False
def
analyse_declarations
(
self
,
env
):
self
.
manager
.
analyse_declarations
(
env
)
self
.
body
.
analyse_declarations
(
env
)
def
analyse_expressions
(
self
,
env
):
self
.
manager
.
analyse_types
(
env
)
self
.
body
.
analyse_expressions
(
env
)
def
generate_function_definitions
(
self
,
env
,
code
):
self
.
manager
.
generate_function_definitions
(
env
,
code
)
self
.
body
.
generate_function_definitions
(
env
,
code
)
def
generate_execution_code
(
self
,
code
):
code
.
putln
(
"/*with:*/ {"
)
self
.
manager
.
generate_evaluation_code
(
code
)
self
.
exit_var
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
manage_ref
=
False
)
code
.
putln
(
"%s = PyObject_GetAttr(%s, %s); %s"
%
(
self
.
exit_var
,
self
.
manager
.
py_result
(),
code
.
get_py_string_const
(
EncodedString
(
'__exit__'
),
identifier
=
True
),
code
.
error_goto_if_null
(
self
.
exit_var
,
self
.
pos
),
))
code
.
put_gotref
(
self
.
exit_var
)
# need to free exit_var in the face of exceptions during setup
old_error_label
=
code
.
new_error_label
()
intermediate_error_label
=
code
.
error_label
enter_func
=
code
.
funcstate
.
allocate_temp
(
py_object_type
,
manage_ref
=
True
)
code
.
putln
(
"%s = PyObject_GetAttr(%s, %s); %s"
%
(
enter_func
,
self
.
manager
.
py_result
(),
code
.
get_py_string_const
(
EncodedString
(
'__enter__'
),
identifier
=
True
),
code
.
error_goto_if_null
(
enter_func
,
self
.
pos
),
))
code
.
put_gotref
(
enter_func
)
self
.
manager
.
generate_disposal_code
(
code
)
self
.
manager
.
free_temps
(
code
)
self
.
target_temp
.
allocate
(
code
)
code
.
putln
(
'%s = PyObject_Call(%s, ((PyObject *)%s), NULL); %s'
%
(
self
.
target_temp
.
result
(),
enter_func
,
Naming
.
empty_tuple
,
code
.
error_goto_if_null
(
self
.
target_temp
.
result
(),
self
.
pos
),
))
code
.
put_gotref
(
self
.
target_temp
.
result
())
code
.
put_decref_clear
(
enter_func
,
py_object_type
)
code
.
funcstate
.
release_temp
(
enter_func
)
if
not
self
.
has_target
:
code
.
put_decref_clear
(
self
.
target_temp
.
result
(),
type
=
py_object_type
)
self
.
target_temp
.
release
(
code
)
# otherwise, WithTargetAssignmentStatNode will do it for us
code
.
error_label
=
old_error_label
self
.
body
.
generate_execution_code
(
code
)
step_over_label
=
code
.
new_label
()
code
.
put_goto
(
step_over_label
)
code
.
put_label
(
intermediate_error_label
)
code
.
put_decref_clear
(
self
.
exit_var
,
py_object_type
)
code
.
put_goto
(
old_error_label
)
code
.
put_label
(
step_over_label
)
code
.
funcstate
.
release_temp
(
self
.
exit_var
)
code
.
putln
(
'}'
)
class
WithTargetAssignmentStatNode
(
AssignmentNode
):
# The target assignment of the 'with' statement value (return
# value of the __enter__() call).
#
# This is a special cased assignment that steals the RHS reference
# and frees its temp.
#
# lhs ExprNode the assignment target
# rhs TempNode the return value of the __enter__() call
child_attrs
=
[
"lhs"
,
"rhs"
]
def
analyse_declarations
(
self
,
env
):
self
.
lhs
.
analyse_target_declaration
(
env
)
def
analyse_types
(
self
,
env
):
self
.
rhs
.
analyse_types
(
env
)
self
.
lhs
.
analyse_target_types
(
env
)
self
.
lhs
.
gil_assignment_check
(
env
)
self
.
orig_rhs
=
self
.
rhs
self
.
rhs
=
self
.
rhs
.
coerce_to
(
self
.
lhs
.
type
,
env
)
def
generate_execution_code
(
self
,
code
):
self
.
rhs
.
generate_evaluation_code
(
code
)
self
.
lhs
.
generate_assignment_code
(
self
.
rhs
,
code
)
self
.
orig_rhs
.
release
(
code
)
def
generate_function_definitions
(
self
,
env
,
code
):
self
.
rhs
.
generate_function_definitions
(
env
,
code
)
def
annotate
(
self
,
code
):
self
.
lhs
.
annotate
(
code
)
self
.
rhs
.
annotate
(
code
)
class
TryExceptStatNode
(
StatNode
):
# try .. except statement
#
...
...
@@ -5203,7 +5330,7 @@ class ExceptClauseNode(Node):
# pattern [ExprNode]
# target ExprNode or None
# body StatNode
# excinfo_target
Name
Node or None optional target for exception info
# excinfo_target
ResultRef
Node or None optional target for exception info
# match_flag string result of exception match
# exc_value ExcValueNode used internally
# function_name string qualified name of enclosing function
...
...
@@ -5221,8 +5348,6 @@ class ExceptClauseNode(Node):
def
analyse_declarations
(
self
,
env
):
if
self
.
target
:
self
.
target
.
analyse_target_declaration
(
env
)
if
self
.
excinfo_target
is
not
None
:
self
.
excinfo_target
.
analyse_target_declaration
(
env
)
self
.
body
.
analyse_declarations
(
env
)
def
analyse_expressions
(
self
,
env
):
...
...
@@ -5243,7 +5368,6 @@ class ExceptClauseNode(Node):
self
.
excinfo_tuple
=
ExprNodes
.
TupleNode
(
pos
=
self
.
pos
,
args
=
[
ExprNodes
.
ExcValueNode
(
pos
=
self
.
pos
,
env
=
env
)
for
x
in
range
(
3
)])
self
.
excinfo_tuple
.
analyse_expressions
(
env
)
self
.
excinfo_target
.
analyse_target_expression
(
env
,
self
.
excinfo_tuple
)
self
.
body
.
analyse_expressions
(
env
)
...
...
@@ -5298,7 +5422,7 @@ class ExceptClauseNode(Node):
for
tempvar
,
node
in
zip
(
exc_vars
,
self
.
excinfo_tuple
.
args
):
node
.
set_var
(
tempvar
)
self
.
excinfo_tuple
.
generate_evaluation_code
(
code
)
self
.
excinfo_target
.
generate_assignment_code
(
self
.
excinfo_tuple
,
code
)
self
.
excinfo_target
.
result_code
=
self
.
excinfo_tuple
.
result
(
)
old_break_label
,
old_continue_label
=
code
.
break_label
,
code
.
continue_label
code
.
break_label
=
code
.
new_label
(
'except_break'
)
...
...
@@ -5308,24 +5432,32 @@ class ExceptClauseNode(Node):
code
.
funcstate
.
exc_vars
=
exc_vars
self
.
body
.
generate_execution_code
(
code
)
code
.
funcstate
.
exc_vars
=
old_exc_vars
if
self
.
excinfo_target
is
not
None
:
self
.
excinfo_tuple
.
generate_disposal_code
(
code
)
for
var
in
exc_vars
:
code
.
put
ln
(
"__Pyx_DECREF(%s); %s = 0;"
%
(
var
,
var
)
)
code
.
put
_decref_clear
(
var
,
py_object_type
)
code
.
put_goto
(
end_label
)
if
code
.
label_used
(
code
.
break_label
):
code
.
put_label
(
code
.
break_label
)
if
self
.
excinfo_target
is
not
None
:
self
.
excinfo_tuple
.
generate_disposal_code
(
code
)
for
var
in
exc_vars
:
code
.
put
ln
(
"__Pyx_DECREF(%s); %s = 0;"
%
(
var
,
var
)
)
code
.
put
_decref_clear
(
var
,
py_object_type
)
code
.
put_goto
(
old_break_label
)
code
.
break_label
=
old_break_label
if
code
.
label_used
(
code
.
continue_label
):
code
.
put_label
(
code
.
continue_label
)
if
self
.
excinfo_target
is
not
None
:
self
.
excinfo_tuple
.
generate_disposal_code
(
code
)
for
var
in
exc_vars
:
code
.
put
ln
(
"__Pyx_DECREF(%s); %s = 0;"
%
(
var
,
var
)
)
code
.
put
_decref_clear
(
var
,
py_object_type
)
code
.
put_goto
(
old_continue_label
)
code
.
continue_label
=
old_continue_label
if
self
.
excinfo_target
is
not
None
:
self
.
excinfo_tuple
.
free_temps
(
code
)
for
temp
in
exc_vars
:
code
.
funcstate
.
release_temp
(
temp
)
...
...
@@ -5365,6 +5497,9 @@ class TryFinallyStatNode(StatNode):
preserve_exception
=
1
# handle exception case, in addition to return/break/continue
handle_error_case
=
True
disallow_continue_in_try_finally
=
0
# There doesn't seem to be any point in disallowing
# continue in the try block, since we have no problem
...
...
@@ -5398,6 +5533,8 @@ class TryFinallyStatNode(StatNode):
old_labels
=
code
.
all_new_labels
()
new_labels
=
code
.
get_all_labels
()
new_error_label
=
code
.
error_label
if
not
self
.
handle_error_case
:
code
.
error_label
=
old_error_label
catch_label
=
code
.
new_label
()
code
.
putln
(
"/*try:*/ {"
)
...
...
@@ -6068,11 +6205,12 @@ static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyOb
raise_utility_code
=
UtilityCode
(
proto
=
"""
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb
, PyObject *cause
); /*proto*/
"""
,
impl
=
"""
#if PY_MAJOR_VERSION < 3
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
/* cause is unused */
Py_XINCREF(type);
Py_XINCREF(value);
Py_XINCREF(tb);
...
...
@@ -6139,7 +6277,7 @@ raise_error:
#else /* Python 3+ */
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb
, PyObject *cause
) {
if (tb == Py_None) {
tb = 0;
} else if (tb && !PyTraceBack_Check(tb)) {
...
...
@@ -6164,6 +6302,29 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
goto bad;
}
if (cause) {
PyObject *fixed_cause;
if (PyExceptionClass_Check(cause)) {
fixed_cause = PyObject_CallObject(cause, NULL);
if (fixed_cause == NULL)
goto bad;
}
else if (PyExceptionInstance_Check(cause)) {
fixed_cause = cause;
Py_INCREF(fixed_cause);
}
else {
PyErr_SetString(PyExc_TypeError,
"exception causes must derive from "
"BaseException");
goto bad;
}
if (!value) {
value = PyObject_CallObject(type, NULL);
}
PyException_SetCause(value, fixed_cause);
}
PyErr_SetObject(type, value);
if (tb) {
...
...
@@ -6300,6 +6461,31 @@ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb)
#------------------------------------------------------------------------------------
swap_exception_utility_code
=
UtilityCode
(
proto
=
"""
static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
"""
,
impl
=
"""
static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb;
PyThreadState *tstate = PyThreadState_GET();
tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value;
tmp_tb = tstate->exc_traceback;
tstate->exc_type = *type;
tstate->exc_value = *value;
tstate->exc_traceback = *tb;
*type = tmp_type;
*value = tmp_value;
*tb = tmp_tb;
}
"""
)
#------------------------------------------------------------------------------------
arg_type_test_utility_code
=
UtilityCode
(
proto
=
"""
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
...
...
Cython/Compiler/Optimize.py
View file @
a17fac09
...
...
@@ -930,7 +930,15 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations):
conds
=
[]
temps
=
[]
for
arg
in
args
:
if
not
arg
.
is_simple
():
try
:
# Trial optimisation to avoid redundant temp
# assignments. However, since is_simple() is meant to
# be called after type analysis, we ignore any errors
# and just play safe in that case.
is_simple_arg
=
arg
.
is_simple
()
except
Exception
:
is_simple_arg
=
False
if
not
is_simple_arg
:
# must evaluate all non-simple RHS before doing the comparisons
arg
=
UtilNodes
.
LetRefNode
(
arg
)
temps
.
append
(
arg
)
...
...
@@ -3134,6 +3142,15 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
return
ExprNodes
.
BoolNode
(
node
.
pos
,
value
=
bool_result
,
constant_result
=
bool_result
)
def
visit_CondExprNode
(
self
,
node
):
self
.
_calculate_const
(
node
)
if
node
.
test
.
constant_result
is
ExprNodes
.
not_a_constant
:
return
node
if
node
.
test
.
constant_result
:
return
node
.
true_val
else
:
return
node
.
false_val
def
visit_IfStatNode
(
self
,
node
):
self
.
visitchildren
(
node
)
# eliminate dead code based on constant condition results
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
a17fac09
...
...
@@ -11,11 +11,12 @@ import Naming
import
ExprNodes
import
Nodes
import
Options
import
Builtin
from
Cython.Compiler.Visitor
import
VisitorTransform
,
TreeVisitor
from
Cython.Compiler.Visitor
import
CythonTransform
,
EnvTransform
,
ScopeTrackingTransform
from
Cython.Compiler.ModuleNode
import
ModuleNode
from
Cython.Compiler.UtilNodes
import
LetNode
,
LetRefNode
from
Cython.Compiler.UtilNodes
import
LetNode
,
LetRefNode
,
ResultRefNode
from
Cython.Compiler.TreeFragment
import
TreeFragment
,
TemplateTransform
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.Errors
import
error
,
warning
,
CompileError
,
InternalError
...
...
@@ -928,81 +929,55 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
class
WithTransform
(
CythonTransform
,
SkipDeclarations
):
# EXCINFO is manually set to a variable that contains
# the exc_info() tuple that can be generated by the enclosing except
# statement.
template_without_target
=
TreeFragment
(
u"""
MGR = EXPR
EXIT = MGR.__exit__
MGR.__enter__()
EXC = True
try:
try:
EXCINFO = None
BODY
except:
EXC = False
if not EXIT(*EXCINFO):
raise
finally:
if EXC:
EXIT(None, None, None)
"""
,
temps
=
[
u'MGR'
,
u'EXC'
,
u"EXIT"
],
pipeline
=
[
NormalizeTree
(
None
)])
template_with_target
=
TreeFragment
(
u"""
MGR = EXPR
EXIT = MGR.__exit__
VALUE = MGR.__enter__()
EXC = True
try:
try:
EXCINFO = None
TARGET = VALUE
BODY
except:
EXC = False
if not EXIT(*EXCINFO):
raise
finally:
if EXC:
EXIT(None, None, None)
MGR = EXIT = VALUE = EXC = None
"""
,
temps
=
[
u'MGR'
,
u'EXC'
,
u"EXIT"
,
u"VALUE"
],
pipeline
=
[
NormalizeTree
(
None
)])
def
visit_WithStatNode
(
self
,
node
):
# TODO: Cleanup badly needed
TemplateTransform
.
temp_name_counter
+=
1
handle
=
"__tmpvar_%d"
%
TemplateTransform
.
temp_name_counter
self
.
visitchildren
(
node
,
[
'body'
])
excinfo_temp
=
ExprNodes
.
NameNode
(
node
.
pos
,
name
=
handle
)
#TempHandle(Builtin.tuple_type)
if
node
.
target
is
not
None
:
result
=
self
.
template_with_target
.
substitute
({
u'EXPR'
:
node
.
manager
,
u'BODY'
:
node
.
body
,
u'TARGET'
:
node
.
target
,
u'EXCINFO'
:
excinfo_temp
},
pos
=
node
.
pos
)
else
:
result
=
self
.
template_without_target
.
substitute
({
u'EXPR'
:
node
.
manager
,
u'BODY'
:
node
.
body
,
u'EXCINFO'
:
excinfo_temp
},
pos
=
node
.
pos
)
# Set except excinfo target to EXCINFO
try_except
=
result
.
stats
[
-
1
].
body
.
stats
[
-
1
]
try_except
.
except_clauses
[
0
].
excinfo_target
=
ExprNodes
.
NameNode
(
node
.
pos
,
name
=
handle
)
# excinfo_temp.ref(node.pos))
# result.stats[-1].body.stats[-1] = TempsBlockNode(
# node.pos, temps=[excinfo_temp], body=try_except)
self
.
visitchildren
(
node
,
'body'
)
pos
=
node
.
pos
body
,
target
,
manager
=
node
.
body
,
node
.
target
,
node
.
manager
node
.
target_temp
=
ExprNodes
.
TempNode
(
pos
,
type
=
PyrexTypes
.
py_object_type
)
if
target
is
not
None
:
node
.
has_target
=
True
body
=
Nodes
.
StatListNode
(
pos
,
stats
=
[
Nodes
.
WithTargetAssignmentStatNode
(
pos
,
lhs
=
target
,
rhs
=
node
.
target_temp
),
body
])
node
.
target
=
None
excinfo_target
=
ResultRefNode
(
pos
=
pos
,
type
=
Builtin
.
tuple_type
,
may_hold_none
=
False
)
except_clause
=
Nodes
.
ExceptClauseNode
(
pos
,
body
=
Nodes
.
IfStatNode
(
pos
,
if_clauses
=
[
Nodes
.
IfClauseNode
(
pos
,
condition
=
ExprNodes
.
NotNode
(
pos
,
operand
=
ExprNodes
.
WithExitCallNode
(
pos
,
with_stat
=
node
,
args
=
excinfo_target
)),
body
=
Nodes
.
ReraiseStatNode
(
pos
),
),
],
else_clause
=
None
),
pattern
=
None
,
target
=
None
,
excinfo_target
=
excinfo_target
,
)
return
result
node
.
body
=
Nodes
.
TryFinallyStatNode
(
pos
,
body
=
Nodes
.
TryExceptStatNode
(
pos
,
body
=
body
,
except_clauses
=
[
except_clause
],
else_clause
=
None
,
),
finally_clause
=
Nodes
.
ExprStatNode
(
pos
,
expr
=
ExprNodes
.
WithExitCallNode
(
pos
,
with_stat
=
node
,
args
=
ExprNodes
.
TupleNode
(
pos
,
args
=
[
ExprNodes
.
NoneNode
(
pos
)
for
_
in
range
(
3
)]
))),
handle_error_case
=
False
,
)
return
node
def
visit_ExprNode
(
self
,
node
):
# With statements are never inside expressions.
...
...
@@ -1602,6 +1577,12 @@ class CreateClosureClasses(CythonTransform):
is_cdef
=
True
)
klass
.
declare_var
(
pos
=
pos
,
name
=
'resume_label'
,
cname
=
'resume_label'
,
type
=
PyrexTypes
.
c_int_type
,
is_cdef
=
True
)
klass
.
declare_var
(
pos
=
pos
,
name
=
'exc_type'
,
cname
=
'exc_type'
,
type
=
PyrexTypes
.
py_object_type
,
is_cdef
=
True
)
klass
.
declare_var
(
pos
=
pos
,
name
=
'exc_value'
,
cname
=
'exc_value'
,
type
=
PyrexTypes
.
py_object_type
,
is_cdef
=
True
)
klass
.
declare_var
(
pos
=
pos
,
name
=
'exc_traceback'
,
cname
=
'exc_traceback'
,
type
=
PyrexTypes
.
py_object_type
,
is_cdef
=
True
)
import
TypeSlots
e
=
klass
.
declare_pyfunction
(
'send'
,
pos
)
...
...
Cython/Compiler/Parsing.py
View file @
a17fac09
...
...
@@ -1172,6 +1172,7 @@ def p_raise_statement(s):
exc_type
=
None
exc_value
=
None
exc_tb
=
None
cause
=
None
if
s
.
sy
not
in
statement_terminators
:
exc_type
=
p_test
(
s
)
if
s
.
sy
==
','
:
...
...
@@ -1180,11 +1181,15 @@ def p_raise_statement(s):
if
s
.
sy
==
','
:
s
.
next
()
exc_tb
=
p_test
(
s
)
elif
s
.
sy
==
'from'
:
s
.
next
()
cause
=
p_test
(
s
)
if
exc_type
or
exc_value
or
exc_tb
:
return
Nodes
.
RaiseStatNode
(
pos
,
exc_type
=
exc_type
,
exc_value
=
exc_value
,
exc_tb
=
exc_tb
)
exc_tb
=
exc_tb
,
cause
=
cause
)
else
:
return
Nodes
.
ReraiseStatNode
(
pos
)
...
...
@@ -1660,15 +1665,27 @@ def p_simple_statement_list(s, ctx, first_statement = 0):
# Parse a series of simple statements on one line
# separated by semicolons.
stat
=
p_simple_statement
(
s
,
first_statement
=
first_statement
)
if
s
.
sy
==
';'
:
stats
=
[
stat
]
pos
=
stat
.
pos
stats
=
[]
if
not
isinstance
(
stat
,
Nodes
.
PassStatNode
):
stats
.
append
(
stat
)
while
s
.
sy
==
';'
:
#print "p_simple_statement_list: maybe more to follow" ###
s
.
next
()
if
s
.
sy
in
(
'NEWLINE'
,
'EOF'
):
break
stats
.
append
(
p_simple_statement
(
s
))
stat
=
Nodes
.
StatListNode
(
stats
[
0
].
pos
,
stats
=
stats
)
stat
=
p_simple_statement
(
s
,
first_statement
=
first_statement
)
if
isinstance
(
stat
,
Nodes
.
PassStatNode
):
continue
stats
.
append
(
stat
)
first_statement
=
False
if
not
stats
:
stat
=
Nodes
.
PassStatNode
(
pos
)
elif
len
(
stats
)
==
1
:
stat
=
stats
[
0
]
else
:
stat
=
Nodes
.
StatListNode
(
pos
,
stats
=
stats
)
s
.
expect_newline
(
"Syntax error in simple statement list"
)
return
stat
...
...
@@ -1805,9 +1822,14 @@ def p_statement_list(s, ctx, first_statement = 0):
pos
=
s
.
position
()
stats
=
[]
while
s
.
sy
not
in
(
'DEDENT'
,
'EOF'
):
stats
.
append
(
p_statement
(
s
,
ctx
,
first_statement
=
first_statement
))
first_statement
=
0
if
len
(
stats
)
==
1
:
stat
=
p_statement
(
s
,
ctx
,
first_statement
=
first_statement
)
if
isinstance
(
stat
,
Nodes
.
PassStatNode
):
continue
stats
.
append
(
stat
)
first_statement
=
False
if
not
stats
:
return
Nodes
.
PassStatNode
(
pos
)
elif
len
(
stats
)
==
1
:
return
stats
[
0
]
else
:
return
Nodes
.
StatListNode
(
pos
,
stats
=
stats
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
a17fac09
...
...
@@ -2739,7 +2739,8 @@ def best_match(args, functions, pos=None, env=None):
possibilities
=
[]
bad_types
=
[]
needed_coercions
=
{}
for
func
,
func_type
in
candidates
:
for
index
,
(
func
,
func_type
)
in
enumerate
(
candidates
):
score
=
[
0
,
0
,
0
,
0
]
for
i
in
range
(
min
(
len
(
args
),
len
(
func_type
.
args
))):
src_type
=
args
[
i
].
type
...
...
@@ -2782,7 +2783,7 @@ def best_match(args, functions, pos=None, env=None):
bad_types
.
append
((
func
,
error_mesg
))
break
else
:
possibilities
.
append
((
score
,
func
))
# so we can sort it
possibilities
.
append
((
score
,
index
,
func
))
# so we can sort it
if
possibilities
:
possibilities
.
sort
()
...
...
@@ -2791,7 +2792,7 @@ def best_match(args, functions, pos=None, env=None):
error
(
pos
,
"ambiguous overloaded method"
)
return
None
function
=
possibilities
[
0
][
1
]
function
=
possibilities
[
0
][
-
1
]
if
function
in
needed_coercions
and
env
:
arg_i
,
coerce_to_type
=
needed_coercions
[
function
]
...
...
Cython/Compiler/Symtab.py
View file @
a17fac09
...
...
@@ -564,11 +564,16 @@ class Scope(object):
entry.is_anonymous = True
return entry
def declare_lambda_function(self,
func_c
name, pos):
def declare_lambda_function(self,
lambda_
name, pos):
# Add an entry for an anonymous Python function.
entry = self.declare_var(None, py_object_type, pos,
cname=func_cname, visibility='private')
entry.name = EncodedString(func_cname)
func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
qualified_name = self.qualify_name(lambda_name)
entry = self.declare(None, func_cname, py_object_type, pos, 'private')
entry.name = lambda_name
entry.qualified_name = qualified_name
entry.pymethdef_cname = pymethdef_cname
entry.func_cname = func_cname
entry.signature = pyfunction_signature
entry.is_anonymous = True
...
...
@@ -927,21 +932,18 @@ class ModuleScope(Scope):
return self.outer_scope.lookup(name, language_level = self.context.language_level)
def declare_builtin(self, name, pos):
if not hasattr(builtins, name) and name not in Code.non_portable_builtins_map:
# 'xrange' and 'BaseException' are special cased in Code.py
if not hasattr(builtins, name)
\
and name not in Code.non_portable_builtins_map
\
and name not in Code.uncachable_builtins:
if self.has_import_star:
entry = self.declare_var(name, py_object_type, pos)
return entry
## elif self.outer_scope is not None:
## entry = self.outer_scope.declare_builtin(name, pos)
## print entry
## return entry
else:
# unknown - assume it's builtin and look it up at runtime
if Options.error_on_unknown_names:
error(pos, "
undeclared
name
not
builtin
:
%
s
" % name)
else:
warning(pos, "
undeclared
name
not
builtin
:
%
s
" % name, 2)
# unknown - assume it's builtin and look it up at runtime
entry = self.declare(name, None, py_object_type, pos, 'private')
entry.is_builtin = 1
return entry
...
...
@@ -950,7 +952,7 @@ class ModuleScope(Scope):
if entry.name == name:
return entry
entry = self.declare(None, None, py_object_type, pos, 'private')
if Options.cache_builtins:
if Options.cache_builtins
and name not in Code.uncachable_builtins
:
entry.is_builtin = 1
entry.is_const = 1 # cached
entry.name = name
...
...
@@ -959,6 +961,7 @@ class ModuleScope(Scope):
self.undeclared_cached_builtins.append(entry)
else:
entry.is_builtin = 1
entry.name = name
return entry
def find_module(self, module_name, pos):
...
...
@@ -1414,6 +1417,12 @@ class GeneratorExpressionScope(Scope):
self
.
entries
[
name
]
=
entry
return
entry
def
declare_lambda_function
(
self
,
func_cname
,
pos
):
return
self
.
outer_scope
.
declare_lambda_function
(
func_cname
,
pos
)
def
add_lambda_def
(
self
,
def_node
):
return
self
.
outer_scope
.
add_lambda_def
(
def_node
)
class
ClosureScope
(
LocalScope
):
...
...
Cython/Compiler/Tests/TestTreeFragment.py
View file @
a17fac09
...
...
@@ -54,11 +54,10 @@ class TestTreeFragments(CythonTest):
x = TMP
"""
)
T
=
F
.
substitute
(
temps
=
[
u"TMP"
])
s
=
T
.
stats
self
.
assert_
(
s
[
0
].
expr
.
name
==
"__tmpvar_1"
)
# self.assert_(isinstance(s[0].expr, TempRefNode))
# self.assert_(isinstance(s[1].rhs, TempRefNode))
# self.assert_(s[0].expr.handle is s[1].rhs.handle)
s
=
T
.
body
.
stats
self
.
assert_
(
isinstance
(
s
[
0
].
expr
,
TempRefNode
))
self
.
assert_
(
isinstance
(
s
[
1
].
rhs
,
TempRefNode
))
self
.
assert_
(
s
[
0
].
expr
.
handle
is
s
[
1
].
rhs
.
handle
)
if
__name__
==
"__main__"
:
import
unittest
...
...
Cython/Compiler/TreeFragment.py
View file @
a17fac09
...
...
@@ -121,16 +121,15 @@ class TemplateTransform(VisitorTransform):
temphandles
=
[]
for
temp
in
temps
:
TemplateTransform
.
temp_name_counter
+=
1
handle
=
"__tmpvar_%d"
%
TemplateTransform
.
temp_name_counter
# handle = UtilNodes.TempHandle(PyrexTypes.py_object_type)
handle
=
UtilNodes
.
TempHandle
(
PyrexTypes
.
py_object_type
)
tempmap
[
temp
]
=
handle
#
temphandles.append(handle)
temphandles
.
append
(
handle
)
self
.
tempmap
=
tempmap
result
=
super
(
TemplateTransform
,
self
).
__call__
(
node
)
#
if temps:
#
result = UtilNodes.TempsBlockNode(self.get_pos(node),
#
temps=temphandles,
#
body=result)
if
temps
:
result
=
UtilNodes
.
TempsBlockNode
(
self
.
get_pos
(
node
),
temps
=
temphandles
,
body
=
result
)
return
result
def
get_pos
(
self
,
node
):
...
...
@@ -161,9 +160,8 @@ class TemplateTransform(VisitorTransform):
def
visit_NameNode
(
self
,
node
):
temphandle
=
self
.
tempmap
.
get
(
node
.
name
)
if
temphandle
:
return
NameNode
(
pos
=
node
.
pos
,
name
=
temphandle
)
# Replace name with temporary
#
return temphandle.ref(self.get_pos(node))
return
temphandle
.
ref
(
self
.
get_pos
(
node
))
else
:
return
self
.
try_substitution
(
node
,
node
.
name
)
...
...
Cython/Compiler/UtilNodes.py
View file @
a17fac09
...
...
@@ -134,6 +134,10 @@ class ResultRefNode(AtomicExprNode):
self
.
type
=
type
assert
self
.
pos
is
not
None
def
clone_node
(
self
):
# nothing to do here
return
self
def
analyse_types
(
self
,
env
):
if
self
.
expression
is
not
None
:
self
.
type
=
self
.
expression
.
type
...
...
Cython/Includes/libcpp/string.pxd
0 → 100644
View file @
a17fac09
cdef
extern
from
"<string>"
namespace
"std"
:
size_t
npos
=
-
1
cdef
cppclass
string
:
string
()
string
(
char
*
)
string
(
char
*
,
size_t
)
string
(
string
&
)
# as a string formed by a repetition of character c, n times.
string
(
size_t
,
char
)
char
*
c_str
()
size_t
size
()
size_t
max_size
()
size_t
length
()
void
resize
(
size_t
)
void
resize
(
size_t
,
char
c
)
size_t
capacity
()
void
reserve
(
size_t
)
void
clear
()
bint
empty
()
char
at
(
size_t
)
char
operator
[](
size_t
)
int
compare
(
string
&
)
string
&
append
(
string
&
)
string
&
append
(
string
&
,
size_t
,
size_t
)
string
&
append
(
char
*
)
string
&
append
(
char
*
,
size_t
)
string
&
append
(
size_t
,
char
)
void
push_back
(
char
c
)
string
&
assign
(
string
&
)
string
&
assign
(
string
&
,
size_t
,
size_t
)
string
&
assign
(
char
*
,
size_t
)
string
&
assign
(
char
*
)
string
&
assign
(
size_t
n
,
char
c
)
string
&
insert
(
size_t
,
string
&
)
string
&
insert
(
size_t
,
string
&
,
size_t
,
size_t
)
string
&
insert
(
size_t
,
char
*
s
,
size_t
)
string
&
insert
(
size_t
,
char
*
s
)
string
&
insert
(
size_t
,
size_t
,
char
c
)
size_t
copy
(
char
*
,
size_t
,
size_t
)
size_t
find
(
string
&
)
size_t
find
(
string
&
,
size_t
)
size_t
find
(
char
*
,
size_t
pos
,
size_t
)
size_t
find
(
char
*
,
size_t
pos
)
size_t
find
(
char
,
size_t
pos
)
size_t
rfind
(
string
&
,
size_t
)
size_t
rfind
(
char
*
s
,
size_t
,
size_t
)
size_t
rfind
(
char
*
,
size_t
pos
)
size_t
rfind
(
char
c
,
size_t
)
size_t
rfind
(
char
c
)
size_t
find_first_of
(
string
&
,
size_t
)
size_t
find_first_of
(
char
*
s
,
size_t
,
size_t
)
size_t
find_first_of
(
char
*
,
size_t
pos
)
size_t
find_first_of
(
char
c
,
size_t
)
size_t
find_first_of
(
char
c
)
size_t
find_first_not_of
(
string
&
,
size_t
)
size_t
find_first_not_of
(
char
*
s
,
size_t
,
size_t
)
size_t
find_first_not_of
(
char
*
,
size_t
pos
)
size_t
find_first_not_of
(
char
c
,
size_t
)
size_t
find_first_not_of
(
char
c
)
size_t
find_last_of
(
string
&
,
size_t
)
size_t
find_last_of
(
char
*
s
,
size_t
,
size_t
)
size_t
find_last_of
(
char
*
,
size_t
pos
)
size_t
find_last_of
(
char
c
,
size_t
)
size_t
find_last_of
(
char
c
)
size_t
find_last_not_of
(
string
&
,
size_t
)
size_t
find_last_not_of
(
char
*
s
,
size_t
,
size_t
)
size_t
find_last_not_of
(
char
*
,
size_t
pos
)
string
substr
(
size_t
,
size_t
)
string
substr
()
string
substr
(
size_t
)
size_t
find_last_not_of
(
char
c
,
size_t
)
size_t
find_last_not_of
(
char
c
)
#string& operator= (string&)
#string& operator= (char*)
#string& operator= (char)
bint
operator
==
(
string
&
)
bint
operator
==
(
char
*
)
bint
operator
!=
(
string
&
rhs
)
bint
operator
!=
(
char
*
)
bint
operator
<
(
string
&
)
bint
operator
<
(
char
*
)
bint
operator
>
(
string
&
)
bint
operator
>
(
char
*
)
bint
operator
<=
(
string
&
)
bint
operator
<=
(
char
*
)
bint
operator
>=
(
string
&
)
bint
operator
>=
(
char
*
)
Cython/Plex/Errors.py
View file @
a17fac09
...
...
@@ -39,7 +39,7 @@ class UnrecognizedInput(PlexError):
def
__init__
(
self
,
scanner
,
state_name
):
self
.
scanner
=
scanner
self
.
position
=
scanner
.
position
()
self
.
position
=
scanner
.
get_
position
()
self
.
state_name
=
state_name
def
__str__
(
self
):
...
...
Cython/Plex/Scanners.py
View file @
a17fac09
...
...
@@ -299,6 +299,11 @@ class Scanner(object):
"""
return
(
self
.
name
,
self
.
start_line
,
self
.
start_col
)
def
get_position
(
self
):
"""Python accessible wrapper around position(), only for error reporting.
"""
return
self
.
position
()
def
begin
(
self
,
state_name
):
"""Set the current state of the scanner to the named state."""
self
.
initial_state
=
(
...
...
pyximport/pyximport.py
View file @
a17fac09
...
...
@@ -261,7 +261,8 @@ class PyImporter(PyxImporter):
self
.
super
=
super
(
PyImporter
,
self
)
self
.
super
.
__init__
(
extension
=
'.py'
,
pyxbuild_dir
=
pyxbuild_dir
)
self
.
uncompilable_modules
=
{}
self
.
blocked_modules
=
[
'Cython'
,
'distutils.extension'
]
self
.
blocked_modules
=
[
'Cython'
,
'distutils.extension'
,
'distutils.sysconfig'
]
def
find_module
(
self
,
fullname
,
package_path
=
None
):
if
fullname
in
sys
.
modules
:
...
...
runtests.py
View file @
a17fac09
...
...
@@ -69,20 +69,18 @@ if sys.platform == 'win32':
distutils_distro
.
parse_config_files
(
cfgfiles
)
EXT_DEP_MODULES
=
{
'
numpy'
:
'tag:
numpy'
,
'
pstats'
:
'tag:
pstats'
,
'
posix'
:
'tag:
posix'
,
'
tag:numpy'
:
'
numpy'
,
'
tag:pstats'
:
'
pstats'
,
'
tag:posix'
:
'
posix'
,
}
def
get_numpy_include_dirs
(
):
def
update_numpy_extension
(
ext
):
import
numpy
return
[
numpy
.
get_include
()]
ext
.
include_dirs
.
append
(
numpy
.
get_include
())
# TODO: use tags
EXT_DEP_INCLUDES
=
[
# test name matcher , callable returning list
(
re
.
compile
(
'numpy_.*'
).
match
,
get_numpy_include_dirs
),
]
EXT_EXTRAS
=
{
'tag:numpy'
:
update_numpy_extension
,
}
# TODO: use tags
VER_DEP_MODULES
=
{
...
...
@@ -101,11 +99,15 @@ VER_DEP_MODULES = {
'run.generators_py'
,
# generators, with statement
'run.pure_py'
,
# decorators, with statement
]),
(
2
,
7
)
:
(
operator
.
lt
,
lambda
x
:
x
in
[
'run.withstat_py'
,
# multi context with statement
]),
# The next line should start (3,); but this is a dictionary, so
# we can only have one (3,) key. Since 2.7 is supposed to be the
# last 2.x release, things would have to change drastically for this
# to be unsafe...
(
2
,
999
):
(
operator
.
lt
,
lambda
x
:
x
in
[
'run.special_methods_T561_py3'
]),
(
2
,
999
):
(
operator
.
lt
,
lambda
x
:
x
in
[
'run.special_methods_T561_py3'
,
'run.test_raisefrom'
,
]),
(
3
,):
(
operator
.
ge
,
lambda
x
:
x
in
[
'run.non_future_division'
,
'compile.extsetslice'
,
'compile.extdelslice'
,
...
...
@@ -155,6 +157,8 @@ def parse_tags(filepath):
parse_tags
=
memoize
(
parse_tags
)
list_unchanging_dir
=
memoize
(
lambda
x
:
os
.
listdir
(
x
))
class
build_ext
(
_build_ext
):
def
build_extension
(
self
,
ext
):
...
...
@@ -241,7 +245,7 @@ class TestBuilder(object):
os
.
makedirs
(
workdir
)
suite
=
unittest
.
TestSuite
()
filenames
=
os
.
list
dir
(
path
)
filenames
=
list_unchanging_
dir
(
path
)
filenames
.
sort
()
for
filename
in
filenames
:
filepath
=
os
.
path
.
join
(
path
,
filename
)
...
...
@@ -293,7 +297,7 @@ class TestBuilder(object):
return
suite
def
build_tests
(
self
,
test_class
,
path
,
workdir
,
module
,
expect_errors
,
tags
):
if
'werror'
in
tags
[
'tag
s
'
]:
if
'werror'
in
tags
[
'tag'
]:
warning_errors
=
True
else
:
warning_errors
=
False
...
...
@@ -353,6 +357,8 @@ class CythonCompileTestCase(unittest.TestCase):
def
setUp
(
self
):
from
Cython.Compiler
import
Options
self
.
_saved_options
=
[
(
name
,
getattr
(
Options
,
name
))
for
name
in
(
'warning_errors'
,
'error_on_unknown_names'
)
]
Options
.
warning_errors
=
self
.
warning_errors
if
self
.
workdir
not
in
sys
.
path
:
...
...
@@ -360,7 +366,8 @@ class CythonCompileTestCase(unittest.TestCase):
def
tearDown
(
self
):
from
Cython.Compiler
import
Options
Options
.
warning_errors
=
False
for
name
,
value
in
self
.
_saved_options
:
setattr
(
Options
,
name
,
value
)
try
:
sys
.
path
.
remove
(
self
.
workdir
)
...
...
@@ -408,18 +415,20 @@ class CythonCompileTestCase(unittest.TestCase):
target
=
'%s.%s'
%
(
module_name
,
self
.
language
)
return
target
def
copy_related_files
(
self
,
test_directory
,
targe
t_directory
,
module_name
):
def
related_files
(
self
,
tes
t_directory
,
module_name
):
is_related
=
re
.
compile
(
'%s_.*[.].*'
%
module_name
).
match
for
filename
in
os
.
listdir
(
test_directory
):
if
is_related
(
filename
):
return
[
filename
for
filename
in
list_unchanging_dir
(
test_directory
)
if
is_related
(
filename
)]
def
copy_files
(
self
,
test_directory
,
target_directory
,
file_list
):
for
filename
in
file_list
:
shutil
.
copy
(
os
.
path
.
join
(
test_directory
,
filename
),
target_directory
)
def
find_source_files
(
self
,
workdir
,
module_name
):
is_related
=
re
.
compile
(
'%s_.*[.]%s'
%
(
module_name
,
self
.
language
)).
match
return
[
self
.
build_target_filename
(
module_name
)]
+
[
filename
for
filename
in
os
.
listdir
(
workdir
)
if
is_related
(
filename
)
and
os
.
path
.
isfile
(
os
.
path
.
join
(
workdir
,
filename
))
]
def
source_files
(
self
,
workdir
,
module_name
,
file_list
):
return
([
self
.
build_target_filename
(
module_name
)]
+
[
filename
for
filename
in
file_list
if
not
os
.
path
.
isfile
(
os
.
path
.
join
(
workdir
,
filename
))])
def
split_source_and_output
(
self
,
test_directory
,
module
,
workdir
):
source_file
=
self
.
find_module_source_file
(
os
.
path
.
join
(
test_directory
,
module
)
+
'.pyx'
)
...
...
@@ -480,6 +489,12 @@ class CythonCompileTestCase(unittest.TestCase):
def
run_distutils
(
self
,
test_directory
,
module
,
workdir
,
incdir
,
extra_extension_args
=
None
):
original_source
=
self
.
find_module_source_file
(
os
.
path
.
join
(
test_directory
,
module
+
'.pyx'
))
try
:
tags
=
parse_tags
(
original_source
)
except
IOError
:
tags
=
{}
cwd
=
os
.
getcwd
()
os
.
chdir
(
workdir
)
try
:
...
...
@@ -490,24 +505,27 @@ class CythonCompileTestCase(unittest.TestCase):
build_extension
.
finalize_options
()
if
COMPILER
:
build_extension
.
compiler
=
COMPILER
ext_include_dirs
=
[]
for
match
,
get_additional_include_dirs
in
EXT_DEP_INCLUDES
:
if
match
(
module
):
ext_include_dirs
+=
get_additional_include_dirs
()
ext_compile_flags
=
CFLAGS
[:]
if
build_extension
.
compiler
==
'mingw32'
:
ext_compile_flags
.
append
(
'-Wno-format'
)
if
extra_extension_args
is
None
:
extra_extension_args
=
{}
self
.
copy_related_files
(
test_directory
,
workdir
,
module
)
related_files
=
self
.
related_files
(
test_directory
,
module
)
self
.
copy_files
(
test_directory
,
workdir
,
related_files
)
extension
=
Extension
(
module
,
sources
=
self
.
find_source_files
(
workdir
,
module
),
include_dirs
=
ext_include_dirs
,
sources
=
self
.
source_files
(
workdir
,
module
,
related_files
),
extra_compile_args
=
ext_compile_flags
,
**
extra_extension_args
)
for
matcher
,
fixer
in
EXT_EXTRAS
.
items
():
if
isinstance
(
matcher
,
str
):
del
EXT_EXTRAS
[
matcher
]
matcher
=
string_selector
(
matcher
)
EXT_EXTRAS
[
matcher
]
=
fixer
if
matcher
(
module
,
tags
):
extension
=
fixer
(
extension
)
or
extension
if
self
.
language
==
'cpp'
:
extension
.
language
=
'c++'
build_extension
.
extensions
=
[
extension
]
...
...
@@ -583,8 +601,15 @@ class CythonRunTestCase(CythonCompileTestCase):
self
.
run_doctests
(
self
.
module
,
result
)
def
run_doctests
(
self
,
module_name
,
result
):
if
sys
.
version_info
[
0
]
>=
3
or
not
hasattr
(
os
,
'fork'
)
or
not
self
.
fork
:
doctest
.
DocTestSuite
(
module_name
).
run
(
result
)
def
run_test
(
result
):
tests
=
doctest
.
DocTestSuite
(
module_name
)
tests
.
run
(
result
)
run_forked_test
(
result
,
run_test
,
self
.
shortDescription
(),
self
.
fork
)
def
run_forked_test
(
result
,
run_func
,
test_name
,
fork
=
True
):
if
not
fork
or
sys
.
version_info
[
0
]
>=
3
or
not
hasattr
(
os
,
'fork'
):
run_func
(
result
)
gc
.
collect
()
return
...
...
@@ -599,15 +624,14 @@ class CythonRunTestCase(CythonCompileTestCase):
tests
=
None
try
:
partial_result
=
PartialTestResult
(
result
)
tests
=
doctest
.
DocTestSuite
(
module_name
)
tests
.
run
(
partial_result
)
run_func
(
partial_result
)
gc
.
collect
()
except
Exception
:
if
tests
is
None
:
# importing failed, try to fake a test class
tests
=
_FakeClass
(
failureException
=
sys
.
exc_info
()[
1
],
_shortDescription
=
self
.
shortDescription
()
,
_shortDescription
=
test_name
,
module_name
=
None
)
partial_result
.
addError
(
tests
,
sys
.
exc_info
())
result_code
=
1
...
...
@@ -738,6 +762,11 @@ class CythonUnitTestCase(CythonRunTestCase):
class
CythonPyregrTestCase
(
CythonRunTestCase
):
def
setUp
(
self
):
CythonRunTestCase
.
setUp
(
self
)
from
Cython.Compiler
import
Options
Options
.
error_on_unknown_names
=
False
def
_run_unittest
(
self
,
result
,
*
classes
):
"""Run tests from unittest.TestCase-derived classes."""
valid_types
=
(
unittest
.
TestSuite
,
unittest
.
TestCase
)
...
...
@@ -763,6 +792,7 @@ class CythonPyregrTestCase(CythonRunTestCase):
except
ImportError
:
# Py3k
from
test
import
support
def
run_test
(
result
):
def
run_unittest
(
*
classes
):
return
self
.
_run_unittest
(
result
,
*
classes
)
def
run_doctest
(
module
,
verbosity
=
None
):
...
...
@@ -778,6 +808,8 @@ class CythonPyregrTestCase(CythonRunTestCase):
except
(
unittest
.
SkipTest
,
support
.
ResourceDenied
):
result
.
addSkip
(
self
,
'ok'
)
run_forked_test
(
result
,
run_test
,
self
.
shortDescription
(),
self
.
fork
)
include_debugger
=
sys
.
version_info
[:
2
]
>
(
2
,
5
)
def
collect_unittests
(
path
,
module_prefix
,
suite
,
selectors
):
...
...
@@ -979,9 +1011,9 @@ class EmbedTest(unittest.TestCase):
class
MissingDependencyExcluder
:
def
__init__
(
self
,
deps
):
# deps: { m
odule name : matcher func
}
# deps: { m
atcher func : module name
}
self
.
exclude_matchers
=
[]
for
m
od
,
matcher
in
deps
.
items
():
for
m
atcher
,
mod
in
deps
.
items
():
try
:
__import__
(
mod
)
except
ImportError
:
...
...
@@ -1168,6 +1200,9 @@ def main():
parser
.
add_option
(
"--coverage-xml"
,
dest
=
"coverage_xml"
,
action
=
"store_true"
,
default
=
False
,
help
=
"collect source coverage data for the Compiler in XML format"
)
parser
.
add_option
(
"--coverage-html"
,
dest
=
"coverage_html"
,
action
=
"store_true"
,
default
=
False
,
help
=
"collect source coverage data for the Compiler in HTML format"
)
parser
.
add_option
(
"-A"
,
"--annotate"
,
dest
=
"annotate_source"
,
action
=
"store_true"
,
default
=
True
,
help
=
"generate annotated HTML versions of the test source files"
)
...
...
@@ -1223,9 +1258,9 @@ def main():
WITH_CYTHON
=
options
.
with_cython
if
options
.
coverage
or
options
.
coverage_xml
:
if
options
.
coverage
or
options
.
coverage_xml
or
options
.
coverage_html
:
if
not
WITH_CYTHON
:
options
.
coverage
=
options
.
coverage_xml
=
False
options
.
coverage
=
options
.
coverage_xml
=
options
.
coverage_html
=
False
else
:
from
coverage
import
coverage
as
_coverage
coverage
=
_coverage
(
branch
=
True
)
...
...
@@ -1339,15 +1374,15 @@ def main():
test_suite
.
addTest
(
filetests
.
build_suite
())
if
options
.
system_pyregr
and
languages
:
sys_pyregr_dir
=
os
.
path
.
join
(
sys
.
prefix
,
'lib'
,
'python'
+
sys
.
version
[:
3
],
'test'
)
if
os
.
path
.
isdir
(
sys_pyregr_dir
):
filetests
=
TestBuilder
(
ROOTDIR
,
WORKDIR
,
selectors
,
exclude_selectors
,
options
.
annotate_source
,
options
.
cleanup_workdir
,
options
.
cleanup_sharedlibs
,
True
,
options
.
cython_only
,
languages
,
test_bugs
,
options
.
fork
,
options
.
language_level
)
test_suite
.
addTest
(
filetests
.
handle_directory
(
os
.
path
.
join
(
sys
.
prefix
,
'lib'
,
'python'
+
sys
.
version
[:
3
],
'test'
),
'pyregr'
))
options
.
fork
,
sys
.
version_info
[
0
])
sys
.
stderr
.
write
(
"Including CPython regression tests in %s
\
n
"
%
sys_pyregr_dir
)
test_suite
.
addTest
(
filetests
.
handle_directory
(
sys_pyregr_dir
,
'pyregr'
))
if
options
.
xml_output_dir
:
from
Cython.Tests.xmlrunner
import
XMLTestRunner
...
...
@@ -1358,7 +1393,7 @@ def main():
result
=
test_runner
.
run
(
test_suite
)
if
options
.
coverage
or
options
.
coverage_xml
:
if
options
.
coverage
or
options
.
coverage_xml
or
options
.
coverage_html
:
coverage
.
stop
()
ignored_modules
=
(
'Options'
,
'Version'
,
'DebugFlags'
,
'CmdLine'
)
modules
=
[
module
for
name
,
module
in
sys
.
modules
.
items
()
...
...
@@ -1369,6 +1404,8 @@ def main():
coverage
.
report
(
modules
,
show_missing
=
0
)
if
options
.
coverage_xml
:
coverage
.
xml_report
(
modules
,
outfile
=
"coverage-report.xml"
)
if
options
.
coverage_html
:
coverage
.
html_report
(
modules
,
directory
=
"coverage-report-html"
)
if
missing_dep_excluder
.
tests_missing_deps
:
sys
.
stderr
.
write
(
"Following tests excluded because of missing dependencies on your system:
\
n
"
)
...
...
setup.py
View file @
a17fac09
...
...
@@ -249,7 +249,11 @@ except ValueError:
try
:
sys
.
argv
.
remove
(
"--no-cython-compile"
)
compile_cython_itself
=
False
except
ValueError
:
compile_cython_itself
=
True
if
compile_cython_itself
:
compile_cython_modules
(
cython_profile
,
cython_compile_more
,
cython_with_refnanny
)
setup_args
.
update
(
setuptools_extra_args
)
...
...
tests/bugs.txt
View file @
a17fac09
...
...
@@ -10,7 +10,6 @@ cfunc_call_tuple_args_T408
compile.cpp_operators
cpp_templated_ctypedef
cpp_structs
with_statement_module_level_T536
function_as_method_T494
closure_inside_cdef_T554
pure_mode_cmethod_inheritance_T583
...
...
@@ -22,12 +21,20 @@ class_scope_T671
# 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
pyregr.test_pep3131
# CPython regression tests that don't make sense
pyregr.test_gdb
pyregr.test_support
# Inlined generators
all
any
builtin_sorted
dictcomp
inlined_generator_expressions
setcomp
tests/compile/future_imports.pyx
0 → 100644
View file @
a17fac09
# mode: compile
from
__future__
import
nested_scopes
from
__future__
import
with_statement
pass
from
__future__
import
nested_scopes
;
from
__future__
import
nested_scopes
tests/errors/w_cdef_override.pyx
View file @
a17fac09
# mode: error
# tag
s
: werror
# tag: werror
cdef
foo
():
pass
...
...
tests/run/arithmetic_analyse_types.pyx
View file @
a17fac09
...
...
@@ -18,40 +18,40 @@ def short_binop(short val):
"""
Arithmetic in C is always done with at least int precision.
>>>
short_binop(3
)
'int called'
>>>
print(short_binop(3)
)
int called
"""
assert
typeof
(
val
+
val
)
==
"int"
,
typeof
(
val
+
val
)
assert
typeof
(
val
-
val
)
==
"int"
,
typeof
(
val
-
val
)
assert
typeof
(
val
&
val
)
==
"int"
,
typeof
(
val
&
val
)
cdef
int_return
x
=
f
(
val
+
val
)
return
x
.
msg
return
x
.
msg
.
decode
(
'ASCII'
)
def
short_unnop
(
short
val
):
"""
Arithmetic in C is always done with at least int precision.
>>>
short_unnop(3
)
'int called'
>>>
print(short_unnop(3)
)
int called
"""
cdef
int_return
x
=
f
(
-
val
)
return
x
.
msg
return
x
.
msg
.
decode
(
'ASCII'
)
def
longlong_binop
(
long
long
val
):
"""
>>>
longlong_binop(3
)
'long long called'
>>>
print(longlong_binop(3)
)
long long called
"""
cdef
longlong_return
x
=
f
(
val
*
val
)
return
x
.
msg
return
x
.
msg
.
decode
(
'ASCII'
)
def
longlong_unnop
(
long
long
val
):
"""
>>>
longlong_unnop(3
)
'long long called'
>>>
print(longlong_unnop(3)
)
long long called
"""
cdef
longlong_return
x
=
f
(
~
val
)
return
x
.
msg
return
x
.
msg
.
decode
(
'ASCII'
)
def
test_bint
(
bint
a
):
...
...
tests/run/arithmetic_analyse_types_helper.h
View file @
a17fac09
/* A set of mutually incompatable return types. */
struct
short_return
{
c
onst
c
har
*
msg
;
};
struct
int_return
{
c
onst
c
har
*
msg
;
};
struct
longlong_return
{
c
onst
c
har
*
msg
;
};
struct
short_return
{
char
*
msg
;
};
struct
int_return
{
char
*
msg
;
};
struct
longlong_return
{
char
*
msg
;
};
/* A set of overloaded methods. */
short_return
f
(
short
arg
)
{
short_return
val
;
val
.
msg
=
"short called"
;
val
.
msg
=
(
char
*
)
"short called"
;
return
val
;
}
int_return
f
(
int
arg
)
{
int_return
val
;
val
.
msg
=
"int called"
;
val
.
msg
=
(
char
*
)
"int called"
;
return
val
;
}
longlong_return
f
(
long
long
arg
)
{
longlong_return
val
;
val
.
msg
=
"long long called"
;
val
.
msg
=
(
char
*
)
"long long called"
;
return
val
;
}
...
...
tests/run/cpp_stl_string.pyx
0 → 100644
View file @
a17fac09
# tag: cpp
from
libcpp.string
cimport
string
b_asdf
=
b'asdf'
b_asdg
=
b'asdg'
b_s
=
b's'
def
test_indexing
(
char
*
py_str
):
"""
>>> test_indexing(b_asdf)
('s', 's')
"""
cdef
string
s
s
=
string
(
py_str
)
return
chr
(
s
[
1
]),
chr
(
s
.
at
(
1
))
def
test_size
(
char
*
py_str
):
"""
>>> test_size(b_asdf)
(4, 4)
"""
cdef
string
s
s
=
string
(
py_str
)
return
s
.
size
(),
s
.
length
()
def
test_compare
(
char
*
a
,
char
*
b
):
"""
>>> test_compare(b_asdf, b_asdf)
0
>>> test_compare(b_asdf, b_asdg) < 0
True
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
return
s
.
compare
(
t
)
def
test_empty
():
"""
>>> test_empty()
(True, False)
"""
cdef
string
a
=
string
(
<
char
*>
b""
)
cdef
string
b
=
string
(
<
char
*>
b"aa"
)
return
a
.
empty
(),
b
.
empty
()
def
test_push_back
(
char
*
a
):
"""
>>> test_push_back(b_asdf) == b_asdf + b_s
True
"""
cdef
string
s
=
string
(
a
)
s
.
push_back
(
<
char
>
ord
(
's'
))
return
s
.
c_str
()
def
test_insert
(
char
*
a
,
char
*
b
,
int
i
):
"""
>>> test_insert('AAAA'.encode('ASCII'), 'BBBB'.encode('ASCII'), 2) == 'AABBBBAA'.encode('ASCII')
True
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
cdef
string
u
=
s
.
insert
(
i
,
t
)
return
u
.
c_str
()
def
test_copy
(
char
*
a
):
"""
>>> test_copy(b_asdf) == b_asdf[1:]
True
"""
cdef
string
t
=
string
(
a
)
cdef
char
buffer
[
6
]
cdef
size_t
length
=
t
.
copy
(
buffer
,
4
,
1
)
buffer
[
length
]
=
c
'
\
0
'
return
buffer
def
test_find
(
char
*
a
,
char
*
b
):
"""
>>> test_find(b_asdf, 'df'.encode('ASCII'))
2
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
cdef
size_t
i
=
s
.
find
(
t
)
return
i
def
test_clear
():
"""
>>> test_clear() == ''.encode('ASCII')
True
"""
cdef
string
s
=
string
(
<
char
*>
"asdf"
)
s
.
clear
()
return
s
.
c_str
()
def
test_assign
(
char
*
a
):
"""
>>> test_assign(b_asdf) == 'ggg'.encode('ASCII')
True
"""
cdef
string
s
=
string
(
a
)
s
.
assign
(
<
char
*>
"ggg"
)
return
s
.
c_str
()
def
test_substr
(
char
*
a
):
"""
>>> test_substr('ABCDEFGH'.encode('ASCII')) == ('BCDEFGH'.encode('ASCII'), 'BCDE'.encode('ASCII'), 'ABCDEFGH'.encode('ASCII'))
True
"""
cdef
string
s
=
string
(
a
)
cdef
string
x
,
y
,
z
x
=
s
.
substr
(
1
)
y
=
s
.
substr
(
1
,
4
)
z
=
s
.
substr
()
return
x
.
c_str
(),
y
.
c_str
(),
z
.
c_str
()
def
test_append
(
char
*
a
,
char
*
b
):
"""
>>> test_append(b_asdf, '1234'.encode('ASCII')) == b_asdf + '1234'.encode('ASCII')
True
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
cdef
string
j
=
s
.
append
(
t
)
return
j
.
c_str
()
def
test_char_compare
(
py_str
):
"""
>>> test_char_compare(b_asdf)
True
"""
cdef
char
*
a
=
py_str
cdef
string
b
=
string
(
a
)
return
b
.
compare
(
b
)
==
0
def
test_cstr
(
char
*
a
):
"""
>>> test_cstr(b_asdf) == b_asdf
True
"""
cdef
string
b
=
string
(
a
)
return
b
.
c_str
()
def
test_equals_operator
(
char
*
a
,
char
*
b
):
"""
>>> test_equals_operator(b_asdf, b_asdf)
(True, False)
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
return
t
==
s
,
t
!=
<
char
*>
"asdf"
def
test_less_than
(
char
*
a
,
char
*
b
):
"""
>>> test_less_than(b_asdf[:-1], b_asdf)
(True, True, True)
>>> test_less_than(b_asdf[:-1], b_asdf[:-1])
(False, False, True)
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
return
(
s
<
t
,
s
<
b
,
s
<=
b
)
def
test_greater_than
(
char
*
a
,
char
*
b
):
"""
>>> test_greater_than(b_asdf[:-1], b_asdf)
(False, False, False)
>>> test_greater_than(b_asdf[:-1], b_asdf[:-1])
(False, False, True)
"""
cdef
string
s
=
string
(
a
)
cdef
string
t
=
string
(
b
)
return
(
s
>
t
,
s
>
b
,
s
>=
b
)
tests/run/cython3.pyx
View file @
a17fac09
# cython: language_level=3
# mode: run
# tag: generators, python3
cimport
cython
...
...
@@ -89,6 +91,16 @@ def list_comp():
assert
x
==
'abc'
# don't leak in Py3 code
return
result
def
list_comp_with_lambda
():
"""
>>> list_comp_with_lambda()
[0, 4, 8]
"""
x
=
'abc'
result
=
[
x
*
2
for
x
in
range
(
5
)
if
(
lambda
x
:
x
%
2
)(
x
)
==
0
]
assert
x
==
'abc'
# don't leak in Py3 code
return
result
module_level_lc
=
[
module_level_loopvar
*
2
for
module_level_loopvar
in
range
(
4
)
]
def
list_comp_module_level
():
"""
...
...
tests/run/flatin.pyx
View file @
a17fac09
...
...
@@ -13,7 +13,7 @@ def test_in(s):
>>> test_in('')
5
"""
if
s
in
(
u'ABC'
,
u'BCD'
):
if
s
in
(
u'ABC'
,
u'BCD'
,
u'ABC'
[:
3
],
u'ABC'
[::
-
1
],
u'ABC'
[
-
1
]
):
return
1
elif
s
.
upper
()
in
(
u'ABC'
,
u'BCD'
):
return
2
...
...
tests/run/funcexceptraisefrom.pyx
0 → 100644
View file @
a17fac09
__doc__
=
u"""
>>> def bar():
... try:
... foo()
... except ValueError:
... if IS_PY3:
... print(isinstance(sys.exc_info()[1].__cause__, TypeError))
... else:
... print(True)
>>> bar()
True
>>> print(sys.exc_info())
(None, None, None)
>>> def bar2():
... try:
... foo2()
... except ValueError:
... if IS_PY3:
... cause = sys.exc_info()[1].__cause__
... print(isinstance(cause, TypeError))
... print(cause.args==('value',))
... pass
... else:
... print(True)
... print(True)
>>> bar2()
True
True
"""
import
sys
IS_PY3
=
sys
.
version_info
[
0
]
>=
3
if
not
IS_PY3
:
sys
.
exc_clear
()
def
foo
():
try
:
raise
TypeError
except
TypeError
:
raise
ValueError
from
TypeError
def
foo2
():
try
:
raise
TypeError
except
TypeError
:
raise
ValueError
()
from
TypeError
(
'value'
)
tests/run/generator_expressions.pyx
0 → 100644
View file @
a17fac09
# mode: run
# tag: generators, lambda
def
genexpr
():
"""
>>> genexpr()
[0, 2, 4, 6, 8]
"""
x
=
'abc'
result
=
list
(
x
*
2
for
x
in
range
(
5
)
)
assert
x
==
'abc'
# don't leak
return
result
def
genexpr_if
():
"""
>>> genexpr_if()
[0, 4, 8]
"""
x
=
'abc'
result
=
list
(
x
*
2
for
x
in
range
(
5
)
if
x
%
2
==
0
)
assert
x
==
'abc'
# don't leak
return
result
def
genexpr_with_lambda
():
"""
>>> genexpr_with_lambda()
[0, 4, 8]
"""
x
=
'abc'
result
=
list
(
x
*
2
for
x
in
range
(
5
)
if
(
lambda
x
:
x
%
2
)(
x
)
==
0
)
assert
x
==
'abc'
# don't leak
return
result
def
genexpr_of_lambdas
(
int
N
):
"""
>>> [ (f(), g()) for f,g in genexpr_of_lambdas(5) ]
[(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)]
"""
return
(
((
lambda
:
x
),
(
lambda
:
x
*
2
))
for
x
in
range
(
N
)
)
tests/run/generators_py.py
View file @
a17fac09
...
...
@@ -167,6 +167,40 @@ def check_yield_in_except():
except
ValueError
:
yield
def
yield_in_except_throw_exc_type
():
"""
>>> import sys
>>> g = yield_in_except_throw_exc_type()
>>> next(g)
>>> g.throw(TypeError)
Traceback (most recent call last):
TypeError
>>> next(g)
Traceback (most recent call last):
StopIteration
"""
try
:
raise
ValueError
except
ValueError
:
yield
def
yield_in_except_throw_instance
():
"""
>>> import sys
>>> g = yield_in_except_throw_instance()
>>> next(g)
>>> g.throw(TypeError())
Traceback (most recent call last):
TypeError
>>> next(g)
Traceback (most recent call last):
StopIteration
"""
try
:
raise
ValueError
except
ValueError
:
yield
def
test_swap_assignment
():
"""
>>> gen = test_swap_assignment()
...
...
tests/run/ifelseexpr_T267.pyx
View file @
a17fac09
# mode: run
# tag: condexpr
# ticket: 267
"""
>>> constants(4)
1
>>> constants(5)
10
>>> temps(4)
1
>>> temps(5)
10
>>> nested(1)
1
>>> nested(2)
2
>>> nested(3)
3
"""
cimport
cython
def
ident
(
x
):
return
x
def
constants
(
x
):
"""
>>> constants(4)
1
>>> constants(5)
10
"""
a
=
1
if
x
<
5
else
10
return
a
def
temps
(
x
):
"""
>>> temps(4)
1
>>> temps(5)
10
"""
return
ident
(
1
)
if
ident
(
x
)
<
ident
(
5
)
else
ident
(
10
)
def
nested
(
x
):
"""
>>> nested(1)
1
>>> nested(2)
2
>>> nested(3)
3
"""
return
1
if
x
==
1
else
(
2
if
x
==
2
else
3
)
@
cython
.
test_fail_if_path_exists
(
'//CondExprNode'
)
def
const_true
(
a
,
b
):
"""
>>> const_true(1,2)
1
"""
return
a
if
1
==
1
else
b
@
cython
.
test_fail_if_path_exists
(
'//CondExprNode'
)
def
const_false
(
a
,
b
):
"""
>>> const_false(1,2)
2
"""
return
a
if
1
!=
1
else
b
tests/run/relativeimport_T542.pyx
View file @
a17fac09
...
...
@@ -20,10 +20,9 @@ def test_relative():
def
test_absolute
():
"""
>>> test_absolute()
>>> test_absolute()
# doctest: +ELLIPSIS
Traceback (most recent call last):
...
ImportError: No module named debug
ImportError: No module named ...debug...
"""
import
debug
return
...
...
tests/run/strliterals.pyx
View file @
a17fac09
...
...
@@ -132,6 +132,18 @@ __doc__ = ur"""
>>> len(bytes_uescape)
28
>>> (sys.version_info[0] >= 3 and sys.maxunicode == 1114111 and len(str_uescape) == 3 or
... sys.version_info[0] >= 3 and sys.maxunicode == 65535 and len(str_uescape) == 4 or
... sys.version_info[0] < 3 and len(str_uescape) == 17 or
... len(str_uescape))
True
>>> (sys.version_info[0] >= 3 and str_uescape[0] == 'c' or
... sys.version_info[0] < 3 and str_uescape[0] == '\\' or
... str_uescape[0])
True
>>> print(str_uescape[-1])
B
>>> newlines == "Aaa\n"
True
...
...
@@ -173,6 +185,7 @@ bresc = br'\12\'\"\\'
uresc
=
ur'\12\'\"\\'
bytes_uescape
=
b'
\
u1234
\
U12345678
\
u
\
u1
\
u
12
\
uX
'
str_uescape = '
\
u0063
\
U00012345
\
x42
'
newlines = "Aaa
\
n
"
...
...
tests/run/test_raisefrom.pyx
0 → 100644
View file @
a17fac09
import
unittest
# adapted from pyregr
class
TestCause
(
unittest
.
TestCase
):
def
test_invalid_cause
(
self
):
try
:
raise
IndexError
from
5
except
TypeError
as
e
:
self
.
assertTrue
(
"exception cause"
in
str
(
e
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_class_cause
(
self
):
try
:
raise
IndexError
from
KeyError
except
IndexError
as
e
:
self
.
assertTrue
(
isinstance
(
e
.
__cause__
,
KeyError
))
else
:
self
.
fail
(
"No exception raised"
)
def
test_instance_cause
(
self
):
cause
=
KeyError
()
try
:
raise
IndexError
from
cause
except
IndexError
as
e
:
self
.
assertTrue
(
e
.
__cause__
is
cause
)
else
:
self
.
fail
(
"No exception raised"
)
def
test_erroneous_cause
(
self
):
class
MyException
(
Exception
):
def
__init__
(
self
):
raise
RuntimeError
()
try
:
raise
IndexError
from
MyException
except
RuntimeError
:
pass
else
:
self
.
fail
(
"No exception raised"
)
tests/run/trybreak.pyx
View file @
a17fac09
__doc__
=
u"""
>>> print(foo())
a
"""
# Indirectly makes sure the cleanup happens correctly on breaking.
def
foo
():
for
x
in
"abc"
:
def
try_except_break
():
"""
>>> print(try_except_break())
a
"""
for
x
in
list
(
"abc"
):
try
:
x
()
except
:
break
for
x
in
"abc"
:
return
x
def
try_break_except
():
"""
>>> print(try_break_except())
a
"""
for
x
in
list
(
"abc"
):
try
:
break
except
:
pass
return
x
def
try_no_break_except_return
():
"""
>>> print(try_no_break_except_return())
a
"""
for
x
in
list
(
"abc"
):
try
:
x
()
break
except
:
return
x
return
x
tests/run/with_statement_module_level_T536.pyx
View file @
a17fac09
...
...
@@ -3,17 +3,32 @@
__doc__
=
"""
>>> inner_result
['ENTER']
>>> result
>>> result # doctest: +ELLIPSIS
['ENTER', ...EXIT (<...ValueError...>,...ValueError..., <traceback object at ...)...]
>>> inner_result_no_exc
['ENTER']
>>> result_no_exc
['ENTER', 'EXIT (None, None, None)']
"""
result
=
[]
class
ContextManager
(
object
):
def
__init__
(
self
,
result
):
self
.
result
=
result
def
__enter__
(
self
):
result
.
append
(
"ENTER"
)
self
.
result
.
append
(
"ENTER"
)
def
__exit__
(
self
,
*
values
):
result
.
append
(
"EXIT %r"
%
(
values
,))
self
.
result
.
append
(
"EXIT %r"
%
(
values
,))
return
True
result_no_exc
=
[]
with
ContextManager
()
as
c
:
with
ContextManager
(
result_no_exc
)
as
c
:
inner_result_no_exc
=
result_no_exc
[:]
result
=
[]
with
ContextManager
(
result
)
as
c
:
inner_result
=
result
[:]
raise
ValueError
(
'TEST'
)
tests/run/withstat.pyx
View file @
a17fac09
...
...
@@ -56,17 +56,6 @@ def with_pass():
with
ContextManager
(
u"value"
)
as
x
:
pass
def
with_return
():
"""
>>> with_return()
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
(
u"value"
)
as
x
:
# FIXME: DISABLED - currently crashes!!
# return x
pass
def
with_exception
(
exit_ret
):
"""
>>> with_exception(None)
...
...
tests/run/withstat_py.py
0 → 100644
View file @
a17fac09
import
sys
def
typename
(
t
):
name
=
type
(
t
).
__name__
if
sys
.
version_info
<
(
2
,
5
):
if
name
==
'classobj'
and
issubclass
(
t
,
MyException
):
name
=
'type'
elif
name
==
'instance'
and
isinstance
(
t
,
MyException
):
name
=
'MyException'
return
"<type '%s'>"
%
name
class
MyException
(
Exception
):
pass
class
ContextManager
(
object
):
def
__init__
(
self
,
value
,
exit_ret
=
None
):
self
.
value
=
value
self
.
exit_ret
=
exit_ret
def
__exit__
(
self
,
a
,
b
,
tb
):
print
(
"exit %s %s %s"
%
(
typename
(
a
),
typename
(
b
),
typename
(
tb
)))
return
self
.
exit_ret
def
__enter__
(
self
):
print
(
"enter"
)
return
self
.
value
def
no_as
():
"""
>>> no_as()
enter
hello
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
(
"value"
):
print
(
"hello"
)
def
basic
():
"""
>>> basic()
enter
value
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
(
"value"
)
as
x
:
print
(
x
)
def
with_pass
():
"""
>>> with_pass()
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
(
"value"
)
as
x
:
pass
def
with_return
():
"""
>>> print(with_return())
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
value
"""
with
ContextManager
(
"value"
)
as
x
:
return
x
def
with_break
():
"""
>>> print(with_break())
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
a
"""
for
c
in
list
(
"abc"
):
with
ContextManager
(
"value"
)
as
x
:
break
print
(
"FAILED"
)
return
c
def
with_continue
():
"""
>>> print(with_continue())
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
enter
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
c
"""
for
c
in
list
(
"abc"
):
with
ContextManager
(
"value"
)
as
x
:
continue
print
(
"FAILED"
)
return
c
def
with_exception
(
exit_ret
):
"""
>>> with_exception(None)
enter
value
exit <type 'type'> <type 'MyException'> <type 'traceback'>
outer except
>>> with_exception(True)
enter
value
exit <type 'type'> <type 'MyException'> <type 'traceback'>
"""
try
:
with
ContextManager
(
"value"
,
exit_ret
=
exit_ret
)
as
value
:
print
(
value
)
raise
MyException
()
except
:
print
(
"outer except"
)
def
functions_in_with
():
"""
>>> f = functions_in_with()
enter
exit <type 'type'> <type 'MyException'> <type 'traceback'>
outer except
>>> f(1)[0]
1
>>> print(f(1)[1])
value
"""
try
:
with
ContextManager
(
"value"
)
as
value
:
def
f
(
x
):
return
x
,
value
make
=
lambda
x
:
x
()
raise
make
(
MyException
)
except
:
print
(
"outer except"
)
return
f
def
multitarget
():
"""
>>> multitarget()
enter
1 2 3 4 5
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
((
1
,
2
,
(
3
,
(
4
,
5
))))
as
(
a
,
b
,
(
c
,
(
d
,
e
))):
print
(
'%s %s %s %s %s'
%
(
a
,
b
,
c
,
d
,
e
))
def
tupletarget
():
"""
>>> tupletarget()
enter
(1, 2, (3, (4, 5)))
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
((
1
,
2
,
(
3
,
(
4
,
5
))))
as
t
:
print
(
t
)
def
multimanager
():
"""
>>> multimanager()
enter
enter
enter
enter
enter
enter
2
value
1 2 3 4 5
nested
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
exit <type 'NoneType'> <type 'NoneType'> <type 'NoneType'>
"""
with
ContextManager
(
1
),
ContextManager
(
2
)
as
x
,
ContextManager
(
'value'
)
as
y
,
\
ContextManager
(
3
),
ContextManager
((
1
,
2
,
(
3
,
(
4
,
5
))))
as
(
a
,
b
,
(
c
,
(
d
,
e
))):
with
ContextManager
(
'nested'
)
as
nested
:
print
(
x
)
print
(
y
)
print
(
'%s %s %s %s %s'
%
(
a
,
b
,
c
,
d
,
e
))
print
(
nested
)
# Tests borrowed from pyregr test_with.py,
# modified to follow the constraints of Cython.
import
unittest
class
Dummy
(
object
):
def
__init__
(
self
,
value
=
None
,
gobble
=
False
):
if
value
is
None
:
value
=
self
self
.
value
=
value
self
.
gobble
=
gobble
self
.
enter_called
=
False
self
.
exit_called
=
False
def
__enter__
(
self
):
self
.
enter_called
=
True
return
self
.
value
def
__exit__
(
self
,
*
exc_info
):
self
.
exit_called
=
True
self
.
exc_info
=
exc_info
if
self
.
gobble
:
return
True
class
InitRaises
(
object
):
def
__init__
(
self
):
raise
RuntimeError
()
class
EnterRaises
(
object
):
def
__enter__
(
self
):
raise
RuntimeError
()
def
__exit__
(
self
,
*
exc_info
):
pass
class
ExitRaises
(
object
):
def
__enter__
(
self
):
pass
def
__exit__
(
self
,
*
exc_info
):
raise
RuntimeError
()
class
NestedWith
(
unittest
.
TestCase
):
"""
>>> NestedWith().runTest()
"""
def
runTest
(
self
):
self
.
testNoExceptions
()
self
.
testExceptionInExprList
()
self
.
testExceptionInEnter
()
self
.
testExceptionInExit
()
self
.
testEnterReturnsTuple
()
def
testNoExceptions
(
self
):
with
Dummy
()
as
a
,
Dummy
()
as
b
:
self
.
assertTrue
(
a
.
enter_called
)
self
.
assertTrue
(
b
.
enter_called
)
self
.
assertTrue
(
a
.
exit_called
)
self
.
assertTrue
(
b
.
exit_called
)
def
testExceptionInExprList
(
self
):
try
:
with
Dummy
()
as
a
,
InitRaises
():
pass
except
:
pass
self
.
assertTrue
(
a
.
enter_called
)
self
.
assertTrue
(
a
.
exit_called
)
def
testExceptionInEnter
(
self
):
try
:
with
Dummy
()
as
a
,
EnterRaises
():
self
.
fail
(
'body of bad with executed'
)
except
RuntimeError
:
pass
else
:
self
.
fail
(
'RuntimeError not reraised'
)
self
.
assertTrue
(
a
.
enter_called
)
self
.
assertTrue
(
a
.
exit_called
)
def
testExceptionInExit
(
self
):
body_executed
=
False
with
Dummy
(
gobble
=
True
)
as
a
,
ExitRaises
():
body_executed
=
True
self
.
assertTrue
(
a
.
enter_called
)
self
.
assertTrue
(
a
.
exit_called
)
self
.
assertTrue
(
body_executed
)
self
.
assertNotEqual
(
a
.
exc_info
[
0
],
None
)
def
testEnterReturnsTuple
(
self
):
with
Dummy
(
value
=
(
1
,
2
))
as
(
a1
,
a2
),
\
Dummy
(
value
=
(
10
,
20
))
as
(
b1
,
b2
):
self
.
assertEquals
(
1
,
a1
)
self
.
assertEquals
(
2
,
a2
)
self
.
assertEquals
(
10
,
b1
)
self
.
assertEquals
(
20
,
b2
)
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