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
6f95c7e3
Commit
6f95c7e3
authored
Apr 28, 2010
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Plain Diff
merged in latest cython-devel
parents
1a3d6371
f31aac14
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
932 additions
and
122 deletions
+932
-122
Cython/Compiler/AnalysedTreeTransforms.py
Cython/Compiler/AnalysedTreeTransforms.py
+2
-1
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+73
-17
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+35
-12
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+111
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+49
-30
Cython/Compiler/TypeSlots.py
Cython/Compiler/TypeSlots.py
+52
-42
tests/errors/break_outside_loop.pyx
tests/errors/break_outside_loop.pyx
+4
-1
tests/errors/continue_outside_loop.pyx
tests/errors/continue_outside_loop.pyx
+3
-1
tests/errors/literal_lists.pyx
tests/errors/literal_lists.pyx
+4
-1
tests/run/autotestdict.pyx
tests/run/autotestdict.pyx
+16
-0
tests/run/bytes_char_coercion.pyx
tests/run/bytes_char_coercion.pyx
+154
-0
tests/run/bytes_indexing.pyx
tests/run/bytes_indexing.pyx
+180
-0
tests/run/consts.pyx
tests/run/consts.pyx
+77
-0
tests/run/for_in_string.pyx
tests/run/for_in_string.pyx
+30
-0
tests/run/py_unicode_type.pyx
tests/run/py_unicode_type.pyx
+99
-15
tests/run/type_slots_nonzero_bool.pyx
tests/run/type_slots_nonzero_bool.pyx
+43
-0
No files found.
Cython/Compiler/AnalysedTreeTransforms.py
View file @
6f95c7e3
...
...
@@ -11,7 +11,8 @@ import Symtab
class
AutoTestDictTransform
(
ScopeTrackingTransform
):
# Handles autotestdict directive
blacklist
=
[
'__cinit__'
,
'__dealloc__'
,
'__richcmp__'
,
'__nonzero__'
,
blacklist
=
[
'__cinit__'
,
'__dealloc__'
,
'__richcmp__'
,
'__nonzero__'
,
'__bool__'
,
'__len__'
,
'__contains__'
]
def
visit_ModuleNode
(
self
,
node
):
...
...
Cython/Compiler/ExprNodes.py
View file @
6f95c7e3
...
...
@@ -329,8 +329,9 @@ class ExprNode(Node):
# time we get the result.
self
.
analyse_types
(
env
)
bool
=
self
.
coerce_to_boolean
(
env
)
temp_bool
=
bool
.
coerce_to_temp
(
env
)
return
temp_bool
if
not
bool
.
is_simple
():
bool
=
bool
.
coerce_to_temp
(
env
)
return
bool
# --------------- Type Inference -----------------
...
...
@@ -559,6 +560,9 @@ class ExprNode(Node):
if
dst_type
.
is_pyobject
:
if
not
src
.
type
.
is_pyobject
:
if
dst_type
is
bytes_type
and
src
.
type
.
is_int
:
src
=
CoerceIntToBytesNode
(
src
,
env
)
else
:
src
=
CoerceToPyTypeNode
(
src
,
env
)
if
not
src
.
type
.
subtype_of
(
dst_type
):
if
not
isinstance
(
src
,
NoneNode
):
...
...
@@ -2023,6 +2027,7 @@ class IndexNode(ExprNode):
"Attempting to index non-array type '%s'"
%
self
.
base
.
type
)
self
.
type
=
PyrexTypes
.
error_type
gil_message
=
"Indexing Python object"
def
nogil_check
(
self
,
env
):
...
...
@@ -4668,7 +4673,12 @@ class TypecastNode(ExprNode):
if
from_py
and
not
to_py
and
self
.
operand
.
is_ephemeral
()
and
not
self
.
type
.
is_numeric
:
error
(
self
.
pos
,
"Casting temporary Python object to non-numeric non-Python type"
)
if
to_py
and
not
from_py
:
if
self
.
operand
.
type
.
can_coerce_to_pyobject
(
env
):
if
self
.
type
is
bytes_type
and
self
.
operand
.
type
.
is_int
:
# FIXME: the type cast node isn't needed in this case
# and can be dropped once analyse_types() can return a
# different node
self
.
operand
=
CoerceIntToBytesNode
(
self
.
operand
,
env
)
elif
self
.
operand
.
type
.
can_coerce_to_pyobject
(
env
):
self
.
result_ctype
=
py_object_type
self
.
operand
=
self
.
operand
.
coerce_to_pyobject
(
env
)
else
:
...
...
@@ -5580,9 +5590,11 @@ class CmpNode(object):
func
=
compile_time_binary_operators
[
self
.
operator
]
operand2_result
=
self
.
operand2
.
constant_result
result
=
func
(
operand1_result
,
operand2_result
)
if
result
and
self
.
cascade
:
result
=
result
and
\
self
.
cascade
.
cascaded_compile_time_value
(
operand2_result
)
if
self
.
cascade
:
self
.
cascade
.
calculate_cascaded_constant_result
(
operand2_result
)
if
self
.
cascade
.
constant_result
:
self
.
constant_result
=
result
and
self
.
cascade
.
constant_result
else
:
self
.
constant_result
=
result
def
cascaded_compile_time_value
(
self
,
operand1
,
denv
):
...
...
@@ -5597,7 +5609,7 @@ class CmpNode(object):
cascade
=
self
.
cascade
if
cascade
:
# FIXME: I bet this must call cascaded_compile_time_value()
result
=
result
and
cascade
.
compile_time_value
(
operand2
,
denv
)
result
=
result
and
cascade
.
c
ascaded_c
ompile_time_value
(
operand2
,
denv
)
return
result
def
is_cpp_comparison
(
self
):
...
...
@@ -5727,10 +5739,8 @@ class CmpNode(object):
def
is_c_string_contains
(
self
):
return
self
.
operator
in
(
'in'
,
'not_in'
)
and
\
((
self
.
operand1
.
type
in
(
PyrexTypes
.
c_char_type
,
PyrexTypes
.
c_uchar_type
)
and
self
.
operand2
.
type
in
(
PyrexTypes
.
c_char_ptr_type
,
PyrexTypes
.
c_uchar_ptr_type
,
bytes_type
))
or
((
self
.
operand1
.
type
.
is_int
and
(
self
.
operand2
.
type
.
is_string
or
self
.
operand2
.
type
is
bytes_type
))
or
(
self
.
operand1
.
type
is
PyrexTypes
.
c_py_unicode_type
and
self
.
operand2
.
type
is
unicode_type
))
...
...
@@ -5894,8 +5904,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
return
()
def
calculate_constant_result
(
self
):
self
.
constant_result
=
self
.
calculate_cascaded_constant_result
(
self
.
operand1
.
constant_result
)
self
.
calculate_cascaded_constant_result
(
self
.
operand1
.
constant_result
)
def
compile_time_value
(
self
,
denv
):
operand1
=
self
.
operand1
.
compile_time_value
(
denv
)
...
...
@@ -6073,6 +6082,10 @@ class CascadedCmpNode(Node, CmpNode):
def
type_dependencies
(
self
,
env
):
return
()
def
has_constant_result
(
self
):
return
self
.
constant_result
is
not
constant_value_not_set
and
\
self
.
constant_result
is
not
not_a_constant
def
analyse_types
(
self
,
env
):
self
.
operand2
.
analyse_types
(
env
)
if
self
.
cascade
:
...
...
@@ -6330,6 +6343,46 @@ class CoerceToPyTypeNode(CoercionNode):
code
.
put_gotref
(
self
.
py_result
())
class
CoerceIntToBytesNode
(
CoerceToPyTypeNode
):
# This node is used to convert a C int type to a Python bytes
# object.
is_temp
=
1
def
__init__
(
self
,
arg
,
env
):
arg
=
arg
.
coerce_to_simple
(
env
)
CoercionNode
.
__init__
(
self
,
arg
)
self
.
type
=
Builtin
.
bytes_type
def
generate_result_code
(
self
,
code
):
arg
=
self
.
arg
arg_result
=
arg
.
result
()
if
arg
.
type
not
in
(
PyrexTypes
.
c_char_type
,
PyrexTypes
.
c_uchar_type
,
PyrexTypes
.
c_schar_type
):
if
arg
.
type
.
signed
:
code
.
putln
(
"if ((%s < 0) || (%s > 255)) {"
%
(
arg_result
,
arg_result
))
else
:
code
.
putln
(
"if (%s > 255) {"
%
arg_result
)
code
.
putln
(
'PyErr_Format(PyExc_OverflowError, '
'"value too large to pack into a byte"); %s'
%
(
code
.
error_goto
(
self
.
pos
)))
code
.
putln
(
'}'
)
temp
=
None
if
arg
.
type
is
not
PyrexTypes
.
c_char_type
:
temp
=
code
.
funcstate
.
allocate_temp
(
PyrexTypes
.
c_char_type
,
manage_ref
=
False
)
code
.
putln
(
"%s = (char)%s;"
%
(
temp
,
arg_result
))
arg_result
=
temp
code
.
putln
(
'%s = PyBytes_FromStringAndSize(&%s, 1); %s'
%
(
self
.
result
(),
arg_result
,
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
if
temp
is
not
None
:
code
.
funcstate
.
release_temp
(
temp
)
code
.
put_gotref
(
self
.
py_result
())
class
CoerceFromPyTypeNode
(
CoercionNode
):
# This node is used to convert a Python object
# to a C data type.
...
...
@@ -6445,6 +6498,7 @@ class CoerceToTempNode(CoercionNode):
def
__init__
(
self
,
arg
,
env
):
CoercionNode
.
__init__
(
self
,
arg
)
self
.
type
=
self
.
arg
.
type
self
.
constant_result
=
self
.
arg
.
constant_result
self
.
is_temp
=
1
if
self
.
type
.
is_pyobject
:
self
.
result_ctype
=
py_object_type
...
...
@@ -6457,6 +6511,8 @@ class CoerceToTempNode(CoercionNode):
def
coerce_to_boolean
(
self
,
env
):
self
.
arg
=
self
.
arg
.
coerce_to_boolean
(
env
)
if
self
.
arg
.
is_simple
():
return
self
.
arg
self
.
type
=
self
.
arg
.
type
self
.
result_ctype
=
self
.
type
return
self
...
...
Cython/Compiler/Nodes.py
View file @
6f95c7e3
...
...
@@ -4039,8 +4039,24 @@ class IfStatNode(StatNode):
if
self
.
else_clause
:
self
.
else_clause
.
analyse_expressions
(
env
)
# eliminate dead code based on constant condition results
if_clauses
=
[]
condition_result
=
None
for
if_clause
in
self
.
if_clauses
:
condition_result
=
if_clause
.
get_constant_condition_result
()
if
condition_result
!=
False
:
if_clauses
.
append
(
if_clause
)
if
condition_result
==
True
:
# other conditions can no longer apply
self
.
else_clause
=
None
break
self
.
if_clauses
=
if_clauses
# FIXME: if only one active code body is left here, we can
# replace the whole node
def
generate_execution_code
(
self
,
code
):
code
.
mark_pos
(
self
.
pos
)
if
self
.
if_clauses
:
end_label
=
code
.
new_label
()
for
if_clause
in
self
.
if_clauses
:
if_clause
.
generate_execution_code
(
code
,
end_label
)
...
...
@@ -4049,6 +4065,8 @@ class IfStatNode(StatNode):
self
.
else_clause
.
generate_execution_code
(
code
)
code
.
putln
(
"}"
)
code
.
put_label
(
end_label
)
elif
self
.
else_clause
:
self
.
else_clause
.
generate_execution_code
(
code
)
def
generate_function_definitions
(
self
,
env
,
code
):
for
clause
in
self
.
if_clauses
:
...
...
@@ -4083,6 +4101,12 @@ class IfClauseNode(Node):
self
.
condition
.
analyse_temp_boolean_expression
(
env
)
self
.
body
.
analyse_expressions
(
env
)
def
get_constant_condition_result
(
self
):
if
self
.
condition
.
has_constant_result
():
return
self
.
condition
.
constant_result
else
:
return
None
def
generate_execution_code
(
self
,
code
,
end_label
):
self
.
condition
.
generate_evaluation_code
(
code
)
code
.
putln
(
...
...
@@ -5258,8 +5282,7 @@ if Options.gcc_branch_hints:
"""
#ifdef __GNUC__
/* Test for GCC > 2.95 */
#if __GNUC__ > 2 ||
\
(__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else /* __GNUC__ > 2 ... */
...
...
Cython/Compiler/Optimize.py
View file @
6f95c7e3
...
...
@@ -1187,7 +1187,71 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
if
isinstance
(
arg
,
ExprNodes
.
SimpleCallNode
):
if
node
.
type
.
is_int
or
node
.
type
.
is_float
:
return
self
.
_optimise_numeric_cast_call
(
node
,
arg
)
elif
isinstance
(
arg
,
ExprNodes
.
IndexNode
)
and
not
arg
.
is_buffer_access
:
index_node
=
arg
.
index
if
isinstance
(
index_node
,
ExprNodes
.
CoerceToPyTypeNode
):
index_node
=
index_node
.
arg
if
index_node
.
type
.
is_int
:
return
self
.
_optimise_int_indexing
(
node
,
arg
,
index_node
)
return
node
PyUnicode_GetItemInt_func_type
=
PyrexTypes
.
CFuncType
(
PyrexTypes
.
c_py_unicode_type
,
[
PyrexTypes
.
CFuncTypeArg
(
"unicode"
,
Builtin
.
unicode_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"index"
,
PyrexTypes
.
c_py_ssize_t_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"check_bounds"
,
PyrexTypes
.
c_int_type
,
None
),
],
exception_value
=
"((Py_UNICODE)-1)"
,
exception_check
=
True
)
PyBytes_GetItemInt_func_type
=
PyrexTypes
.
CFuncType
(
PyrexTypes
.
c_char_type
,
[
PyrexTypes
.
CFuncTypeArg
(
"bytes"
,
Builtin
.
bytes_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"index"
,
PyrexTypes
.
c_py_ssize_t_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"check_bounds"
,
PyrexTypes
.
c_int_type
,
None
),
],
exception_value
=
"((char)-1)"
,
exception_check
=
True
)
def
_optimise_int_indexing
(
self
,
coerce_node
,
arg
,
index_node
):
env
=
self
.
current_env
()
bound_check_bool
=
env
.
directives
[
'boundscheck'
]
and
1
or
0
if
arg
.
base
.
type
is
Builtin
.
unicode_type
:
if
coerce_node
.
type
is
PyrexTypes
.
c_py_unicode_type
:
# unicode[index] -> Py_UNICODE
bound_check_node
=
ExprNodes
.
IntNode
(
coerce_node
.
pos
,
value
=
str
(
bound_check_bool
),
constant_result
=
bound_check_bool
)
return
ExprNodes
.
PythonCapiCallNode
(
coerce_node
.
pos
,
"__Pyx_PyUnicode_GetItemInt"
,
self
.
PyUnicode_GetItemInt_func_type
,
args
=
[
arg
.
base
.
as_none_safe_node
(
"'NoneType' object is not subscriptable"
),
index_node
.
coerce_to
(
PyrexTypes
.
c_py_ssize_t_type
,
env
),
bound_check_node
,
],
is_temp
=
True
,
utility_code
=
unicode_index_utility_code
)
elif
arg
.
base
.
type
is
Builtin
.
bytes_type
:
if
coerce_node
.
type
in
(
PyrexTypes
.
c_char_type
,
PyrexTypes
.
c_uchar_type
):
# bytes[index] -> char
bound_check_node
=
ExprNodes
.
IntNode
(
coerce_node
.
pos
,
value
=
str
(
bound_check_bool
),
constant_result
=
bound_check_bool
)
node
=
ExprNodes
.
PythonCapiCallNode
(
coerce_node
.
pos
,
"__Pyx_PyBytes_GetItemInt"
,
self
.
PyBytes_GetItemInt_func_type
,
args
=
[
arg
.
base
.
as_none_safe_node
(
"'NoneType' object is not subscriptable"
),
index_node
.
coerce_to
(
PyrexTypes
.
c_py_ssize_t_type
,
env
),
bound_check_node
,
],
is_temp
=
True
,
utility_code
=
bytes_index_utility_code
)
if
coerce_node
.
type
is
not
PyrexTypes
.
c_char_type
:
node
=
node
.
coerce_to
(
coerce_node
.
type
,
env
)
return
node
return
coerce_node
def
_optimise_numeric_cast_call
(
self
,
node
,
arg
):
function
=
arg
.
function
...
...
@@ -2140,14 +2204,17 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
def
_inject_int_default_argument
(
self
,
node
,
args
,
arg_index
,
type
,
default_value
):
assert
len
(
args
)
>=
arg_index
if
len
(
args
)
==
arg_index
:
args
.
append
(
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
str
(
default_value
),
type
=
type
))
args
.
append
(
ExprNodes
.
IntNode
(
node
.
pos
,
value
=
str
(
default_value
),
type
=
type
,
constant_result
=
default_value
))
else
:
args
[
arg_index
]
=
args
[
arg_index
].
coerce_to
(
type
,
self
.
current_env
())
def
_inject_bint_default_argument
(
self
,
node
,
args
,
arg_index
,
default_value
):
assert
len
(
args
)
>=
arg_index
if
len
(
args
)
==
arg_index
:
args
.
append
(
ExprNodes
.
BoolNode
(
node
.
pos
,
value
=
bool
(
default_value
)))
default_value
=
bool
(
default_value
)
args
.
append
(
ExprNodes
.
BoolNode
(
node
.
pos
,
value
=
default_value
,
constant_result
=
default_value
))
else
:
args
[
arg_index
]
=
args
[
arg_index
].
coerce_to_boolean
(
self
.
current_env
())
...
...
@@ -2348,6 +2415,48 @@ bad:
)
unicode_index_utility_code
=
UtilityCode
(
proto
=
"""
static CYTHON_INLINE Py_UNICODE __Pyx_PyUnicode_GetItemInt(PyObject* unicode, Py_ssize_t index, int check_bounds); /* proto */
"""
,
impl
=
"""
static CYTHON_INLINE Py_UNICODE __Pyx_PyUnicode_GetItemInt(PyObject* unicode, Py_ssize_t index, int check_bounds) {
if (check_bounds) {
if (unlikely(index >= PyUnicode_GET_SIZE(unicode)) |
unlikely(index < -PyUnicode_GET_SIZE(unicode))) {
PyErr_Format(PyExc_IndexError, "string index out of range");
return (Py_UNICODE)-1;
}
}
if (index < 0)
index += PyUnicode_GET_SIZE(unicode);
return PyUnicode_AS_UNICODE(unicode)[index];
}
"""
)
bytes_index_utility_code
=
UtilityCode
(
proto
=
"""
static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* unicode, Py_ssize_t index, int check_bounds); /* proto */
"""
,
impl
=
"""
static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* bytes, Py_ssize_t index, int check_bounds) {
if (check_bounds) {
if (unlikely(index >= PyBytes_GET_SIZE(bytes)) |
unlikely(index < -PyBytes_GET_SIZE(bytes))) {
PyErr_Format(PyExc_IndexError, "string index out of range");
return -1;
}
}
if (index < 0)
index += PyBytes_GET_SIZE(bytes);
return PyBytes_AS_STRING(bytes)[index];
}
"""
)
include_string_h_utility_code
=
UtilityCode
(
proto
=
"""
#include <string.h>
...
...
Cython/Compiler/PyrexTypes.py
View file @
6f95c7e3
...
...
@@ -881,17 +881,60 @@ class CBIntType(CIntType):
class
CPyUnicodeIntType
(
CIntType
):
# Py_UNICODE
#
Conversion from a unicode string to Py_UNICODE at runtime is not
#
currently supported and may never be - we only convert from and
#
to integers here. The maximum value for a Py_UNICODE is
#
1114111, so PyInt_FromLong() will do just fine her
e.
#
Py_UNICODE coerces from and to single character unicode strings,
#
but we also allow Python integers as input. The value range for
#
Py_UNICODE is 0..1114111, which is checked when converting from
#
an integer valu
e.
to_py_function
=
"PyInt_FromLong"
from_py_function
=
"__Pyx_PyInt_AsPy_UNICODE"
to_py_function
=
"PyUnicode_FromOrdinal"
from_py_function
=
"__Pyx_PyObject_AsPy_UNICODE"
def
create_from_py_utility_code
(
self
,
env
):
env
.
use_utility_code
(
pyobject_as_py_unicode_utility_code
)
return
True
def
sign_and_name
(
self
):
return
"Py_UNICODE"
pyobject_as_py_unicode_utility_code
=
UtilityCode
(
proto
=
'''
static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject*);
'''
,
impl
=
'''
static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject* x) {
static long maxval = 0;
long ival;
if (PyUnicode_Check(x)) {
if (unlikely(PyUnicode_GET_SIZE(x) != 1)) {
PyErr_Format(PyExc_ValueError,
"only single character unicode strings can be converted to Py_UNICODE, got length "
#if PY_VERSION_HEX < 0x02050000
"%d",
#else
"%zd",
#endif
PyUnicode_GET_SIZE(x));
return (Py_UNICODE)-1;
}
return PyUnicode_AS_UNICODE(x)[0];
}
if (unlikely(!maxval))
maxval = (long)PyUnicode_GetMax();
ival = __Pyx_PyInt_AsLong(x);
if (unlikely(ival < 0)) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_OverflowError,
"cannot convert negative value to Py_UNICODE");
return (Py_UNICODE)-1;
} else if (unlikely(ival > maxval)) {
PyErr_SetString(PyExc_OverflowError,
"value too large to convert to Py_UNICODE");
return (Py_UNICODE)-1;
}
return (Py_UNICODE)ival;
}
'''
)
class
CPySSizeTType
(
CIntType
):
...
...
@@ -2512,10 +2555,6 @@ type_conversion_predeclarations = """
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
#ifdef Py_USING_UNICODE
static CYTHON_INLINE Py_UNICODE __Pyx_PyInt_AsPy_UNICODE(PyObject*);
#endif
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
...
...
@@ -2580,26 +2619,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
return res;
}
#ifdef Py_USING_UNICODE
static CYTHON_INLINE Py_UNICODE __Pyx_PyInt_AsPy_UNICODE(PyObject* x) {
long ival = __Pyx_PyInt_AsLong(x);
static long maxval = 0;
if (unlikely(!maxval))
maxval = (long)PyUnicode_GetMax();
if (unlikely(ival < 0)) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_OverflowError,
"can't convert negative value to Py_UNICODE");
return (Py_UNICODE)-1;
} else if (unlikely(ival > maxval)) {
PyErr_SetString(PyExc_OverflowError,
"value too large to convert to Py_UNICODE");
return (Py_UNICODE)-1;
}
return (Py_UNICODE)ival;
}
#endif
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
PyObject* x = PyNumber_Index(b);
...
...
Cython/Compiler/TypeSlots.py
View file @
6f95c7e3
...
...
@@ -126,15 +126,16 @@ class SlotDescriptor(object):
# slot_name string Member name of the slot in the type object
# is_initialised_dynamically Is initialised by code in the module init function
# flag Py_TPFLAGS_XXX value indicating presence of slot
# py3
k
Indicates presence of slot in Python 3
# py3
Indicates presence of slot in Python 3
# py2 Indicates presence of slot in Python 2
# ifdef Full #ifdef string that slot is wrapped in. Using this causes py3
k
, py2 and flags to be ignored.)
# ifdef Full #ifdef string that slot is wrapped in. Using this causes py3, py2 and flags to be ignored.)
def
__init__
(
self
,
slot_name
,
dynamic
=
0
,
flag
=
None
,
py3k
=
True
,
py2
=
True
,
ifdef
=
None
):
def
__init__
(
self
,
slot_name
,
dynamic
=
0
,
flag
=
None
,
py3
=
True
,
py2
=
True
,
ifdef
=
None
):
self
.
slot_name
=
slot_name
self
.
is_initialised_dynamically
=
dynamic
self
.
flag
=
flag
self
.
py3
k
=
py3k
self
.
py3
=
py3
self
.
py2
=
py2
self
.
ifdef
=
ifdef
...
...
@@ -144,26 +145,26 @@ class SlotDescriptor(object):
else
:
value
=
self
.
slot_code
(
scope
)
flag
=
self
.
flag
py3
k
=
self
.
py3k
py3
=
self
.
py3
py2
=
self
.
py2
if
self
.
ifdef
:
code
.
putln
(
"#if %s"
%
self
.
ifdef
)
else
:
if
not
py3
k
:
if
not
py3
:
code
.
putln
(
"#if PY_MAJOR_VERSION < 3"
)
elif
not
py2
:
code
.
putln
(
"#if PY_MAJOR_VERSION >= 3"
)
if
flag
:
code
.
putln
(
"#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)"
%
flag
)
if
py3
k
==
'<RESERVED>'
:
if
py3
==
'<RESERVED>'
:
code
.
putln
(
"#if PY_MAJOR_VERSION >= 3"
)
code
.
putln
(
"0, /*reserved*/"
)
code
.
putln
(
"#else"
)
code
.
putln
(
"%s, /*%s*/"
%
(
value
,
self
.
slot_name
))
if
py3
k
==
'<RESERVED>'
:
if
py3
==
'<RESERVED>'
:
code
.
putln
(
"#endif"
)
if
flag
or
(
not
py3
k
or
not
py2
)
or
self
.
ifdef
:
if
flag
or
(
not
py3
or
not
py2
)
or
self
.
ifdef
:
code
.
putln
(
"#endif"
)
# Some C implementations have trouble statically
...
...
@@ -188,8 +189,8 @@ class FixedSlot(SlotDescriptor):
#
# value string
def
__init__
(
self
,
slot_name
,
value
,
py3k
=
True
,
py2
=
True
,
ifdef
=
None
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
py3k
=
py3k
,
py2
=
py2
,
ifdef
=
ifdef
)
def
__init__
(
self
,
slot_name
,
value
,
flag
=
None
,
py3
=
True
,
py2
=
True
,
ifdef
=
None
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
flag
=
flag
,
py3
=
py3
,
py2
=
py2
,
ifdef
=
ifdef
)
self
.
value
=
value
def
slot_code
(
self
,
scope
):
...
...
@@ -199,8 +200,8 @@ class FixedSlot(SlotDescriptor):
class
EmptySlot
(
FixedSlot
):
# Descriptor for a type slot whose value is always 0.
def
__init__
(
self
,
slot_name
,
py3k
=
True
,
py2
=
True
,
ifdef
=
None
):
FixedSlot
.
__init__
(
self
,
slot_name
,
"0"
,
py3k
=
py3k
,
py2
=
py2
,
ifdef
=
ifdef
)
def
__init__
(
self
,
slot_name
,
flag
=
None
,
py3
=
True
,
py2
=
True
,
ifdef
=
None
):
FixedSlot
.
__init__
(
self
,
slot_name
,
"0"
,
flag
=
flag
,
py3
=
py3
,
py2
=
py2
,
ifdef
=
ifdef
)
class
MethodSlot
(
SlotDescriptor
):
...
...
@@ -208,22 +209,31 @@ class MethodSlot(SlotDescriptor):
#
# signature Signature
# method_name string The __xxx__ name of the method
#
default string or None Default value of the slot
#
alternatives [string] Alternative list of __xxx__ names for the method
def
__init__
(
self
,
signature
,
slot_name
,
method_name
,
default
=
None
,
flag
=
None
,
py3k
=
True
,
py2
=
True
,
ifdef
=
None
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
flag
=
flag
,
py3k
=
py3k
,
py2
=
py2
,
ifdef
=
ifdef
)
def
__init__
(
self
,
signature
,
slot_name
,
method_name
,
fallback
=
None
,
flag
=
None
,
py3
=
True
,
py2
=
True
,
ifdef
=
None
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
flag
=
flag
,
py3
=
py3
,
py2
=
py2
,
ifdef
=
ifdef
)
self
.
signature
=
signature
self
.
slot_name
=
slot_name
self
.
method_name
=
method_name
self
.
default
=
default
self
.
alternatives
=
[]
method_name_to_slot
[
method_name
]
=
self
#
if
fallback
:
self
.
alternatives
.
append
(
fallback
)
for
alt
in
(
self
.
py2
,
self
.
py3
):
if
isinstance
(
alt
,
(
tuple
,
list
)):
slot_name
,
method_name
=
alt
self
.
alternatives
.
append
(
method_name
)
method_name_to_slot
[
method_name
]
=
self
def
slot_code
(
self
,
scope
):
entry
=
scope
.
lookup_here
(
self
.
method_name
)
if
entry
and
entry
.
func_cname
:
return
entry
.
func_cname
if
self
.
default
is
not
None
:
entry
=
scope
.
lookup_here
(
self
.
default
)
for
method_name
in
self
.
alternatives
:
entry
=
scope
.
lookup_here
(
method_name
)
if
entry
and
entry
.
func_cname
:
return
entry
.
func_cname
return
"0"
...
...
@@ -235,8 +245,8 @@ class InternalMethodSlot(SlotDescriptor):
#
# slot_name string Member name of the slot in the type object
def
__init__
(
self
,
slot_name
,
py2
=
True
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
py2
=
py2
)
def
__init__
(
self
,
slot_name
,
**
kargs
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
**
kargs
)
def
slot_code
(
self
,
scope
):
return
scope
.
mangle_internal
(
self
.
slot_name
)
...
...
@@ -246,8 +256,8 @@ class GCDependentSlot(InternalMethodSlot):
# Descriptor for a slot whose value depends on whether
# the type participates in GC.
def
__init__
(
self
,
slot_name
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
)
def
__init__
(
self
,
slot_name
,
**
kargs
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
**
kargs
)
def
slot_code
(
self
,
scope
):
if
not
scope
.
needs_gc
():
...
...
@@ -267,8 +277,8 @@ class GCDependentSlot(InternalMethodSlot):
class
ConstructorSlot
(
InternalMethodSlot
):
# Descriptor for tp_new and tp_dealloc.
def
__init__
(
self
,
slot_name
,
method
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
)
def
__init__
(
self
,
slot_name
,
method
,
**
kargs
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
**
kargs
)
self
.
method
=
method
def
slot_code
(
self
,
scope
):
...
...
@@ -294,8 +304,8 @@ class SyntheticSlot(InternalMethodSlot):
# alternative default value will be placed in the type
# slot.
def
__init__
(
self
,
slot_name
,
user_methods
,
default_value
,
py2
=
True
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
py2
=
py2
)
def
__init__
(
self
,
slot_name
,
user_methods
,
default_value
,
**
kargs
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
**
kargs
)
self
.
user_methods
=
user_methods
self
.
default_value
=
default_value
...
...
@@ -550,32 +560,32 @@ PyNumberMethods = (
MethodSlot
(
binaryfunc
,
"nb_add"
,
"__add__"
),
MethodSlot
(
binaryfunc
,
"nb_subtract"
,
"__sub__"
),
MethodSlot
(
binaryfunc
,
"nb_multiply"
,
"__mul__"
),
MethodSlot
(
binaryfunc
,
"nb_divide"
,
"__div__"
,
py3
k
=
False
),
MethodSlot
(
binaryfunc
,
"nb_divide"
,
"__div__"
,
py3
=
False
),
MethodSlot
(
binaryfunc
,
"nb_remainder"
,
"__mod__"
),
MethodSlot
(
binaryfunc
,
"nb_divmod"
,
"__divmod__"
),
MethodSlot
(
ternaryfunc
,
"nb_power"
,
"__pow__"
),
MethodSlot
(
unaryfunc
,
"nb_negative"
,
"__neg__"
),
MethodSlot
(
unaryfunc
,
"nb_positive"
,
"__pos__"
),
MethodSlot
(
unaryfunc
,
"nb_absolute"
,
"__abs__"
),
MethodSlot
(
inquiry
,
"nb_nonzero"
,
"__nonzero__"
),
MethodSlot
(
inquiry
,
"nb_nonzero"
,
"__nonzero__"
,
py3
=
(
"nb_bool"
,
"__bool__"
)
),
MethodSlot
(
unaryfunc
,
"nb_invert"
,
"__invert__"
),
MethodSlot
(
binaryfunc
,
"nb_lshift"
,
"__lshift__"
),
MethodSlot
(
binaryfunc
,
"nb_rshift"
,
"__rshift__"
),
MethodSlot
(
binaryfunc
,
"nb_and"
,
"__and__"
),
MethodSlot
(
binaryfunc
,
"nb_xor"
,
"__xor__"
),
MethodSlot
(
binaryfunc
,
"nb_or"
,
"__or__"
),
EmptySlot
(
"nb_coerce"
,
py3
k
=
False
),
MethodSlot
(
unaryfunc
,
"nb_int"
,
"__int__"
,
default
=
"__long__"
),
MethodSlot
(
unaryfunc
,
"nb_long"
,
"__long__"
,
default
=
"__int__"
,
py3k
=
"<RESERVED>"
),
EmptySlot
(
"nb_coerce"
,
py3
=
False
),
MethodSlot
(
unaryfunc
,
"nb_int"
,
"__int__"
,
fallback
=
"__long__"
),
MethodSlot
(
unaryfunc
,
"nb_long"
,
"__long__"
,
fallback
=
"__int__"
,
py3
=
"<RESERVED>"
),
MethodSlot
(
unaryfunc
,
"nb_float"
,
"__float__"
),
MethodSlot
(
unaryfunc
,
"nb_oct"
,
"__oct__"
,
py3
k
=
False
),
MethodSlot
(
unaryfunc
,
"nb_hex"
,
"__hex__"
,
py3
k
=
False
),
MethodSlot
(
unaryfunc
,
"nb_oct"
,
"__oct__"
,
py3
=
False
),
MethodSlot
(
unaryfunc
,
"nb_hex"
,
"__hex__"
,
py3
=
False
),
# Added in release 2.0
MethodSlot
(
ibinaryfunc
,
"nb_inplace_add"
,
"__iadd__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_subtract"
,
"__isub__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_multiply"
,
"__imul__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_divide"
,
"__idiv__"
,
py3
k
=
False
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_divide"
,
"__idiv__"
,
py3
=
False
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_remainder"
,
"__imod__"
),
MethodSlot
(
ternaryfunc
,
"nb_inplace_power"
,
"__ipow__"
),
# NOT iternaryfunc!!!
MethodSlot
(
ibinaryfunc
,
"nb_inplace_lshift"
,
"__ilshift__"
),
...
...
@@ -615,10 +625,10 @@ PyMappingMethods = (
)
PyBufferProcs
=
(
MethodSlot
(
getreadbufferproc
,
"bf_getreadbuffer"
,
"__getreadbuffer__"
,
py3
k
=
False
),
MethodSlot
(
getwritebufferproc
,
"bf_getwritebuffer"
,
"__getwritebuffer__"
,
py3
k
=
False
),
MethodSlot
(
getsegcountproc
,
"bf_getsegcount"
,
"__getsegcount__"
,
py3
k
=
False
),
MethodSlot
(
getcharbufferproc
,
"bf_getcharbuffer"
,
"__getcharbuffer__"
,
py3
k
=
False
),
MethodSlot
(
getreadbufferproc
,
"bf_getreadbuffer"
,
"__getreadbuffer__"
,
py3
=
False
),
MethodSlot
(
getwritebufferproc
,
"bf_getwritebuffer"
,
"__getwritebuffer__"
,
py3
=
False
),
MethodSlot
(
getsegcountproc
,
"bf_getsegcount"
,
"__getsegcount__"
,
py3
=
False
),
MethodSlot
(
getcharbufferproc
,
"bf_getcharbuffer"
,
"__getcharbuffer__"
,
py3
=
False
),
MethodSlot
(
getbufferproc
,
"bf_getbuffer"
,
"__getbuffer__"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
),
MethodSlot
(
releasebufferproc
,
"bf_releasebuffer"
,
"__releasebuffer__"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
)
...
...
@@ -637,7 +647,7 @@ slot_table = (
EmptySlot
(
"tp_print"
),
#MethodSlot(printfunc, "tp_print", "__print__"),
EmptySlot
(
"tp_getattr"
),
EmptySlot
(
"tp_setattr"
),
MethodSlot
(
cmpfunc
,
"tp_compare"
,
"__cmp__"
),
MethodSlot
(
cmpfunc
,
"tp_compare"
,
"__cmp__"
,
py3
=
'<RESERVED>'
),
MethodSlot
(
reprfunc
,
"tp_repr"
,
"__repr__"
),
SuiteSlot
(
PyNumberMethods
,
"PyNumberMethods"
,
"tp_as_number"
),
...
...
tests/errors/break_outside_loop.pyx
View file @
6f95c7e3
...
...
@@ -16,11 +16,14 @@ except: pass
try
:
break
finally
:
pass
if
True
:
if
bool_result
()
:
break
else
:
break
def
bool_result
():
return
True
_ERRORS
=
u'''
2:0: break statement not inside loop
...
...
tests/errors/continue_outside_loop.pyx
View file @
6f95c7e3
...
...
@@ -16,11 +16,13 @@ except: pass
try
:
continue
finally
:
pass
if
True
:
if
bool_result
()
:
continue
else
:
continue
def
bool_result
():
return
True
_ERRORS
=
u'''
2:0: continue statement not inside loop
...
...
tests/errors/literal_lists.pyx
View file @
6f95c7e3
def
f
():
cdef
int
*
p
if
False
:
if
false
()
:
p
=
[
1
,
2
,
3
]
def
false
():
return
False
_ERRORS
=
u"""
4:10: Literal list must be assigned to pointer at time of declaration
"""
tests/run/autotestdict.pyx
View file @
6f95c7e3
...
...
@@ -126,4 +126,20 @@ cdef class MyCdefClass:
False
"""
cdef
class
MyOtherCdefClass
:
"""
Needs no hack
>>> True
True
"""
def
__bool__
(
self
):
"""
Should not be included, as it can't be looked up with getattr in Py 2
>>> True
False
"""
cdef
func
()
tests/run/bytes_char_coercion.pyx
0 → 100644
View file @
6f95c7e3
cimport
cython
def
coerce_char_default
(
char
c
):
"""
Default char -> int coercion
>>> coerce_char_default(ord('A')) == ord('A')
True
"""
return
c
def
coerce_uchar_default
(
unsigned
char
c
):
"""
Default char -> int coercion
>>> coerce_uchar_default(ord('A')) == ord('A')
True
"""
return
c
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_char_bytes_cast
(
char
c
):
"""
Explicit char -> bytes coercion
>>> coerce_char_bytes_cast(ord('A')) == 'A'.encode('ASCII')
True
"""
return
<
bytes
>
c
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_uchar_bytes_cast
(
unsigned
char
c
):
"""
Explicit uchar -> bytes coercion
>>> coerce_uchar_bytes_cast(ord('A')) == 'A'.encode('ASCII')
True
>>> b = coerce_uchar_bytes_cast(ord('
\
\
xff'))
>>> b == '
\
\
xff' or b == '
\
\
xff'.encode('ISO-8859-1') # Py2 or Py3
True
"""
return
<
bytes
>
c
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_int_bytes_cast
(
int
c
):
"""
Explicit int -> bytes coercion
>>> coerce_int_bytes_cast(ord('A')) == 'A'.encode('ASCII')
True
>>> coerce_int_bytes_cast(ord('A') + 0x100)
Traceback (most recent call last):
OverflowError: value too large to pack into a byte
>>> coerce_int_bytes_cast(ord('A') - 0x100)
Traceback (most recent call last):
OverflowError: value too large to pack into a byte
"""
return
<
bytes
>
c
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_uint_bytes_cast
(
unsigned
int
c
):
"""
Explicit uint -> bytes coercion
>>> coerce_uint_bytes_cast(ord('A')) == 'A'.encode('ASCII')
True
>>> b = coerce_uint_bytes_cast(ord('
\
\
xff'))
>>> b == '
\
\
xff' or b == '
\
\
xff'.encode('ISO-8859-1') # Py2 or Py3
True
>>> coerce_uint_bytes_cast(ord('A') + 0x100)
Traceback (most recent call last):
OverflowError: value too large to pack into a byte
"""
return
<
bytes
>
c
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_char_bytes_assign
(
char
c
):
"""
Implicit char -> bytes coercion in assignments
>>> coerce_char_bytes_assign(ord('A')) == 'A'.encode('ASCII')
True
"""
cdef
bytes
s
=
c
return
s
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_uchar_bytes_assign
(
unsigned
char
c
):
"""
Implicit uchar -> bytes coercion in assignments
>>> coerce_uchar_bytes_assign(ord('A')) == 'A'.encode('ASCII')
True
>>> b = coerce_uchar_bytes_assign(ord('
\
\
xff'))
>>> b == '
\
\
xff' or b == '
\
\
xff'.encode('ISO-8859-1') # Py2 or Py3
True
"""
cdef
bytes
s
=
c
return
s
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_int_bytes_assign
(
int
c
):
"""
Implicit int -> bytes coercion in assignments
>>> coerce_int_bytes_assign(ord('A')) == 'A'.encode('ASCII')
True
>>> coerce_int_bytes_assign(ord('A') + 0x100)
Traceback (most recent call last):
OverflowError: value too large to pack into a byte
>>> coerce_int_bytes_assign(ord('A') - 0x100)
Traceback (most recent call last):
OverflowError: value too large to pack into a byte
"""
cdef
bytes
s
=
c
return
s
@
cython
.
test_assert_path_exists
(
"//CoerceIntToBytesNode"
)
@
cython
.
test_fail_if_path_exists
(
"//CoerceToPyTypeNode"
)
def
coerce_uint_bytes_assign
(
unsigned
int
c
):
"""
Implicit uint -> bytes coercion in assignments
>>> coerce_uint_bytes_assign(ord('A')) == 'A'.encode('ASCII')
True
>>> b = coerce_uint_bytes_assign(ord('
\
\
xff'))
>>> b == '
\
\
xff' or b == '
\
\
xff'.encode('ISO-8859-1') # Py2 or Py3
True
>>> coerce_uint_bytes_assign(ord('A') + 0x100)
Traceback (most recent call last):
OverflowError: value too large to pack into a byte
"""
cdef
bytes
s
=
c
return
s
tests/run/bytes_indexing.pyx
0 → 100644
View file @
6f95c7e3
cimport
cython
cdef
bytes
b12345
=
b'12345'
def
index_literal
(
int
i
):
"""
Python 3 returns integer values on indexing, Py2 returns byte
string literals...
>>> index_literal(0) in (ord('1'), '1')
True
>>> index_literal(-5) in (ord('1'), '1')
True
>>> index_literal(2) in (ord('3'), '3')
True
>>> index_literal(4) in (ord('5'), '5')
True
"""
return
b"12345"
[
i
]
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_literal_char_cast
(
int
i
):
"""
>>> index_literal_char_cast(0) == ord('1')
True
>>> index_literal_char_cast(-5) == ord('1')
True
>>> index_literal_char_cast(2) == ord('3')
True
>>> index_literal_char_cast(4) == ord('5')
True
>>> index_literal_char_cast(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
return
<
char
>
(
b"12345"
[
i
])
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_nonliteral_char_cast
(
int
i
):
"""
>>> index_nonliteral_char_cast(0) == ord('1')
True
>>> index_nonliteral_char_cast(-5) == ord('1')
True
>>> index_nonliteral_char_cast(2) == ord('3')
True
>>> index_nonliteral_char_cast(4) == ord('5')
True
>>> index_nonliteral_char_cast(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
return
<
char
>
(
b12345
[
i
])
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_literal_uchar_cast
(
int
i
):
"""
>>> index_literal_uchar_cast(0) == ord('1')
True
>>> index_literal_uchar_cast(-5) == ord('1')
True
>>> index_literal_uchar_cast(2) == ord('3')
True
>>> index_literal_uchar_cast(4) == ord('5')
True
>>> index_literal_uchar_cast(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
return
<
unsigned
char
>
(
b"12345"
[
i
])
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_nonliteral_uchar_cast
(
int
i
):
"""
>>> index_nonliteral_uchar_cast(0) == ord('1')
True
>>> index_nonliteral_uchar_cast(-5) == ord('1')
True
>>> index_nonliteral_uchar_cast(2) == ord('3')
True
>>> index_nonliteral_uchar_cast(4) == ord('5')
True
>>> index_nonliteral_uchar_cast(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
return
<
unsigned
char
>
(
b12345
[
i
])
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_literal_char_coerce
(
int
i
):
"""
>>> index_literal_char_coerce(0) == ord('1')
True
>>> index_literal_char_coerce(-5) == ord('1')
True
>>> index_literal_char_coerce(2) == ord('3')
True
>>> index_literal_char_coerce(4) == ord('5')
True
>>> index_literal_char_coerce(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
cdef
char
result
=
b"12345"
[
i
]
return
result
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_nonliteral_char_coerce
(
int
i
):
"""
>>> index_nonliteral_char_coerce(0) == ord('1')
True
>>> index_nonliteral_char_coerce(-5) == ord('1')
True
>>> index_nonliteral_char_coerce(2) == ord('3')
True
>>> index_nonliteral_char_coerce(4) == ord('5')
True
>>> index_nonliteral_char_coerce(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
cdef
char
result
=
b12345
[
i
]
return
result
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
@
cython
.
boundscheck
(
False
)
def
index_literal_char_coerce_no_check
(
int
i
):
"""
>>> index_literal_char_coerce_no_check(0) == ord('1')
True
>>> index_literal_char_coerce_no_check(-5) == ord('1')
True
>>> index_literal_char_coerce_no_check(2) == ord('3')
True
>>> index_literal_char_coerce_no_check(4) == ord('5')
True
"""
cdef
char
result
=
b"12345"
[
i
]
return
result
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
@
cython
.
boundscheck
(
False
)
def
index_nonliteral_char_coerce_no_check
(
int
i
):
"""
>>> index_nonliteral_char_coerce_no_check(0) == ord('1')
True
>>> index_nonliteral_char_coerce_no_check(-5) == ord('1')
True
>>> index_nonliteral_char_coerce_no_check(2) == ord('3')
True
>>> index_nonliteral_char_coerce_no_check(4) == ord('5')
True
"""
cdef
char
result
=
b12345
[
i
]
return
result
tests/run/consts.pyx
View file @
6f95c7e3
import
sys
IS_PY3
=
sys
.
version_info
[
0
]
>=
3
cimport
cython
DEF
INT_VAL
=
1
def
_func
(
a
,
b
,
c
):
return
a
+
b
+
c
...
...
@@ -76,3 +80,76 @@ def lists():
True
"""
return
[
1
,
2
,
3
]
+
[
4
,
5
,
6
]
def
int_bool_result
():
"""
>>> int_bool_result()
True
"""
if
5
:
return
True
else
:
return
False
@
cython
.
test_fail_if_path_exists
(
"//PrimaryCmpNode"
)
def
if_compare_true
():
"""
>>> if_compare_true()
True
"""
if
0
==
0
:
return
True
else
:
return
False
@
cython
.
test_fail_if_path_exists
(
"//PrimaryCmpNode"
)
def
if_compare_false
():
"""
>>> if_compare_false()
False
"""
if
0
==
1
or
1
==
0
:
return
True
else
:
return
False
@
cython
.
test_fail_if_path_exists
(
"//PrimaryCmpNode"
)
def
if_compare_cascaded
():
"""
>>> if_compare_cascaded()
True
"""
if
0
<
1
<
2
<
3
:
return
True
else
:
return
False
@
cython
.
test_fail_if_path_exists
(
"//CoerceToBooleanNode"
,
"//ListNode"
)
def
list_bool_result
():
"""
>>> list_bool_result()
True
"""
if
[
1
,
2
,
3
]:
return
True
else
:
return
False
def
compile_time_DEF
():
"""
>>> compile_time_DEF()
(1, False, True, True, False)
"""
return
INT_VAL
,
INT_VAL
==
0
,
INT_VAL
!=
0
,
INT_VAL
==
1
,
INT_VAL
!=
1
@
cython
.
test_fail_if_path_exists
(
"//PrimaryCmpNode"
)
def
compile_time_DEF_if
():
"""
>>> compile_time_DEF_if()
True
"""
if
INT_VAL
!=
0
:
return
True
else
:
return
False
tests/run/for_in_string.pyx
View file @
6f95c7e3
...
...
@@ -70,6 +70,36 @@ def for_char_in_enumerate_bytes(bytes s):
else
:
return
'X'
@
cython
.
test_assert_path_exists
(
"//ForFromStatNode"
)
@
cython
.
test_fail_if_path_exists
(
"//ForInStatNode"
)
def
for_pyvar_in_char_ptr
(
char
*
c_string
):
"""
>>> for_pyvar_in_char_ptr( (bytes_abc+bytes_ABC) * 2 )
[True, True, True, False, False, False, True, True, True, False]
>>> for_pyvar_in_char_ptr( bytes_abc_null * 2 )
[True, False, True, False, True, True, False, True, False, True]
"""
in_test
=
[]
cdef
object
c
for
c
in
c_string
[:
10
]:
in_test
.
append
(
c
in
b'abc'
)
return
in_test
@
cython
.
test_assert_path_exists
(
"//ForFromStatNode"
)
@
cython
.
test_fail_if_path_exists
(
"//ForInStatNode"
)
def
for_char_in_char_ptr
(
char
*
c_string
):
"""
>>> for_char_in_char_ptr( (bytes_abc+bytes_ABC) * 2 )
[True, True, True, False, False, False, True, True, True, False]
>>> for_char_in_char_ptr( bytes_abc_null * 2 )
[True, False, True, False, True, True, False, True, False, True]
"""
in_test
=
[]
cdef
char
c
for
c
in
c_string
[:
10
]:
in_test
.
append
(
c
in
b'abc'
)
return
in_test
@
cython
.
test_assert_path_exists
(
"//ForFromStatNode"
)
@
cython
.
test_fail_if_path_exists
(
"//ForInStatNode"
)
def
for_pyunicode_in_unicode
(
unicode
s
):
...
...
tests/run/py_unicode_type.pyx
View file @
6f95c7e3
# -*- coding: iso-8859-1 -*-
cimport
cython
cdef
Py_UNICODE
char_ASCII
=
u'A'
cdef
Py_UNICODE
char_KLINGON
=
u'
\
uF8D2
'
def
compare_ASCII
():
"""
>>> compare_ASCII()
...
...
@@ -16,9 +17,9 @@ def compare_ASCII():
print
(
char_ASCII
==
u'
\
uF8D2
'
)
def
compare_
KLINGON
():
def
compare_
klingon
():
"""
>>> compare_
ASCII
()
>>> compare_
klingon
()
True
False
False
...
...
@@ -39,31 +40,114 @@ def index_literal(int i):
>>> index_literal(4) == '5'
True
"""
# runtime casts are not currently supported
#return <Py_UNICODE>(u"12345"[i])
return
u"12345"
[
i
]
def
unicode_cardinal
(
Py_UNICODE
i
):
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_literal_pyunicode_cast
(
int
i
):
"""
>>> import sys
>>> index_literal_pyunicode_cast(0) == '1'
True
>>> index_literal_pyunicode_cast(-5) == '1'
True
>>> index_literal_pyunicode_cast(2) == '3'
True
>>> index_literal_pyunicode_cast(4) == '5'
True
>>> index_literal_pyunicode_coerce(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
return
<
Py_UNICODE
>
(
u"12345"
[
i
])
>>> unicode_cardinal(0)
0
>>> unicode_cardinal(1)
1
>>> unicode_cardinal(sys.maxunicode) == sys.maxunicode
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
def
index_literal_pyunicode_coerce
(
int
i
):
"""
>>> index_literal_pyunicode_coerce(0) == '1'
True
>>> index_literal_pyunicode_coerce(-5) == '1'
True
>>> index_literal_pyunicode_coerce(2) == '3'
True
>>> index_literal_pyunicode_coerce(4) == '5'
True
>>> index_literal_pyunicode_coerce(6)
Traceback (most recent call last):
IndexError: string index out of range
"""
cdef
Py_UNICODE
result
=
u"12345"
[
i
]
return
result
>>> unicode_cardinal(-1) #doctest: +ELLIPSIS
@
cython
.
test_assert_path_exists
(
"//PythonCapiCallNode"
)
@
cython
.
test_fail_if_path_exists
(
"//IndexNode"
,
"//CoerceFromPyTypeNode"
)
@
cython
.
boundscheck
(
False
)
def
index_literal_pyunicode_coerce_no_check
(
int
i
):
"""
>>> index_literal_pyunicode_coerce_no_check(0) == '1'
True
>>> index_literal_pyunicode_coerce_no_check(-5) == '1'
True
>>> index_literal_pyunicode_coerce_no_check(2) == '3'
True
>>> index_literal_pyunicode_coerce_no_check(4) == '5'
True
"""
cdef
Py_UNICODE
result
=
u"12345"
[
i
]
return
result
from
cpython.unicode
cimport
PyUnicode_FromOrdinal
import
sys
u0
=
u'
\
x00
'
u1
=
u'
\
x01
'
umax
=
PyUnicode_FromOrdinal
(
sys
.
maxunicode
)
def
unicode_ordinal
(
Py_UNICODE
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: ...
>>> unicode_cardinal(sys.maxunicode+1) #doctest: +ELLIPSIS
Value too large:
>>> unicode_ordinal(sys.maxunicode+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_UNICODE, 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_UNICODE, got length 2
"""
return
i
tests/run/type_slots_nonzero_bool.pyx
0 → 100644
View file @
6f95c7e3
__doc__
=
"""
>>> not not BoolA(0)
False
>>> not not BoolA(1)
True
>>> not not BoolB(0)
False
>>> not not BoolB(1)
True
>>> not not BoolX(0)
False
>>> not not BoolX(1)
True
>>> not not BoolY(0)
False
>>> not not BoolY(1)
True
"""
cdef
class
BoolA
:
cdef
bint
value
def
__cinit__
(
self
,
bint
value
):
self
.
value
=
value
def
__nonzero__
(
self
):
return
self
.
value
cdef
class
BoolB
:
cdef
bint
value
def
__cinit__
(
self
,
bint
value
):
self
.
value
=
value
def
__bool__
(
self
):
return
self
.
value
cdef
class
BoolX
(
BoolA
):
pass
cdef
class
BoolY
(
BoolB
):
pass
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