Skip to content

Commit

Permalink
ENH: core: emit ComplexWarning also when array scalars are cast to re…
Browse files Browse the repository at this point in the history
…al/int

(cherry picked from commit d82003b)
  • Loading branch information
pv committed Sep 20, 2010
1 parent 23ab0a4 commit 1bc88b9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
44 changes: 40 additions & 4 deletions numpy/core/src/scalarmathmodule.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -973,11 +973,35 @@ NONZERO_NAME(@name@_,)(PyObject *a)
}
/**end repeat**/


static void
emit_complexwarning()
{
static PyObject *cls = NULL;
if (cls == NULL) {
PyObject *mod;
mod = PyImport_ImportModule("numpy.core");
assert(mod != NULL);
cls = PyObject_GetAttrString(mod, "ComplexWarning");
assert(cls != NULL);
Py_DECREF(mod);
}
#if PY_VERSION_HEX >= 0x02050000
PyErr_WarnEx(cls,
"Casting complex values to real discards the imaginary "
"part", 0);
#else
PyErr_Warn(cls,
"Casting complex values to real discards the imaginary "
"part");
#endif
}

/**begin repeat
*
* #name=byte,ubyte,short,ushort,int,uint,long,ulong,longlong,ulonglong,float,double,longdouble,cfloat,cdouble,clongdouble#
* #Name=Byte,UByte,Short,UShort,Int,UInt,Long,ULong,LongLong,ULongLong,Float,Double,LongDouble,CFloat,CDouble,CLongDouble#
* #cmplx=,,,,,,,,,,,,,.real,.real,.real#
* #cmplx=0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1#
* #sign=(signed,unsigned)*5,,,,,,#
* #unsigntyp=0,1,0,1,0,1,0,1,0,1,1*6#
* #ctype=long*8,PY_LONG_LONG*2,double*6#
Expand All @@ -987,12 +1011,19 @@ NONZERO_NAME(@name@_,)(PyObject *a)
static PyObject *
@name@_int(PyObject *obj)
{
@sign@ @ctype@ x= PyArrayScalar_VAL(obj, @Name@)@cmplx@;
#if @cmplx@
@sign@ @ctype@ x= PyArrayScalar_VAL(obj, @Name@).real;
#else
@sign@ @ctype@ x= PyArrayScalar_VAL(obj, @Name@);
#endif
#if @realtyp@
double ix;
modf(x, &ix);
x = ix;
#endif
#if @cmplx@
emit_complexwarning();
#endif

/*
* For unsigned type, the (@ctype@) cast just does what is implicitely done by
Expand All @@ -1013,14 +1044,19 @@ static PyObject *
*
* #name=(byte,ubyte,short,ushort,int,uint,long,ulong,longlong,ulonglong,float,double,longdouble,cfloat,cdouble,clongdouble)*2#
* #Name=(Byte,UByte,Short,UShort,Int,UInt,Long,ULong,LongLong,ULongLong,Float,Double,LongDouble,CFloat,CDouble,CLongDouble)*2#
* #cmplx=(,,,,,,,,,,,,,.real,.real,.real)*2#
* #cmplx=(0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1)*2#
* #which=long*16,float*16#
* #func=(PyLong_FromLongLong, PyLong_FromUnsignedLongLong)*5,PyLong_FromDouble*6,PyFloat_FromDouble*16#
*/
static PyObject *
@name@_@which@(PyObject *obj)
{
return @func@((PyArrayScalar_VAL(obj, @Name@))@cmplx@);
#if @cmplx@
emit_complexwarning();
return @func@((PyArrayScalar_VAL(obj, @Name@)).real);
#else
return @func@((PyArrayScalar_VAL(obj, @Name@)));
#endif
}
/**end repeat**/

Expand Down
13 changes: 12 additions & 1 deletion numpy/core/tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import copy
from os import path
from numpy.testing import *
from numpy.testing.utils import _assert_valid_refcount
from numpy.testing.utils import _assert_valid_refcount, WarningManager
from numpy.compat import asbytes, asunicode, asbytes_nested
import warnings
import tempfile
import numpy as np

Expand Down Expand Up @@ -1404,5 +1405,15 @@ def test_fromfile_tofile_seeks(self):

f.close()

def test_complex_scalar_warning(self):
for tp in [np.csingle, np.cdouble, np.clongdouble]:
x = tp(1+2j)
assert_warns(np.ComplexWarning, float, x)
ctx = WarningManager()
ctx.__enter__()
warnings.simplefilter('ignore')
assert_equal(float(x), float(x.real))
ctx.__exit__()

if __name__ == "__main__":
run_module_suite()

0 comments on commit 1bc88b9

Please sign in to comment.