Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
82b34c5d
Commit
82b34c5d
authored
Feb 21, 2010
by
Mark Dickinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #5211: Fix complex type to avoid implicit calls to
complex.__coerce__. Thanks Meador Inge for the patch.
parent
51f12045
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
109 additions
and
30 deletions
+109
-30
Doc/reference/datamodel.rst
Doc/reference/datamodel.rst
+6
-4
Lib/test/test_complex.py
Lib/test/test_complex.py
+55
-0
Misc/NEWS
Misc/NEWS
+3
-0
Objects/complexobject.c
Objects/complexobject.c
+45
-26
No files found.
Doc/reference/datamodel.rst
View file @
82b34c5d
...
...
@@ -2271,13 +2271,15 @@ will not be supported.
*
In the current implementation, the built-in numeric types :class:`int`,
:class:`long` and :class:`float` do not use coercion; the type :class:`complex`
however does use coercion for binary operators and rich comparisons, despite
the above rules. The difference can become apparent when subclassing these
types. Over time, the type :class:`complex` may be fixed to avoid coercion.
:class:`long`, :class:`float`, and :class:`complex` do not use coercion.
All these types implement a :meth:`__coerce__` method, for use by the built-in
:func:`coerce` function.
.. versionchanged:: 2.7
The complex type no longer makes implicit calls to the :meth:`__coerce__`
method for mixed-type binary arithmetic operations.
.. _context-managers:
...
...
Lib/test/test_complex.py
View file @
82b34c5d
...
...
@@ -358,6 +358,61 @@ class ComplexTest(unittest.TestCase):
self
.
assertAlmostEqual
(
complex
(
complex1
(
1j
)),
2j
)
self
.
assertRaises
(
TypeError
,
complex
,
complex2
(
1j
))
def
test_subclass
(
self
):
class
xcomplex
(
complex
):
def
__add__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
+
other
)
__radd__
=
__add__
def
__sub__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
+
other
)
__rsub__
=
__sub__
def
__mul__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
*
other
)
__rmul__
=
__mul__
def
__div__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
/
other
)
def
__rdiv__
(
self
,
other
):
return
xcomplex
(
other
/
complex
(
self
))
__truediv__
=
__div__
__rtruediv__
=
__rdiv__
def
__floordiv__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
//
other
)
def
__rfloordiv__
(
self
,
other
):
return
xcomplex
(
other
//
complex
(
self
))
def
__pow__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
**
other
)
def
__rpow__
(
self
,
other
):
return
xcomplex
(
other
**
complex
(
self
)
)
def
__mod__
(
self
,
other
):
return
xcomplex
(
complex
(
self
)
%
other
)
def
__rmod__
(
self
,
other
):
return
xcomplex
(
other
%
complex
(
self
))
infix_binops
=
(
'+'
,
'-'
,
'*'
,
'**'
,
'%'
,
'//'
,
'/'
)
xcomplex_values
=
(
xcomplex
(
1
),
xcomplex
(
123.0
),
xcomplex
(
-
10
+
2j
),
xcomplex
(
3
+
187j
),
xcomplex
(
3
-
78j
))
test_values
=
(
1
,
123.0
,
10
-
19j
,
xcomplex
(
1
+
2j
),
xcomplex
(
1
+
87j
),
xcomplex
(
10
+
90j
))
for
op
in
infix_binops
:
for
x
in
xcomplex_values
:
for
y
in
test_values
:
a
=
'x %s y'
%
op
b
=
'y %s x'
%
op
self
.
assertTrue
(
type
(
eval
(
a
))
is
type
(
eval
(
b
))
is
xcomplex
)
def
test_hash
(
self
):
for
x
in
xrange
(
-
30
,
30
):
self
.
assertEqual
(
hash
(
x
),
hash
(
complex
(
x
,
0
)))
...
...
Misc/NEWS
View file @
82b34c5d
...
...
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 4?
Core and Builtins
-----------------
- Issue #5211: the complex type no longer uses implicit coercion in
mixed-type binary arithmetic operations.
Library
-------
...
...
Objects/complexobject.c
View file @
82b34c5d
...
...
@@ -513,43 +513,54 @@ to_complex(PyObject **pobj, Py_complex *pc)
static
PyObject
*
complex_add
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_add
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
result
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
PyFPE_START_PROTECT
(
"complex_add"
,
return
0
)
result
=
c_sum
(
v
->
cval
,
w
->
cval
);
result
=
c_sum
(
a
,
b
);
PyFPE_END_PROTECT
(
result
)
return
PyComplex_FromCComplex
(
result
);
}
static
PyObject
*
complex_sub
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_sub
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
result
;
Py_complex
result
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);;
PyFPE_START_PROTECT
(
"complex_sub"
,
return
0
)
result
=
c_diff
(
v
->
cval
,
w
->
cval
);
result
=
c_diff
(
a
,
b
);
PyFPE_END_PROTECT
(
result
)
return
PyComplex_FromCComplex
(
result
);
}
static
PyObject
*
complex_mul
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_mul
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
result
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
PyFPE_START_PROTECT
(
"complex_mul"
,
return
0
)
result
=
c_prod
(
v
->
cval
,
w
->
cval
);
result
=
c_prod
(
a
,
b
);
PyFPE_END_PROTECT
(
result
)
return
PyComplex_FromCComplex
(
result
);
}
static
PyObject
*
complex_div
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_div
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
quot
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
PyFPE_START_PROTECT
(
"complex_div"
,
return
0
)
errno
=
0
;
quot
=
c_quot
(
v
->
cval
,
w
->
cval
);
quot
=
c_quot
(
a
,
b
);
PyFPE_END_PROTECT
(
quot
)
if
(
errno
==
EDOM
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"complex division"
);
...
...
@@ -559,10 +570,12 @@ complex_div(PyComplexObject *v, PyComplexObject *w)
}
static
PyObject
*
complex_classic_div
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_classic_div
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
quot
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
if
(
Py_DivisionWarningFlag
>=
2
&&
PyErr_Warn
(
PyExc_DeprecationWarning
,
"classic complex division"
)
<
0
)
...
...
@@ -570,7 +583,7 @@ complex_classic_div(PyComplexObject *v, PyComplexObject *w)
PyFPE_START_PROTECT
(
"complex_classic_div"
,
return
0
)
errno
=
0
;
quot
=
c_quot
(
v
->
cval
,
w
->
cval
);
quot
=
c_quot
(
a
,
b
);
PyFPE_END_PROTECT
(
quot
)
if
(
errno
==
EDOM
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"complex division"
);
...
...
@@ -580,47 +593,51 @@ complex_classic_div(PyComplexObject *v, PyComplexObject *w)
}
static
PyObject
*
complex_remainder
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_remainder
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
div
,
mod
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
return
NULL
;
errno
=
0
;
div
=
c_quot
(
v
->
cval
,
w
->
cval
);
/* The raw divisor value. */
div
=
c_quot
(
a
,
b
);
/* The raw divisor value. */
if
(
errno
==
EDOM
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"complex remainder"
);
return
NULL
;
}
div
.
real
=
floor
(
div
.
real
);
/* Use the floor of the real part. */
div
.
imag
=
0
.
0
;
mod
=
c_diff
(
v
->
cval
,
c_prod
(
w
->
cval
,
div
));
mod
=
c_diff
(
a
,
c_prod
(
b
,
div
));
return
PyComplex_FromCComplex
(
mod
);
}
static
PyObject
*
complex_divmod
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_divmod
(
Py
Object
*
v
,
Py
Object
*
w
)
{
Py_complex
div
,
mod
;
PyObject
*
d
,
*
m
,
*
z
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
return
NULL
;
errno
=
0
;
div
=
c_quot
(
v
->
cval
,
w
->
cval
);
/* The raw divisor value. */
div
=
c_quot
(
a
,
b
);
/* The raw divisor value. */
if
(
errno
==
EDOM
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"complex divmod()"
);
return
NULL
;
}
div
.
real
=
floor
(
div
.
real
);
/* Use the floor of the real part. */
div
.
imag
=
0
.
0
;
mod
=
c_diff
(
v
->
cval
,
c_prod
(
w
->
cval
,
div
));
mod
=
c_diff
(
a
,
c_prod
(
b
,
div
));
d
=
PyComplex_FromCComplex
(
div
);
m
=
PyComplex_FromCComplex
(
mod
);
z
=
PyTuple_Pack
(
2
,
d
,
m
);
...
...
@@ -638,8 +655,7 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
if
(
z
!=
Py_None
)
{
if
(
z
!=
Py_None
)
{
PyErr_SetString
(
PyExc_ValueError
,
"complex modulo"
);
return
NULL
;
}
...
...
@@ -668,10 +684,12 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
}
static
PyObject
*
complex_int_div
(
Py
ComplexObject
*
v
,
PyComplex
Object
*
w
)
complex_int_div
(
Py
Object
*
v
,
Py
Object
*
w
)
{
PyObject
*
t
,
*
r
;
Py_complex
a
,
b
;
TO_COMPLEX
(
v
,
a
);
TO_COMPLEX
(
w
,
b
);
if
(
PyErr_Warn
(
PyExc_DeprecationWarning
,
"complex divmod(), // and % are deprecated"
)
<
0
)
return
NULL
;
...
...
@@ -1282,7 +1300,8 @@ PyTypeObject PyComplex_Type = {
PyObject_GenericGetAttr
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_CHECKTYPES
|
Py_TPFLAGS_BASETYPE
,
/* tp_flags */
complex_doc
,
/* tp_doc */
0
,
/* tp_traverse */
0
,
/* tp_clear */
...
...
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