Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
13617b61
Commit
13617b61
authored
Feb 01, 2019
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '0.29.x'
parents
b8e2e12e
272efcf6
Changes
7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
283 additions
and
9 deletions
+283
-9
CHANGES.rst
CHANGES.rst
+7
-0
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+11
-0
Cython/Utility/Optimize.c
Cython/Utility/Optimize.c
+53
-9
tests/run/float_division.pyx
tests/run/float_division.pyx
+69
-0
tests/run/future_division.pyx
tests/run/future_division.pyx
+70
-0
tests/run/modop.pyx
tests/run/modop.pyx
+3
-0
tests/run/non_future_division.pyx
tests/run/non_future_division.pyx
+70
-0
No files found.
CHANGES.rst
View file @
13617b61
...
@@ -92,6 +92,13 @@ Other changes
...
@@ -92,6 +92,13 @@ Other changes
*
Support
for
Python
2.6
was
removed
.
*
Support
for
Python
2.6
was
removed
.
0.29.4
(
2019
-
02
-
01
)
===================
*
Division
of
numeric
constants
by
a
runtime
value
of
0
could
fail
to
raise
a
``
ZeroDivisionError
``.
(
Github
issue
#
2820
)
0.29.3
(
2019
-
01
-
19
)
0.29.3
(
2019
-
01
-
19
)
===================
===================
...
...
Cython/Compiler/Optimize.py
View file @
13617b61
...
@@ -3166,6 +3166,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
...
@@ -3166,6 +3166,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
PyrexTypes
.
CFuncTypeArg
(
"op2"
,
PyrexTypes
.
py_object_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"op2"
,
PyrexTypes
.
py_object_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"cval"
,
ctype
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"cval"
,
ctype
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"inplace"
,
PyrexTypes
.
c_bint_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"inplace"
,
PyrexTypes
.
c_bint_type
,
None
),
PyrexTypes
.
CFuncTypeArg
(
"zerodiv_check"
,
PyrexTypes
.
c_bint_type
,
None
),
],
exception_value
=
None
if
ret_type
.
is_pyobject
else
ret_type
.
exception_value
))
],
exception_value
=
None
if
ret_type
.
is_pyobject
else
ret_type
.
exception_value
))
for
ctype
in
(
PyrexTypes
.
c_long_type
,
PyrexTypes
.
c_double_type
)
for
ctype
in
(
PyrexTypes
.
c_long_type
,
PyrexTypes
.
c_double_type
)
for
ret_type
in
(
PyrexTypes
.
py_object_type
,
PyrexTypes
.
c_bint_type
)
for
ret_type
in
(
PyrexTypes
.
py_object_type
,
PyrexTypes
.
c_bint_type
)
...
@@ -3300,12 +3301,22 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
...
@@ -3300,12 +3301,22 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
# Cut off at an integer border that is still safe for all operations.
# Cut off at an integer border that is still safe for all operations.
return
node
return
node
if
operator
in
(
'TrueDivide'
,
'FloorDivide'
,
'Divide'
,
'Remainder'
):
if
args
[
1
].
constant_result
==
0
:
# Don't optimise division by 0. :)
return
node
args
=
list
(
args
)
args
=
list
(
args
)
args
.
append
((
ExprNodes
.
FloatNode
if
is_float
else
ExprNodes
.
IntNode
)(
args
.
append
((
ExprNodes
.
FloatNode
if
is_float
else
ExprNodes
.
IntNode
)(
numval
.
pos
,
value
=
numval
.
value
,
constant_result
=
numval
.
constant_result
,
numval
.
pos
,
value
=
numval
.
value
,
constant_result
=
numval
.
constant_result
,
type
=
num_type
))
type
=
num_type
))
inplace
=
node
.
inplace
if
isinstance
(
node
,
ExprNodes
.
NumBinopNode
)
else
False
inplace
=
node
.
inplace
if
isinstance
(
node
,
ExprNodes
.
NumBinopNode
)
else
False
args
.
append
(
ExprNodes
.
BoolNode
(
node
.
pos
,
value
=
inplace
,
constant_result
=
inplace
))
args
.
append
(
ExprNodes
.
BoolNode
(
node
.
pos
,
value
=
inplace
,
constant_result
=
inplace
))
if
is_float
or
operator
not
in
(
'Eq'
,
'Ne'
):
# "PyFloatBinop" and "PyIntBinop" take an additional "check for zero division" argument.
zerodivision_check
=
arg_order
==
'CObj'
and
(
not
node
.
cdivision
if
isinstance
(
node
,
ExprNodes
.
DivNode
)
else
False
)
args
.
append
(
ExprNodes
.
BoolNode
(
node
.
pos
,
value
=
zerodivision_check
,
constant_result
=
zerodivision_check
))
utility_code
=
TempitaUtilityCode
.
load_cached
(
utility_code
=
TempitaUtilityCode
.
load_cached
(
"PyFloatBinop"
if
is_float
else
"PyIntCompare"
if
operator
in
(
'Eq'
,
'Ne'
)
else
"PyIntBinop"
,
"PyFloatBinop"
if
is_float
else
"PyIntCompare"
if
operator
in
(
'Eq'
,
'Ne'
)
else
"PyIntBinop"
,
...
...
Cython/Utility/Optimize.c
View file @
13617b61
This diff is collapsed.
Click to expand it.
tests/run/float_division.pyx
View file @
13617b61
...
@@ -26,6 +26,39 @@ def float_by_float():
...
@@ -26,6 +26,39 @@ def float_by_float():
return
3.0
/
2.0
return
3.0
/
2.0
def
div_by_0
(
x
):
"""
>>> div_by_0(0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_by_0(0.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_by_0(1) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_by_0(1.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> float('inf') / 0.0 # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_by_0(float('inf')) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_by_0(float('-inf')) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> float('nan') / 0.0 # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_by_0(float('nan')) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
"""
return
x
/
0.0
def
div_1_by
(
x
):
def
div_1_by
(
x
):
"""
"""
>>> div_1_by(1.0)
>>> div_1_by(1.0)
...
@@ -42,6 +75,12 @@ def div_1_by(x):
...
@@ -42,6 +75,12 @@ def div_1_by(x):
-0.0
-0.0
>>> div_1_by(float('nan'))
>>> div_1_by(float('nan'))
nan
nan
>>> div_1_by(0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_1_by(0.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
"""
"""
return
1.0
/
x
return
1.0
/
x
...
@@ -116,6 +155,12 @@ def div_neg_2_by(x):
...
@@ -116,6 +155,12 @@ def div_neg_2_by(x):
nan
nan
>>> div_neg_2_by(float('nan'))
>>> div_neg_2_by(float('nan'))
nan
nan
>>> div_neg_2_by(0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_neg_2_by(0.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
"""
"""
return
(
-
2.0
)
/
x
return
(
-
2.0
)
/
x
...
@@ -148,6 +193,12 @@ def div_nan_by(x):
...
@@ -148,6 +193,12 @@ def div_nan_by(x):
nan
nan
>>> div_nan_by(float('nan'))
>>> div_nan_by(float('nan'))
nan
nan
>>> div_nan_by(0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_nan_by(0.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
"""
"""
return
float
(
"nan"
)
/
x
return
float
(
"nan"
)
/
x
...
@@ -182,6 +233,15 @@ def div_inf_by(x):
...
@@ -182,6 +233,15 @@ def div_inf_by(x):
nan
nan
>>> div_inf_by(float('-inf'))
>>> div_inf_by(float('-inf'))
nan
nan
>>> float("inf") / 0.0 # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_inf_by(0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_inf_by(0.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
"""
"""
return
float
(
"inf"
)
/
x
return
float
(
"inf"
)
/
x
...
@@ -196,5 +256,14 @@ def div_neg_inf_by(x):
...
@@ -196,5 +256,14 @@ def div_neg_inf_by(x):
inf
inf
>>> div_neg_inf_by(-1.0)
>>> div_neg_inf_by(-1.0)
inf
inf
>>> float("-inf") / 0.0 # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_neg_inf_by(0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
>>> div_neg_inf_by(0.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: float division...
"""
"""
return
float
(
"-inf"
)
/
x
return
float
(
"-inf"
)
/
x
tests/run/future_division.pyx
View file @
13617b61
...
@@ -157,3 +157,73 @@ def int_int(int a, int b):
...
@@ -157,3 +157,73 @@ def int_int(int a, int b):
(0.5, 2.0)
(0.5, 2.0)
"""
"""
return
a
/
b
,
b
/
a
return
a
/
b
,
b
/
a
def
div_by_0
(
a
):
"""
>>> div_by_0(0)
'OK'
>>> div_by_0(0.0)
'OK'
"""
try
:
1
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 1"
try
:
1
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 2"
try
:
5.0
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 3"
try
:
5.0
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 4"
try
:
5
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 5"
try
:
5
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 6"
try
:
(
2
**
15
)
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 7"
try
:
(
2
**
15
)
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 8"
try
:
(
2
**
30
)
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 9"
try
:
(
2
**
30
)
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 10"
return
'OK'
tests/run/modop.pyx
View file @
13617b61
...
@@ -7,6 +7,9 @@ def modobj(obj2, obj3):
...
@@ -7,6 +7,9 @@ def modobj(obj2, obj3):
1
1
>>> modobj('%d', 5)
>>> modobj('%d', 5)
'5'
'5'
>>> modobj(1, 0) # doctest: +ELLIPSIS
Traceback (most recent call last):
ZeroDivisionError: integer division or modulo by zero
"""
"""
obj1
=
obj2
%
obj3
obj1
=
obj2
%
obj3
return
obj1
return
obj1
...
...
tests/run/non_future_division.pyx
View file @
13617b61
...
@@ -143,3 +143,73 @@ def int_int(int a, int b):
...
@@ -143,3 +143,73 @@ def int_int(int a, int b):
(0, 2)
(0, 2)
"""
"""
return
a
/
b
,
b
/
a
return
a
/
b
,
b
/
a
def
div_by_0
(
a
):
"""
>>> div_by_0(0)
'OK'
>>> div_by_0(0.0)
'OK'
"""
try
:
1
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 1"
try
:
1
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 2"
try
:
5.0
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 3"
try
:
5.0
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 4"
try
:
5
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 5"
try
:
5
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 6"
try
:
(
2
**
15
)
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 7"
try
:
(
2
**
15
)
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 8"
try
:
(
2
**
30
)
/
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 9"
try
:
(
2
**
30
)
//
a
except
ZeroDivisionError
:
pass
else
:
return
"FAIL 10"
return
'OK'
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