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
Hide 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
...
@@ -11,7 +11,8 @@ import Symtab
class
AutoTestDictTransform
(
ScopeTrackingTransform
):
class
AutoTestDictTransform
(
ScopeTrackingTransform
):
# Handles autotestdict directive
# Handles autotestdict directive
blacklist
=
[
'__cinit__'
,
'__dealloc__'
,
'__richcmp__'
,
'__nonzero__'
,
blacklist
=
[
'__cinit__'
,
'__dealloc__'
,
'__richcmp__'
,
'__nonzero__'
,
'__bool__'
,
'__len__'
,
'__contains__'
]
'__len__'
,
'__contains__'
]
def
visit_ModuleNode
(
self
,
node
):
def
visit_ModuleNode
(
self
,
node
):
...
...
Cython/Compiler/ExprNodes.py
View file @
6f95c7e3
...
@@ -329,8 +329,9 @@ class ExprNode(Node):
...
@@ -329,8 +329,9 @@ class ExprNode(Node):
# time we get the result.
# time we get the result.
self
.
analyse_types
(
env
)
self
.
analyse_types
(
env
)
bool
=
self
.
coerce_to_boolean
(
env
)
bool
=
self
.
coerce_to_boolean
(
env
)
temp_bool
=
bool
.
coerce_to_temp
(
env
)
if
not
bool
.
is_simple
():
return
temp_bool
bool
=
bool
.
coerce_to_temp
(
env
)
return
bool
# --------------- Type Inference -----------------
# --------------- Type Inference -----------------
...
@@ -559,7 +560,10 @@ class ExprNode(Node):
...
@@ -559,7 +560,10 @@ class ExprNode(Node):
if
dst_type
.
is_pyobject
:
if
dst_type
.
is_pyobject
:
if
not
src
.
type
.
is_pyobject
:
if
not
src
.
type
.
is_pyobject
:
src
=
CoerceToPyTypeNode
(
src
,
env
)
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
src
.
type
.
subtype_of
(
dst_type
):
if
not
isinstance
(
src
,
NoneNode
):
if
not
isinstance
(
src
,
NoneNode
):
src
=
PyTypeTestNode
(
src
,
dst_type
,
env
)
src
=
PyTypeTestNode
(
src
,
dst_type
,
env
)
...
@@ -2023,6 +2027,7 @@ class IndexNode(ExprNode):
...
@@ -2023,6 +2027,7 @@ class IndexNode(ExprNode):
"Attempting to index non-array type '%s'"
%
"Attempting to index non-array type '%s'"
%
self
.
base
.
type
)
self
.
base
.
type
)
self
.
type
=
PyrexTypes
.
error_type
self
.
type
=
PyrexTypes
.
error_type
gil_message
=
"Indexing Python object"
gil_message
=
"Indexing Python object"
def
nogil_check
(
self
,
env
):
def
nogil_check
(
self
,
env
):
...
@@ -4668,7 +4673,12 @@ class TypecastNode(ExprNode):
...
@@ -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
:
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"
)
error
(
self
.
pos
,
"Casting temporary Python object to non-numeric non-Python type"
)
if
to_py
and
not
from_py
:
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
.
result_ctype
=
py_object_type
self
.
operand
=
self
.
operand
.
coerce_to_pyobject
(
env
)
self
.
operand
=
self
.
operand
.
coerce_to_pyobject
(
env
)
else
:
else
:
...
@@ -5580,11 +5590,13 @@ class CmpNode(object):
...
@@ -5580,11 +5590,13 @@ class CmpNode(object):
func
=
compile_time_binary_operators
[
self
.
operator
]
func
=
compile_time_binary_operators
[
self
.
operator
]
operand2_result
=
self
.
operand2
.
constant_result
operand2_result
=
self
.
operand2
.
constant_result
result
=
func
(
operand1_result
,
operand2_result
)
result
=
func
(
operand1_result
,
operand2_result
)
if
result
and
self
.
cascade
:
if
self
.
cascade
:
result
=
result
and
\
self
.
cascade
.
calculate_cascaded_constant_result
(
operand2_result
)
self
.
cascade
.
cascaded_compile_time_value
(
operand2_result
)
if
self
.
cascade
.
constant_result
:
self
.
constant_result
=
result
self
.
constant_result
=
result
and
self
.
cascade
.
constant_result
else
:
self
.
constant_result
=
result
def
cascaded_compile_time_value
(
self
,
operand1
,
denv
):
def
cascaded_compile_time_value
(
self
,
operand1
,
denv
):
func
=
get_compile_time_binop
(
self
)
func
=
get_compile_time_binop
(
self
)
operand2
=
self
.
operand2
.
compile_time_value
(
denv
)
operand2
=
self
.
operand2
.
compile_time_value
(
denv
)
...
@@ -5597,7 +5609,7 @@ class CmpNode(object):
...
@@ -5597,7 +5609,7 @@ class CmpNode(object):
cascade
=
self
.
cascade
cascade
=
self
.
cascade
if
cascade
:
if
cascade
:
# FIXME: I bet this must call cascaded_compile_time_value()
# 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
return
result
def
is_cpp_comparison
(
self
):
def
is_cpp_comparison
(
self
):
...
@@ -5727,10 +5739,8 @@ class CmpNode(object):
...
@@ -5727,10 +5739,8 @@ class CmpNode(object):
def
is_c_string_contains
(
self
):
def
is_c_string_contains
(
self
):
return
self
.
operator
in
(
'in'
,
'not_in'
)
and
\
return
self
.
operator
in
(
'in'
,
'not_in'
)
and
\
((
self
.
operand1
.
type
in
(
PyrexTypes
.
c_char_type
,
PyrexTypes
.
c_uchar_type
)
((
self
.
operand1
.
type
.
is_int
and
self
.
operand2
.
type
in
(
PyrexTypes
.
c_char_ptr_type
,
and
(
self
.
operand2
.
type
.
is_string
or
self
.
operand2
.
type
is
bytes_type
))
or
PyrexTypes
.
c_uchar_ptr_type
,
bytes_type
))
or
(
self
.
operand1
.
type
is
PyrexTypes
.
c_py_unicode_type
(
self
.
operand1
.
type
is
PyrexTypes
.
c_py_unicode_type
and
self
.
operand2
.
type
is
unicode_type
))
and
self
.
operand2
.
type
is
unicode_type
))
...
@@ -5894,8 +5904,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
...
@@ -5894,8 +5904,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
return
()
return
()
def
calculate_constant_result
(
self
):
def
calculate_constant_result
(
self
):
self
.
constant_result
=
self
.
calculate_cascaded_constant_result
(
self
.
calculate_cascaded_constant_result
(
self
.
operand1
.
constant_result
)
self
.
operand1
.
constant_result
)
def
compile_time_value
(
self
,
denv
):
def
compile_time_value
(
self
,
denv
):
operand1
=
self
.
operand1
.
compile_time_value
(
denv
)
operand1
=
self
.
operand1
.
compile_time_value
(
denv
)
...
@@ -6073,6 +6082,10 @@ class CascadedCmpNode(Node, CmpNode):
...
@@ -6073,6 +6082,10 @@ class CascadedCmpNode(Node, CmpNode):
def
type_dependencies
(
self
,
env
):
def
type_dependencies
(
self
,
env
):
return
()
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
):
def
analyse_types
(
self
,
env
):
self
.
operand2
.
analyse_types
(
env
)
self
.
operand2
.
analyse_types
(
env
)
if
self
.
cascade
:
if
self
.
cascade
:
...
@@ -6294,7 +6307,7 @@ class CoerceToPyTypeNode(CoercionNode):
...
@@ -6294,7 +6307,7 @@ class CoerceToPyTypeNode(CoercionNode):
CoercionNode
.
__init__
(
self
,
arg
)
CoercionNode
.
__init__
(
self
,
arg
)
if
not
arg
.
type
.
create_to_py_utility_code
(
env
):
if
not
arg
.
type
.
create_to_py_utility_code
(
env
):
error
(
arg
.
pos
,
error
(
arg
.
pos
,
"Cannot convert '%s' to Python object"
%
arg
.
type
)
"Cannot convert '%s' to Python object"
%
arg
.
type
)
if
type
is
not
py_object_type
:
if
type
is
not
py_object_type
:
self
.
type
=
py_object_type
self
.
type
=
py_object_type
elif
arg
.
type
.
is_string
:
elif
arg
.
type
.
is_string
:
...
@@ -6330,6 +6343,46 @@ class CoerceToPyTypeNode(CoercionNode):
...
@@ -6330,6 +6343,46 @@ class CoerceToPyTypeNode(CoercionNode):
code
.
put_gotref
(
self
.
py_result
())
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
):
class
CoerceFromPyTypeNode
(
CoercionNode
):
# This node is used to convert a Python object
# This node is used to convert a Python object
# to a C data type.
# to a C data type.
...
@@ -6445,6 +6498,7 @@ class CoerceToTempNode(CoercionNode):
...
@@ -6445,6 +6498,7 @@ class CoerceToTempNode(CoercionNode):
def
__init__
(
self
,
arg
,
env
):
def
__init__
(
self
,
arg
,
env
):
CoercionNode
.
__init__
(
self
,
arg
)
CoercionNode
.
__init__
(
self
,
arg
)
self
.
type
=
self
.
arg
.
type
self
.
type
=
self
.
arg
.
type
self
.
constant_result
=
self
.
arg
.
constant_result
self
.
is_temp
=
1
self
.
is_temp
=
1
if
self
.
type
.
is_pyobject
:
if
self
.
type
.
is_pyobject
:
self
.
result_ctype
=
py_object_type
self
.
result_ctype
=
py_object_type
...
@@ -6457,6 +6511,8 @@ class CoerceToTempNode(CoercionNode):
...
@@ -6457,6 +6511,8 @@ class CoerceToTempNode(CoercionNode):
def
coerce_to_boolean
(
self
,
env
):
def
coerce_to_boolean
(
self
,
env
):
self
.
arg
=
self
.
arg
.
coerce_to_boolean
(
env
)
self
.
arg
=
self
.
arg
.
coerce_to_boolean
(
env
)
if
self
.
arg
.
is_simple
():
return
self
.
arg
self
.
type
=
self
.
arg
.
type
self
.
type
=
self
.
arg
.
type
self
.
result_ctype
=
self
.
type
self
.
result_ctype
=
self
.
type
return
self
return
self
...
...
Cython/Compiler/Nodes.py
View file @
6f95c7e3
...
@@ -4038,24 +4038,42 @@ class IfStatNode(StatNode):
...
@@ -4038,24 +4038,42 @@ class IfStatNode(StatNode):
if_clause
.
analyse_expressions
(
env
)
if_clause
.
analyse_expressions
(
env
)
if
self
.
else_clause
:
if
self
.
else_clause
:
self
.
else_clause
.
analyse_expressions
(
env
)
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
):
def
generate_execution_code
(
self
,
code
):
code
.
mark_pos
(
self
.
pos
)
code
.
mark_pos
(
self
.
pos
)
end_label
=
code
.
new_label
()
if
self
.
if_clauses
:
for
if_clause
in
self
.
if_clauses
:
end_label
=
code
.
new_label
()
if_clause
.
generate_execution_code
(
code
,
end_label
)
for
if_clause
in
self
.
if_clauses
:
if
self
.
else_clause
:
if_clause
.
generate_execution_code
(
code
,
end_label
)
code
.
putln
(
"/*else*/ {"
)
if
self
.
else_clause
:
code
.
putln
(
"/*else*/ {"
)
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
)
self
.
else_clause
.
generate_execution_code
(
code
)
code
.
putln
(
"}"
)
code
.
put_label
(
end_label
)
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
):
for
clause
in
self
.
if_clauses
:
for
clause
in
self
.
if_clauses
:
clause
.
generate_function_definitions
(
env
,
code
)
clause
.
generate_function_definitions
(
env
,
code
)
if
self
.
else_clause
is
not
None
:
if
self
.
else_clause
is
not
None
:
self
.
else_clause
.
generate_function_definitions
(
env
,
code
)
self
.
else_clause
.
generate_function_definitions
(
env
,
code
)
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
for
if_clause
in
self
.
if_clauses
:
for
if_clause
in
self
.
if_clauses
:
if_clause
.
annotate
(
code
)
if_clause
.
annotate
(
code
)
...
@@ -4082,7 +4100,13 @@ class IfClauseNode(Node):
...
@@ -4082,7 +4100,13 @@ class IfClauseNode(Node):
self
.
condition
=
\
self
.
condition
=
\
self
.
condition
.
analyse_temp_boolean_expression
(
env
)
self
.
condition
.
analyse_temp_boolean_expression
(
env
)
self
.
body
.
analyse_expressions
(
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
):
def
generate_execution_code
(
self
,
code
,
end_label
):
self
.
condition
.
generate_evaluation_code
(
code
)
self
.
condition
.
generate_evaluation_code
(
code
)
code
.
putln
(
code
.
putln
(
...
@@ -5258,8 +5282,7 @@ if Options.gcc_branch_hints:
...
@@ -5258,8 +5282,7 @@ if Options.gcc_branch_hints:
"""
"""
#ifdef __GNUC__
#ifdef __GNUC__
/* Test for GCC > 2.95 */
/* Test for GCC > 2.95 */
#if __GNUC__ > 2 ||
\
#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
(__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
#define likely(x) __builtin_expect(!!(x), 1)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else /* __GNUC__ > 2 ... */
#else /* __GNUC__ > 2 ... */
...
...
Cython/Compiler/Optimize.py
View file @
6f95c7e3
...
@@ -1187,8 +1187,72 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -1187,8 +1187,72 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
if
isinstance
(
arg
,
ExprNodes
.
SimpleCallNode
):
if
isinstance
(
arg
,
ExprNodes
.
SimpleCallNode
):
if
node
.
type
.
is_int
or
node
.
type
.
is_float
:
if
node
.
type
.
is_int
or
node
.
type
.
is_float
:
return
self
.
_optimise_numeric_cast_call
(
node
,
arg
)
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
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
):
def
_optimise_numeric_cast_call
(
self
,
node
,
arg
):
function
=
arg
.
function
function
=
arg
.
function
if
not
isinstance
(
function
,
ExprNodes
.
NameNode
)
\
if
not
isinstance
(
function
,
ExprNodes
.
NameNode
)
\
...
@@ -2140,14 +2204,17 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
...
@@ -2140,14 +2204,17 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
def
_inject_int_default_argument
(
self
,
node
,
args
,
arg_index
,
type
,
default_value
):
def
_inject_int_default_argument
(
self
,
node
,
args
,
arg_index
,
type
,
default_value
):
assert
len
(
args
)
>=
arg_index
assert
len
(
args
)
>=
arg_index
if
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
:
else
:
args
[
arg_index
]
=
args
[
arg_index
].
coerce_to
(
type
,
self
.
current_env
())
args
[
arg_index
]
=
args
[
arg_index
].
coerce_to
(
type
,
self
.
current_env
())
def
_inject_bint_default_argument
(
self
,
node
,
args
,
arg_index
,
default_value
):
def
_inject_bint_default_argument
(
self
,
node
,
args
,
arg_index
,
default_value
):
assert
len
(
args
)
>=
arg_index
assert
len
(
args
)
>=
arg_index
if
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
:
else
:
args
[
arg_index
]
=
args
[
arg_index
].
coerce_to_boolean
(
self
.
current_env
())
args
[
arg_index
]
=
args
[
arg_index
].
coerce_to_boolean
(
self
.
current_env
())
...
@@ -2348,6 +2415,48 @@ bad:
...
@@ -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
(
include_string_h_utility_code
=
UtilityCode
(
proto
=
"""
proto
=
"""
#include <string.h>
#include <string.h>
...
...
Cython/Compiler/PyrexTypes.py
View file @
6f95c7e3
...
@@ -881,17 +881,60 @@ class CBIntType(CIntType):
...
@@ -881,17 +881,60 @@ class CBIntType(CIntType):
class
CPyUnicodeIntType
(
CIntType
):
class
CPyUnicodeIntType
(
CIntType
):
# Py_UNICODE
# Py_UNICODE
#
Conversion from a unicode string to Py_UNICODE at runtime is not
#
Py_UNICODE coerces from and to single character unicode strings,
#
currently supported and may never be - we only convert from and
#
but we also allow Python integers as input. The value range for
#
to integers here. The maximum value for a Py_UNICODE is
#
Py_UNICODE is 0..1114111, which is checked when converting from
#
1114111, so PyInt_FromLong() will do just fine her
e.
#
an integer valu
e.
to_py_function
=
"PyInt_FromLong"
to_py_function
=
"PyUnicode_FromOrdinal"
from_py_function
=
"__Pyx_PyInt_AsPy_UNICODE"
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
):
def
sign_and_name
(
self
):
return
"Py_UNICODE"
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
):
class
CPySSizeTType
(
CIntType
):
...
@@ -2512,10 +2555,6 @@ type_conversion_predeclarations = """
...
@@ -2512,10 +2555,6 @@ type_conversion_predeclarations = """
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
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 Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
...
@@ -2580,26 +2619,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
...
@@ -2580,26 +2619,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
return res;
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) {
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_ssize_t ival;
Py_ssize_t ival;
PyObject* x = PyNumber_Index(b);
PyObject* x = PyNumber_Index(b);
...
...
Cython/Compiler/TypeSlots.py
View file @
6f95c7e3
...
@@ -126,16 +126,17 @@ class SlotDescriptor(object):
...
@@ -126,16 +126,17 @@ class SlotDescriptor(object):
# slot_name string Member name of the slot in the type 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
# is_initialised_dynamically Is initialised by code in the module init function
# flag Py_TPFLAGS_XXX value indicating presence of slot
# 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
# 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
.
slot_name
=
slot_name
self
.
is_initialised_dynamically
=
dynamic
self
.
is_initialised_dynamically
=
dynamic
self
.
flag
=
flag
self
.
flag
=
flag
self
.
py3
k
=
py3k
self
.
py3
=
py3
self
.
py2
=
py2
self
.
py2
=
py2
self
.
ifdef
=
ifdef
self
.
ifdef
=
ifdef
def
generate
(
self
,
scope
,
code
):
def
generate
(
self
,
scope
,
code
):
...
@@ -144,26 +145,26 @@ class SlotDescriptor(object):
...
@@ -144,26 +145,26 @@ class SlotDescriptor(object):
else
:
else
:
value
=
self
.
slot_code
(
scope
)
value
=
self
.
slot_code
(
scope
)
flag
=
self
.
flag
flag
=
self
.
flag
py3
k
=
self
.
py3k
py3
=
self
.
py3
py2
=
self
.
py2
py2
=
self
.
py2
if
self
.
ifdef
:
if
self
.
ifdef
:
code
.
putln
(
"#if %s"
%
self
.
ifdef
)
code
.
putln
(
"#if %s"
%
self
.
ifdef
)
else
:
else
:
if
not
py3
k
:
if
not
py3
:
code
.
putln
(
"#if PY_MAJOR_VERSION < 3"
)
code
.
putln
(
"#if PY_MAJOR_VERSION < 3"
)
elif
not
py2
:
elif
not
py2
:
code
.
putln
(
"#if PY_MAJOR_VERSION >= 3"
)
code
.
putln
(
"#if PY_MAJOR_VERSION >= 3"
)
if
flag
:
if
flag
:
code
.
putln
(
"#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)"
%
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
(
"#if PY_MAJOR_VERSION >= 3"
)
code
.
putln
(
"0, /*reserved*/"
)
code
.
putln
(
"0, /*reserved*/"
)
code
.
putln
(
"#else"
)
code
.
putln
(
"#else"
)
code
.
putln
(
"%s, /*%s*/"
%
(
value
,
self
.
slot_name
))
code
.
putln
(
"%s, /*%s*/"
%
(
value
,
self
.
slot_name
))
if
py3
k
==
'<RESERVED>'
:
if
py3
==
'<RESERVED>'
:
code
.
putln
(
"#endif"
)
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"
)
code
.
putln
(
"#endif"
)
# Some C implementations have trouble statically
# Some C implementations have trouble statically
...
@@ -188,8 +189,8 @@ class FixedSlot(SlotDescriptor):
...
@@ -188,8 +189,8 @@ class FixedSlot(SlotDescriptor):
#
#
# value string
# value string
def
__init__
(
self
,
slot_name
,
value
,
py3k
=
True
,
py2
=
True
,
ifdef
=
None
):
def
__init__
(
self
,
slot_name
,
value
,
flag
=
None
,
py3
=
True
,
py2
=
True
,
ifdef
=
None
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
py3k
=
py3k
,
py2
=
py2
,
ifdef
=
ifdef
)
SlotDescriptor
.
__init__
(
self
,
slot_name
,
flag
=
flag
,
py3
=
py3
,
py2
=
py2
,
ifdef
=
ifdef
)
self
.
value
=
value
self
.
value
=
value
def
slot_code
(
self
,
scope
):
def
slot_code
(
self
,
scope
):
...
@@ -199,8 +200,8 @@ class FixedSlot(SlotDescriptor):
...
@@ -199,8 +200,8 @@ class FixedSlot(SlotDescriptor):
class
EmptySlot
(
FixedSlot
):
class
EmptySlot
(
FixedSlot
):
# Descriptor for a type slot whose value is always 0.
# Descriptor for a type slot whose value is always 0.
def
__init__
(
self
,
slot_name
,
py3k
=
True
,
py2
=
True
,
ifdef
=
None
):
def
__init__
(
self
,
slot_name
,
flag
=
None
,
py3
=
True
,
py2
=
True
,
ifdef
=
None
):
FixedSlot
.
__init__
(
self
,
slot_name
,
"0"
,
py3k
=
py3k
,
py2
=
py2
,
ifdef
=
ifdef
)
FixedSlot
.
__init__
(
self
,
slot_name
,
"0"
,
flag
=
flag
,
py3
=
py3
,
py2
=
py2
,
ifdef
=
ifdef
)
class
MethodSlot
(
SlotDescriptor
):
class
MethodSlot
(
SlotDescriptor
):
...
@@ -208,22 +209,31 @@ class MethodSlot(SlotDescriptor):
...
@@ -208,22 +209,31 @@ class MethodSlot(SlotDescriptor):
#
#
# signature Signature
# signature Signature
# method_name string The __xxx__ name of the method
# 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
):
def
__init__
(
self
,
signature
,
slot_name
,
method_name
,
fallback
=
None
,
SlotDescriptor
.
__init__
(
self
,
slot_name
,
flag
=
flag
,
py3k
=
py3k
,
py2
=
py2
,
ifdef
=
ifdef
)
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
.
signature
=
signature
self
.
slot_name
=
slot_name
self
.
slot_name
=
slot_name
self
.
method_name
=
method_name
self
.
method_name
=
method_name
self
.
default
=
default
self
.
alternatives
=
[]
method_name_to_slot
[
method_name
]
=
self
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
):
def
slot_code
(
self
,
scope
):
entry
=
scope
.
lookup_here
(
self
.
method_name
)
entry
=
scope
.
lookup_here
(
self
.
method_name
)
if
entry
and
entry
.
func_cname
:
if
entry
and
entry
.
func_cname
:
return
entry
.
func_cname
return
entry
.
func_cname
if
self
.
default
is
not
None
:
for
method_name
in
self
.
alternatives
:
entry
=
scope
.
lookup_here
(
self
.
default
)
entry
=
scope
.
lookup_here
(
method_name
)
if
entry
and
entry
.
func_cname
:
if
entry
and
entry
.
func_cname
:
return
entry
.
func_cname
return
entry
.
func_cname
return
"0"
return
"0"
...
@@ -235,8 +245,8 @@ class InternalMethodSlot(SlotDescriptor):
...
@@ -235,8 +245,8 @@ class InternalMethodSlot(SlotDescriptor):
#
#
# slot_name string Member name of the slot in the type object
# slot_name string Member name of the slot in the type object
def
__init__
(
self
,
slot_name
,
py2
=
True
):
def
__init__
(
self
,
slot_name
,
**
kargs
):
SlotDescriptor
.
__init__
(
self
,
slot_name
,
py2
=
py2
)
SlotDescriptor
.
__init__
(
self
,
slot_name
,
**
kargs
)
def
slot_code
(
self
,
scope
):
def
slot_code
(
self
,
scope
):
return
scope
.
mangle_internal
(
self
.
slot_name
)
return
scope
.
mangle_internal
(
self
.
slot_name
)
...
@@ -246,8 +256,8 @@ class GCDependentSlot(InternalMethodSlot):
...
@@ -246,8 +256,8 @@ class GCDependentSlot(InternalMethodSlot):
# Descriptor for a slot whose value depends on whether
# Descriptor for a slot whose value depends on whether
# the type participates in GC.
# the type participates in GC.
def
__init__
(
self
,
slot_name
):
def
__init__
(
self
,
slot_name
,
**
kargs
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
)
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
**
kargs
)
def
slot_code
(
self
,
scope
):
def
slot_code
(
self
,
scope
):
if
not
scope
.
needs_gc
():
if
not
scope
.
needs_gc
():
...
@@ -267,8 +277,8 @@ class GCDependentSlot(InternalMethodSlot):
...
@@ -267,8 +277,8 @@ class GCDependentSlot(InternalMethodSlot):
class
ConstructorSlot
(
InternalMethodSlot
):
class
ConstructorSlot
(
InternalMethodSlot
):
# Descriptor for tp_new and tp_dealloc.
# Descriptor for tp_new and tp_dealloc.
def
__init__
(
self
,
slot_name
,
method
):
def
__init__
(
self
,
slot_name
,
method
,
**
kargs
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
)
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
**
kargs
)
self
.
method
=
method
self
.
method
=
method
def
slot_code
(
self
,
scope
):
def
slot_code
(
self
,
scope
):
...
@@ -294,8 +304,8 @@ class SyntheticSlot(InternalMethodSlot):
...
@@ -294,8 +304,8 @@ class SyntheticSlot(InternalMethodSlot):
# alternative default value will be placed in the type
# alternative default value will be placed in the type
# slot.
# slot.
def
__init__
(
self
,
slot_name
,
user_methods
,
default_value
,
py2
=
True
):
def
__init__
(
self
,
slot_name
,
user_methods
,
default_value
,
**
kargs
):
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
py2
=
py2
)
InternalMethodSlot
.
__init__
(
self
,
slot_name
,
**
kargs
)
self
.
user_methods
=
user_methods
self
.
user_methods
=
user_methods
self
.
default_value
=
default_value
self
.
default_value
=
default_value
...
@@ -550,32 +560,32 @@ PyNumberMethods = (
...
@@ -550,32 +560,32 @@ PyNumberMethods = (
MethodSlot
(
binaryfunc
,
"nb_add"
,
"__add__"
),
MethodSlot
(
binaryfunc
,
"nb_add"
,
"__add__"
),
MethodSlot
(
binaryfunc
,
"nb_subtract"
,
"__sub__"
),
MethodSlot
(
binaryfunc
,
"nb_subtract"
,
"__sub__"
),
MethodSlot
(
binaryfunc
,
"nb_multiply"
,
"__mul__"
),
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_remainder"
,
"__mod__"
),
MethodSlot
(
binaryfunc
,
"nb_divmod"
,
"__divmod__"
),
MethodSlot
(
binaryfunc
,
"nb_divmod"
,
"__divmod__"
),
MethodSlot
(
ternaryfunc
,
"nb_power"
,
"__pow__"
),
MethodSlot
(
ternaryfunc
,
"nb_power"
,
"__pow__"
),
MethodSlot
(
unaryfunc
,
"nb_negative"
,
"__neg__"
),
MethodSlot
(
unaryfunc
,
"nb_negative"
,
"__neg__"
),
MethodSlot
(
unaryfunc
,
"nb_positive"
,
"__pos__"
),
MethodSlot
(
unaryfunc
,
"nb_positive"
,
"__pos__"
),
MethodSlot
(
unaryfunc
,
"nb_absolute"
,
"__abs__"
),
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
(
unaryfunc
,
"nb_invert"
,
"__invert__"
),
MethodSlot
(
binaryfunc
,
"nb_lshift"
,
"__lshift__"
),
MethodSlot
(
binaryfunc
,
"nb_lshift"
,
"__lshift__"
),
MethodSlot
(
binaryfunc
,
"nb_rshift"
,
"__rshift__"
),
MethodSlot
(
binaryfunc
,
"nb_rshift"
,
"__rshift__"
),
MethodSlot
(
binaryfunc
,
"nb_and"
,
"__and__"
),
MethodSlot
(
binaryfunc
,
"nb_and"
,
"__and__"
),
MethodSlot
(
binaryfunc
,
"nb_xor"
,
"__xor__"
),
MethodSlot
(
binaryfunc
,
"nb_xor"
,
"__xor__"
),
MethodSlot
(
binaryfunc
,
"nb_or"
,
"__or__"
),
MethodSlot
(
binaryfunc
,
"nb_or"
,
"__or__"
),
EmptySlot
(
"nb_coerce"
,
py3
k
=
False
),
EmptySlot
(
"nb_coerce"
,
py3
=
False
),
MethodSlot
(
unaryfunc
,
"nb_int"
,
"__int__"
,
default
=
"__long__"
),
MethodSlot
(
unaryfunc
,
"nb_int"
,
"__int__"
,
fallback
=
"__long__"
),
MethodSlot
(
unaryfunc
,
"nb_long"
,
"__long__"
,
default
=
"__int__"
,
py3k
=
"<RESERVED>"
),
MethodSlot
(
unaryfunc
,
"nb_long"
,
"__long__"
,
fallback
=
"__int__"
,
py3
=
"<RESERVED>"
),
MethodSlot
(
unaryfunc
,
"nb_float"
,
"__float__"
),
MethodSlot
(
unaryfunc
,
"nb_float"
,
"__float__"
),
MethodSlot
(
unaryfunc
,
"nb_oct"
,
"__oct__"
,
py3
k
=
False
),
MethodSlot
(
unaryfunc
,
"nb_oct"
,
"__oct__"
,
py3
=
False
),
MethodSlot
(
unaryfunc
,
"nb_hex"
,
"__hex__"
,
py3
k
=
False
),
MethodSlot
(
unaryfunc
,
"nb_hex"
,
"__hex__"
,
py3
=
False
),
# Added in release 2.0
# Added in release 2.0
MethodSlot
(
ibinaryfunc
,
"nb_inplace_add"
,
"__iadd__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_add"
,
"__iadd__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_subtract"
,
"__isub__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_subtract"
,
"__isub__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_multiply"
,
"__imul__"
),
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
(
ibinaryfunc
,
"nb_inplace_remainder"
,
"__imod__"
),
MethodSlot
(
ternaryfunc
,
"nb_inplace_power"
,
"__ipow__"
),
# NOT iternaryfunc!!!
MethodSlot
(
ternaryfunc
,
"nb_inplace_power"
,
"__ipow__"
),
# NOT iternaryfunc!!!
MethodSlot
(
ibinaryfunc
,
"nb_inplace_lshift"
,
"__ilshift__"
),
MethodSlot
(
ibinaryfunc
,
"nb_inplace_lshift"
,
"__ilshift__"
),
...
@@ -615,10 +625,10 @@ PyMappingMethods = (
...
@@ -615,10 +625,10 @@ PyMappingMethods = (
)
)
PyBufferProcs
=
(
PyBufferProcs
=
(
MethodSlot
(
getreadbufferproc
,
"bf_getreadbuffer"
,
"__getreadbuffer__"
,
py3
k
=
False
),
MethodSlot
(
getreadbufferproc
,
"bf_getreadbuffer"
,
"__getreadbuffer__"
,
py3
=
False
),
MethodSlot
(
getwritebufferproc
,
"bf_getwritebuffer"
,
"__getwritebuffer__"
,
py3
k
=
False
),
MethodSlot
(
getwritebufferproc
,
"bf_getwritebuffer"
,
"__getwritebuffer__"
,
py3
=
False
),
MethodSlot
(
getsegcountproc
,
"bf_getsegcount"
,
"__getsegcount__"
,
py3
k
=
False
),
MethodSlot
(
getsegcountproc
,
"bf_getsegcount"
,
"__getsegcount__"
,
py3
=
False
),
MethodSlot
(
getcharbufferproc
,
"bf_getcharbuffer"
,
"__getcharbuffer__"
,
py3
k
=
False
),
MethodSlot
(
getcharbufferproc
,
"bf_getcharbuffer"
,
"__getcharbuffer__"
,
py3
=
False
),
MethodSlot
(
getbufferproc
,
"bf_getbuffer"
,
"__getbuffer__"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
),
MethodSlot
(
getbufferproc
,
"bf_getbuffer"
,
"__getbuffer__"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
),
MethodSlot
(
releasebufferproc
,
"bf_releasebuffer"
,
"__releasebuffer__"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
)
MethodSlot
(
releasebufferproc
,
"bf_releasebuffer"
,
"__releasebuffer__"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
)
...
@@ -637,7 +647,7 @@ slot_table = (
...
@@ -637,7 +647,7 @@ slot_table = (
EmptySlot
(
"tp_print"
),
#MethodSlot(printfunc, "tp_print", "__print__"),
EmptySlot
(
"tp_print"
),
#MethodSlot(printfunc, "tp_print", "__print__"),
EmptySlot
(
"tp_getattr"
),
EmptySlot
(
"tp_getattr"
),
EmptySlot
(
"tp_setattr"
),
EmptySlot
(
"tp_setattr"
),
MethodSlot
(
cmpfunc
,
"tp_compare"
,
"__cmp__"
),
MethodSlot
(
cmpfunc
,
"tp_compare"
,
"__cmp__"
,
py3
=
'<RESERVED>'
),
MethodSlot
(
reprfunc
,
"tp_repr"
,
"__repr__"
),
MethodSlot
(
reprfunc
,
"tp_repr"
,
"__repr__"
),
SuiteSlot
(
PyNumberMethods
,
"PyNumberMethods"
,
"tp_as_number"
),
SuiteSlot
(
PyNumberMethods
,
"PyNumberMethods"
,
"tp_as_number"
),
...
...
tests/errors/break_outside_loop.pyx
View file @
6f95c7e3
...
@@ -16,11 +16,14 @@ except: pass
...
@@ -16,11 +16,14 @@ except: pass
try
:
break
try
:
break
finally
:
pass
finally
:
pass
if
True
:
if
bool_result
()
:
break
break
else
:
else
:
break
break
def
bool_result
():
return
True
_ERRORS
=
u'''
_ERRORS
=
u'''
2:0: break statement not inside loop
2:0: break statement not inside loop
...
...
tests/errors/continue_outside_loop.pyx
View file @
6f95c7e3
...
@@ -16,11 +16,13 @@ except: pass
...
@@ -16,11 +16,13 @@ except: pass
try
:
continue
try
:
continue
finally
:
pass
finally
:
pass
if
True
:
if
bool_result
()
:
continue
continue
else
:
else
:
continue
continue
def
bool_result
():
return
True
_ERRORS
=
u'''
_ERRORS
=
u'''
2:0: continue statement not inside loop
2:0: continue statement not inside loop
...
...
tests/errors/literal_lists.pyx
View file @
6f95c7e3
def
f
():
def
f
():
cdef
int
*
p
cdef
int
*
p
if
False
:
if
false
()
:
p
=
[
1
,
2
,
3
]
p
=
[
1
,
2
,
3
]
def
false
():
return
False
_ERRORS
=
u"""
_ERRORS
=
u"""
4:10: Literal list must be assigned to pointer at time of declaration
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:
...
@@ -126,4 +126,20 @@ cdef class MyCdefClass:
False
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
()
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
import
sys
IS_PY3
=
sys
.
version_info
[
0
]
>=
3
IS_PY3
=
sys
.
version_info
[
0
]
>=
3
cimport
cython
DEF
INT_VAL
=
1
def
_func
(
a
,
b
,
c
):
def
_func
(
a
,
b
,
c
):
return
a
+
b
+
c
return
a
+
b
+
c
...
@@ -76,3 +80,76 @@ def lists():
...
@@ -76,3 +80,76 @@ def lists():
True
True
"""
"""
return
[
1
,
2
,
3
]
+
[
4
,
5
,
6
]
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):
...
@@ -70,6 +70,36 @@ def for_char_in_enumerate_bytes(bytes s):
else
:
else
:
return
'X'
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_assert_path_exists
(
"//ForFromStatNode"
)
@
cython
.
test_fail_if_path_exists
(
"//ForInStatNode"
)
@
cython
.
test_fail_if_path_exists
(
"//ForInStatNode"
)
def
for_pyunicode_in_unicode
(
unicode
s
):
def
for_pyunicode_in_unicode
(
unicode
s
):
...
...
tests/run/py_unicode_type.pyx
View file @
6f95c7e3
# -*- coding: iso-8859-1 -*-
# -*- coding: iso-8859-1 -*-
cimport
cython
cdef
Py_UNICODE
char_ASCII
=
u'A'
cdef
Py_UNICODE
char_ASCII
=
u'A'
cdef
Py_UNICODE
char_KLINGON
=
u'
\
uF8D2
'
cdef
Py_UNICODE
char_KLINGON
=
u'
\
uF8D2
'
def
compare_ASCII
():
def
compare_ASCII
():
"""
"""
>>> compare_ASCII()
>>> compare_ASCII()
...
@@ -16,9 +17,9 @@ def compare_ASCII():
...
@@ -16,9 +17,9 @@ def compare_ASCII():
print
(
char_ASCII
==
u'
\
uF8D2
'
)
print
(
char_ASCII
==
u'
\
uF8D2
'
)
def
compare_
KLINGON
():
def
compare_
klingon
():
"""
"""
>>> compare_
ASCII
()
>>> compare_
klingon
()
True
True
False
False
False
False
...
@@ -39,31 +40,114 @@ def index_literal(int i):
...
@@ -39,31 +40,114 @@ def index_literal(int i):
>>> index_literal(4) == '5'
>>> index_literal(4) == '5'
True
True
"""
"""
# runtime casts are not currently supported
#return <Py_UNICODE>(u"12345"[i])
return
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
):
"""
>>> 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
])
@
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
@
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
):
"""
"""
>>> import sys
>>> 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
>>> unicode_cardinal(0)
from
cpython.unicode
cimport
PyUnicode_FromOrdinal
0
import
sys
>>> unicode_cardinal(1)
1
u0
=
u'
\
x00
'
>>> unicode_cardinal(sys.maxunicode) == sys.maxunicode
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
True
>>> ord(unicode_ordinal(u0)) == 0
>>> unicode_cardinal(-1) #doctest: +ELLIPSIS
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):
Traceback (most recent call last):
...
...
OverflowError: ...
OverflowError: ...
>>> unicode_cardinal(sys.maxunicode+1) #doctest: +ELLIPSIS
Value too large:
>>> unicode_ordinal(sys.maxunicode+1) #doctest: +ELLIPSIS
Traceback (most recent call last):
Traceback (most recent call last):
...
...
OverflowError: ...
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
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