123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790 |
- import contextlib
- import sys
- import warnings
- import itertools
- import operator
- import platform
- import pytest
- from hypothesis import given, settings, Verbosity, assume
- from hypothesis.strategies import sampled_from
- import numpy as np
- from numpy.testing import (
- assert_, assert_equal, assert_raises, assert_almost_equal,
- assert_array_equal, IS_PYPY, suppress_warnings, _gen_alignment_data,
- assert_warns, assert_raises_regex,
- )
- types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc,
- np.int_, np.uint, np.longlong, np.ulonglong,
- np.single, np.double, np.longdouble, np.csingle,
- np.cdouble, np.clongdouble]
- floating_types = np.floating.__subclasses__()
- complex_floating_types = np.complexfloating.__subclasses__()
- # This compares scalarmath against ufuncs.
- class TestTypes:
- def test_types(self):
- for atype in types:
- a = atype(1)
- assert_(a == 1, "error with %r: got %r" % (atype, a))
- def test_type_add(self):
- # list of types
- for k, atype in enumerate(types):
- a_scalar = atype(3)
- a_array = np.array([3], dtype=atype)
- for l, btype in enumerate(types):
- b_scalar = btype(1)
- b_array = np.array([1], dtype=btype)
- c_scalar = a_scalar + b_scalar
- c_array = a_array + b_array
- # It was comparing the type numbers, but the new ufunc
- # function-finding mechanism finds the lowest function
- # to which both inputs can be cast - which produces 'l'
- # when you do 'q' + 'b'. The old function finding mechanism
- # skipped ahead based on the first argument, but that
- # does not produce properly symmetric results...
- assert_equal(c_scalar.dtype, c_array.dtype,
- "error with types (%d/'%c' + %d/'%c')" %
- (k, np.dtype(atype).char, l, np.dtype(btype).char))
- def test_type_create(self):
- for k, atype in enumerate(types):
- a = np.array([1, 2, 3], atype)
- b = atype([1, 2, 3])
- assert_equal(a, b)
- def test_leak(self):
- # test leak of scalar objects
- # a leak would show up in valgrind as still-reachable of ~2.6MB
- for i in range(200000):
- np.add(1, 1)
- class TestBaseMath:
- def test_blocked(self):
- # test alignments offsets for simd instructions
- # alignments for vz + 2 * (vs - 1) + 1
- for dt, sz in [(np.float32, 11), (np.float64, 7), (np.int32, 11)]:
- for out, inp1, inp2, msg in _gen_alignment_data(dtype=dt,
- type='binary',
- max_size=sz):
- exp1 = np.ones_like(inp1)
- inp1[...] = np.ones_like(inp1)
- inp2[...] = np.zeros_like(inp2)
- assert_almost_equal(np.add(inp1, inp2), exp1, err_msg=msg)
- assert_almost_equal(np.add(inp1, 2), exp1 + 2, err_msg=msg)
- assert_almost_equal(np.add(1, inp2), exp1, err_msg=msg)
- np.add(inp1, inp2, out=out)
- assert_almost_equal(out, exp1, err_msg=msg)
- inp2[...] += np.arange(inp2.size, dtype=dt) + 1
- assert_almost_equal(np.square(inp2),
- np.multiply(inp2, inp2), err_msg=msg)
- # skip true divide for ints
- if dt != np.int32:
- assert_almost_equal(np.reciprocal(inp2),
- np.divide(1, inp2), err_msg=msg)
- inp1[...] = np.ones_like(inp1)
- np.add(inp1, 2, out=out)
- assert_almost_equal(out, exp1 + 2, err_msg=msg)
- inp2[...] = np.ones_like(inp2)
- np.add(2, inp2, out=out)
- assert_almost_equal(out, exp1 + 2, err_msg=msg)
- def test_lower_align(self):
- # check data that is not aligned to element size
- # i.e doubles are aligned to 4 bytes on i386
- d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
- o = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
- assert_almost_equal(d + d, d * 2)
- np.add(d, d, out=o)
- np.add(np.ones_like(d), d, out=o)
- np.add(d, np.ones_like(d), out=o)
- np.add(np.ones_like(d), d)
- np.add(d, np.ones_like(d))
- class TestPower:
- def test_small_types(self):
- for t in [np.int8, np.int16, np.float16]:
- a = t(3)
- b = a ** 4
- assert_(b == 81, "error with %r: got %r" % (t, b))
- def test_large_types(self):
- for t in [np.int32, np.int64, np.float32, np.float64, np.longdouble]:
- a = t(51)
- b = a ** 4
- msg = "error with %r: got %r" % (t, b)
- if np.issubdtype(t, np.integer):
- assert_(b == 6765201, msg)
- else:
- assert_almost_equal(b, 6765201, err_msg=msg)
- def test_integers_to_negative_integer_power(self):
- # Note that the combination of uint64 with a signed integer
- # has common type np.float64. The other combinations should all
- # raise a ValueError for integer ** negative integer.
- exp = [np.array(-1, dt)[()] for dt in 'bhilq']
- # 1 ** -1 possible special case
- base = [np.array(1, dt)[()] for dt in 'bhilqBHILQ']
- for i1, i2 in itertools.product(base, exp):
- if i1.dtype != np.uint64:
- assert_raises(ValueError, operator.pow, i1, i2)
- else:
- res = operator.pow(i1, i2)
- assert_(res.dtype.type is np.float64)
- assert_almost_equal(res, 1.)
- # -1 ** -1 possible special case
- base = [np.array(-1, dt)[()] for dt in 'bhilq']
- for i1, i2 in itertools.product(base, exp):
- if i1.dtype != np.uint64:
- assert_raises(ValueError, operator.pow, i1, i2)
- else:
- res = operator.pow(i1, i2)
- assert_(res.dtype.type is np.float64)
- assert_almost_equal(res, -1.)
- # 2 ** -1 perhaps generic
- base = [np.array(2, dt)[()] for dt in 'bhilqBHILQ']
- for i1, i2 in itertools.product(base, exp):
- if i1.dtype != np.uint64:
- assert_raises(ValueError, operator.pow, i1, i2)
- else:
- res = operator.pow(i1, i2)
- assert_(res.dtype.type is np.float64)
- assert_almost_equal(res, .5)
- def test_mixed_types(self):
- typelist = [np.int8, np.int16, np.float16,
- np.float32, np.float64, np.int8,
- np.int16, np.int32, np.int64]
- for t1 in typelist:
- for t2 in typelist:
- a = t1(3)
- b = t2(2)
- result = a**b
- msg = ("error with %r and %r:"
- "got %r, expected %r") % (t1, t2, result, 9)
- if np.issubdtype(np.dtype(result), np.integer):
- assert_(result == 9, msg)
- else:
- assert_almost_equal(result, 9, err_msg=msg)
- def test_modular_power(self):
- # modular power is not implemented, so ensure it errors
- a = 5
- b = 4
- c = 10
- expected = pow(a, b, c) # noqa: F841
- for t in (np.int32, np.float32, np.complex64):
- # note that 3-operand power only dispatches on the first argument
- assert_raises(TypeError, operator.pow, t(a), b, c)
- assert_raises(TypeError, operator.pow, np.array(t(a)), b, c)
- def floordiv_and_mod(x, y):
- return (x // y, x % y)
- def _signs(dt):
- if dt in np.typecodes['UnsignedInteger']:
- return (+1,)
- else:
- return (+1, -1)
- class TestModulus:
- def test_modulus_basic(self):
- dt = np.typecodes['AllInteger'] + np.typecodes['Float']
- for op in [floordiv_and_mod, divmod]:
- for dt1, dt2 in itertools.product(dt, dt):
- for sg1, sg2 in itertools.product(_signs(dt1), _signs(dt2)):
- fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
- msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
- a = np.array(sg1*71, dtype=dt1)[()]
- b = np.array(sg2*19, dtype=dt2)[()]
- div, rem = op(a, b)
- assert_equal(div*b + rem, a, err_msg=msg)
- if sg2 == -1:
- assert_(b < rem <= 0, msg)
- else:
- assert_(b > rem >= 0, msg)
- def test_float_modulus_exact(self):
- # test that float results are exact for small integers. This also
- # holds for the same integers scaled by powers of two.
- nlst = list(range(-127, 0))
- plst = list(range(1, 128))
- dividend = nlst + [0] + plst
- divisor = nlst + plst
- arg = list(itertools.product(dividend, divisor))
- tgt = list(divmod(*t) for t in arg)
- a, b = np.array(arg, dtype=int).T
- # convert exact integer results from Python to float so that
- # signed zero can be used, it is checked.
- tgtdiv, tgtrem = np.array(tgt, dtype=float).T
- tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
- tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)
- for op in [floordiv_and_mod, divmod]:
- for dt in np.typecodes['Float']:
- msg = 'op: %s, dtype: %s' % (op.__name__, dt)
- fa = a.astype(dt)
- fb = b.astype(dt)
- # use list comprehension so a_ and b_ are scalars
- div, rem = zip(*[op(a_, b_) for a_, b_ in zip(fa, fb)])
- assert_equal(div, tgtdiv, err_msg=msg)
- assert_equal(rem, tgtrem, err_msg=msg)
- def test_float_modulus_roundoff(self):
- # gh-6127
- dt = np.typecodes['Float']
- for op in [floordiv_and_mod, divmod]:
- for dt1, dt2 in itertools.product(dt, dt):
- for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
- fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
- msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
- a = np.array(sg1*78*6e-8, dtype=dt1)[()]
- b = np.array(sg2*6e-8, dtype=dt2)[()]
- div, rem = op(a, b)
- # Equal assertion should hold when fmod is used
- assert_equal(div*b + rem, a, err_msg=msg)
- if sg2 == -1:
- assert_(b < rem <= 0, msg)
- else:
- assert_(b > rem >= 0, msg)
- def test_float_modulus_corner_cases(self):
- # Check remainder magnitude.
- for dt in np.typecodes['Float']:
- b = np.array(1.0, dtype=dt)
- a = np.nextafter(np.array(0.0, dtype=dt), -b)
- rem = operator.mod(a, b)
- assert_(rem <= b, 'dt: %s' % dt)
- rem = operator.mod(-a, -b)
- assert_(rem >= -b, 'dt: %s' % dt)
- # Check nans, inf
- with suppress_warnings() as sup:
- sup.filter(RuntimeWarning, "invalid value encountered in remainder")
- sup.filter(RuntimeWarning, "divide by zero encountered in remainder")
- sup.filter(RuntimeWarning, "divide by zero encountered in floor_divide")
- sup.filter(RuntimeWarning, "divide by zero encountered in divmod")
- sup.filter(RuntimeWarning, "invalid value encountered in divmod")
- for dt in np.typecodes['Float']:
- fone = np.array(1.0, dtype=dt)
- fzer = np.array(0.0, dtype=dt)
- finf = np.array(np.inf, dtype=dt)
- fnan = np.array(np.nan, dtype=dt)
- rem = operator.mod(fone, fzer)
- assert_(np.isnan(rem), 'dt: %s' % dt)
- # MSVC 2008 returns NaN here, so disable the check.
- #rem = operator.mod(fone, finf)
- #assert_(rem == fone, 'dt: %s' % dt)
- rem = operator.mod(fone, fnan)
- assert_(np.isnan(rem), 'dt: %s' % dt)
- rem = operator.mod(finf, fone)
- assert_(np.isnan(rem), 'dt: %s' % dt)
- for op in [floordiv_and_mod, divmod]:
- div, mod = op(fone, fzer)
- assert_(np.isinf(div)) and assert_(np.isnan(mod))
- def test_inplace_floordiv_handling(self):
- # issue gh-12927
- # this only applies to in-place floordiv //=, because the output type
- # promotes to float which does not fit
- a = np.array([1, 2], np.int64)
- b = np.array([1, 2], np.uint64)
- pattern = 'could not be coerced to provided output parameter'
- with assert_raises_regex(TypeError, pattern):
- a //= b
- class TestComplexDivision:
- def test_zero_division(self):
- with np.errstate(all="ignore"):
- for t in [np.complex64, np.complex128]:
- a = t(0.0)
- b = t(1.0)
- assert_(np.isinf(b/a))
- b = t(complex(np.inf, np.inf))
- assert_(np.isinf(b/a))
- b = t(complex(np.inf, np.nan))
- assert_(np.isinf(b/a))
- b = t(complex(np.nan, np.inf))
- assert_(np.isinf(b/a))
- b = t(complex(np.nan, np.nan))
- assert_(np.isnan(b/a))
- b = t(0.)
- assert_(np.isnan(b/a))
- def test_signed_zeros(self):
- with np.errstate(all="ignore"):
- for t in [np.complex64, np.complex128]:
- # tupled (numerator, denominator, expected)
- # for testing as expected == numerator/denominator
- data = (
- (( 0.0,-1.0), ( 0.0, 1.0), (-1.0,-0.0)),
- (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
- (( 0.0,-1.0), (-0.0,-1.0), ( 1.0, 0.0)),
- (( 0.0,-1.0), (-0.0, 1.0), (-1.0, 0.0)),
- (( 0.0, 1.0), ( 0.0,-1.0), (-1.0, 0.0)),
- (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
- ((-0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
- ((-0.0, 1.0), ( 0.0,-1.0), (-1.0,-0.0))
- )
- for cases in data:
- n = cases[0]
- d = cases[1]
- ex = cases[2]
- result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
- # check real and imag parts separately to avoid comparison
- # in array context, which does not account for signed zeros
- assert_equal(result.real, ex[0])
- assert_equal(result.imag, ex[1])
- def test_branches(self):
- with np.errstate(all="ignore"):
- for t in [np.complex64, np.complex128]:
- # tupled (numerator, denominator, expected)
- # for testing as expected == numerator/denominator
- data = list()
- # trigger branch: real(fabs(denom)) > imag(fabs(denom))
- # followed by else condition as neither are == 0
- data.append((( 2.0, 1.0), ( 2.0, 1.0), (1.0, 0.0)))
- # trigger branch: real(fabs(denom)) > imag(fabs(denom))
- # followed by if condition as both are == 0
- # is performed in test_zero_division(), so this is skipped
- # trigger else if branch: real(fabs(denom)) < imag(fabs(denom))
- data.append((( 1.0, 2.0), ( 1.0, 2.0), (1.0, 0.0)))
- for cases in data:
- n = cases[0]
- d = cases[1]
- ex = cases[2]
- result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
- # check real and imag parts separately to avoid comparison
- # in array context, which does not account for signed zeros
- assert_equal(result.real, ex[0])
- assert_equal(result.imag, ex[1])
- class TestConversion:
- def test_int_from_long(self):
- l = [1e6, 1e12, 1e18, -1e6, -1e12, -1e18]
- li = [10**6, 10**12, 10**18, -10**6, -10**12, -10**18]
- for T in [None, np.float64, np.int64]:
- a = np.array(l, dtype=T)
- assert_equal([int(_m) for _m in a], li)
- a = np.array(l[:3], dtype=np.uint64)
- assert_equal([int(_m) for _m in a], li[:3])
- def test_iinfo_long_values(self):
- for code in 'bBhH':
- res = np.array(np.iinfo(code).max + 1, dtype=code)
- tgt = np.iinfo(code).min
- assert_(res == tgt)
- for code in np.typecodes['AllInteger']:
- res = np.array(np.iinfo(code).max, dtype=code)
- tgt = np.iinfo(code).max
- assert_(res == tgt)
- for code in np.typecodes['AllInteger']:
- res = np.typeDict[code](np.iinfo(code).max)
- tgt = np.iinfo(code).max
- assert_(res == tgt)
- def test_int_raise_behaviour(self):
- def overflow_error_func(dtype):
- np.typeDict[dtype](np.iinfo(dtype).max + 1)
- for code in 'lLqQ':
- assert_raises(OverflowError, overflow_error_func, code)
- def test_int_from_infinite_longdouble(self):
- # gh-627
- x = np.longdouble(np.inf)
- assert_raises(OverflowError, int, x)
- with suppress_warnings() as sup:
- sup.record(np.ComplexWarning)
- x = np.clongdouble(np.inf)
- assert_raises(OverflowError, int, x)
- assert_equal(len(sup.log), 1)
- @pytest.mark.skipif(not IS_PYPY, reason="Test is PyPy only (gh-9972)")
- def test_int_from_infinite_longdouble___int__(self):
- x = np.longdouble(np.inf)
- assert_raises(OverflowError, x.__int__)
- with suppress_warnings() as sup:
- sup.record(np.ComplexWarning)
- x = np.clongdouble(np.inf)
- assert_raises(OverflowError, x.__int__)
- assert_equal(len(sup.log), 1)
- @pytest.mark.skipif(np.finfo(np.double) == np.finfo(np.longdouble),
- reason="long double is same as double")
- @pytest.mark.skipif(platform.machine().startswith("ppc"),
- reason="IBM double double")
- def test_int_from_huge_longdouble(self):
- # Produce a longdouble that would overflow a double,
- # use exponent that avoids bug in Darwin pow function.
- exp = np.finfo(np.double).maxexp - 1
- huge_ld = 2 * 1234 * np.longdouble(2) ** exp
- huge_i = 2 * 1234 * 2 ** exp
- assert_(huge_ld != np.inf)
- assert_equal(int(huge_ld), huge_i)
- def test_int_from_longdouble(self):
- x = np.longdouble(1.5)
- assert_equal(int(x), 1)
- x = np.longdouble(-10.5)
- assert_equal(int(x), -10)
- def test_numpy_scalar_relational_operators(self):
- # All integer
- for dt1 in np.typecodes['AllInteger']:
- assert_(1 > np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
- assert_(not 1 < np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
- for dt2 in np.typecodes['AllInteger']:
- assert_(np.array(1, dtype=dt1)[()] > np.array(0, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- assert_(not np.array(1, dtype=dt1)[()] < np.array(0, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- #Unsigned integers
- for dt1 in 'BHILQP':
- assert_(-1 < np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
- assert_(not -1 > np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
- assert_(-1 != np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
- #unsigned vs signed
- for dt2 in 'bhilqp':
- assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- assert_(np.array(1, dtype=dt1)[()] != np.array(-1, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- #Signed integers and floats
- for dt1 in 'bhlqp' + np.typecodes['Float']:
- assert_(1 > np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
- assert_(not 1 < np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
- assert_(-1 == np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
- for dt2 in 'bhlqp' + np.typecodes['Float']:
- assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- assert_(np.array(-1, dtype=dt1)[()] == np.array(-1, dtype=dt2)[()],
- "type %s and %s failed" % (dt1, dt2))
- def test_scalar_comparison_to_none(self):
- # Scalars should just return False and not give a warnings.
- # The comparisons are flagged by pep8, ignore that.
- with warnings.catch_warnings(record=True) as w:
- warnings.filterwarnings('always', '', FutureWarning)
- assert_(not np.float32(1) == None)
- assert_(not np.str_('test') == None)
- # This is dubious (see below):
- assert_(not np.datetime64('NaT') == None)
- assert_(np.float32(1) != None)
- assert_(np.str_('test') != None)
- # This is dubious (see below):
- assert_(np.datetime64('NaT') != None)
- assert_(len(w) == 0)
- # For documentation purposes, this is why the datetime is dubious.
- # At the time of deprecation this was no behaviour change, but
- # it has to be considered when the deprecations are done.
- assert_(np.equal(np.datetime64('NaT'), None))
- #class TestRepr:
- # def test_repr(self):
- # for t in types:
- # val = t(1197346475.0137341)
- # val_repr = repr(val)
- # val2 = eval(val_repr)
- # assert_equal( val, val2 )
- class TestRepr:
- def _test_type_repr(self, t):
- finfo = np.finfo(t)
- last_fraction_bit_idx = finfo.nexp + finfo.nmant
- last_exponent_bit_idx = finfo.nexp
- storage_bytes = np.dtype(t).itemsize*8
- # could add some more types to the list below
- for which in ['small denorm', 'small norm']:
- # Values from https://en.wikipedia.org/wiki/IEEE_754
- constr = np.array([0x00]*storage_bytes, dtype=np.uint8)
- if which == 'small denorm':
- byte = last_fraction_bit_idx // 8
- bytebit = 7-(last_fraction_bit_idx % 8)
- constr[byte] = 1 << bytebit
- elif which == 'small norm':
- byte = last_exponent_bit_idx // 8
- bytebit = 7-(last_exponent_bit_idx % 8)
- constr[byte] = 1 << bytebit
- else:
- raise ValueError('hmm')
- val = constr.view(t)[0]
- val_repr = repr(val)
- val2 = t(eval(val_repr))
- if not (val2 == 0 and val < 1e-100):
- assert_equal(val, val2)
- def test_float_repr(self):
- # long double test cannot work, because eval goes through a python
- # float
- for t in [np.float32, np.float64]:
- self._test_type_repr(t)
- if not IS_PYPY:
- # sys.getsizeof() is not valid on PyPy
- class TestSizeOf:
- def test_equal_nbytes(self):
- for type in types:
- x = type(0)
- assert_(sys.getsizeof(x) > x.nbytes)
- def test_error(self):
- d = np.float32()
- assert_raises(TypeError, d.__sizeof__, "a")
- class TestMultiply:
- def test_seq_repeat(self):
- # Test that basic sequences get repeated when multiplied with
- # numpy integers. And errors are raised when multiplied with others.
- # Some of this behaviour may be controversial and could be open for
- # change.
- accepted_types = set(np.typecodes["AllInteger"])
- deprecated_types = {'?'}
- forbidden_types = (
- set(np.typecodes["All"]) - accepted_types - deprecated_types)
- forbidden_types -= {'V'} # can't default-construct void scalars
- for seq_type in (list, tuple):
- seq = seq_type([1, 2, 3])
- for numpy_type in accepted_types:
- i = np.dtype(numpy_type).type(2)
- assert_equal(seq * i, seq * int(i))
- assert_equal(i * seq, int(i) * seq)
- for numpy_type in deprecated_types:
- i = np.dtype(numpy_type).type()
- assert_equal(
- assert_warns(DeprecationWarning, operator.mul, seq, i),
- seq * int(i))
- assert_equal(
- assert_warns(DeprecationWarning, operator.mul, i, seq),
- int(i) * seq)
- for numpy_type in forbidden_types:
- i = np.dtype(numpy_type).type()
- assert_raises(TypeError, operator.mul, seq, i)
- assert_raises(TypeError, operator.mul, i, seq)
- def test_no_seq_repeat_basic_array_like(self):
- # Test that an array-like which does not know how to be multiplied
- # does not attempt sequence repeat (raise TypeError).
- # See also gh-7428.
- class ArrayLike:
- def __init__(self, arr):
- self.arr = arr
- def __array__(self):
- return self.arr
- # Test for simple ArrayLike above and memoryviews (original report)
- for arr_like in (ArrayLike(np.ones(3)), memoryview(np.ones(3))):
- assert_array_equal(arr_like * np.float32(3.), np.full(3, 3.))
- assert_array_equal(np.float32(3.) * arr_like, np.full(3, 3.))
- assert_array_equal(arr_like * np.int_(3), np.full(3, 3))
- assert_array_equal(np.int_(3) * arr_like, np.full(3, 3))
- class TestNegative:
- def test_exceptions(self):
- a = np.ones((), dtype=np.bool_)[()]
- assert_raises(TypeError, operator.neg, a)
- def test_result(self):
- types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
- with suppress_warnings() as sup:
- sup.filter(RuntimeWarning)
- for dt in types:
- a = np.ones((), dtype=dt)[()]
- assert_equal(operator.neg(a) + a, 0)
- class TestSubtract:
- def test_exceptions(self):
- a = np.ones((), dtype=np.bool_)[()]
- assert_raises(TypeError, operator.sub, a, a)
- def test_result(self):
- types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
- with suppress_warnings() as sup:
- sup.filter(RuntimeWarning)
- for dt in types:
- a = np.ones((), dtype=dt)[()]
- assert_equal(operator.sub(a, a), 0)
- class TestAbs:
- def _test_abs_func(self, absfunc):
- for tp in floating_types + complex_floating_types:
- x = tp(-1.5)
- assert_equal(absfunc(x), 1.5)
- x = tp(0.0)
- res = absfunc(x)
- # assert_equal() checks zero signedness
- assert_equal(res, 0.0)
- x = tp(-0.0)
- res = absfunc(x)
- assert_equal(res, 0.0)
- x = tp(np.finfo(tp).max)
- assert_equal(absfunc(x), x.real)
- x = tp(np.finfo(tp).tiny)
- assert_equal(absfunc(x), x.real)
- x = tp(np.finfo(tp).min)
- assert_equal(absfunc(x), -x.real)
- def test_builtin_abs(self):
- self._test_abs_func(abs)
- def test_numpy_abs(self):
- self._test_abs_func(np.abs)
- class TestBitShifts:
- @pytest.mark.parametrize('type_code', np.typecodes['AllInteger'])
- @pytest.mark.parametrize('op',
- [operator.rshift, operator.lshift], ids=['>>', '<<'])
- def test_shift_all_bits(self, type_code, op):
- """ Shifts where the shift amount is the width of the type or wider """
- # gh-2449
- dt = np.dtype(type_code)
- nbits = dt.itemsize * 8
- for val in [5, -5]:
- for shift in [nbits, nbits + 4]:
- val_scl = dt.type(val)
- shift_scl = dt.type(shift)
- res_scl = op(val_scl, shift_scl)
- if val_scl < 0 and op is operator.rshift:
- # sign bit is preserved
- assert_equal(res_scl, -1)
- else:
- assert_equal(res_scl, 0)
- # Result on scalars should be the same as on arrays
- val_arr = np.array([val]*32, dtype=dt)
- shift_arr = np.array([shift]*32, dtype=dt)
- res_arr = op(val_arr, shift_arr)
- assert_equal(res_arr, res_scl)
- @contextlib.contextmanager
- def recursionlimit(n):
- o = sys.getrecursionlimit()
- try:
- sys.setrecursionlimit(n)
- yield
- finally:
- sys.setrecursionlimit(o)
- objecty_things = [object(), None]
- reasonable_operators_for_scalars = [
- operator.lt, operator.le, operator.eq, operator.ne, operator.ge,
- operator.gt, operator.add, operator.floordiv, operator.mod,
- operator.mul, operator.matmul, operator.pow, operator.sub,
- operator.truediv,
- ]
- @given(sampled_from(objecty_things),
- sampled_from(reasonable_operators_for_scalars),
- sampled_from(types))
- @settings(verbosity=Verbosity.verbose)
- def test_operator_object_left(o, op, type_):
- try:
- with recursionlimit(200):
- op(o, type_(1))
- except TypeError:
- pass
- @given(sampled_from(objecty_things),
- sampled_from(reasonable_operators_for_scalars),
- sampled_from(types))
- def test_operator_object_right(o, op, type_):
- try:
- with recursionlimit(200):
- op(type_(1), o)
- except TypeError:
- pass
- @given(sampled_from(reasonable_operators_for_scalars),
- sampled_from(types),
- sampled_from(types))
- def test_operator_scalars(op, type1, type2):
- try:
- op(type1(1), type2(1))
- except TypeError:
- pass
- @pytest.mark.parametrize("op", reasonable_operators_for_scalars)
- def test_longdouble_inf_loop(op):
- try:
- op(np.longdouble(3), None)
- except TypeError:
- pass
- try:
- op(None, np.longdouble(3))
- except TypeError:
- pass
- @pytest.mark.parametrize("op", reasonable_operators_for_scalars)
- def test_clongdouble_inf_loop(op):
- if op in {operator.mod} and False:
- pytest.xfail("The modulo operator is known to be broken")
- try:
- op(np.clongdouble(3), None)
- except TypeError:
- pass
- try:
- op(None, np.longdouble(3))
- except TypeError:
- pass
|