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
Gwenaël Samain
cython
Commits
719f7569
Commit
719f7569
authored
Feb 01, 2011
by
Vitja Makarov
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote branch 'upstream/master'
parents
e7f05c6c
1f735bf4
Changes
17
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
675 additions
and
141 deletions
+675
-141
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+118
-38
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+3
-3
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+13
-12
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+1
-0
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+78
-0
Cython/Debugger/Tests/TestLibCython.py
Cython/Debugger/Tests/TestLibCython.py
+149
-74
Cython/Debugger/Tests/test_libcython_in_gdb.py
Cython/Debugger/Tests/test_libcython_in_gdb.py
+2
-2
Cython/Tests/xmlrunner.py
Cython/Tests/xmlrunner.py
+1
-1
Cython/__init__.py
Cython/__init__.py
+1
-1
runtests.py
runtests.py
+22
-5
tests/errors/e_strcoerce.pyx
tests/errors/e_strcoerce.pyx
+1
-1
tests/errors/py_ucs4_type_errors.pyx
tests/errors/py_ucs4_type_errors.pyx
+24
-0
tests/errors/py_unicode_type_errors.pyx
tests/errors/py_unicode_type_errors.pyx
+3
-3
tests/errors/string_assignments.pyx
tests/errors/string_assignments.pyx
+1
-1
tests/run/isinstance.pyx
tests/run/isinstance.pyx
+17
-0
tests/run/py_ucs4_type.pyx
tests/run/py_ucs4_type.pyx
+197
-0
tests/run/temp_sideeffects_T654.pyx
tests/run/temp_sideeffects_T654.pyx
+44
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
719f7569
This diff is collapsed.
Click to expand it.
Cython/Compiler/Nodes.py
View file @
719f7569
...
@@ -607,9 +607,6 @@ class CFuncDeclaratorNode(CDeclaratorNode):
...
@@ -607,9 +607,6 @@ class CFuncDeclaratorNode(CDeclaratorNode):
error
(
self
.
exception_value
.
pos
,
error
(
self
.
exception_value
.
pos
,
"Exception value incompatible with function return type"
)
"Exception value incompatible with function return type"
)
exc_check
=
self
.
exception_check
exc_check
=
self
.
exception_check
if
return_type
.
is_array
:
error
(
self
.
pos
,
"Function cannot return an array"
)
if
return_type
.
is_cfunction
:
if
return_type
.
is_cfunction
:
error
(
self
.
pos
,
error
(
self
.
pos
,
"Function cannot return a function"
)
"Function cannot return a function"
)
...
@@ -1658,6 +1655,9 @@ class CFuncDefNode(FuncDefNode):
...
@@ -1658,6 +1655,9 @@ class CFuncDefNode(FuncDefNode):
api
=
self
.
api
,
modifiers
=
self
.
modifiers
)
api
=
self
.
api
,
modifiers
=
self
.
modifiers
)
self
.
entry
.
inline_func_in_pxd
=
self
.
inline_in_pxd
self
.
entry
.
inline_func_in_pxd
=
self
.
inline_in_pxd
self
.
return_type
=
type
.
return_type
self
.
return_type
=
type
.
return_type
if
self
.
return_type
.
is_array
and
visibility
!=
'extern'
:
error
(
self
.
pos
,
"Function cannot return an array"
)
if
self
.
overridable
and
not
env
.
is_module_scope
:
if
self
.
overridable
and
not
env
.
is_module_scope
:
if
len
(
self
.
args
)
<
1
or
not
self
.
args
[
0
].
type
.
is_pyobject
:
if
len
(
self
.
args
)
<
1
or
not
self
.
args
[
0
].
type
.
is_pyobject
:
...
...
Cython/Compiler/Optimize.py
View file @
719f7569
...
@@ -1937,7 +1937,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -1937,7 +1937,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
node
.
pos
,
cfunc_name
,
self
.
PyObject_Size_func_type
,
node
.
pos
,
cfunc_name
,
self
.
PyObject_Size_func_type
,
args
=
[
arg
],
args
=
[
arg
],
is_temp
=
node
.
is_temp
)
is_temp
=
node
.
is_temp
)
elif
arg
.
type
is
PyrexTypes
.
c_py_unicode_type
:
elif
arg
.
type
.
is_unicode_char
:
return
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
'1'
,
constant_result
=
1
,
return
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
'1'
,
constant_result
=
1
,
type
=
node
.
type
)
type
=
node
.
type
)
else
:
else
:
...
@@ -1995,14 +1995,15 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -1995,14 +1995,15 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
builtin_type
=
entry
.
type
builtin_type
=
entry
.
type
if
builtin_type
and
builtin_type
is
not
Builtin
.
type_type
:
if
builtin_type
and
builtin_type
is
not
Builtin
.
type_type
:
type_check_function
=
entry
.
type
.
type_check_function
(
exact
=
False
)
type_check_function
=
entry
.
type
.
type_check_function
(
exact
=
False
)
if
type_check_function
in
tests
:
continue
tests
.
append
(
type_check_function
)
type_check_args
=
[
arg
]
type_check_args
=
[
arg
]
elif
test_type_node
.
type
is
Builtin
.
type_type
:
elif
test_type_node
.
type
is
Builtin
.
type_type
:
type_check_function
=
'__Pyx_TypeCheck'
type_check_function
=
'__Pyx_TypeCheck'
type_check_args
=
[
arg
,
test_type_node
]
type_check_args
=
[
arg
,
test_type_node
]
else
:
else
:
return
node
return
node
if
type_check_function
not
in
tests
:
tests
.
append
(
type_check_function
)
test_nodes
.
append
(
test_nodes
.
append
(
ExprNodes
.
PythonCapiCallNode
(
ExprNodes
.
PythonCapiCallNode
(
test_type_node
.
pos
,
type_check_function
,
self
.
Py_type_check_func_type
,
test_type_node
.
pos
,
type_check_function
,
self
.
Py_type_check_func_type
,
...
@@ -2028,7 +2029,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -2028,7 +2029,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
return
node
return
node
arg
=
pos_args
[
0
]
arg
=
pos_args
[
0
]
if
isinstance
(
arg
,
ExprNodes
.
CoerceToPyTypeNode
):
if
isinstance
(
arg
,
ExprNodes
.
CoerceToPyTypeNode
):
if
arg
.
arg
.
type
is
PyrexTypes
.
c_py_unicode_type
:
if
arg
.
arg
.
type
.
is_unicode_char
:
return
arg
.
arg
.
coerce_to
(
node
.
type
,
self
.
current_env
())
return
arg
.
arg
.
coerce_to
(
node
.
type
,
self
.
current_env
())
return
node
return
node
...
@@ -2191,7 +2192,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -2191,7 +2192,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
return
node
return
node
ustring
=
args
[
0
]
ustring
=
args
[
0
]
if
not
isinstance
(
ustring
,
ExprNodes
.
CoerceToPyTypeNode
)
or
\
if
not
isinstance
(
ustring
,
ExprNodes
.
CoerceToPyTypeNode
)
or
\
ustring
.
arg
.
type
is
not
PyrexTypes
.
c_py_unicode_type
:
not
ustring
.
arg
.
type
.
is_unicode_char
:
return
node
return
node
uchar
=
ustring
.
arg
uchar
=
ustring
.
arg
method_name
=
node
.
function
.
attribute
method_name
=
node
.
function
.
attribute
...
@@ -2230,7 +2231,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -2230,7 +2231,7 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
return
node
return
node
ustring
=
args
[
0
]
ustring
=
args
[
0
]
if
not
isinstance
(
ustring
,
ExprNodes
.
CoerceToPyTypeNode
)
or
\
if
not
isinstance
(
ustring
,
ExprNodes
.
CoerceToPyTypeNode
)
or
\
ustring
.
arg
.
type
is
not
PyrexTypes
.
c_py_unicode_type
:
not
ustring
.
arg
.
type
.
is_unicode_char
:
return
node
return
node
uchar
=
ustring
.
arg
uchar
=
ustring
.
arg
method_name
=
node
.
function
.
attribute
method_name
=
node
.
function
.
attribute
...
...
Cython/Compiler/Parsing.py
View file @
719f7569
...
@@ -2049,6 +2049,7 @@ basic_c_type_names = ("void", "char", "int", "float", "double", "bint")
...
@@ -2049,6 +2049,7 @@ basic_c_type_names = ("void", "char", "int", "float", "double", "bint")
special_basic_c_types
=
{
special_basic_c_types
=
{
# name : (signed, longness)
# name : (signed, longness)
"Py_UNICODE"
:
(
0
,
0
),
"Py_UNICODE"
:
(
0
,
0
),
"Py_UCS4"
:
(
0
,
0
),
"Py_ssize_t"
:
(
2
,
0
),
"Py_ssize_t"
:
(
2
,
0
),
"ssize_t"
:
(
2
,
0
),
"ssize_t"
:
(
2
,
0
),
"size_t"
:
(
0
,
0
),
"size_t"
:
(
0
,
0
),
...
...
Cython/Compiler/PyrexTypes.py
View file @
719f7569
...
@@ -49,6 +49,7 @@ class PyrexType(BaseType):
...
@@ -49,6 +49,7 @@ class PyrexType(BaseType):
# is_typedef boolean Is a typedef type
# is_typedef boolean Is a typedef type
# is_string boolean Is a C char * type
# is_string boolean Is a C char * type
# is_unicode boolean Is a UTF-8 encoded C char * type
# is_unicode boolean Is a UTF-8 encoded C char * type
# is_unicode_char boolean Is either Py_UCS4 or Py_UNICODE
# is_returncode boolean Is used only to signal exceptions
# is_returncode boolean Is used only to signal exceptions
# is_error boolean Is the dummy error type
# is_error boolean Is the dummy error type
# is_buffer boolean Is buffer access type
# is_buffer boolean Is buffer access type
...
@@ -101,6 +102,7 @@ class PyrexType(BaseType):
...
@@ -101,6 +102,7 @@ class PyrexType(BaseType):
is_typedef
=
0
is_typedef
=
0
is_string
=
0
is_string
=
0
is_unicode
=
0
is_unicode
=
0
is_unicode_char
=
0
is_returncode
=
0
is_returncode
=
0
is_error
=
0
is_error
=
0
is_buffer
=
0
is_buffer
=
0
...
@@ -924,9 +926,81 @@ class CBIntType(CIntType):
...
@@ -924,9 +926,81 @@ class CBIntType(CIntType):
return
"<CNumericType bint>"
return
"<CNumericType bint>"
class
CPyUCS4IntType
(
CIntType
):
# Py_UCS4
is_unicode_char
=
True
# Py_UCS4 coerces from and to single character unicode strings (or
# at most two characters on 16bit Unicode builds), but we also
# allow Python integers as input. The value range for Py_UCS4
# is 0..1114111, which is checked when converting from an integer
# value.
to_py_function
=
"PyUnicode_FromOrdinal"
from_py_function
=
"__Pyx_PyObject_AsPy_UCS4"
def
create_from_py_utility_code
(
self
,
env
):
env
.
use_utility_code
(
pyobject_as_py_ucs4_utility_code
)
return
True
def
sign_and_name
(
self
):
return
"Py_UCS4"
pyobject_as_py_ucs4_utility_code
=
UtilityCode
(
proto
=
'''
static CYTHON_INLINE Py_UCS4 __Pyx_PyObject_AsPy_UCS4(PyObject*);
'''
,
impl
=
'''
static CYTHON_INLINE Py_UCS4 __Pyx_PyObject_AsPy_UCS4(PyObject* x) {
long ival;
if (PyUnicode_Check(x)) {
if (likely(PyUnicode_GET_SIZE(x) == 1)) {
return PyUnicode_AS_UNICODE(x)[0];
}
#if Py_UNICODE_SIZE == 2
else if (PyUnicode_GET_SIZE(x) == 2) {
Py_UCS4 high_val = PyUnicode_AS_UNICODE(x)[0];
if (high_val >= 0xD800 && high_val <= 0xDBFF) {
Py_UCS4 low_val = PyUnicode_AS_UNICODE(x)[1];
if (low_val >= 0xDC00 && low_val <= 0xDFFF) {
return 0x10000 | ((high_val & ((1<<10)-1)) << 10) | (low_val & ((1<<10)-1));
}
}
}
#endif
PyErr_Format(PyExc_ValueError,
"only single character unicode strings can be converted to Py_UCS4, got length "
#if PY_VERSION_HEX < 0x02050000
"%d",
#else
"%zd",
#endif
PyUnicode_GET_SIZE(x));
return (Py_UCS4)-1;
}
ival = __Pyx_PyInt_AsLong(x);
if (unlikely(ival < 0)) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_OverflowError,
"cannot convert negative value to Py_UCS4");
return (Py_UCS4)-1;
} else if (unlikely(ival > 1114111)) {
PyErr_SetString(PyExc_OverflowError,
"value too large to convert to Py_UCS4");
return (Py_UCS4)-1;
}
return (Py_UCS4)ival;
}
'''
)
class
CPyUnicodeIntType
(
CIntType
):
class
CPyUnicodeIntType
(
CIntType
):
# Py_UNICODE
# Py_UNICODE
is_unicode_char
=
True
# Py_UNICODE coerces from and to single character unicode strings,
# Py_UNICODE coerces from and to single character unicode strings,
# but we also allow Python integers as input. The value range for
# but we also allow Python integers as input. The value range for
# Py_UNICODE is 0..1114111, which is checked when converting from
# Py_UNICODE is 0..1114111, which is checked when converting from
...
@@ -2306,6 +2380,7 @@ c_anon_enum_type = CAnonEnumType(-1)
...
@@ -2306,6 +2380,7 @@ c_anon_enum_type = CAnonEnumType(-1)
c_returncode_type
=
CReturnCodeType
(
RANK_INT
)
c_returncode_type
=
CReturnCodeType
(
RANK_INT
)
c_bint_type
=
CBIntType
(
RANK_INT
)
c_bint_type
=
CBIntType
(
RANK_INT
)
c_py_unicode_type
=
CPyUnicodeIntType
(
RANK_INT
-
0.5
,
UNSIGNED
)
c_py_unicode_type
=
CPyUnicodeIntType
(
RANK_INT
-
0.5
,
UNSIGNED
)
c_py_ucs4_type
=
CPyUCS4IntType
(
RANK_LONG
-
0.5
,
UNSIGNED
)
c_py_ssize_t_type
=
CPySSizeTType
(
RANK_LONG
+
0.5
,
SIGNED
)
c_py_ssize_t_type
=
CPySSizeTType
(
RANK_LONG
+
0.5
,
SIGNED
)
c_ssize_t_type
=
CSSizeTType
(
RANK_LONG
+
0.5
,
SIGNED
)
c_ssize_t_type
=
CSSizeTType
(
RANK_LONG
+
0.5
,
SIGNED
)
c_size_t_type
=
CSizeTType
(
RANK_LONG
+
0.5
,
UNSIGNED
)
c_size_t_type
=
CSizeTType
(
RANK_LONG
+
0.5
,
UNSIGNED
)
...
@@ -2367,6 +2442,7 @@ modifiers_and_name_to_type = {
...
@@ -2367,6 +2442,7 @@ modifiers_and_name_to_type = {
(
1
,
0
,
"bint"
):
c_bint_type
,
(
1
,
0
,
"bint"
):
c_bint_type
,
(
0
,
0
,
"Py_UNICODE"
):
c_py_unicode_type
,
(
0
,
0
,
"Py_UNICODE"
):
c_py_unicode_type
,
(
0
,
0
,
"Py_UCS4"
):
c_py_ucs4_type
,
(
2
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
(
2
,
0
,
"Py_ssize_t"
):
c_py_ssize_t_type
,
(
2
,
0
,
"ssize_t"
)
:
c_ssize_t_type
,
(
2
,
0
,
"ssize_t"
)
:
c_ssize_t_type
,
(
0
,
0
,
"size_t"
)
:
c_size_t_type
,
(
0
,
0
,
"size_t"
)
:
c_size_t_type
,
...
@@ -2614,6 +2690,8 @@ def parse_basic_type(name):
...
@@ -2614,6 +2690,8 @@ def parse_basic_type(name):
longness
=
0
longness
=
0
if
name
==
'Py_UNICODE'
:
if
name
==
'Py_UNICODE'
:
signed
=
0
signed
=
0
elif
name
==
'Py_UCS4'
:
signed
=
0
elif
name
==
'Py_ssize_t'
:
elif
name
==
'Py_ssize_t'
:
signed
=
2
signed
=
2
elif
name
==
'ssize_t'
:
elif
name
==
'ssize_t'
:
...
...
Cython/Debugger/Tests/TestLibCython.py
View file @
719f7569
...
@@ -29,6 +29,49 @@ with open(codefile) as f:
...
@@ -29,6 +29,49 @@ with open(codefile) as f:
# can't access the module anymore. Get it from sys.modules instead.
# can't access the module anymore. Get it from sys.modules instead.
build_ext
=
sys
.
modules
[
'Cython.Distutils.build_ext'
]
build_ext
=
sys
.
modules
[
'Cython.Distutils.build_ext'
]
have_gdb
=
None
def
test_gdb
():
global
have_gdb
if
have_gdb
is
None
:
try
:
p
=
subprocess
.
Popen
([
'gdb'
,
'-v'
],
stdout
=
subprocess
.
PIPE
)
have_gdb
=
True
except
OSError
:
# gdb was not installed
have_gdb
=
False
else
:
gdb_version
=
p
.
stdout
.
read
().
decode
(
'ascii'
)
p
.
wait
()
p
.
stdout
.
close
()
if
have_gdb
:
# Based on Lib/test/test_gdb.py
regex
=
"^GNU gdb [^
\
d]*(
\
d+)
\
.(
\
d+)"
gdb_version_number
=
list
(
map
(
int
,
re
.
search
(
regex
,
gdb_version
).
groups
()))
if
gdb_version_number
>=
[
7
,
2
]:
python_version_script
=
tempfile
.
NamedTemporaryFile
(
mode
=
'w+'
)
python_version_script
.
write
(
'python import sys; print("%s %s" % sys.version_info[:2])'
)
python_version_script
.
flush
()
p
=
subprocess
.
Popen
([
'gdb'
,
'-batch'
,
'-x'
,
python_version_script
.
name
],
stdout
=
subprocess
.
PIPE
)
python_version
=
p
.
stdout
.
read
().
decode
(
'ascii'
)
p
.
wait
()
python_version_number
=
list
(
map
(
int
,
python_version
.
split
()))
# Be Python 3 compatible
if
(
not
have_gdb
or
gdb_version_number
<
[
7
,
2
]
or
python_version_number
<
[
2
,
6
]):
warnings
.
warn
(
'Skipping gdb tests, need gdb >= 7.2 with Python >= 2.6'
)
have_gdb
=
False
return
have_gdb
class
DebuggerTestCase
(
unittest
.
TestCase
):
class
DebuggerTestCase
(
unittest
.
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -36,6 +79,9 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -36,6 +79,9 @@ class DebuggerTestCase(unittest.TestCase):
Run gdb and have cygdb import the debug information from the code
Run gdb and have cygdb import the debug information from the code
defined in TestParseTreeTransforms's setUp method
defined in TestParseTreeTransforms's setUp method
"""
"""
if
not
test_gdb
():
return
self
.
tempdir
=
tempfile
.
mkdtemp
()
self
.
tempdir
=
tempfile
.
mkdtemp
()
self
.
destfile
=
os
.
path
.
join
(
self
.
tempdir
,
'codefile.pyx'
)
self
.
destfile
=
os
.
path
.
join
(
self
.
tempdir
,
'codefile.pyx'
)
self
.
debug_dest
=
os
.
path
.
join
(
self
.
tempdir
,
self
.
debug_dest
=
os
.
path
.
join
(
self
.
tempdir
,
...
@@ -44,6 +90,7 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -44,6 +90,7 @@ class DebuggerTestCase(unittest.TestCase):
self
.
cfuncs_destfile
=
os
.
path
.
join
(
self
.
tempdir
,
'cfuncs'
)
self
.
cfuncs_destfile
=
os
.
path
.
join
(
self
.
tempdir
,
'cfuncs'
)
self
.
cwd
=
os
.
getcwd
()
self
.
cwd
=
os
.
getcwd
()
try
:
os
.
chdir
(
self
.
tempdir
)
os
.
chdir
(
self
.
tempdir
)
shutil
.
copy
(
codefile
,
self
.
destfile
)
shutil
.
copy
(
codefile
,
self
.
destfile
)
...
@@ -58,7 +105,6 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -58,7 +105,6 @@ class DebuggerTestCase(unittest.TestCase):
)
)
optimization_disabler
=
build_ext
.
Optimization
()
optimization_disabler
=
build_ext
.
Optimization
()
optimization_disabler
.
disable_optimization
()
cython_compile_testcase
=
runtests
.
CythonCompileTestCase
(
cython_compile_testcase
=
runtests
.
CythonCompileTestCase
(
workdir
=
self
.
tempdir
,
workdir
=
self
.
tempdir
,
...
@@ -67,6 +113,14 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -67,6 +113,14 @@ class DebuggerTestCase(unittest.TestCase):
**
opts
**
opts
)
)
new_stderr
=
open
(
os
.
devnull
,
'w'
)
stderr
=
sys
.
stderr
sys
.
stderr
=
new_stderr
optimization_disabler
.
disable_optimization
()
try
:
cython_compile_testcase
.
run_cython
(
cython_compile_testcase
.
run_cython
(
targetdir
=
self
.
tempdir
,
targetdir
=
self
.
tempdir
,
incdir
=
None
,
incdir
=
None
,
...
@@ -84,8 +138,9 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -84,8 +138,9 @@ class DebuggerTestCase(unittest.TestCase):
extra_extension_args
=
{
'extra_objects'
:[
'cfuncs.o'
]},
extra_extension_args
=
{
'extra_objects'
:[
'cfuncs.o'
]},
**
opts
**
opts
)
)
finally
:
optimization_disabler
.
restore_state
()
optimization_disabler
.
restore_state
()
sys
.
stderr
=
stderr
# ext = Cython.Distutils.extension.Extension(
# ext = Cython.Distutils.extension.Extension(
# 'codefile',
# 'codefile',
...
@@ -99,7 +154,13 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -99,7 +154,13 @@ class DebuggerTestCase(unittest.TestCase):
# cmdclass=dict(build_ext=Cython.Distutils.build_ext)
# cmdclass=dict(build_ext=Cython.Distutils.build_ext)
# )
# )
except
:
os
.
chdir
(
self
.
cwd
)
raise
def
tearDown
(
self
):
def
tearDown
(
self
):
if
not
test_gdb
():
return
os
.
chdir
(
self
.
cwd
)
os
.
chdir
(
self
.
cwd
)
shutil
.
rmtree
(
self
.
tempdir
)
shutil
.
rmtree
(
self
.
tempdir
)
...
@@ -107,6 +168,9 @@ class DebuggerTestCase(unittest.TestCase):
...
@@ -107,6 +168,9 @@ class DebuggerTestCase(unittest.TestCase):
class
GdbDebuggerTestCase
(
DebuggerTestCase
):
class
GdbDebuggerTestCase
(
DebuggerTestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
if
not
test_gdb
():
return
super
(
GdbDebuggerTestCase
,
self
).
setUp
()
super
(
GdbDebuggerTestCase
,
self
).
setUp
()
prefix_code
=
textwrap
.
dedent
(
'''
\
prefix_code
=
textwrap
.
dedent
(
'''
\
...
@@ -167,6 +231,11 @@ class GdbDebuggerTestCase(DebuggerTestCase):
...
@@ -167,6 +231,11 @@ class GdbDebuggerTestCase(DebuggerTestCase):
p
.
stdout
.
close
()
p
.
stdout
.
close
()
if
have_gdb
:
if
have_gdb
:
# Based on Lib/test/test_gdb.py
regex
=
"^GNU gdb [^
\
d]*(
\
d+)
\
.(
\
d+)"
gdb_version_number
=
list
(
map
(
int
,
re
.
search
(
regex
,
gdb_version
).
groups
()))
if
gdb_version_number
>=
[
7
,
2
]:
python_version_script
=
tempfile
.
NamedTemporaryFile
(
mode
=
'w+'
)
python_version_script
=
tempfile
.
NamedTemporaryFile
(
mode
=
'w+'
)
python_version_script
.
write
(
python_version_script
.
write
(
'python import sys; print("%s %s" % sys.version_info[:2])'
)
'python import sys; print("%s %s" % sys.version_info[:2])'
)
...
@@ -175,16 +244,12 @@ class GdbDebuggerTestCase(DebuggerTestCase):
...
@@ -175,16 +244,12 @@ class GdbDebuggerTestCase(DebuggerTestCase):
stdout
=
subprocess
.
PIPE
)
stdout
=
subprocess
.
PIPE
)
python_version
=
p
.
stdout
.
read
().
decode
(
'ascii'
)
python_version
=
p
.
stdout
.
read
().
decode
(
'ascii'
)
p
.
wait
()
p
.
wait
()
python_version_number
=
[
int
(
a
)
for
a
in
python_version
.
split
()]
python_version_number
=
list
(
map
(
int
,
python_version
.
split
()))
if
have_gdb
:
# Based on Lib/test/test_gdb.py
regex
=
"^GNU gdb [^
\
d]*(
\
d+)
\
.(
\
d+)"
gdb_version_number
=
re
.
search
(
regex
,
gdb_version
).
groups
()
# Be Python 3 compatible
# Be Python 3 compatible
if
(
not
have_gdb
if
(
not
have_gdb
or
list
(
map
(
int
,
gdb_version_number
))
<
[
7
,
2
]
or
gdb_version_number
<
[
7
,
2
]
or
python_version_number
<
[
2
,
6
]):
or
python_version_number
<
[
2
,
6
]):
self
.
p
=
None
self
.
p
=
None
warnings
.
warn
(
warnings
.
warn
(
...
@@ -197,6 +262,9 @@ class GdbDebuggerTestCase(DebuggerTestCase):
...
@@ -197,6 +262,9 @@ class GdbDebuggerTestCase(DebuggerTestCase):
env
=
env
)
env
=
env
)
def
tearDown
(
self
):
def
tearDown
(
self
):
if
not
test_gdb
():
return
super
(
GdbDebuggerTestCase
,
self
).
tearDown
()
super
(
GdbDebuggerTestCase
,
self
).
tearDown
()
if
self
.
p
:
if
self
.
p
:
self
.
p
.
stderr
.
close
()
self
.
p
.
stderr
.
close
()
...
@@ -207,17 +275,24 @@ class GdbDebuggerTestCase(DebuggerTestCase):
...
@@ -207,17 +275,24 @@ class GdbDebuggerTestCase(DebuggerTestCase):
class
TestAll
(
GdbDebuggerTestCase
):
class
TestAll
(
GdbDebuggerTestCase
):
def
test_all
(
self
):
def
test_all
(
self
):
if
self
.
p
is
None
:
if
not
test_gdb
()
:
return
return
out
,
err
=
self
.
p
.
communicate
()
out
,
err
=
self
.
p
.
communicate
()
err
=
err
.
decode
(
'UTF-8'
)
err
=
err
.
decode
(
'UTF-8'
)
exit_status
=
self
.
p
.
wait
()
if
exit_status
==
1
:
sys
.
stderr
.
write
(
err
)
elif
exit_status
>=
2
:
border
=
'*'
*
30
border
=
'*'
*
30
start
=
'%s v INSIDE GDB v %s'
%
(
border
,
border
)
start
=
'%s v INSIDE GDB v %s'
%
(
border
,
border
)
end
=
'%s ^ INSIDE GDB ^ %s'
%
(
border
,
border
)
end
=
'%s ^ INSIDE GDB ^ %s'
%
(
border
,
border
)
errmsg
=
'
\
n
%s
\
n
%s%s'
%
(
start
,
err
,
end
)
errmsg
=
'
\
n
%s
\
n
%s%s'
%
(
start
,
err
,
end
)
self
.
assertEquals
(
0
,
self
.
p
.
wait
(),
errmsg
)
sys
.
stderr
.
write
(
err
)
sys
.
stderr
.
write
(
errmsg
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
Cython/Debugger/Tests/test_libcython_in_gdb.py
View file @
719f7569
...
@@ -428,7 +428,7 @@ def run_unittest_in_module(modulename):
...
@@ -428,7 +428,7 @@ def run_unittest_in_module(modulename):
"debugging information. Either compile python with "
"debugging information. Either compile python with "
"-g or get a debug build (configure with --with-pydebug)."
)
"-g or get a debug build (configure with --with-pydebug)."
)
warnings
.
warn
(
msg
)
warnings
.
warn
(
msg
)
os
.
_exit
(
0
)
os
.
_exit
(
1
)
else
:
else
:
m
=
__import__
(
modulename
,
fromlist
=
[
''
])
m
=
__import__
(
modulename
,
fromlist
=
[
''
])
tests
=
inspect
.
getmembers
(
m
,
inspect
.
isclass
)
tests
=
inspect
.
getmembers
(
m
,
inspect
.
isclass
)
...
@@ -453,7 +453,7 @@ def runtests():
...
@@ -453,7 +453,7 @@ def runtests():
success_libpython
=
run_unittest_in_module
(
test_libpython_in_gdb
.
__name__
)
success_libpython
=
run_unittest_in_module
(
test_libpython_in_gdb
.
__name__
)
if
not
success_libcython
or
not
success_libpython
:
if
not
success_libcython
or
not
success_libpython
:
sys
.
exit
(
1
)
sys
.
exit
(
2
)
def
main
(
version
,
trace_code
=
False
):
def
main
(
version
,
trace_code
=
False
):
global
inferior_python_version
global
inferior_python_version
...
...
Cython/Tests/xmlrunner.py
View file @
719f7569
...
@@ -194,7 +194,7 @@ class _XMLTestResult(_TextTestResult):
...
@@ -194,7 +194,7 @@ class _XMLTestResult(_TextTestResult):
module
=
''
module
=
''
testcase_name
=
module
+
testcase
.
__name__
testcase_name
=
module
+
testcase
.
__name__
if
not
tests_by_testcase
.
has_key
(
testcase_name
)
:
if
testcase_name
not
in
tests_by_testcase
:
tests_by_testcase
[
testcase_name
]
=
[]
tests_by_testcase
[
testcase_name
]
=
[]
tests_by_testcase
[
testcase_name
].
append
(
test_info
)
tests_by_testcase
[
testcase_name
].
append
(
test_info
)
...
...
Cython/__init__.py
View file @
719f7569
__version__
=
"0.14.1rc
2
"
__version__
=
"0.14.1rc
3
"
# Void cython.* directives (for case insensitive operating systems).
# Void cython.* directives (for case insensitive operating systems).
from
Cython.Shadow
import
*
from
Cython.Shadow
import
*
runtests.py
View file @
719f7569
...
@@ -26,7 +26,6 @@ try:
...
@@ -26,7 +26,6 @@ try:
except
ImportError
:
# No threads, no problems
except
ImportError
:
# No threads, no problems
threading
=
None
threading
=
None
WITH_CYTHON
=
True
WITH_CYTHON
=
True
from
distutils.dist
import
Distribution
from
distutils.dist
import
Distribution
...
@@ -34,6 +33,18 @@ from distutils.core import Extension
...
@@ -34,6 +33,18 @@ from distutils.core import Extension
from
distutils.command.build_ext
import
build_ext
as
_build_ext
from
distutils.command.build_ext
import
build_ext
as
_build_ext
distutils_distro
=
Distribution
()
distutils_distro
=
Distribution
()
if
sys
.
platform
==
'win32'
:
# TODO: Figure out why this hackery (see http://thread.gmane.org/gmane.comp.python.cython.devel/8280/).
config_files
=
distutils_distro
.
find_config_files
()
try
:
config_files
.
remove
(
'setup.cfg'
)
except
ValueError
:
pass
distutils_distro
.
parse_config_files
(
config_files
)
cfgfiles
=
distutils_distro
.
find_config_files
()
try
:
cfgfiles
.
remove
(
'setup.cfg'
)
except
ValueError
:
pass
distutils_distro
.
parse_config_files
(
cfgfiles
)
TEST_DIRS
=
[
'compile'
,
'errors'
,
'run'
,
'wrappers'
,
'pyregr'
,
'build'
]
TEST_DIRS
=
[
'compile'
,
'errors'
,
'run'
,
'wrappers'
,
'pyregr'
,
'build'
]
TEST_RUN_DIRS
=
[
'run'
,
'wrappers'
,
'pyregr'
]
TEST_RUN_DIRS
=
[
'run'
,
'wrappers'
,
'pyregr'
]
...
@@ -981,6 +992,9 @@ def check_thread_termination(ignore_seen=True):
...
@@ -981,6 +992,9 @@ def check_thread_termination(ignore_seen=True):
raise
PendingThreadsError
(
"left-over threads found after running test"
)
raise
PendingThreadsError
(
"left-over threads found after running test"
)
def
main
():
def
main
():
DISTDIR
=
os
.
path
.
join
(
os
.
getcwd
(),
os
.
path
.
dirname
(
sys
.
argv
[
0
]))
from
optparse
import
OptionParser
from
optparse
import
OptionParser
parser
=
OptionParser
()
parser
=
OptionParser
()
parser
.
add_option
(
"--no-cleanup"
,
dest
=
"cleanup_workdir"
,
parser
.
add_option
(
"--no-cleanup"
,
dest
=
"cleanup_workdir"
,
...
@@ -1051,12 +1065,15 @@ def main():
...
@@ -1051,12 +1065,15 @@ def main():
parser
.
add_option
(
"--exit-ok"
,
dest
=
"exit_ok"
,
default
=
False
,
parser
.
add_option
(
"--exit-ok"
,
dest
=
"exit_ok"
,
default
=
False
,
action
=
"store_true"
,
action
=
"store_true"
,
help
=
"exit without error code even on test failures"
)
help
=
"exit without error code even on test failures"
)
parser
.
add_option
(
"--root-dir"
,
dest
=
"root_dir"
,
default
=
os
.
path
.
join
(
DISTDIR
,
'tests'
),
help
=
"working directory"
)
parser
.
add_option
(
"--work-dir"
,
dest
=
"work_dir"
,
default
=
os
.
path
.
join
(
os
.
getcwd
(),
'BUILD'
),
help
=
"working directory"
)
options
,
cmd_args
=
parser
.
parse_args
()
options
,
cmd_args
=
parser
.
parse_args
()
DISTDIR
=
os
.
path
.
join
(
os
.
getcwd
(),
os
.
path
.
dirname
(
sys
.
argv
[
0
]))
ROOTDIR
=
os
.
path
.
abspath
(
options
.
root_dir
)
ROOTDIR
=
os
.
path
.
join
(
DISTDIR
,
'tests'
)
WORKDIR
=
os
.
path
.
abspath
(
options
.
work_dir
)
WORKDIR
=
os
.
path
.
join
(
os
.
getcwd
(),
'BUILD'
)
if
sys
.
version_info
[
0
]
>=
3
:
if
sys
.
version_info
[
0
]
>=
3
:
options
.
doctests
=
False
options
.
doctests
=
False
...
@@ -1167,7 +1184,7 @@ def main():
...
@@ -1167,7 +1184,7 @@ def main():
exclude_selectors
+=
[
re
.
compile
(
r
,
re
.
I
|
re
.
U
).
search
for
r
in
options
.
exclude
]
exclude_selectors
+=
[
re
.
compile
(
r
,
re
.
I
|
re
.
U
).
search
for
r
in
options
.
exclude
]
if
not
test_bugs
:
if
not
test_bugs
:
exclude_selectors
+=
[
FileListExcluder
(
"tests/bugs.txt"
)
]
exclude_selectors
+=
[
FileListExcluder
(
os
.
path
.
join
(
ROOTDIR
,
"bugs.txt"
)
)
]
if
sys
.
platform
in
[
'win32'
,
'cygwin'
]
and
sys
.
version_info
<
(
2
,
6
):
if
sys
.
platform
in
[
'win32'
,
'cygwin'
]
and
sys
.
version_info
<
(
2
,
6
):
exclude_selectors
+=
[
lambda
x
:
x
==
"run.specialfloat"
]
exclude_selectors
+=
[
lambda
x
:
x
==
"run.specialfloat"
]
...
...
tests/errors/e_strcoerce.pyx
View file @
719f7569
...
@@ -13,5 +13,5 @@ _ERRORS = """
...
@@ -13,5 +13,5 @@ _ERRORS = """
2:14: Only single-character string literals can be coerced into ints.
2:14: Only single-character string literals can be coerced into ints.
3:14: Only single-character string literals can be coerced into ints.
3:14: Only single-character string literals can be coerced into ints.
6:15: Only single-character string literals can be coerced into ints.
6:15: Only single-character string literals can be coerced into ints.
9:14: Unicode literals do not support coercion to C types other than Py_UNICODE.
9:14: Unicode literals do not support coercion to C types other than Py_UNICODE
or Py_UCS4
.
"""
"""
tests/errors/py_ucs4_type_errors.pyx
0 → 100644
View file @
719f7569
# -*- coding: iso-8859-1 -*-
cdef
Py_UCS4
char_ASCII
=
u'A'
cdef
Py_UCS4
char_KLINGON
=
u'
\
uF8D2
'
def
char_too_long_ASCII
():
cdef
Py_UCS4
c
=
u'AB'
def
char_too_long_Unicode
():
cdef
Py_UCS4
c
=
u'A
\
uF8D2
'
def
char_too_long_bytes
():
cdef
Py_UCS4
c
=
b'AB'
def
char_too_long_latin1
():
cdef
Py_UCS4
char_bytes_latin1
=
b'
\
xf6
'
_ERRORS
=
"""
7:21: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.
10:21: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.
13:21: Only single-character string literals can be coerced into ints.
16:37: Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.
"""
tests/errors/py_unicode_type_errors.pyx
View file @
719f7569
...
@@ -17,8 +17,8 @@ def char_too_long_latin1():
...
@@ -17,8 +17,8 @@ def char_too_long_latin1():
_ERRORS
=
"""
_ERRORS
=
"""
7:24: Only single-character Unicode string literals can be coerced into
Py_UNICODE.
7:24: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/
Py_UNICODE.
10:24: Only single-character Unicode string literals
can be coerced into
Py_UNICODE.
10:24: Only single-character Unicode string literals
or surrogate pairs can be coerced into Py_UCS4/
Py_UNICODE.
13:24: Only single-character string literals can be coerced into ints.
13:24: Only single-character string literals can be coerced into ints.
16:40: Bytes literals cannot coerce to Py_UNICODE, use a unicode literal instead.
16:40: Bytes literals cannot coerce to Py_UNICODE
/Py_UCS4
, use a unicode literal instead.
"""
"""
tests/errors/string_assignments.pyx
View file @
719f7569
...
@@ -50,7 +50,7 @@ cdef list l_f2 = b1
...
@@ -50,7 +50,7 @@ cdef list l_f2 = b1
cdef
list
l_f3
=
u1
cdef
list
l_f3
=
u1
_ERRORS
=
u"""
_ERRORS
=
u"""
25:20: Unicode literals do not support coercion to C types other than Py_UNICODE.
25:20: Unicode literals do not support coercion to C types other than Py_UNICODE
or Py_UCS4
.
26:22: Unicode objects do not support coercion to C types.
26:22: Unicode objects do not support coercion to C types.
27:22: 'str' objects do not support coercion to C types (use 'bytes'?).
27:22: 'str' objects do not support coercion to C types (use 'bytes'?).
...
...
tests/run/isinstance.pyx
View file @
719f7569
...
@@ -77,6 +77,23 @@ def test_custom():
...
@@ -77,6 +77,23 @@ def test_custom():
assert
isinstance
(
A
(),
A
)
assert
isinstance
(
A
(),
A
)
return
True
return
True
cdef
class
B
:
pass
cdef
class
C
:
pass
def
test_custom_tuple
(
obj
):
"""
>>> test_custom_tuple(A())
True
>>> test_custom_tuple(B())
True
>>> test_custom_tuple(C())
False
"""
return
isinstance
(
obj
,
(
A
,
B
))
def
test_nested
(
x
):
def
test_nested
(
x
):
"""
"""
>>> test_nested(1)
>>> test_nested(1)
...
...
tests/run/py_ucs4_type.pyx
0 → 100644
View file @
719f7569
# -*- coding: iso-8859-1 -*-
cimport
cython
cdef
Py_UCS4
char_ASCII
=
u'A'
cdef
Py_UCS4
char_KLINGON
=
u'
\
uF8D2
'
def
compare_ASCII
():
"""
>>> compare_ASCII()
True
False
False
"""
print
(
char_ASCII
==
u'A'
)
print
(
char_ASCII
==
u'B'
)
print
(
char_ASCII
==
u'
\
uF8D2
'
)
def
compare_klingon
():
"""
>>> compare_klingon()
True
False
False
"""
print
(
char_KLINGON
==
u'
\
uF8D2
'
)
print
(
char_KLINGON
==
u'A'
)
print
(
char_KLINGON
==
u'B'
)
from
cpython.unicode
cimport
PyUnicode_FromOrdinal
import
sys
u0
=
u'
\
x00
'
u1
=
u'
\
x01
'
umax
=
PyUnicode_FromOrdinal
(
sys
.
maxunicode
)
def
unicode_ordinal
(
Py_UCS4
i
):
"""
>>> ord(unicode_ordinal(0)) == 0
True
>>> ord(unicode_ordinal(1)) == 1
True
>>> ord(unicode_ordinal(sys.maxunicode)) == sys.maxunicode
True
>>> ord(unicode_ordinal(u0)) == 0
True
>>> ord(unicode_ordinal(u1)) == 1
True
>>> ord(unicode_ordinal(umax)) == sys.maxunicode
True
Value too small:
>>> unicode_ordinal(-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
Value too large:
>>> unicode_ordinal(1114111+1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
Less than one character:
>>> unicode_ordinal(u0[:0])
Traceback (most recent call last):
...
ValueError: only single character unicode strings can be converted to Py_UCS4, got length 0
More than one character:
>>> unicode_ordinal(u0+u1)
Traceback (most recent call last):
...
ValueError: only single character unicode strings can be converted to Py_UCS4, got length 2
"""
return
i
@
cython
.
test_assert_path_exists
(
'//PythonCapiCallNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode'
)
def
unicode_type_methods
(
Py_UCS4
uchar
):
"""
>>> unicode_type_methods(ord('A'))
[True, True, False, False, False, False, False, True, True]
>>> unicode_type_methods(ord('a'))
[True, True, False, False, True, False, False, False, False]
>>> unicode_type_methods(ord('8'))
[True, False, True, True, False, True, False, False, False]
>>> unicode_type_methods(ord('
\
\
t'))
[False, False, False, False, False, False, True, False, False]
"""
return
[
# character types
uchar
.
isalnum
(),
uchar
.
isalpha
(),
uchar
.
isdecimal
(),
uchar
.
isdigit
(),
uchar
.
islower
(),
uchar
.
isnumeric
(),
uchar
.
isspace
(),
uchar
.
istitle
(),
uchar
.
isupper
(),
]
@
cython
.
test_assert_path_exists
(
'//PythonCapiCallNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode'
)
def
unicode_methods
(
Py_UCS4
uchar
):
"""
>>> unicode_methods(ord('A')) == ['a', 'A', 'A']
True
>>> unicode_methods(ord('a')) == ['a', 'A', 'A']
True
"""
return
[
# character conversion
uchar
.
lower
(),
uchar
.
upper
(),
uchar
.
title
(),
]
@
cython
.
test_assert_path_exists
(
'//IntNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode'
,
'//PythonCapiCallNode'
)
def
len_uchar
(
Py_UCS4
uchar
):
"""
>>> len_uchar(ord('A'))
1
"""
return
len
(
uchar
)
def
index_uchar
(
Py_UCS4
uchar
,
Py_ssize_t
i
):
"""
>>> index_uchar(ord('A'), 0) == ('A', 'A', 'A')
True
>>> index_uchar(ord('A'), -1) == ('A', 'A', 'A')
True
>>> index_uchar(ord('A'), 1)
Traceback (most recent call last):
IndexError: string index out of range
"""
return
uchar
[
0
],
uchar
[
-
1
],
uchar
[
i
]
mixed_ustring
=
u'AbcDefGhIjKlmnoP'
lower_ustring
=
mixed_ustring
.
lower
()
upper_ustring
=
mixed_ustring
.
lower
()
@
cython
.
test_assert_path_exists
(
'//PythonCapiCallNode'
,
'//ForFromStatNode'
)
@
cython
.
test_fail_if_path_exists
(
'//SimpleCallNode'
,
'//ForInStatNode'
)
def
count_lower_case_characters
(
unicode
ustring
):
"""
>>> count_lower_case_characters(mixed_ustring)
10
>>> count_lower_case_characters(lower_ustring)
16
"""
cdef
Py_ssize_t
count
=
0
for
uchar
in
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/temp_sideeffects_T654.pyx
0 → 100644
View file @
719f7569
# function call arguments
arg_order
=
[]
cdef
int
f
():
arg_order
.
append
(
1
)
return
1
def
g
():
arg_order
.
append
(
2
)
return
2
cdef
call2
(
int
x
,
object
o
):
return
x
,
o
def
test_c_call
():
"""
>>> arg_order
[]
>>> test_c_call()
(1, 2)
>>> arg_order
[1, 2]
"""
return
call2
(
f
(),
g
())
# module globals
cdef
object
X
=
1
cdef
redefine_global
():
global
X
x
,
X
=
X
,
2
return
x
cdef
call3
(
object
x1
,
int
o
,
object
x2
):
return
(
x1
,
o
,
x2
)
def
test_global_redefine
():
"""
>>> test_global_redefine()
(1, 1, 2)
"""
return
call3
(
X
,
redefine_global
(),
X
)
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