NumPy 源码解析(八十一)
.\numpy\numpy\_core\tests\test_defchararray.py
import pytest
import numpy as np
from numpy._core.multiarray import _vec_string
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_raises,
assert_raises_regex
)
kw_unicode_true = {'unicode': True}
kw_unicode_false = {'unicode': False}
class TestBasic:
def test_from_object_array(self):
A = np.array([['abc', 2],
['long ', '0123456789']], dtype='O')
B = np.char.array(A)
assert_equal(B.dtype.itemsize, 10)
assert_array_equal(B, [[b'abc', b'2'],
[b'long', b'0123456789']])
def test_from_object_array_unicode(self):
A = np.array([['abc', 'Sigma \u03a3'],
['long ', '0123456789']], dtype='O')
assert_raises(ValueError, np.char.array, (A,))
B = np.char.array(A, **kw_unicode_true)
assert_equal(B.dtype.itemsize, 10 * np.array('a', 'U').dtype.itemsize)
assert_array_equal(B, [['abc', 'Sigma \u03a3'],
['long', '0123456789']])
def test_from_string_array(self):
A = np.array([[b'abc', b'foo'],
[b'long ', b'0123456789']])
assert_equal(A.dtype.type, np.bytes_)
B = np.char.array(A)
assert_array_equal(B, A)
assert_equal(B.dtype, A.dtype)
assert_equal(B.shape, A.shape)
B[0, 0] = 'changed'
assert_(B[0, 0] != A[0, 0])
C = np.char.asarray(A)
assert_array_equal(C, A)
assert_equal(C.dtype, A.dtype)
C[0, 0] = 'changed again'
assert_(C[0, 0] != B[0, 0])
assert_(C[0, 0] == A[0, 0])
def test_from_unicode_array(self):
A = np.array([['abc', 'Sigma \u03a3'],
['long ', '0123456789']])
assert_equal(A.dtype.type, np.str_)
B = np.char.array(A)
assert_array_equal(B, A)
assert_equal(B.dtype, A.dtype)
assert_equal(B.shape, A.shape)
B = np.char.array(A, **kw_unicode_true)
assert_array_equal(B, A)
assert_equal(B.dtype, A.dtype)
assert_equal(B.shape, A.shape)
def fail():
np.char.array(A, **kw_unicode_false)
assert_raises(UnicodeEncodeError, fail)
def test_unicode_upconvert(self):
A = np.char.array(['abc'])
B = np.char.array(['\u03a3'])
assert_(issubclass((A + B).dtype.type, np.str_))
def test_from_string(self):
A = np.char.array(b'abc')
assert_equal(len(A), 1)
assert_equal(len(A[0]), 3)
assert_(issubclass(A.dtype.type, np.bytes_))
def test_from_unicode(self):
A = np.char.array('\u03a3')
assert_equal(len(A), 1)
assert_equal(len(A[0]), 1)
assert_equal(A.itemsize, 4)
assert_(issubclass(A.dtype.type, np.str_))
class TestVecString:
def test_non_existent_method(self):
def fail():
_vec_string('a', np.bytes_, 'bogus')
assert_raises(AttributeError, fail)
def test_non_string_array(self):
def fail():
_vec_string(1, np.bytes_, 'strip')
assert_raises(TypeError, fail)
def test_invalid_args_tuple(self):
def fail():
_vec_string(['a'], np.bytes_, 'strip', 1)
assert_raises(TypeError, fail)
def test_invalid_type_descr(self):
def fail():
_vec_string(['a'], 'BOGUS', 'strip')
assert_raises(TypeError, fail)
def test_invalid_function_args(self):
def fail():
_vec_string(['a'], np.bytes_, 'strip', (1,))
assert_raises(TypeError, fail)
def test_invalid_result_type(self):
def fail():
_vec_string(['a'], np.int_, 'strip')
assert_raises(TypeError, fail)
def test_broadcast_error(self):
def fail():
_vec_string([['abc', 'def']], np.int_, 'find', (['a', 'd', 'j'],))
assert_raises(ValueError, fail)
class TestWhitespace:
def setup_method(self):
self.A = np.array([['abc ', '123 '],
['789 ', 'xyz ']]).view(np.char.chararray)
self.B = np.array([['abc', '123'],
['789', 'xyz']]).view(np.char.chararray)
def test1(self):
assert_(np.all(self.A == self.B))
assert_(np.all(self.A >= self.B))
assert_(np.all(self.A <= self.B))
assert_(not np.any(self.A > self.B))
assert_(not np.any(self.A < self.B))
assert_(not np.any(self.A != self.B))
class TestChar:
def setup_method(self):
self.A = np.array('abc1', dtype='c').view(np.char.chararray)
def test_it(self):
assert_equal(self.A.shape, (4,))
assert_equal(self.A.upper()[:2].tobytes(), b'AB')
class TestComparisons:
def setup_method(self):
self.A = np.array([['abc', 'abcc', '123'],
['789', 'abc', 'xyz']]).view(np.char.chararray)
self.B = np.array([['efg', 'efg', '123 '],
['051', 'efgg', 'tuv']]).view(np.char.chararray)
def test_not_equal(self):
assert_array_equal((self.A != self.B),
[[True, True, False], [True, True, True]])
def test_equal(self):
assert_array_equal((self.A == self.B),
[[False, False, True], [False, False, False]])
def test_greater_equal(self):
assert_array_equal((self.A >= self.B),
[[False, False, True], [True, False, True]])
def test_less_equal(self):
assert_array_equal((self.A <= self.B),
[[True, True, True], [False, True, False]])
def test_greater(self):
assert_array_equal((self.A > self.B),
[[False, False, False], [True, False, True]])
def test_less(self):
assert_array_equal((self.A < self.B),
[[True, True, False], [False, True, False]])
def test_type(self):
out1 = np.char.equal(self.A, self.B)
out2 = np.char.equal('a', 'a')
assert_(isinstance(out1, np.ndarray))
assert_(isinstance(out2, np.ndarray))
class TestComparisonsMixed1(TestComparisons):
"""Ticket #1276"""
def setup_method(self):
TestComparisons.setup_method(self)
self.B = np.array(
[['efg', 'efg', '123 '],
['051', 'efgg', 'tuv']], np.str_).view(np.char.chararray)
class TestComparisonsMixed2(TestComparisons):
"""Ticket #1276"""
def setup_method(self):
TestComparisons.setup_method(self)
self.A = np.array(
[['abc', 'abcc', '123'],
['789', 'abc', 'xyz']], np.str_).view(np.char.chararray)
def setup_method(self):
self.A = np.array([[' abc ', ''],
['12345', 'MixedCase'],
['123 \t 345 \0 ', 'UPPER']]) \
.view(np.char.chararray)
self.B = np.array([[' \u03a3 ', ''],
['12345', 'MixedCase'],
['123 \t 345 \0 ', 'UPPER']]) \
.view(np.char.chararray)
self.C = (np.array(['ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'01234567890123456789012345'])
.view(np.char.chararray))
def test_len(self):
assert_(issubclass(np.char.str_len(self.A).dtype.type, np.integer))
assert_array_equal(np.char.str_len(self.A), [[5, 0], [5, 9], [12, 5]])
assert_array_equal(np.char.str_len(self.B), [[3, 0], [5, 9], [12, 5]])
def test_count(self):
assert_(issubclass(self.A.count('').dtype.type, np.integer))
assert_array_equal(self.A.count('a'), [[1, 0], [0, 1], [0, 0]])
assert_array_equal(self.A.count('123'), [[0, 0], [1, 0], [1, 0]])
assert_array_equal(self.A.count('a', 0, 2), [[1, 0], [0, 0], [0, 0]])
assert_array_equal(self.B.count('a'), [[0, 0], [0, 1], [0, 0]])
assert_array_equal(self.B.count('123'), [[0, 0], [1, 0], [1, 0]])
def test_endswith(self):
assert_(issubclass(self.A.endswith('').dtype.type, np.bool))
assert_array_equal(self.A.endswith(' '), [[1, 0], [0, 0], [1, 0]])
assert_array_equal(self.A.endswith('3', 0, 3), [[0, 0], [1, 0], [1, 0]])
def fail():
self.A.endswith('3', 'fdjk')
assert_raises(TypeError, fail)
@pytest.mark.parametrize(
"dtype, encode",
[("U", str),
("S", lambda x: x.encode('ascii')),
])
def test_find(self, dtype, encode):
A = self.A.astype(dtype)
assert_(issubclass(A.find(encode('a')).dtype.type, np.integer))
assert_array_equal(A.find(encode('a')),
[[1, -1], [-1, 6], [-1, -1]])
assert_array_equal(A.find(encode('3')),
[[-1, -1], [2, -1], [2, -1]])
assert_array_equal(A.find(encode('a'), 0, 2),
[[1, -1], [-1, -1], [-1, -1]])
assert_array_equal(A.find([encode('1'), encode('P')]),
[[-1, -1], [0, -1], [0, 1]])
C = self.C.astype(dtype)
assert_array_equal(C.find(encode('M')), [12, -1])
def fail():
self.A.index('a')
assert_raises(ValueError, fail)
assert_(np.char.index('abcba', 'b') == 1)
assert_(issubclass(np.char.index('abcba', 'b').dtype.type, np.integer))
def test_isalnum(self):
assert_(issubclass(self.A.isalnum().dtype.type, np.bool))
assert_array_equal(self.A.isalnum(), [[False, False], [True, True], [False, True]])
def test_isalpha(self):
assert_(issubclass(self.A.isalpha().dtype.type, np.bool))
assert_array_equal(self.A.isalpha(), [[False, False], [False, True], [False, True]])
def test_isdigit(self):
assert_(issubclass(self.A.isdigit().dtype.type, np.bool))
assert_array_equal(self.A.isdigit(), [[False, False], [True, False], [False, False]])
def test_islower(self):
assert_(issubclass(self.A.islower().dtype.type, np.bool))
assert_array_equal(self.A.islower(), [[True, False], [False, False], [False, False]])
def test_isspace(self):
assert_(issubclass(self.A.isspace().dtype.type, np.bool))
assert_array_equal(self.A.isspace(), [[False, False], [False, False], [False, False]])
def test_istitle(self):
assert_(issubclass(self.A.istitle().dtype.type, np.bool))
assert_array_equal(self.A.istitle(), [[False, False], [False, False], [False, False]])
def test_isupper(self):
assert_(issubclass(self.A.isupper().dtype.type, np.bool))
assert_array_equal(self.A.isupper(), [[False, False], [False, False], [False, True]])
def test_rfind(self):
assert_(issubclass(self.A.rfind('a').dtype.type, np.integer))
assert_array_equal(self.A.rfind('a'), [[1, -1], [-1, 6], [-1, -1]])
assert_array_equal(self.A.rfind('3'), [[-1, -1], [2, -1], [6, -1]])
assert_array_equal(self.A.rfind('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]])
assert_array_equal(self.A.rfind(['1', 'P']), [[-1, -1], [0, -1], [0, 2]])
def test_rindex(self):
def fail():
self.A.rindex('a')
assert_raises(ValueError, fail)
assert_(np.char.rindex('abcba', 'b') == 3)
assert_(issubclass(np.char.rindex('abcba', 'b').dtype.type, np.integer))
def test_startswith(self):
assert_(issubclass(self.A.startswith('').dtype.type, np.bool))
assert_array_equal(self.A.startswith(' '), [[1, 0], [0, 0], [0, 0]])
class TestMethods:
def setup_method(self):
self.A = np.array([[' abc ', ''],
['12345', 'MixedCase'],
['123 \t 345 \0 ', 'UPPER']],
dtype='S').view(np.char.chararray)
self.B = np.array([[' \u03a3 ', ''],
['12345', 'MixedCase'],
['123 \t 345 \0 ', 'UPPER']]).view(
np.char.chararray)
def test_capitalize(self):
tgt = [[b' abc ', b''],
[b'12345', b'Mixedcase'],
[b'123 \t 345 \0 ', b'Upper']]
assert_(issubclass(self.A.capitalize().dtype.type, np.bytes_))
assert_array_equal(self.A.capitalize(), tgt)
tgt = [[' \u03c3 ', ''],
['12345', 'Mixedcase'],
['123 \t 345 \0 ', 'Upper']]
assert_(issubclass(self.B.capitalize().dtype.type, np.str_))
assert_array_equal(self.B.capitalize(), tgt)
def test_center(self):
assert_(issubclass(self.A.center(10).dtype.type, np.bytes_))
C = self.A.center([10, 20])
assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
C = self.A.center(20, b'#')
assert_(np.all(C.startswith(b'#')))
assert_(np.all(C.endswith(b'#')))
C = np.char.center(b'FOO', [[10, 20], [15, 8]])
tgt = [[b' FOO ', b' FOO '],
[b' FOO ', b' FOO ']]
assert_(issubclass(C.dtype.type, np.bytes_))
assert_array_equal(C, tgt)
def test_decode(self):
A = np.char.array([b'\\u03a3'])
assert_(A.decode('unicode-escape')[0] == '\u03a3')
def test_encode(self):
B = self.B.encode('unicode_escape')
assert_(B[0][0] == str(' \\u03a3 ').encode('latin1'))
def test_expandtabs(self):
T = self.A.expandtabs()
assert_(T[2, 0] == b'123 345 \0')
def test_join(self):
A0 = self.A.decode('ascii')
A = np.char.join([',', '#'], A0)
assert_(issubclass(A.dtype.type, np.str_))
tgt = np.array([[' ,a,b,c, ', ''],
['1,2,3,4,5', 'M#i#x#e#d#C#a#s#e'],
['1,2,3, ,\t, ,3,4,5, ,\x00, ', 'U#P#P#E#R']])
assert_array_equal(np.char.join([',', '#'], A0), tgt)
def test_ljust(self):
assert_(issubclass(self.A.ljust(10).dtype.type, np.bytes_))
C = self.A.ljust([10, 20])
assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
C = self.A.ljust(20, b'#')
assert_array_equal(C.startswith(b'#'), [
[False, True], [False, False], [False, False]])
assert_(np.all(C.endswith(b'#')))
C = np.char.ljust(b'FOO', [[10, 20], [15, 8]])
tgt = [[b'FOO ', b'FOO '],
[b'FOO ', b'FOO ']]
assert_(issubclass(C.dtype.type, np.bytes_))
assert_array_equal(C, tgt)
def test_lower(self):
tgt = [[b' abc ', b''],
[b'12345', b'mixedcase'],
[b'123 \t 345 \0 ', b'upper']]
assert_(issubclass(self.A.lower().dtype.type, np.bytes_))
assert_array_equal(self.A.lower(), tgt)
tgt = [[' \u03c3 ', ''],
['12345', 'mixedcase'],
['123 \t 345 \0 ', 'upper']]
assert_(issubclass(self.B.lower().dtype.type, np.str_))
assert_array_equal(self.B.lower(), tgt)
def test_lstrip(self):
tgt = [[b'abc ', b''],
[b'12345', b'MixedCase'],
[b'123 \t 345 \0 ', b'UPPER']]
assert_(issubclass(self.A.lstrip().dtype.type, np.bytes_))
assert_array_equal(self.A.lstrip(), tgt)
tgt = [[b' abc', b''],
[b'2345', b'ixedCase'],
[b'23 \t 345 \x00', b'UPPER']]
assert_array_equal(self.A.lstrip([b'1', b'M']), tgt)
tgt = [['\u03a3 ', ''],
['12345', 'MixedCase'],
['123 \t 345 \0 ', 'UPPER']]
assert_(issubclass(self.B.lstrip().dtype.type, np.str_))
assert_array_equal(self.B.lstrip(), tgt)
def test_partition(self):
P = self.A.partition([b'3', b'M'])
tgt = [[(b' abc ', b'', b''), (b'', b'', b'')],
[(b'12', b'3', b'45'), (b'', b'M', b'ixedCase')],
[(b'12', b'3', b' \t 345 \0 '), (b'UPPER', b'', b'')]]
assert_(issubclass(P.dtype.type, np.bytes_))
assert_array_equal(P, tgt)
def test_replace(self):
R = self.A.replace([b'3', b'a'],
[b'##########', b'@'])
tgt = [[b' abc ', b''],
[b'12##########45', b'MixedC@se'],
[b'12########## \t ##########45 \x00 ', b'UPPER']]
assert_(issubclass(R.dtype.type, np.bytes_))
assert_array_equal(R, tgt)
S1 = self.A.replace(b'A very long byte string, longer than A', b'')
assert_array_equal(S1, self.A)
S2 = self.A.replace(b'', b'')
assert_array_equal(S2, self.A)
S3 = self.A.replace(b'3', b'3')
assert_array_equal(S3, self.A)
S4 = self.A.replace(b'3', b'', count=0)
assert_array_equal(S4, self.A)
def test_replace_count_and_size(self):
a = np.array(['0123456789' * i for i in range(4)]).view(np.char.chararray)
r1 = a.replace('5', 'ABCDE')
assert r1.dtype.itemsize == (3*10 + 3*4) * 4
assert_array_equal(r1, np.array(['01234ABCDE6789' * i for i in range(4)]))
r2 = a.replace('5', 'ABCDE', count=1)
assert r2.dtype.itemsize == (3*10 + 4) * 4
r3 = a.replace('5', 'ABCDE', count=0)
assert r3.dtype.itemsize == a.dtype.itemsize
assert_array_equal(r3, a)
r4 = a.replace('5', 'ABCDE', count=-1)
assert r4.dtype.itemsize == (3*10 + 3*4) * 4
assert_array_equal(r4, r1)
r5 = a.replace('5', 'ABCDE', count=[-1, -1, -1, 1])
assert r5.dtype.itemsize == (3*10 + 4) * 4
assert_array_equal(r5, np.array(['01234ABCDE6789' * i for i in range(3)] + ['01234ABCDE6789' + '0123456789' * 2]))
def test_replace_broadcasting(self):
a = np.array('0,0,0').view(np.char.chararray)
r1 = a.replace('0', '1', count=np.arange(3))
assert r1.dtype == a.dtype
assert_array_equal(r1, np.array(['0,0,0', '1,0,0', '1,1,0']))
r2 = a.replace('0', [['1'], ['2']], count=np.arange(1, 4))
assert_array_equal(r2, np.array([['1,0,0', '1,1,0', '1,1,1'], ['2,0,0', '2,2,0', '2,2,2']]))
r3 = a.replace(['0', '0,0', '0,0,0'], 'X')
assert_array_equal(r3, np.array(['X,X,X', 'X,0', 'X']))
def test_rjust(self):
assert_(issubclass(self.A.rjust(10).dtype.type, np.bytes_))
C = self.A.rjust([10, 20])
assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
C = self.A.rjust(20, b'#')
assert_(np.all(C.startswith(b'#')))
assert_array_equal(C.endswith(b'#'),
[[False, True], [False, False], [False, False]])
C = np.char.rjust(b'FOO', [[10, 20], [15, 8]])
tgt = [[b' FOO', b' FOO'],
[b' FOO', b' FOO']]
assert_(issubclass(C.dtype.type, np.bytes_))
assert_array_equal(C, tgt)
def test_rpartition(self):
P = self.A.rpartition([b'3', b'M'])
tgt = [[(b'', b'', b' abc '), (b'', b'', b'')],
[(b'12', b'3', b'45'), (b'', b'M', b'ixedCase')],
[(b'123 \t ', b'3', b'45 \0 '), (b'', b'', b'UPPER')]]
assert_(issubclass(P.dtype.type, np.bytes_))
assert_array_equal(P, tgt)
def test_rsplit(self):
A = self.A.rsplit(b'3')
tgt = [[[b' abc '], [b'']],
[[b'12', b'45'], [b'MixedCase']],
[[b'12', b' \t ', b'45 \x00 '], [b'UPPER']]]
assert_(issubclass(A.dtype.type, np.object_))
assert_equal(A.tolist(), tgt)
def test_rstrip(self):
assert_(issubclass(self.A.rstrip().dtype.type, np.bytes_))
tgt = [[b' abc', b''],
[b'12345', b'MixedCase'],
[b'123 \t 345', b'UPPER']]
assert_array_equal(self.A.rstrip(), tgt)
tgt = [[b' abc ', b''],
[b'1234', b'MixedCase'],
[b'123 \t 345 \x00', b'UPP']
]
assert_array_equal(self.A.rstrip([b'5', b'ER']), tgt)
tgt = [[' \u03a3', ''],
['12345', 'MixedCase'],
['123 \t 345', 'UPPER']]
assert_(issubclass(self.B.rstrip().dtype.type, np.str_))
assert_array_equal(self.B.rstrip(), tgt)
def test_strip(self):
tgt = [[b'abc', b''],
[b'12345', b'MixedCase'],
[b'123 \t 345', b'UPPER']]
assert_(issubclass(self.A.strip().dtype.type, np.bytes_))
assert_array_equal(self.A.strip(), tgt)
tgt = [[b' abc ', b''],
[b'234', b'ixedCas'],
[b'23 \t 345 \x00', b'UPP']]
assert_array_equal(self.A.strip([b'15', b'EReM']), tgt)
tgt = [['\u03a3', ''],
['12345', 'MixedCase'],
['123 \t 345', 'UPPER']]
assert_(issubclass(self.B.strip().dtype.type, np.str_))
assert_array_equal(self.B.strip(), tgt)
def test_split(self):
A = self.A.split(b'3')
tgt = [
[[b' abc '], [b'']],
[[b'12', b'45'], [b'MixedCase']],
[[b'12', b' \t ', b'45 \x00 '], [b'UPPER']]]
assert_(issubclass(A.dtype.type, np.object_))
assert_equal(A.tolist(), tgt)
def test_splitlines(self):
A = np.char.array(['abc\nfds\nwer']).splitlines()
assert_(issubclass(A.dtype.type, np.object_))
assert_(A.shape == (1,))
assert_(len(A[0]) == 3)
def test_swapcase(self):
tgt = [[b' ABC ', b''],
[b'12345', b'mIXEDcASE'],
[b'123 \t 345 \0 ', b'upper']]
assert_(issubclass(self.A.swapcase().dtype.type, np.bytes_))
assert_array_equal(self.A.swapcase(), tgt)
tgt = [[' \u03c3 ', ''],
['12345', 'mIXEDcASE'],
['123 \t 345 \0 ', 'upper']]
assert_(issubclass(self.B.swapcase().dtype.type, np.str_))
assert_array_equal(self.B.swapcase(), tgt)
def test_title(self):
tgt = [[b' Abc ', b''],
[b'12345', b'Mixedcase'],
[b'123 \t 345 \0 ', b'Upper']]
assert_(issubclass(self.A.title().dtype.type, np.bytes_))
assert_array_equal(self.A.title(), tgt)
tgt = [[' \u03a3 ', ''],
['12345', 'Mixedcase'],
['123 \t 345 \0 ', 'Upper']]
assert_(issubclass(self.B.title().dtype.type, np.str_))
assert_array_equal(self.B.title(), tgt)
def test_upper(self):
tgt = [[b' ABC ', b''],
[b'12345', b'MIXEDCASE'],
[b'123 \t 345 \0 ', b'UPPER']]
assert_(issubclass(self.A.upper().dtype.type, np.bytes_))
assert_array_equal(self.A.upper(), tgt)
tgt = [[' \u03a3 ', ''],
['12345', 'MIXEDCASE'],
['123 \t 345 \0 ', 'UPPER']]
assert_(issubclass(self.B.upper().dtype.type, np.str_))
assert_array_equal(self.B.upper(), tgt)
def test_isnumeric(self):
def fail():
self.A.isnumeric()
assert_raises(TypeError, fail)
assert_(issubclass(self.B.isnumeric().dtype.type, np.bool))
assert_array_equal(self.B.isnumeric(), [
[False, False], [True, False], [False, False]])
def test_isdecimal(self):
def fail():
self.A.isdecimal()
assert_raises(TypeError, fail)
assert_(issubclass(self.B.isdecimal().dtype.type, np.bool))
assert_array_equal(self.B.isdecimal(), [
[False, False], [True, False], [False, False]])
class TestOperations:
def setup_method(self):
self.A = np.array([['abc', '123'],
['789', 'xyz']]).view(np.char.chararray)
self.B = np.array([['efg', '456'],
['051', 'tuv']]).view(np.char.chararray)
def test_add(self):
AB = np.array([['abcefg', '123456'],
['789051', 'xyztuv']]).view(np.char.chararray)
assert_array_equal(AB, (self.A + self.B))
assert_(len((self.A + self.B)[0][0]) == 6)
def test_radd(self):
QA = np.array([['qabc', 'q123'],
['q789', 'qxyz']]).view(np.char.chararray)
assert_array_equal(QA, ('q' + self.A))
def test_mul(self):
A = self.A
for r in (2, 3, 5, 7, 197):
Ar = np.array([[A[0, 0]*r, A[0, 1]*r],
[A[1, 0]*r, A[1, 1]*r]]).view(np.char.chararray)
assert_array_equal(Ar, (self.A * r))
for ob in [object(), 'qrs']:
with assert_raises_regex(ValueError,
'Can only multiply by integers'):
A*ob
def test_rmul(self):
A = self.A
for r in (2, 3, 5, 7, 197):
Ar = np.array([[A[0, 0]*r, A[0, 1]*r],
[A[1, 0]*r, A[1, 1]*r]]).view(np.char.chararray)
assert_array_equal(Ar, (r * self.A))
for ob in [object(), 'qrs']:
with assert_raises_regex(ValueError,
'Can only multiply by integers'):
ob * A
def test_mod(self):
"""Ticket #856"""
F = np.array([['%d', '%f'], ['%s', '%r']]).view(np.char.chararray)
C = np.array([[3, 7], [19, 1]], dtype=np.int64)
FC = np.array([['3', '7.000000'],
['19', 'np.int64(1)']]).view(np.char.chararray)
assert_array_equal(FC, F % C)
A = np.array([['%.3f', '%d'], ['%s', '%r']]).view(np.char.chararray)
A1 = np.array([['1.000', '1'],
['1', repr(np.array(1)[()])]]).view(np.char.chararray)
assert_array_equal(A1, (A % 1))
A2 = np.array([['1.000', '2'],
['3', repr(np.array(4)[()])]]).view(np.char.chararray)
assert_array_equal(A2, (A % [[1, 2], [3, 4]]))
def test_rmod(self):
assert_(("%s" % self.A) == str(self.A))
assert_(("%r" % self.A) == repr(self.A))
for ob in [42, object()]:
with assert_raises_regex(
TypeError, "unsupported operand type.* and 'chararray'"):
ob % self.A
def test_slice(self):
"""Regression test for https://github.com/numpy/numpy/issues/5982"""
arr = np.array([['abc ', 'def '], ['geh ', 'ijk ']],
dtype='S4').view(np.char.chararray)
sl1 = arr[:]
assert_array_equal(sl1, arr)
assert_(sl1.base is arr)
assert_(sl1.base.base is arr.base)
sl2 = arr[:, :]
assert_array_equal(sl2, arr)
assert_(sl2.base is arr)
assert_(sl2.base.base is arr.base)
assert_(arr[0, 0] == b'abc')
@pytest.mark.parametrize('data', [['plate', ' ', 'shrimp'],
[b'retro', b' ', b'encabulator']])
def test_getitem_length_zero_item(self, data):
a = np.char.array(data)
assert_equal(a[1], a.dtype.type())
class TestMethodsEmptyArray:
def setup_method(self):
self.U = np.array([], dtype='U')
self.S = np.array([], dtype='S')
def test_encode(self):
res = np.char.encode(self.U)
assert_array_equal(res, [])
assert_(res.dtype.char == 'S')
def test_decode(self):
res = np.char.decode(self.S)
assert_array_equal(res, [])
assert_(res.dtype.char == 'U')
def test_decode_with_reshape(self):
res = np.char.decode(self.S.reshape((1, 0, 1)))
assert_(res.shape == (1, 0, 1))
class TestMethodsScalarValues:
def test_mod(self):
A = np.array([[' abc ', ''],
['12345', 'MixedCase'],
['123 \t 345 \0 ', 'UPPER']], dtype='S')
tgt = [[b'123 abc ', b'123'],
[b'12312345', b'123MixedCase'],
[b'123123 \t 345 \0 ', b'123UPPER']]
assert_array_equal(np.char.mod(b"123%s", A), tgt)
def test_decode(self):
bytestring = b'\x81\xc1\x81\xc1\x81\xc1'
assert_equal(np.char.decode(bytestring, encoding='cp037'),
'aAaAaA')
def test_encode(self):
unicode = 'aAaAaA'
assert_equal(np.char.encode(unicode, encoding='cp037'),
b'\x81\xc1\x81\xc1\x81\xc1')
def test_expandtabs(self):
s = "\tone level of indentation\n\t\ttwo levels of indentation"
assert_equal(
np.char.expandtabs(s, tabsize=2),
" one level of indentation\n two levels of indentation"
)
def test_join(self):
seps = np.array(['-', '_'])
assert_array_equal(np.char.join(seps, 'hello'),
['h-e-l-l-o', 'h_e_l_l_o'])
def test_partition(self):
assert_equal(np.char.partition('This string', ' '),
['This', ' ', 'string'])
def test_rpartition(self):
assert_equal(np.char.rpartition('This string here', ' '),
['This string', ' ', 'here'])
def test_replace(self):
assert_equal(np.char.replace('Python is good', 'good', 'great'),
'Python is great')
def test_empty_indexing():
"""Regression test for ticket 1948."""
s = np.char.chararray((4,))
assert_(s[[]].size == 0)
.\numpy\numpy\_core\tests\test_deprecations.py
"""
Tests related to deprecation warnings. Also a convenient place
to document how deprecations should eventually be turned into errors.
"""
import datetime
import operator
import warnings
import pytest
import tempfile
import re
import sys
import numpy as np
from numpy.testing import (
assert_raises, assert_warns, assert_, assert_array_equal, SkipTest,
KnownFailureException, break_cycles, temppath
)
from numpy._core._multiarray_tests import fromstring_null_term_c_api
try:
import pytz
_has_pytz = True
except ImportError:
_has_pytz = False
class _DeprecationTestCase:
message = ''
warning_cls = DeprecationWarning
def setup_method(self):
self.warn_ctx = warnings.catch_warnings(record=True)
self.log = self.warn_ctx.__enter__()
warnings.filterwarnings("always", category=self.warning_cls)
warnings.filterwarnings("always", message=self.message,
category=self.warning_cls)
def teardown_method(self):
self.warn_ctx.__exit__()
def assert_not_deprecated(self, function, args=(), kwargs={}):
"""Test that warnings are not raised.
This is just a shorthand for:
self.assert_deprecated(function, num=0, ignore_others=True,
exceptions=tuple(), args=args, kwargs=kwargs)
"""
self.assert_deprecated(function, num=0, ignore_others=True,
exceptions=tuple(), args=args, kwargs=kwargs)
class _VisibleDeprecationTestCase(_DeprecationTestCase):
warning_cls = np.exceptions.VisibleDeprecationWarning
class TestDTypeAttributeIsDTypeDeprecation(_DeprecationTestCase):
message = r".*`.dtype` attribute"
def test_deprecation_dtype_attribute_is_dtype(self):
class dt:
dtype = "f8"
class vdt(np.void):
dtype = "f,f"
self.assert_deprecated(lambda: np.dtype(dt))
self.assert_deprecated(lambda: np.dtype(dt()))
self.assert_deprecated(lambda: np.dtype(vdt))
self.assert_deprecated(lambda: np.dtype(vdt(1)))
class TestTestDeprecated:
def test_assert_deprecated(self):
test_case_instance = _DeprecationTestCase()
test_case_instance.setup_method()
assert_raises(AssertionError,
test_case_instance.assert_deprecated,
lambda: None)
def foo():
warnings.warn("foo", category=DeprecationWarning, stacklevel=2)
test_case_instance.assert_deprecated(foo)
test_case_instance.teardown_method()
class TestNonNumericConjugate(_DeprecationTestCase):
"""
Deprecate no-op behavior of ndarray.conjugate on non-numeric dtypes,
which conflicts with the error behavior of np.conjugate.
"""
def test_conjugate(self):
for a in np.array(5), np.array(5j):
self.assert_not_deprecated(a.conjugate)
for a in (np.array('s'), np.array('2016', 'M'),
np.array((1, 2), [('a', int), ('b', int)])):
self.assert_deprecated(a.conjugate)
class TestDatetimeEvent(_DeprecationTestCase):
def test_3_tuple(self):
for cls in (np.datetime64, np.timedelta64):
self.assert_not_deprecated(cls, args=(1, ('ms', 2)))
self.assert_not_deprecated(cls, args=(1, ('ms', 2, 1, None)))
self.assert_deprecated(cls, args=(1, ('ms', 2, 'event')))
self.assert_deprecated(cls, args=(1, ('ms', 2, 63)))
self.assert_deprecated(cls, args=(1, ('ms', 2, 1, 'event')))
self.assert_deprecated(cls, args=(1, ('ms', 2, 1, 63)))
class TestTruthTestingEmptyArrays(_DeprecationTestCase):
message = '.*truth value of an empty array is ambiguous.*'
def test_1d(self):
self.assert_deprecated(bool, args=(np.array([]),))
def test_2d(self):
self.assert_deprecated(bool, args=(np.zeros((1, 0)),))
self.assert_deprecated(bool, args=(np.zeros((0, 1)),))
self.assert_deprecated(bool, args=(np.zeros((0, 0)),))
class TestBincount(_DeprecationTestCase):
def test_bincount_minlength(self):
self.assert_deprecated(lambda: np.bincount([1, 2, 3], minlength=None))
class TestGeneratorSum(_DeprecationTestCase):
def test_generator_sum(self):
self.assert_deprecated(np.sum, args=((i for i in range(5)),))
class TestFromstring(_DeprecationTestCase):
def test_fromstring(self):
self.assert_deprecated(np.fromstring, args=('\x00'*80,))
class TestFromStringAndFileInvalidData(_DeprecationTestCase):
message = "string or file could not be read to its end"
@pytest.mark.parametrize("invalid_str", [",invalid_data", "invalid_sep"])
def test_deprecate_unparsable_data_file(self, invalid_str):
x = np.array([1.51, 2, 3.51, 4], dtype=float)
with tempfile.TemporaryFile(mode="w") as f:
x.tofile(f, sep=',', format='%.2f')
f.write(invalid_str)
f.seek(0)
self.assert_deprecated(lambda: np.fromfile(f, sep=","))
f.seek(0)
self.assert_deprecated(lambda: np.fromfile(f, sep=",", count=5))
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
f.seek(0)
res = np.fromfile(f, sep=",", count=4)
assert_array_equal(res, x)
@pytest.mark.parametrize("invalid_str", [",invalid_data", "invalid_sep"])
def test_deprecate_unparsable_string(self, invalid_str):
x = np.array([1.51, 2, 3.51, 4], dtype=float)
x_str = "1.51,2,3.51,4{}".format(invalid_str)
self.assert_deprecated(lambda: np.fromstring(x_str, sep=","))
self.assert_deprecated(lambda: np.fromstring(x_str, sep=",", count=5))
bytestr = x_str.encode("ascii")
self.assert_deprecated(lambda: fromstring_null_term_c_api(bytestr))
with assert_warns(DeprecationWarning):
res = np.fromstring(x_str, sep=",", count=5)
assert_array_equal(res[:-1], x)
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
res = np.fromstring(x_str, sep=",", count=4)
assert_array_equal(res, x)
class TestToString(_DeprecationTestCase):
message = re.escape("tostring() is deprecated. Use tobytes() instead.")
def test_tostring(self):
arr = np.array(list(b"test\xFF"), dtype=np.uint8)
self.assert_deprecated(arr.tostring)
def test_tostring_matches_tobytes(self):
arr = np.array(list(b"test\xFF"), dtype=np.uint8)
b = arr.tobytes()
with assert_warns(DeprecationWarning):
s = arr.tostring()
assert s == b
class TestDTypeCoercion(_DeprecationTestCase):
message = "Converting .* to a dtype .*is deprecated"
deprecated_types = [
np.generic, np.flexible, np.number,
np.inexact, np.floating, np.complexfloating,
np.integer, np.unsignedinteger, np.signedinteger,
np.character,
]
def test_dtype_coercion(self):
for scalar_type in self.deprecated_types:
self.assert_deprecated(np.dtype, args=(scalar_type,))
def test_array_construction(self):
for scalar_type in self.deprecated_types:
self.assert_deprecated(np.array, args=([], scalar_type,))
def test_not_deprecated(self):
for group in np._core.sctypes.values():
for scalar_type in group:
self.assert_not_deprecated(np.dtype, args=(scalar_type,))
for scalar_type in [type, dict, list, tuple]:
self.assert_not_deprecated(np.dtype, args=(scalar_type,))
class BuiltInRoundComplexDType(_DeprecationTestCase):
deprecated_types = [np.csingle, np.cdouble, np.clongdouble]
not_deprecated_types = [
np.int8, np.int16, np.int32, np.int64,
np.uint8, np.uint16, np.uint32, np.uint64,
np.float16, np.float32, np.float64,
]
def test_deprecated(self):
for scalar_type in self.deprecated_types:
scalar = scalar_type(0)
self.assert_deprecated(round, args=(scalar,))
self.assert_deprecated(round, args=(scalar, 0))
self.assert_deprecated(round, args=(scalar,), kwargs={'ndigits': 0})
def test_not_deprecated(self):
for scalar_type in self.not_deprecated_types:
scalar = scalar_type(0)
self.assert_not_deprecated(round, args=(scalar,))
self.assert_not_deprecated(round, args=(scalar, 0))
self.assert_not_deprecated(round, args=(scalar,), kwargs={'ndigits': 0})
class TestIncorrectAdvancedIndexWithEmptyResult(_DeprecationTestCase):
message = "Out of bound index found. This was previously ignored.*"
@pytest.mark.parametrize("index", [([3, 0],), ([0, 0], [3, 0])])
def test_empty_subspace(self, index):
arr = np.ones((2, 2, 0))
self.assert_deprecated(arr.__getitem__, args=(index,))
self.assert_deprecated(arr.__setitem__, args=(index, 0.))
arr2 = np.ones((2, 2, 1))
index2 = (slice(0, 0),) + index
self.assert_deprecated(arr2.__getitem__, args=(index2,))
self.assert_deprecated(arr2.__setitem__, args=(index2, 0.))
def test_empty_index_broadcast_not_deprecated(self):
arr = np.ones((2, 2, 2))
index = ([[3], [2]], [])
self.assert_not_deprecated(arr.__getitem__, args=(index,))
self.assert_not_deprecated(arr.__setitem__,
args=(index, np.empty((2, 0, 2))))
class TestNonExactMatchDeprecation(_DeprecationTestCase):
def test_non_exact_match(self):
arr = np.array([[3, 6, 6], [4, 5, 1]])
self.assert_deprecated(lambda: np.ravel_multi_index(arr, (7, 6), mode='Cilp'))
self.assert_deprecated(lambda: np.searchsorted(arr[0], 4, side='Random'))
class TestMatrixInOuter(_DeprecationTestCase):
message = (r"add.outer\(\) was passed a numpy matrix as "
r"(first|second) argument.")
def test_deprecated(self):
arr = np.array([1, 2, 3])
m = np.array([1, 2, 3]).view(np.matrix)
self.assert_deprecated(np.add.outer, args=(m, m), num=2)
self.assert_deprecated(np.add.outer, args=(arr, m))
self.assert_deprecated(np.add.outer, args=(m, arr))
self.assert_not_deprecated(np.add.outer, args=(arr, arr))
class FlatteningConcatenateUnsafeCast(_DeprecationTestCase):
message = "concatenate with `axis=None` will use same-kind casting"
def test_deprecated(self):
self.assert_deprecated(np.concatenate,
args=(([0.], [1.]),),
kwargs=dict(axis=None, out=np.empty(2, dtype=np.int64)))
def test_not_deprecated(self):
self.assert_not_deprecated(np.concatenate,
args=(([0.], [1.]),),
kwargs={'axis': None, 'out': np.empty(2, dtype=np.int64),
'casting': "unsafe"})
with assert_raises(TypeError):
np.concatenate(([0.], [1.]), out=np.empty(2, dtype=np.int64),
casting="same_kind")
class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase):
"""
技术上,应该不可能创建 numpy 对象标量,但存在一个理论上允许的反序列化路径。该路径无效且必须导致警告。
"""
message = "Unpickling a scalar with object dtype is deprecated."
def test_deprecated(self):
ctor = np._core.multiarray.scalar
self.assert_deprecated(lambda: ctor(np.dtype("O"), 1))
class TestSingleElementSignature(_DeprecationTestCase):
message = r"The use of a length 1"
def test_deprecated(self):
self.assert_deprecated(lambda: np.add(1, 2, signature="d"))
self.assert_deprecated(lambda: np.add(1, 2, sig=(np.dtype("l"),)))
class TestCtypesGetter(_DeprecationTestCase):
warning_cls = DeprecationWarning
ctypes = np.array([1]).ctypes
@pytest.mark.parametrize(
"name", ["get_data", "get_shape", "get_strides", "get_as_parameter"]
)
def test_deprecated(self, name: str) -> None:
func = getattr(self.ctypes, name)
self.assert_deprecated(lambda: func())
@pytest.mark.parametrize(
"name", ["data", "shape", "strides", "_as_parameter_"]
)
def test_not_deprecated(self, name: str) -> None:
self.assert_not_deprecated(lambda: getattr(self.ctypes, name))
PARTITION_DICT = {
"partition method": np.arange(10).partition,
"argpartition method": np.arange(10).argpartition,
"partition function": lambda kth: np.partition(np.arange(10), kth),
"argpartition function": lambda kth: np.argpartition(np.arange(10), kth),
}
@pytest.mark.parametrize("func", PARTITION_DICT.values(), ids=PARTITION_DICT)
class TestPartitionBoolIndex(_DeprecationTestCase):
warning_cls = DeprecationWarning
message = "Passing booleans as partition index is deprecated"
def test_deprecated(self, func):
self.assert_deprecated(lambda: func(True))
self.assert_deprecated(lambda: func([False, True]))
def test_not_deprecated(self, func):
self.assert_not_deprecated(lambda: func(1))
self.assert_not_deprecated(lambda: func([0, 1]))
class TestMachAr(_DeprecationTestCase):
warning_cls = DeprecationWarning
def test_deprecated_module(self):
self.assert_deprecated(lambda: getattr(np._core, "MachAr"))
class TestQuantileInterpolationDeprecation(_DeprecationTestCase):
@pytest.mark.parametrize("func",
[np.percentile, np.quantile, np.nanpercentile, np.nanquantile])
def test_deprecated(self, func):
self.assert_deprecated(
lambda: func([0., 1.], 0., interpolation="linear"))
self.assert_deprecated(
lambda: func([0., 1.], 0., interpolation="nearest"))
@pytest.mark.parametrize("func",
[np.percentile, np.quantile, np.nanpercentile, np.nanquantile])
def test_both_passed(self, func):
with warnings.catch_warnings():
warnings.simplefilter("always", DeprecationWarning)
with pytest.raises(TypeError):
func([0., 1.], 0., interpolation="nearest", method="nearest")
class TestArrayFinalizeNone(_DeprecationTestCase):
message = "Setting __array_finalize__ = None"
def test_use_none_is_deprecated(self):
class NoFinalize(np.ndarray):
__array_finalize__ = None
self.assert_deprecated(lambda: np.array(1).view(NoFinalize))
class TestLoadtxtParseIntsViaFloat(_DeprecationTestCase):
message = r"loadtxt\(\): Parsing an integer via a float is deprecated.*"
@pytest.mark.parametrize("dtype", np.typecodes["AllInteger"])
def test_deprecated_warning(self, dtype):
with pytest.warns(DeprecationWarning, match=self.message):
np.loadtxt(["10.5"], dtype=dtype)
@pytest.mark.parametrize("dtype", np.typecodes["AllInteger"])
def test_deprecated_raised(self, dtype):
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
try:
np.loadtxt(["10.5"], dtype=dtype)
except ValueError as e:
assert isinstance(e.__cause__, DeprecationWarning)
class TestScalarConversion(_DeprecationTestCase):
def test_float_conversion(self):
self.assert_deprecated(float, args=(np.array([3.14]),))
def test_behaviour(self):
b = np.array([[3.14]])
c = np.zeros(5)
with pytest.warns(DeprecationWarning):
c[0] = b
class TestPyIntConversion(_DeprecationTestCase):
message = r".*stop allowing conversion of out-of-bound.*"
@pytest.mark.parametrize("dtype", np.typecodes["AllInteger"])
def test_deprecated_scalar(self, dtype):
dtype = np.dtype(dtype)
info = np.iinfo(dtype)
def scalar(value, dtype):
dtype.type(value)
def assign(value, dtype):
arr = np.array([0, 0, 0], dtype=dtype)
arr[2] = value
def create(value, dtype):
np.array([value], dtype=dtype)
for creation_func in [scalar, assign, create]:
try:
self.assert_deprecated(
lambda: creation_func(info.min - 1, dtype))
except OverflowError:
pass
try:
self.assert_deprecated(
lambda: creation_func(info.max + 1, dtype))
except OverflowError:
pass
@pytest.mark.parametrize("name", ["str", "bytes", "object"])
def test_future_scalar_attributes(name):
assert name not in dir(np)
with pytest.warns(FutureWarning,
match=f"In the future .*{name}"):
assert not hasattr(np, name)
np.dtype(name)
name in np._core.sctypeDict
@pytest.mark.filterwarnings("ignore:In the future:FutureWarning")
class TestRemovedGlobals:
@pytest.mark.parametrize("name",
["object", "float", "complex", "str", "int"])
def test_attributeerror_includes_info(self, name):
msg = f".*\n`np.{name}` was a deprecated alias for the builtin"
with pytest.raises(AttributeError, match=msg):
getattr(np, name)
class TestDeprecatedFinfo(_DeprecationTestCase):
def test_deprecated_none(self):
self.assert_deprecated(np.finfo, args=(None,))
class TestMathAlias(_DeprecationTestCase):
def test_deprecated_np_lib_math(self):
self.assert_deprecated(lambda: np.lib.math)
class TestLibImports(_DeprecationTestCase):
def test_lib_functions_deprecation_call(self):
from numpy.lib._utils_impl import safe_eval
from numpy.lib._npyio_impl import recfromcsv, recfromtxt
from numpy.lib._function_base_impl import disp
from numpy.lib._shape_base_impl import get_array_wrap
from numpy._core.numerictypes import maximum_sctype
from numpy.lib.tests.test_io import TextIO
from numpy import in1d, row_stack, trapz
self.assert_deprecated(lambda: safe_eval("None"))
data_gen = lambda: TextIO('A,B\n0,1\n2,3')
kwargs = dict(delimiter=",", missing_values="N/A", names=True)
self.assert_deprecated(lambda: recfromcsv(data_gen()))
self.assert_deprecated(lambda: recfromtxt(data_gen(), **kwargs))
self.assert_deprecated(lambda: disp("test"))
self.assert_deprecated(lambda: get_array_wrap())
self.assert_deprecated(lambda: maximum_sctype(int))
self.assert_deprecated(lambda: in1d([1], [1]))
self.assert_deprecated(lambda: row_stack([[]]))
self.assert_deprecated(lambda: trapz([1], [1]))
self.assert_deprecated(lambda: np.chararray)
class TestDeprecatedDTypeAliases(_DeprecationTestCase):
def _check_for_warning(self, func):
with warnings.catch_warnings(record=True) as caught_warnings:
func()
assert len(caught_warnings) == 1
w = caught_warnings[0]
assert w.category is DeprecationWarning
assert "alias 'a' was deprecated in NumPy 2.0" in str(w.message)
def test_a_dtype_alias(self):
for dtype in ["a", "a10"]:
f = lambda: np.dtype(dtype)
self._check_for_warning(f)
self.assert_deprecated(f)
f = lambda: np.array(["hello", "world"]).astype("a10")
self._check_for_warning(f)
self.assert_deprecated(f)
class TestDeprecatedArrayWrap(_DeprecationTestCase):
message = "__array_wrap__.*"
def test_deprecated(self):
class Test1:
def __array__(self, dtype=None, copy=None):
return np.arange(4)
def __array_wrap__(self, arr, context=None):
self.called = True
return 'pass context'
class Test2(Test1):
def __array_wrap__(self, arr):
self.called = True
return 'pass'
test1 = Test1()
test2 = Test2()
self.assert_deprecated(lambda: np.negative(test1))
assert test1.called
self.assert_deprecated(lambda: np.negative(test2))
assert test2.called
class TestDeprecatedDTypeParenthesizedRepeatCount(_DeprecationTestCase):
message = "Passing in a parenthesized single number"
@pytest.mark.parametrize("string", ["(2)i,", "(3)3S,", "f,(2)f"])
def test_parenthesized_repeat_count(self, string):
self.assert_deprecated(np.dtype, args=(string,))
class TestDeprecatedSaveFixImports(_DeprecationTestCase):
message = "The 'fix_imports' flag is deprecated and has no effect."
def test_deprecated(self):
with temppath(suffix='.npy') as path:
sample_args = (path, np.array(np.zeros((1024, 10))))
self.assert_not_deprecated(np.save, args=sample_args)
self.assert_deprecated(np.save, args=sample_args,
kwargs={'fix_imports': True})
self.assert_deprecated(np.save, args=sample_args,
kwargs={'fix_imports': False})
for allow_pickle in [True, False]:
self.assert_not_deprecated(np.save, args=sample_args,
kwargs={'allow_pickle': allow_pickle})
self.assert_deprecated(np.save, args=sample_args,
kwargs={'allow_pickle': allow_pickle,
'fix_imports': True})
self.assert_deprecated(np.save, args=sample_args,
kwargs={'allow_pickle': allow_pickle,
'fix_imports': False})
.\numpy\numpy\_core\tests\test_dlpack.py
import sys
import pytest
import numpy as np
from numpy.testing import assert_array_equal, IS_PYPY
def new_and_old_dlpack():
yield np.arange(5)
class OldDLPack(np.ndarray):
def __dlpack__(self, stream=None):
return super().__dlpack__(stream=None)
yield np.arange(5).view(OldDLPack)
class TestDLPack:
@pytest.mark.skipif(IS_PYPY, reason="PyPy can't get refcounts.")
@pytest.mark.parametrize("max_version", [(0, 0), None, (1, 0), (100, 3)])
def test_dunder_dlpack_refcount(self, max_version):
x = np.arange(5)
y = x.__dlpack__(max_version=max_version)
assert sys.getrefcount(x) == 3
del y
assert sys.getrefcount(x) == 2
def test_dunder_dlpack_stream(self):
x = np.arange(5)
x.__dlpack__(stream=None)
with pytest.raises(RuntimeError):
x.__dlpack__(stream=1)
def test_dunder_dlpack_copy(self):
x = np.arange(5)
x.__dlpack__(copy=True)
x.__dlpack__(copy=None)
x.__dlpack__(copy=False)
with pytest.raises(ValueError):
x.__dlpack__(copy=np.array([1, 2, 3]))
def test_strides_not_multiple_of_itemsize(self):
dt = np.dtype([('int', np.int32), ('char', np.int8)])
y = np.zeros((5,), dtype=dt)
z = y['int']
with pytest.raises(BufferError):
np.from_dlpack(z)
@pytest.mark.skipif(IS_PYPY, reason="PyPy can't get refcounts.")
@pytest.mark.parametrize("arr", new_and_old_dlpack())
def test_from_dlpack_refcount(self, arr):
arr = arr.copy()
y = np.from_dlpack(arr)
assert sys.getrefcount(arr) == 3
del y
assert sys.getrefcount(arr) == 2
@pytest.mark.parametrize("dtype", [
np.bool,
np.int8, np.int16, np.int32, np.int64,
np.uint8, np.uint16, np.uint32, np.uint64,
np.float16, np.float32, np.float64,
np.complex64, np.complex128
])
@pytest.mark.parametrize("arr", new_and_old_dlpack())
def test_dtype_passthrough(self, arr, dtype):
x = arr.astype(dtype)
y = np.from_dlpack(x)
assert y.dtype == x.dtype
assert_array_equal(x, y)
def test_invalid_dtype(self):
x = np.asarray(np.datetime64('2021-05-27'))
with pytest.raises(BufferError):
np.from_dlpack(x)
def test_invalid_byte_swapping(self):
dt = np.dtype('=i8').newbyteorder()
x = np.arange(5, dtype=dt)
with pytest.raises(BufferError):
np.from_dlpack(x)
def test_non_contiguous(self):
x = np.arange(25).reshape((5, 5))
y1 = x[0]
assert_array_equal(y1, np.from_dlpack(y1))
y2 = x[:, 0]
assert_array_equal(y2, np.from_dlpack(y2))
y3 = x[1, :]
assert_array_equal(y3, np.from_dlpack(y3))
y4 = x[1]
assert_array_equal(y4, np.from_dlpack(y4))
y5 = np.diagonal(x).copy()
assert_array_equal(y5, np.from_dlpack(y5))
@pytest.mark.parametrize("ndim", range(33))
def test_higher_dims(self, ndim):
shape = (1,) * ndim
x = np.zeros(shape, dtype=np.float64)
assert shape == np.from_dlpack(x).shape
def test_dlpack_device(self):
x = np.arange(5)
assert x.__dlpack_device__() == (1, 0)
y = np.from_dlpack(x)
assert y.__dlpack_device__() == (1, 0)
z = y[::2]
assert z.__dlpack_device__() == (1, 0)
def dlpack_deleter_exception(self, max_version):
x = np.arange(5)
_ = x.__dlpack__(max_version=max_version)
raise RuntimeError
@pytest.mark.parametrize("max_version", [None, (1, 0)])
def test_dlpack_destructor_exception(self, max_version):
with pytest.raises(RuntimeError):
self.dlpack_deleter_exception(max_version=max_version)
def test_readonly(self):
x = np.arange(5)
x.flags.writeable = False
with pytest.raises(BufferError):
x.__dlpack__()
y = np.from_dlpack(x)
assert not y.flags.writeable
def test_ndim0(self):
x = np.array(1.0)
y = np.from_dlpack(x)
assert_array_equal(x, y)
def test_size1dims_arrays(self):
x = np.ndarray(dtype='f8', shape=(10, 5, 1), strides=(8, 80, 4),
buffer=np.ones(1000, dtype=np.uint8), order='F')
y = np.from_dlpack(x)
assert_array_equal(x, y)
def test_copy(self):
x = np.arange(5)
y = np.from_dlpack(x)
assert np.may_share_memory(x, y)
y = np.from_dlpack(x, copy=False)
assert np.may_share_memory(x, y)
y = np.from_dlpack(x, copy=True)
assert not np.may_share_memory(x, y)
def test_device(self):
x = np.arange(5)
x.__dlpack__(dl_device=(1, 0))
np.from_dlpack(x, device="cpu")
np.from_dlpack(x, device=None)
with pytest.raises(ValueError):
x.__dlpack__(dl_device=(10, 0))
with pytest.raises(ValueError):
np.from_dlpack(x, device="gpu")
.\numpy\numpy\_core\tests\test_dtype.py
import sys
import operator
import pytest
import ctypes
import gc
import types
import pickle
import numpy as np
import numpy.dtypes
from numpy._core._rational_tests import rational
from numpy._core._multiarray_tests import create_custom_field_dtype
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_raises, HAS_REFCOUNT,
IS_PYSTON, _OLD_PROMOTION)
from itertools import permutations
import random
import hypothesis
from hypothesis.extra import numpy as hynp
def assert_dtype_equal(a, b):
assert_equal(a, b)
assert_equal(hash(a), hash(b),
"two equivalent types do not hash to the same value !")
def assert_dtype_not_equal(a, b):
assert_(a != b)
assert_(hash(a) != hash(b),
"two different types hash to the same value !")
class TestBuiltin:
@pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object])
def test_run(self, t):
"""Only test hash runs at all."""
dt = np.dtype(t)
hash(dt)
@pytest.mark.parametrize('t', [int, float])
def test_dtype(self, t):
dt = np.dtype(t)
dt2 = dt.newbyteorder("<")
dt3 = dt.newbyteorder(">")
if dt == dt2:
assert_(dt.byteorder != dt2.byteorder, "bogus test")
assert_dtype_equal(dt, dt2)
else:
assert_(dt.byteorder != dt3.byteorder, "bogus test")
assert_dtype_equal(dt, dt3)
def test_equivalent_dtype_hashing(self):
uintp = np.dtype(np.uintp)
if uintp.itemsize == 4:
left = uintp
right = np.dtype(np.uint32)
else:
left = uintp
right = np.dtype(np.ulonglong)
assert_(left == right)
assert_(hash(left) == hash(right))
def test_invalid_types(self):
assert_raises(TypeError, np.dtype, 'O3')
assert_raises(TypeError, np.dtype, 'O5')
assert_raises(TypeError, np.dtype, 'O7')
assert_raises(TypeError, np.dtype, 'b3')
assert_raises(TypeError, np.dtype, 'h4')
assert_raises(TypeError, np.dtype, 'I5')
assert_raises(TypeError, np.dtype, 'e3')
assert_raises(TypeError, np.dtype, 'f5')
if np.dtype('g').itemsize == 8 or np.dtype('g').itemsize == 16:
assert_raises(TypeError, np.dtype, 'g12')
elif np.dtype('g').itemsize == 12:
assert_raises(TypeError, np.dtype, 'g16')
if np.dtype('l').itemsize == 8:
assert_raises(TypeError, np.dtype, 'l4')
assert_raises(TypeError, np.dtype, 'L4')
else:
assert_raises(TypeError, np.dtype, 'l8')
assert_raises(TypeError, np.dtype, 'L8')
if np.dtype('q').itemsize == 8:
assert_raises(TypeError, np.dtype, 'q4')
assert_raises(TypeError, np.dtype, 'Q4')
else:
assert_raises(TypeError, np.dtype, 'q8')
assert_raises(TypeError, np.dtype, 'Q8')
assert_raises(TypeError, np.dtype, 'S-1')
assert_raises(TypeError, np.dtype, 'U-1')
assert_raises(TypeError, np.dtype, 'V-1')
def test_richcompare_invalid_dtype_equality(self):
assert not np.dtype(np.int32) == 7, "dtype richcompare failed for =="
assert np.dtype(np.int32) != 7, "dtype richcompare failed for !="
@pytest.mark.parametrize(
'operation',
[operator.le, operator.lt, operator.ge, operator.gt])
def test_richcompare_invalid_dtype_comparison(self, operation):
with pytest.raises(TypeError):
operation(np.dtype(np.int32), 7)
@pytest.mark.parametrize("dtype",
['Bool', 'Bytes0', 'Complex32', 'Complex64',
'Datetime64', 'Float16', 'Float32', 'Float64',
'Int8', 'Int16', 'Int32', 'Int64',
'Object0', 'Str0', 'Timedelta64',
'UInt8', 'UInt16', 'Uint32', 'UInt32',
'Uint64', 'UInt64', 'Void0',
"Float128", "Complex128"])
def test_numeric_style_types_are_invalid(self, dtype):
with assert_raises(TypeError):
np.dtype(dtype)
def test_expired_dtypes_with_bad_bytesize(self):
match: str = r".*removed in NumPy 2.0.*"
with pytest.raises(TypeError, match=match):
np.dtype("int0")
with pytest.raises(TypeError, match=match):
np.dtype("uint0")
with pytest.raises(TypeError, match=match):
np.dtype("bool8")
with pytest.raises(TypeError, match=match):
np.dtype("bytes0")
with pytest.raises(TypeError, match=match):
np.dtype("str0")
with pytest.raises(TypeError, match=match):
np.dtype("object0")
with pytest.raises(TypeError, match=match):
np.dtype("void0")
@pytest.mark.parametrize(
'value',
['m8', 'M8', 'datetime64', 'timedelta64',
'i4, (2,3)f8, f4', 'S3, 3u8, (3,4)S10',
'>f', '<f', '=f', '|f',
])
def test_dtype_bytes_str_equivalence(self, value):
bytes_value = value.encode('ascii')
from_bytes = np.dtype(bytes_value)
from_str = np.dtype(value)
assert_dtype_equal(from_bytes, from_str)
def test_dtype_from_bytes(self):
assert_raises(TypeError, np.dtype, b'')
assert_raises(TypeError, np.dtype, b'|')
assert_dtype_equal(np.dtype(bytes([0])), np.dtype('bool'))
assert_dtype_equal(np.dtype(bytes([17])), np.dtype(object))
assert_dtype_equal(np.dtype(b'f'), np.dtype('float32'))
assert_raises(TypeError, np.dtype, b'\xff')
assert_raises(TypeError, np.dtype, b's\xff')
def test_bad_param(self):
assert_raises(ValueError, np.dtype,
{'names':['f0', 'f1'],
'formats':['i4', 'i1'],
'offsets':[0, 4],
'itemsize':4})
assert_raises(ValueError, np.dtype,
{'names':['f0', 'f1'],
'formats':['i4', 'i1'],
'offsets':[0, 4],
'itemsize':9}, align=True)
assert_raises(ValueError, np.dtype,
{'names':['f0', 'f1'],
'formats':['i1', 'f4'],
'offsets':[0, 2]}, align=True)
def test_field_order_equality(self):
x = np.dtype({'names': ['A', 'B'],
'formats': ['i4', 'f4'],
'offsets': [0, 4]})
y = np.dtype({'names': ['B', 'A'],
'formats': ['i4', 'f4'],
'offsets': [4, 0]})
assert_equal(x == y, False)
assert np.can_cast(x, y, casting="safe")
@pytest.mark.parametrize(
["type_char", "char_size", "scalar_type"],
[["U", 4, np.str_],
["S", 1, np.bytes_]])
def test_create_string_dtypes_directly(
self, type_char, char_size, scalar_type):
dtype_class = type(np.dtype(type_char))
dtype = dtype_class(8)
assert dtype.type is scalar_type
assert dtype.itemsize == 8*char_size
def test_create_invalid_string_errors(self):
one_too_big = np.iinfo(np.intc).max + 1
with pytest.raises(TypeError):
type(np.dtype("U"))(one_too_big // 4)
with pytest.raises(TypeError):
type(np.dtype("U"))(np.iinfo(np.intp).max // 4 + 1)
if one_too_big < sys.maxsize:
with pytest.raises(TypeError):
type(np.dtype("S"))(one_too_big)
with pytest.raises(ValueError):
type(np.dtype("U"))(-1)
with pytest.raises((TypeError, OverflowError)):
type(np.dtype("S"))(2**61)
with pytest.raises(TypeError):
np.dtype("S1234hello")
def test_leading_zero_parsing(self):
dt1 = np.dtype('S010')
dt2 = np.dtype('S10')
assert dt1 == dt2
assert repr(dt1) == "dtype('S10')"
assert dt1.itemsize == 10
class TestRecord:
def test_equivalent_record(self):
"""Test whether equivalent record dtypes hash the same."""
a = np.dtype([('yo', int)])
b = np.dtype([('yo', int)])
assert_dtype_equal(a, b)
def test_different_names(self):
a = np.dtype([('yo', int)])
b = np.dtype([('ye', int)])
assert_dtype_not_equal(a, b)
def test_different_titles(self):
a = np.dtype({'names': ['r', 'b'],
'formats': ['u1', 'u1'],
'titles': ['Red pixel', 'Blue pixel']})
b = np.dtype({'names': ['r', 'b'],
'formats': ['u1', 'u1'],
'titles': ['RRed pixel', 'Blue pixel']})
assert_dtype_not_equal(a, b)
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
def test_refcount_dictionary_setting(self):
names = ["name1"]
formats = ["f8"]
titles = ["t1"]
offsets = [0]
d = dict(names=names, formats=formats, titles=titles, offsets=offsets)
refcounts = {k: sys.getrefcount(i) for k, i in d.items()}
np.dtype(d)
refcounts_new = {k: sys.getrefcount(i) for k, i in d.items()}
assert refcounts == refcounts_new
def test_mutate(self):
a = np.dtype([('yo', int)])
b = np.dtype([('yo', int)])
c = np.dtype([('ye', int)])
assert_dtype_equal(a, b)
assert_dtype_not_equal(a, c)
a.names = ['ye']
assert_dtype_equal(a, c)
assert_dtype_not_equal(a, b)
state = b.__reduce__()[2]
a.__setstate__(state)
assert_dtype_equal(a, b)
assert_dtype_not_equal(a, c)
def test_init_simple_structured(self):
dt1 = np.dtype("i, i")
assert dt1.names == ("f0", "f1")
dt2 = np.dtype("i,")
assert dt2.names == ("f0",)
def test_mutate_error(self):
a = np.dtype("i,i")
with pytest.raises(ValueError, match="must replace all names at once"):
a.names = ["f0"]
with pytest.raises(ValueError, match=".*and not string"):
a.names = ["f0", b"not a unicode name"]
def test_not_lists(self):
"""Test if an appropriate exception is raised when passing bad values to
the dtype constructor.
"""
assert_raises(TypeError, np.dtype,
dict(names={'A', 'B'}, formats=['f8', 'i4']))
assert_raises(TypeError, np.dtype,
dict(names=['A', 'B'], formats={'f8', 'i4'}))
def test_aligned_size(self):
dt = np.dtype('i4, i1', align=True)
assert_equal(dt.itemsize, 8)
dt = np.dtype([('f0', 'i4'), ('f1', 'i1')], align=True)
assert_equal(dt.itemsize, 8)
dt = np.dtype({'names':['f0', 'f1'],
'formats':['i4', 'u1'],
'offsets':[0, 4]}, align=True)
assert_equal(dt.itemsize, 8)
dt = np.dtype({'f0': ('i4', 0), 'f1':('u1', 4)}, align=True)
assert_equal(dt.itemsize, 8)
dt1 = np.dtype([('f0', 'i4'),
('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
('f2', 'i1')], align=True)
assert_equal(dt1.itemsize, 20)
dt2 = np.dtype({'names':['f0', 'f1', 'f2'],
'formats':['i4',
[('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
'i1'],
'offsets':[0, 4, 16]}, align=True)
assert_equal(dt2.itemsize, 20)
dt3 = np.dtype({'f0': ('i4', 0),
'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
'f2': ('i1', 16)}, align=True)
assert_equal(dt3.itemsize, 20)
assert_equal(dt1, dt2)
assert_equal(dt2, dt3)
dt1 = np.dtype([('f0', 'i4'),
('f1', [('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')]),
('f2', 'i1')], align=False)
assert_equal(dt1.itemsize, 11)
dt2 = np.dtype({'names':['f0', 'f1', 'f2'],
'formats':['i4',
[('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')],
'i1'],
'offsets':[0, 4, 10]}, align=False)
assert_equal(dt2.itemsize, 11)
dt3 = np.dtype({'f0': ('i4', 0),
'f1': ([('f1', 'i1'), ('f2', 'i4'), ('f3', 'i1')], 4),
'f2': ('i1', 10)}, align=False)
assert_equal(dt3.itemsize, 11)
assert_equal(dt1, dt2)
assert_equal(dt2, dt3)
dt1 = np.dtype([('a', '|i1'),
('b', [('f0', '<i2'),
('f1', '<f4')], 2)], align=True)
assert_equal(dt1.descr, [('a', '|i1'), ('', '|V3'),
('b', [('f0', '<i2'), ('', '|V2'),
('f1', '<f4')], (2,))])
def test_empty_struct_alignment(self):
dt = np.dtype([], align=True)
assert_equal(dt.alignment, 1)
dt = np.dtype([('f0', [])], align=True)
assert_equal(dt.alignment, 1)
dt = np.dtype({'names': [],
'formats': [],
'offsets': []}, align=True)
assert_equal(dt.alignment, 1)
dt = np.dtype({'names': ['f0'],
'formats': [[]],
'offsets': [0]}, align=True)
assert_equal(dt.alignment, 1)
def test_union_struct(self):
dt = np.dtype({'names':['f0', 'f1', 'f2'], 'formats':['<u4', '<u2', '<u2'],
'offsets':[0, 0, 2]}, align=True)
assert_equal(dt.itemsize, 4)
a = np.array([3], dtype='<u4').view(dt)
a['f1'] = 10
a['f2'] = 36
assert_equal(a['f0'], 10 + 36*256*256)
dt = np.dtype({'names':['f0', 'f1', 'f2'], 'formats':['<u4', '<u2', '<u2'],
'offsets':[4, 0, 2]}, align=True)
assert_equal(dt.itemsize, 8)
dt2 = np.dtype({'names':['f2', 'f0', 'f1'],
'formats':['<u4', '<u2', '<u2'],
'offsets':[4, 0, 2]}, align=True)
vals = [(0, 1, 2), (3, 2**15-1, 4)]
vals2 = [(0, 1, 2), (3, 2**15-1, 4)]
a = np.array(vals, dt)
b = np.array(vals2, dt2)
assert_equal(a.astype(dt2), b)
assert_equal(b.astype(dt), a)
assert_equal(a.view(dt2), b)
assert_equal(b.view(dt), a)
assert_raises(TypeError, np.dtype,
{'names':['f0', 'f1'],
'formats':['O', 'i1'],
'offsets':[0, 2]})
assert_raises(TypeError, np.dtype,
{'names':['f0', 'f1'],
'formats':['i4', 'O'],
'offsets':[0, 3]})
assert_raises(TypeError, np.dtype,
{'names':['f0', 'f1'],
'formats':[[('a', 'O')], 'i1'],
'offsets':[0, 2]})
assert_raises(TypeError, np.dtype,
{'names':['f0', 'f1'],
'formats':['i4', [('a', 'O')]],
'offsets':[0, 3]})
dt = np.dtype({'names':['f0', 'f1'],
'formats':['i1', 'O'],
'offsets':[np.dtype('intp').itemsize, 0]})
def test_subarray_list(self, obj, dtype, expected):
dtype = np.dtype(dtype)
res = np.array(obj, dtype=dtype)
if expected is None:
expected = np.empty(len(obj), dtype=dtype)
for i in range(len(expected)):
expected[i] = obj[i]
assert_array_equal(res, expected)
def test_parenthesized_single_number(self):
with pytest.raises(TypeError, match="not understood"):
np.dtype("(2)f4")
with pytest.warns(DeprecationWarning,
match="parenthesized single number"):
np.dtype("(2)f4,")
def test_comma_datetime(self):
dt = np.dtype('M8[D],datetime64[Y],i8')
assert_equal(dt, np.dtype([('f0', 'M8[D]'),
('f1', 'datetime64[Y]'),
('f2', 'i8')]))
def test_from_dictproxy(self):
dt = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'f4']})
assert_dtype_equal(dt, np.dtype(dt.fields))
dt2 = np.dtype((np.void, dt.fields))
assert_equal(dt2.fields, dt.fields)
def test_from_dict_with_zero_width_field(self):
dt = np.dtype([('val1', np.float32, (0,)), ('val2', int)])
dt2 = np.dtype({'names': ['val1', 'val2'],
'formats': [(np.float32, (0,)), int]})
assert_dtype_equal(dt, dt2)
assert_equal(dt.fields['val1'][0].itemsize, 0)
assert_equal(dt.itemsize, dt.fields['val2'][0].itemsize)
def test_bool_commastring(self):
d = np.dtype('?,?,?')
assert_equal(len(d.names), 3)
for n in d.names:
assert_equal(d.fields[n][0], np.dtype('?'))
def test_nonint_offsets(self):
def make_dtype(off):
return np.dtype({'names': ['A'], 'formats': ['i4'],
'offsets': [off]})
assert_raises(TypeError, make_dtype, 'ASD')
assert_raises(OverflowError, make_dtype, 2**70)
assert_raises(TypeError, make_dtype, 2.3)
assert_raises(ValueError, make_dtype, -10)
dt = make_dtype(np.uint32(0))
np.zeros(1, dtype=dt)[0].item()
def test_fields_by_index(self):
dt = np.dtype([('a', np.int8), ('b', np.float32, 3)])
assert_dtype_equal(dt[0], np.dtype(np.int8))
assert_dtype_equal(dt[1], np.dtype((np.float32, 3)))
assert_dtype_equal(dt[-1], dt[1])
assert_dtype_equal(dt[-2], dt[0])
assert_raises(IndexError, lambda: dt[-3])
assert_raises(TypeError, operator.getitem, dt, 3.0)
assert_equal(dt[1], dt[np.int8(1)])
@pytest.mark.parametrize('align_flag',[False, True])
def test_multifield_index(self, align_flag):
dt = np.dtype([
(('title', 'col1'), '<U20'), ('A', '<f8'), ('B', '<f8')
], align=align_flag)
dt_sub = dt[['B', 'col1']]
assert_equal(
dt_sub,
np.dtype({
'names': ['B', 'col1'],
'formats': ['<f8', '<U20'],
'offsets': [88, 0],
'titles': [None, 'title'],
'itemsize': 96
})
)
assert_equal(dt_sub.isalignedstruct, align_flag)
dt_sub = dt[['B']]
assert_equal(
dt_sub,
np.dtype({
'names': ['B'],
'formats': ['<f8'],
'offsets': [88],
'itemsize': 96
})
)
assert_equal(dt_sub.isalignedstruct, align_flag)
dt_sub = dt[[]]
assert_equal(
dt_sub,
np.dtype({
'names': [],
'formats': [],
'offsets': [],
'itemsize': 96
})
)
assert_equal(dt_sub.isalignedstruct, align_flag)
assert_raises(TypeError, operator.getitem, dt, ())
assert_raises(TypeError, operator.getitem, dt, [1, 2, 3])
assert_raises(TypeError, operator.getitem, dt, ['col1', 2])
assert_raises(KeyError, operator.getitem, dt, ['fake'])
assert_raises(KeyError, operator.getitem, dt, ['title'])
assert_raises(ValueError, operator.getitem, dt, ['col1', 'col1'])
def test_partial_dict(self):
assert_raises(ValueError, np.dtype,
{'formats': ['i4', 'i4'], 'f0': ('i4', 0), 'f1':('i4', 4)})
def test_fieldless_views(self):
a = np.zeros(2, dtype={'names':[], 'formats':[], 'offsets':[],
'itemsize':8})
assert_raises(ValueError, a.view, np.dtype([]))
d = np.dtype((np.dtype([]), 10))
assert_equal(d.shape, (10,))
assert_equal(d.itemsize, 0)
assert_equal(d.base, np.dtype([]))
arr = np.fromiter((() for i in range(10)), [])
assert_equal(arr.dtype, np.dtype([]))
assert_raises(ValueError, np.frombuffer, b'', dtype=[])
assert_equal(np.frombuffer(b'', dtype=[], count=2),
np.empty(2, dtype=[]))
assert_raises(ValueError, np.dtype, ([], 'f8'))
assert_raises(ValueError, np.zeros(1, dtype='i4').view, [])
assert_equal(np.zeros(2, dtype=[]) == np.zeros(2, dtype=[]),
np.ones(2, dtype=bool))
assert_equal(np.zeros((1, 2), dtype=[]) == a,
np.ones((1, 2), dtype=bool))
def test_nonstructured_with_object(self):
arr = np.recarray((0,), dtype="O")
assert arr.dtype.names is None
assert arr.dtype.hasobject
del arr
class TestSubarray:
def test_single_subarray(self):
a = np.dtype((int, (2)))
b = np.dtype((int, (2,)))
assert_dtype_equal(a, b)
assert_equal(type(a.subdtype[1]), tuple)
assert_equal(type(b.subdtype[1]), tuple)
def test_equivalent_record(self):
"""Test whether equivalent subarray dtypes hash the same."""
a = np.dtype((int, (2, 3)))
b = np.dtype((int, (2, 3)))
assert_dtype_equal(a, b)
def test_nonequivalent_record(self):
"""Test whether different subarray dtypes hash differently."""
a = np.dtype((int, (2, 3)))
b = np.dtype((int, (3, 2)))
assert_dtype_not_equal(a, b)
a = np.dtype((int, (2, 3)))
b = np.dtype((int, (2, 2)))
assert_dtype_not_equal(a, b)
a = np.dtype((int, (1, 2, 3)))
b = np.dtype((int, (1, 2)))
assert_dtype_not_equal(a, b)
def test_shape_equal(self):
"""Test some data types that are equal"""
assert_dtype_equal(np.dtype('f8'), np.dtype(('f8', tuple())))
assert_dtype_equal(np.dtype('(1,)f8'), np.dtype(('f8', 1)))
assert np.dtype(('f8', 1)).shape == (1,)
assert_dtype_equal(np.dtype((int, 2)), np.dtype((int, (2,))))
assert_dtype_equal(np.dtype(('<f4', (3, 2))), np.dtype(('<f4', (3, 2))))
d = ([('a', 'f4', (1, 2)), ('b', 'f8', (3, 1))], (3, 2))
assert_dtype_equal(np.dtype(d), np.dtype(d))
def test_shape_simple(self):
"""Test some simple cases that shouldn't be equal"""
assert_dtype_not_equal(np.dtype('f8'), np.dtype(('f8', (1,))))
assert_dtype_not_equal(np.dtype(('f8', (1,))), np.dtype(('f8', (1, 1))))
assert_dtype_not_equal(np.dtype(('f4', (3, 2))), np.dtype(('f4', (2, 3))))
def test_shape_monster(self):
"""Test some more complicated cases that shouldn't be equal"""
assert_dtype_not_equal(
np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
np.dtype(([('a', 'f4', (1, 2)), ('b', 'f8', (1, 3))], (2, 2))))
assert_dtype_not_equal(
np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
np.dtype(([('a', 'f4', (2, 1)), ('b', 'i8', (1, 3))], (2, 2))))
assert_dtype_not_equal(
np.dtype(([('a', 'f4', (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
np.dtype(([('e', 'f8', (1, 3)), ('d', 'f4', (2, 1))], (2, 2))))
assert_dtype_not_equal(
np.dtype(([('a', [('a', 'i4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))),
np.dtype(([('a', [('a', 'u4', 6)], (2, 1)), ('b', 'f8', (1, 3))], (2, 2))))
def test_shape_sequence(self):
a = np.array([1, 2, 3], dtype=np.int16)
l = [1, 2, 3]
dt = np.dtype([('a', 'f4', a)])
assert_(isinstance(dt['a'].shape, tuple))
assert_(isinstance(dt['a'].shape[0], int))
dt = np.dtype([('a', 'f4', l)])
assert_(isinstance(dt['a'].shape, tuple))
class IntLike:
def __index__(self):
return 3
def __int__(self):
return 3
dt = np.dtype([('a', 'f4', IntLike())])
assert_(isinstance(dt['a'].shape, tuple))
assert_(isinstance(dt['a'].shape[0], int))
dt = np.dtype([('a', 'f4', (IntLike(),))])
assert_(isinstance(dt['a'].shape, tuple))
assert_(isinstance(dt['a'].shape[0], int))
def test_shape_matches_ndim(self):
dt = np.dtype([('a', 'f4', ())])
assert_equal(dt['a'].shape, ())
assert_equal(dt['a'].ndim, 0)
dt = np.dtype([('a', 'f4')])
assert_equal(dt['a'].shape, ())
assert_equal(dt['a'].ndim, 0)
dt = np.dtype([('a', 'f4', 4)])
assert_equal(dt['a'].shape, (4,))
assert_equal(dt['a'].ndim, 1)
dt = np.dtype([('a', 'f4', (1, 2, 3))])
assert_equal(dt['a'].shape, (1, 2, 3))
assert_equal(dt['a'].ndim, 3)
def test_shape_invalid(self):
max_int = np.iinfo(np.intc).max
max_intp = np.iinfo(np.intp).max
assert_raises(ValueError, np.dtype, [('a', 'f4', max_int // 4 + 1)])
assert_raises(ValueError, np.dtype, [('a', 'f4', max_int + 1)])
assert_raises(ValueError, np.dtype, [('a', 'f4', (max_int, 2))])
assert_raises(ValueError, np.dtype, [('a', 'f4', max_intp + 1)])
assert_raises(ValueError, np.dtype, [('a', 'f4', -1)])
assert_raises(ValueError, np.dtype, [('a', 'f4', (-1, -1))])
def test_alignment(self):
t1 = np.dtype('(1,)i4', align=True)
t2 = np.dtype('2i4', align=True)
assert_equal(t1.alignment, t2.alignment)
def test_aligned_empty(self):
dt = np.dtype([], align=True)
assert dt == np.dtype([])
dt = np.dtype({"names": [], "formats": [], "itemsize": 0}, align=True)
assert dt == np.dtype([])
def test_subarray_base_item(self):
arr = np.ones(3, dtype=[("f", "i", 3)])
assert arr["f"].base is arr
item = arr.item(0)
assert type(item) is tuple and len(item) == 1
assert item[0].base is arr
def test_subarray_cast_copies(self):
arr = np.ones(3, dtype=[("f", "i", 3)])
cast = arr.astype(object)
for fields in cast:
assert type(fields) == tuple and len(fields) == 1
subarr = fields[0]
assert subarr.base is None
assert subarr.flags.owndata
def iter_struct_object_dtypes():
"""
Iterates over a few complex dtypes and object pattern which
fill the array with a given object (defaults to a singleton).
Yields
------
dtype : dtype
Data type for NumPy arrays.
pattern : tuple
Structured tuple for use with `np.array`.
count : int
Number of objects stored in the dtype.
singleton : object
A singleton object. The returned pattern is constructed so that
all objects inside the datatype are set to the singleton.
"""
obj = object()
dt = np.dtype([('b', 'O', (2, 3))])
p = ([[obj] * 3] * 2,)
yield pytest.param(dt, p, 6, obj, id="<subarray>")
dt = np.dtype([('a', 'i4'), ('b', 'O', (2, 3))])
p = (0, [[obj] * 3] * 2)
yield pytest.param(dt, p, 6, obj, id="<subarray in field>")
dt = np.dtype([('a', 'i4'),
('b', [('ba', 'O'), ('bb', 'i1')], (2, 3))])
p = (0, [[(obj, 0)] * 3] * 2)
yield pytest.param(dt, p, 6, obj, id="<structured subarray 1>")
dt = np.dtype([('a', 'i4'),
('b', [('ba', 'O'), ('bb', 'O')], (2, 3))])
p = (0, [[(obj, obj)] * 3] * 2)
yield pytest.param(dt, p, 12, obj, id="<structured subarray 2>")
@pytest.mark.skipif(
sys.version_info >= (3, 12),
reason="Python 3.12 has immortal refcounts, this test will no longer "
"work. See gh-23986"
)
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
class TestStructuredObjectRefcounting:
"""These tests cover various uses of complicated structured types which
include objects and thus require reference counting.
"""
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
iter_struct_object_dtypes())
@pytest.mark.parametrize(["creation_func", "creation_obj"], [
pytest.param(np.empty, None,
marks=pytest.mark.skip("unreliable due to python's behaviour")),
(np.ones, 1),
(np.zeros, 0)])
def test_structured_object_create_delete(self, dt, pat, count, singleton,
creation_func, creation_obj):
"""Structured object reference counting in creation and deletion"""
gc.collect()
before = sys.getrefcount(creation_obj)
arr = creation_func(3, dt)
now = sys.getrefcount(creation_obj)
assert now - before == count * 3
del arr
now = sys.getrefcount(creation_obj)
assert now == before
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
iter_struct_object_dtypes())
def test_structured_object_item_setting(self, dt, pat, count, singleton):
"""Structured object reference counting for simple item setting"""
one = 1
gc.collect()
before = sys.getrefcount(singleton)
arr = np.array([pat] * 3, dt)
assert sys.getrefcount(singleton) - before == count * 3
before2 = sys.getrefcount(one)
arr[...] = one
after2 = sys.getrefcount(one)
assert after2 - before2 == count * 3
del arr
gc.collect()
assert sys.getrefcount(one) == before2
assert sys.getrefcount(singleton) == before
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
iter_struct_object_dtypes())
@pytest.mark.parametrize(
['shape', 'index', 'items_changed'],
[((3,), ([0, 2],), 2),
((3, 2), ([0, 2], slice(None)), 4),
((3, 2), ([0, 2], [1]), 2),
((3,), ([True, False, True]), 2)])
def test_structured_object_indexing(self, shape, index, items_changed,
dt, pat, count, singleton):
"""Structured object reference counting for advanced indexing."""
val0 = -4
val1 = -5
arr = np.full(shape, val0, dt)
gc.collect()
before_val0 = sys.getrefcount(val0)
before_val1 = sys.getrefcount(val1)
part = arr[index]
after_val0 = sys.getrefcount(val0)
assert after_val0 - before_val0 == count * items_changed
del part
arr[index] = val1
gc.collect()
after_val0 = sys.getrefcount(val0)
after_val1 = sys.getrefcount(val1)
assert before_val0 - after_val0 == count * items_changed
assert after_val1 - before_val1 == count * items_changed
@pytest.mark.parametrize(['dt', 'pat', 'count', 'singleton'],
iter_struct_object_dtypes())
def test_structured_object_take_and_repeat(self, dt, pat, count, singleton):
"""Structured object reference counting for specialized functions.
The older functions such as take and repeat use different code paths
then item setting (when writing this).
"""
indices = [0, 1]
arr = np.array([pat] * 3, dt)
gc.collect()
before = sys.getrefcount(singleton)
res = arr.take(indices)
after = sys.getrefcount(singleton)
assert after - before == count * 2
new = res.repeat(10)
gc.collect()
after_repeat = sys.getrefcount(singleton)
assert after_repeat - after == count * 2 * 10
class TestStructuredDtypeSparseFields:
"""Tests subarray fields which contain sparse dtypes so that
not all memory is used by the dtype work. Such dtype's should
leave the underlying memory unchanged.
"""
dtype = np.dtype([('a', {'names':['aa', 'ab'], 'formats':['f', 'f'],
'offsets':[0, 4]}, (2, 3))])
sparse_dtype = np.dtype([('a', {'names':['ab'], 'formats':['f'],
'offsets':[4]}, (2, 3))])
def test_sparse_field_assignment(self):
arr = np.zeros(3, self.dtype)
sparse_arr = arr.view(self.sparse_dtype)
sparse_arr[...] = np.finfo(np.float32).max
assert_array_equal(arr["a"]["aa"], np.zeros((3, 2, 3)))
def test_sparse_field_assignment_fancy(self):
arr = np.zeros(3, self.dtype)
sparse_arr = arr.view(self.sparse_dtype)
sparse_arr[[0, 1, 2]] = np.finfo(np.float32).max
assert_array_equal(arr["a"]["aa"], np.zeros((3, 2, 3)))
class TestMonsterType:
"""Test deeply nested subtypes."""
def test1(self):
simple1 = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
'titles': ['Red pixel', 'Blue pixel']})
a = np.dtype([('yo', int), ('ye', simple1),
('yi', np.dtype((int, (3, 2))))])
b = np.dtype([('yo', int), ('ye', simple1),
('yi', np.dtype((int, (3, 2))))])
assert_dtype_equal(a, b)
c = np.dtype([('yo', int), ('ye', simple1),
('yi', np.dtype((a, (3, 2))))])
d = np.dtype([('yo', int), ('ye', simple1),
('yi', np.dtype((a, (3, 2))))])
assert_dtype_equal(c, d)
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_list_recursion(self):
l = list()
l.append(('f', l))
with pytest.raises(RecursionError):
np.dtype(l)
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_tuple_recursion(self):
d = np.int32
for i in range(100000):
d = (d, (1,))
with pytest.raises(RecursionError):
np.dtype(d)
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_dict_recursion(self):
d = dict(names=['self'], formats=[None], offsets=[0])
d['formats'][0] = d
with pytest.raises(RecursionError):
np.dtype(d)
class TestMetadata:
def test_no_metadata(self):
d = np.dtype(int)
assert_(d.metadata is None)
def test_metadata_takes_dict(self):
d = np.dtype(int, metadata={'datum': 1})
assert_(d.metadata == {'datum': 1})
def test_metadata_rejects_nondict(self):
assert_raises(TypeError, np.dtype, int, metadata='datum')
assert_raises(TypeError, np.dtype, int, metadata=1)
assert_raises(TypeError, np.dtype, int, metadata=None)
def test_nested_metadata(self):
d = np.dtype([('a', np.dtype(int, metadata={'datum': 1}))])
assert_(d['a'].metadata == {'datum': 1})
def test_base_metadata_copied(self):
d = np.dtype((np.void, np.dtype('i4,i4', metadata={'datum': 1})))
assert_(d.metadata == {'datum': 1})
class TestString:
def test_repr_structured(self):
dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)),
('rtile', '>f4', (64, 36))], (3,)),
('bottom', [('bleft', ('>f4', (8, 64)), (1,)),
('bright', '>f4', (8, 36))])])
assert_equal(repr(dt),
"dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)), "
"('rtile', '>f4', (64, 36))], (3,)), "
"('bottom', [('bleft', ('>f4', (8, 64)), (1,)), "
"('bright', '>f4', (8, 36))])])")
dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'],
'offsets': [0, 1, 2],
'titles': ['Red pixel', 'Green pixel', 'Blue pixel']},
align=True)
assert_equal(repr(dt),
"dtype([(('Red pixel', 'r'), 'u1'), "
"(('Green pixel', 'g'), 'u1'), "
"(('Blue pixel', 'b'), 'u1')], align=True)")
def test_repr_structured_not_packed(self):
dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'],
'formats': ['<u4', 'u1', 'u1', 'u1'],
'offsets': [0, 0, 1, 2],
'titles': ['Color', 'Red pixel',
'Green pixel', 'Blue pixel']}, align=True)
assert_equal(repr(dt),
"dtype({'names': ['rgba', 'r', 'g', 'b'],"
" 'formats': ['<u4', 'u1', 'u1', 'u1'],"
" 'offsets': [0, 0, 1, 2],"
" 'titles': ['Color', 'Red pixel', "
"'Green pixel', 'Blue pixel'],"
" 'itemsize': 4}, align=True)")
dt = np.dtype({'names': ['r', 'b'], 'formats': ['u1', 'u1'],
'offsets': [0, 2],
'titles': ['Red pixel', 'Blue pixel'],
'itemsize': 4})
assert_equal(repr(dt),
"dtype({'names': ['r', 'b'], "
"'formats': ['u1', 'u1'], "
"'offsets': [0, 2], "
"'titles': ['Red pixel', 'Blue pixel'], "
"'itemsize': 4})")
def test_repr_structured_datetime(self):
dt = np.dtype([('a', '<M8[D]'), ('b', '<m8[us]')])
assert_equal(repr(dt),
"dtype([('a', '<M8[D]'), ('b', '<m8[us]')])")
def test_repr_str_subarray(self):
dt = np.dtype(('<i2', (1,)))
assert_equal(repr(dt), "dtype(('<i2', (1,)))")
assert_equal(str(dt), "('<i2', (1,))")
def test_base_dtype_with_object_type(self):
np.array(['a'], dtype="O").astype(("O", [("name", "O")]))
def test_empty_string_to_object(self):
np.array(["", ""]).astype(object)
def test_void_subclass_unsized(self):
dt = np.dtype(np.record)
assert_equal(repr(dt), "dtype('V')")
assert_equal(str(dt), '|V0')
assert_equal(dt.name, 'record')
def test_void_subclass_sized(self):
dt = np.dtype((np.record, 2))
assert_equal(repr(dt), "dtype('V2')")
assert_equal(str(dt), '|V2')
assert_equal(dt.name, 'record16')
def test_void_subclass_fields(self):
dt = np.dtype((np.record, [('a', '<u2')]))
assert_equal(repr(dt), "dtype((numpy.record, [('a', '<u2')]))")
assert_equal(str(dt), "(numpy.record, [('a', '<u2')])")
assert_equal(dt.name, 'record16')
class TestDtypeAttributeDeletion:
def test_dtype_non_writable_attributes_deletion(self):
dt = np.dtype(np.double)
attr = ["subdtype", "descr", "str", "name", "base", "shape",
"isbuiltin", "isnative", "isalignedstruct", "fields",
"metadata", "hasobject"]
for s in attr:
assert_raises(AttributeError, delattr, dt, s)
def test_dtype_writable_attributes_deletion(self):
dt = np.dtype(np.double)
attr = ["names"]
for s in attr:
assert_raises(AttributeError, delattr, dt, s)
class TestDtypeAttributes:
def test_descr_has_trailing_void(self):
dtype = np.dtype({
'names': ['A', 'B'],
'formats': ['f4', 'f4'],
'offsets': [0, 8],
'itemsize': 16})
new_dtype = np.dtype(dtype.descr)
assert_equal(new_dtype.itemsize, 16)
def test_name_dtype_subclass(self):
class user_def_subcls(np.void):
pass
assert_equal(np.dtype(user_def_subcls).name, 'user_def_subcls')
def test_zero_stride(self):
arr = np.ones(1, dtype="i8")
arr = np.broadcast_to(arr, 10)
assert arr.strides == (0,)
with pytest.raises(ValueError):
arr.dtype = "i1"
class TestDTypeMakeCanonical:
def check_canonical(self, dtype, canonical):
"""
Check most properties relevant to "canonical" versions of a dtype,
which is mainly native byte order for datatypes supporting this.
The main work is checking structured dtypes with fields, where we
reproduce most the actual logic used in the C-code.
"""
assert type(dtype) is type(canonical)
assert np.can_cast(dtype, canonical, casting="equiv")
assert np.can_cast(canonical, dtype, casting="equiv")
assert canonical.isnative
assert np.result_type(canonical) == canonical
if not dtype.names:
assert dtype.flags == canonical.flags
return
assert dtype.flags & 0b10000
assert dtype.fields.keys() == canonical.fields.keys()
def aligned_offset(offset, alignment):
return -(-offset // alignment) * alignment
totalsize = 0
max_alignment = 1
for name in dtype.names:
new_field_descr = canonical.fields[name][0]
self.check_canonical(dtype.fields[name][0], new_field_descr)
expected = 0b11011 & new_field_descr.flags
assert (canonical.flags & expected) == expected
if canonical.isalignedstruct:
totalsize = aligned_offset(totalsize, new_field_descr.alignment)
max_alignment = max(new_field_descr.alignment, max_alignment)
assert canonical.fields[name][1] == totalsize
assert dtype.fields[name][2:] == canonical.fields[name][2:]
totalsize += new_field_descr.itemsize
if canonical.isalignedstruct:
totalsize = aligned_offset(totalsize, max_alignment)
assert canonical.itemsize == totalsize
assert canonical.alignment == max_alignment
def test_simple(self):
dt = np.dtype(">i4")
assert np.result_type(dt).isnative
assert np.result_type(dt).num == dt.num
struct_dt = np.dtype(">i4,<i1,i8,V3")[["f0", "f2"]]
canonical = np.result_type(struct_dt)
assert canonical.itemsize == 4+8
assert canonical.isnative
struct_dt = np.dtype(">i1,<i4,i8,V3", align=True)[["f0", "f2"]]
canonical = np.result_type(struct_dt)
assert canonical.isalignedstruct
assert canonical.itemsize == np.dtype("i8").alignment + 8
assert canonical.isnative
def test_object_flag_not_inherited(self):
arr = np.ones(3, "i,O,i")[["f0", "f2"]]
assert arr.dtype.hasobject
canonical_dt = np.result_type(arr.dtype)
assert not canonical_dt.hasobject
@pytest.mark.slow
@hypothesis.given(dtype=hynp.nested_dtypes())
def test_make_canonical_hypothesis(self, dtype):
canonical = np.result_type(dtype)
self.check_canonical(dtype, canonical)
two_arg_result = np.result_type(dtype, dtype)
assert np.can_cast(two_arg_result, canonical, casting="no")
@pytest.mark.slow
@hypothesis.given(
dtype=hypothesis.extra.numpy.array_dtypes(
subtype_strategy=hypothesis.extra.numpy.array_dtypes(),
min_size=5, max_size=10, allow_subarrays=True))
def test_structured(self, dtype):
field_subset = random.sample(dtype.names, k=4)
dtype_with_empty_space = dtype[field_subset]
assert dtype_with_empty_space.itemsize == dtype.itemsize
canonicalized = np.result_type(dtype_with_empty_space)
self.check_canonical(dtype_with_empty_space, canonicalized)
two_arg_result = np.promote_types(
dtype_with_empty_space, dtype_with_empty_space)
assert np.can_cast(two_arg_result, canonicalized, casting="no")
dtype_aligned = np.dtype(dtype.descr, align=not dtype.isalignedstruct)
dtype_with_empty_space = dtype_aligned[field_subset]
assert dtype_with_empty_space.itemsize == dtype_aligned.itemsize
canonicalized = np.result_type(dtype_with_empty_space)
self.check_canonical(dtype_with_empty_space, canonicalized)
two_arg_result = np.promote_types(
dtype_with_empty_space, dtype_with_empty_space)
assert np.can_cast(two_arg_result, canonicalized, casting="no")
class TestPickling:
def check_pickling(self, dtype):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
buf = pickle.dumps(dtype, proto)
assert b"_DType_reconstruct" not in buf
assert b"dtype" in buf
pickled = pickle.loads(buf)
assert_equal(pickled, dtype)
assert_equal(pickled.descr, dtype.descr)
if dtype.metadata is not None:
assert_equal(pickled.metadata, dtype.metadata)
x = np.zeros(3, dtype=dtype)
y = np.zeros(3, dtype=pickled)
assert_equal(x, y)
assert_equal(x[0], y[0])
@pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object,
bool])
def test_builtin(self, t):
self.check_pickling(np.dtype(t))
def test_structured(self):
dt = np.dtype(([('a', '>f4', (2, 1)), ('b', '<f8', (1, 3))], (2, 2)))
self.check_pickling(dt)
def test_structured_aligned(self):
dt = np.dtype('i4, i1', align=True)
self.check_pickling(dt)
def test_structured_unaligned(self):
dt = np.dtype('i4, i1', align=False)
self.check_pickling(dt)
def test_structured_padded(self):
dt = np.dtype({
'names': ['A', 'B'],
'formats': ['f4', 'f4'],
'offsets': [0, 8],
'itemsize': 16})
self.check_pickling(dt)
def test_structured_titles(self):
dt = np.dtype({'names': ['r', 'b'],
'formats': ['u1', 'u1'],
'titles': ['Red pixel', 'Blue pixel']})
self.check_pickling(dt)
@pytest.mark.parametrize('base', ['m8', 'M8'])
@pytest.mark.parametrize('unit', ['', 'Y', 'M', 'W', 'D', 'h', 'm', 's',
'ms', 'us', 'ns', 'ps', 'fs', 'as'])
def test_datetime(self, base, unit):
dt = np.dtype('%s[%s]' % (base, unit) if unit else base)
self.check_pickling(dt)
if unit:
dt = np.dtype('%s[7%s]' % (base, unit))
self.check_pickling(dt)
def test_metadata(self):
dt = np.dtype(int, metadata={'datum': 1})
self.check_pickling(dt)
@pytest.mark.parametrize("DType",
[type(np.dtype(t)) for t in np.typecodes['All']] +
[type(np.dtype(rational)), np.dtype])
def test_pickle_dtype_class(self, DType):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
roundtrip_DType = pickle.loads(pickle.dumps(DType, proto))
assert roundtrip_DType is DType
@pytest.mark.parametrize("dt",
[np.dtype(t) for t in np.typecodes['All']] +
[np.dtype(rational)])
def test_pickle_dtype_instance(self, dt):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
roundtrip_dt = pickle.loads(pickle.dumps(dt, proto))
assert roundtrip_dt == dt
def test_pickle_dtype(self, dt):
pre_pickle_hash = hash(dt)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
roundtrip_dt = pickle.loads(pickle.dumps(dt, proto))
assert roundtrip_dt == dt
assert hash(dt) == pre_pickle_hash
class TestPromotion:
"""Test cases related to more complex DType promotions. Further promotion
tests are defined in `test_numeric.py`
"""
@np._no_nep50_warning()
@pytest.mark.parametrize(["other", "expected", "expected_weak"],
[(2**16-1, np.complex64, None),
(2**32-1, np.complex128, np.complex64),
(np.float16(2), np.complex64, None),
(np.float32(2), np.complex64, None),
(np.longdouble(2), np.complex64, np.clongdouble),
(np.longdouble(np.nextafter(1.7e308, 0.)),
np.complex128, np.clongdouble),
(np.longdouble(np.nextafter(1.7e308, np.inf)),
np.clongdouble, None),
(np.complex64(2), np.complex64, None),
(np.clongdouble(2), np.complex64, np.clongdouble),
(np.clongdouble(np.nextafter(1.7e308, 0.) * 1j),
np.complex128, np.clongdouble),
(np.clongdouble(np.nextafter(1.7e308, np.inf)),
np.clongdouble, None),
])
def test_complex_other_value_based(self,
weak_promotion, other, expected, expected_weak):
if weak_promotion and expected_weak is not None:
expected = expected_weak
min_complex = np.dtype(np.complex64)
res = np.result_type(other, min_complex)
assert res == expected
res = np.minimum(other, np.ones(3, dtype=min_complex)).dtype
assert res == expected
@pytest.mark.parametrize(["other", "expected"],
[(np.bool, np.complex128),
(np.int64, np.complex128),
(np.float16, np.complex64),
(np.float32, np.complex64),
(np.float64, np.complex128),
(np.longdouble, np.clongdouble),
(np.complex64, np.complex64),
(np.complex128, np.complex128),
(np.clongdouble, np.clongdouble),
])
def test_complex_scalar_value_based(self, other, expected):
complex_scalar = 1j
res = np.result_type(other, complex_scalar)
assert res == expected
res = np.minimum(np.ones(3, dtype=other), complex_scalar).dtype
assert res == expected
def test_complex_pyscalar_promote_rational(self):
with pytest.raises(TypeError,
match=r".* no common DType exists for the given inputs"):
np.result_type(1j, rational)
with pytest.raises(TypeError,
match=r".* no common DType exists for the given inputs"):
np.result_type(1j, rational(1, 2))
@pytest.mark.parametrize("val", [2, 2**32, 2**63, 2**64, 2*100])
def test_python_integer_promotion(self, val):
expected_dtype = np.dtype(int)
assert np.result_type(val, 0) == expected_dtype
assert np.result_type(val, np.int8(0)) == np.int8
@pytest.mark.parametrize(["other", "expected"],
[(1, rational), (1., np.float64)])
@np._no_nep50_warning()
def test_float_int_pyscalar_promote_rational(
self, weak_promotion, other, expected):
if not weak_promotion and type(other) == float:
with pytest.raises(TypeError,
match=r".* do not have a common DType"):
np.result_type(other, rational)
else:
assert np.result_type(other, rational) == expected
assert np.result_type(other, rational(1, 2)) == expected
@pytest.mark.parametrize(["dtypes", "expected"], [
([np.uint16, np.int16, np.float16], np.float32),
([np.uint16, np.int8, np.float16], np.float32),
([np.uint8, np.int16, np.float16], np.float32),
([1, 1, np.float64], np.float64),
([1, 1., np.complex128], np.complex128),
([1, 1j, np.float64], np.complex128),
([1., 1., np.int64], np.float64),
([1., 1j, np.float64], np.complex128),
([1j, 1j, np.float64], np.complex128),
([1, True, np.bool], np.int_),
])
def test_permutations_do_not_influence_result(self, dtypes, expected):
for perm in permutations(dtypes):
assert np.result_type(*perm) == expected
def test_rational_dtype():
a = np.array([1111], dtype=rational).astype
assert_raises(OverflowError, a, 'int8')
x = rational(1)
assert_equal(np.array([x,x]).dtype, np.dtype(rational))
def test_dtypes_are_true():
assert bool(np.dtype('f8'))
assert bool(np.dtype('i8'))
assert bool(np.dtype([('a', 'i8'), ('b', 'f4')]))
def test_invalid_dtype_string():
assert_raises(TypeError, np.dtype, 'f8,i8,[f8,i8]')
assert_raises(TypeError, np.dtype, 'Fl\xfcgel')
def test_keyword_argument():
assert np.dtype(dtype=np.float64) == np.dtype(np.float64)
class TestFromDTypeAttribute:
def test_simple(self):
class dt:
dtype = np.dtype("f8")
assert np.dtype(dt) == np.float64
assert np.dtype(dt()) == np.float64
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_recursion(self):
class dt:
pass
dt.dtype = dt
with pytest.raises(RecursionError):
np.dtype(dt)
dt_instance = dt()
dt_instance.dtype = dt
with pytest.raises(RecursionError):
np.dtype(dt_instance)
def test_void_subtype(self):
class dt(np.void):
dtype = np.dtype("f,f")
np.dtype(dt)
np.dtype(dt(1))
@pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_void_subtype_recursion(self):
class vdt(np.void):
pass
vdt.dtype = vdt
with pytest.raises(RecursionError):
np.dtype(vdt)
with pytest.raises(RecursionError):
np.dtype(vdt(1))
class TestDTypeClasses:
@pytest.mark.parametrize("dtype", list(np.typecodes['All']) + [rational])
def test_basic_dtypes_subclass_properties(self, dtype):
dtype = np.dtype(dtype)
assert isinstance(dtype, np.dtype)
assert type(dtype) is not np.dtype
if dtype.type.__name__ != "rational":
dt_name = type(dtype).__name__.lower().removesuffix("dtype")
if dt_name == "uint" or dt_name == "int":
dt_name += "c"
sc_name = dtype.type.__name__
assert dt_name == sc_name.strip("_")
assert type(dtype).__module__ == "numpy.dtypes"
assert getattr(numpy.dtypes, type(dtype).__name__) is type(dtype)
else:
assert type(dtype).__name__ == "dtype[rational]"
assert type(dtype).__module__ == "numpy"
assert not type(dtype)._abstract
parametric = (np.void, np.str_, np.bytes_, np.datetime64, np.timedelta64)
if dtype.type not in parametric:
assert not type(dtype)._parametric
assert type(dtype)() is dtype
else:
assert type(dtype)._parametric
with assert_raises(TypeError):
type(dtype)()
def test_dtype_superclass(self):
assert type(np.dtype) is not type
assert isinstance(np.dtype, type)
assert type(np.dtype).__name__ == "_DTypeMeta"
assert type(np.dtype).__module__ == "numpy"
assert np.dtype._abstract
def test_is_numeric(self):
all_codes = set(np.typecodes['All'])
numeric_codes = set(np.typecodes['AllInteger'] +
np.typecodes['AllFloat'] + '?')
non_numeric_codes = all_codes - numeric_codes
for code in numeric_codes:
assert type(np.dtype(code))._is_numeric
for code in non_numeric_codes:
assert not type(np.dtype(code))._is_numeric
@pytest.mark.parametrize("int_", ["UInt", "Int"])
@pytest.mark.parametrize("size", [8, 16, 32, 64])
def test_integer_alias_names(self, int_, size):
DType = getattr(numpy.dtypes, f"{int_}{size}DType")
sctype = getattr(numpy, f"{int_.lower()}{size}")
assert DType.type is sctype
assert DType.__name__.lower().removesuffix("dtype") == sctype.__name__
@pytest.mark.parametrize("name",
["Half", "Float", "Double", "CFloat", "CDouble"])
def test_float_alias_names(self, name):
with pytest.raises(AttributeError):
getattr(numpy.dtypes, name + "DType") is numpy.dtypes.Float16DType
class TestFromCTypes:
@staticmethod
def check(ctype, dtype):
dtype = np.dtype(dtype)
assert np.dtype(ctype) == dtype
assert np.dtype(ctype()) == dtype
assert ctypes.sizeof(ctype) == dtype.itemsize
def test_array(self):
c8 = ctypes.c_uint8
self.check(3 * c8, (np.uint8, (3,)))
self.check(1 * c8, (np.uint8, (1,)))
self.check(0 * c8, (np.uint8, (0,)))
self.check(1 * (3 * c8), ((np.uint8, (3,)), (1,)))
self.check(3 * (1 * c8), ((np.uint8, (1,)), (3,)))
def test_padded_structure(self):
class PaddedStruct(ctypes.Structure):
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16)
]
expected = np.dtype([
('a', np.uint8),
('b', np.uint16)
], align=True)
self.check(PaddedStruct, expected)
def test_bit_fields(self):
class BitfieldStruct(ctypes.Structure):
_fields_ = [
('a', ctypes.c_uint8, 7),
('b', ctypes.c_uint8, 1)
]
assert_raises(TypeError, np.dtype, BitfieldStruct)
assert_raises(TypeError, np.dtype, BitfieldStruct())
def test_pointer(self):
p_uint8 = ctypes.POINTER(ctypes.c_uint8)
assert_raises(TypeError, np.dtype, p_uint8)
def test_size_t(self):
assert np.dtype(np.uintp) is np.dtype("N")
self.check(ctypes.c_size_t, np.uintp)
def test_void_pointer(self):
self.check(ctypes.c_void_p, "P")
def test_union(self):
class Union(ctypes.Union):
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16),
]
expected = np.dtype(dict(
names=['a', 'b'],
formats=[np.uint8, np.uint16],
offsets=[0, 0],
itemsize=2
))
self.check(Union, expected)
def test_union_with_struct_packed(self):
class Struct(ctypes.Structure):
_pack_ = 1
_fields_ = [
('one', ctypes.c_uint8),
('two', ctypes.c_uint32)
]
class Union(ctypes.Union):
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16),
('c', ctypes.c_uint32),
('d', Struct),
]
expected = np.dtype(dict(
names=['a', 'b', 'c', 'd'],
formats=['u1', np.uint16, np.uint32, [('one', 'u1'), ('two', np.uint32)]],
offsets=[0, 0, 0, 0],
itemsize=ctypes.sizeof(Union)
))
self.check(Union, expected)
def test_union_packed(self):
class Struct(ctypes.Structure):
_fields_ = [
('one', ctypes.c_uint8),
('two', ctypes.c_uint32)
]
_pack_ = 1
class Union(ctypes.Union):
_pack_ = 1
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16),
('c', ctypes.c_uint32),
('d', Struct),
]
expected = np.dtype(dict(
names=['a', 'b', 'c', 'd'],
formats=['u1', np.uint16, np.uint32, [('one', 'u1'), ('two', np.uint32)]],
offsets=[0, 0, 0, 0],
itemsize=ctypes.sizeof(Union)
))
self.check(Union, expected)
def test_packed_structure(self):
class PackedStructure(ctypes.Structure):
_pack_ = 1
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16)
]
expected = np.dtype([
('a', np.uint8),
('b', np.uint16)
])
self.check(PackedStructure, expected)
def test_large_packed_structure(self):
class PackedStructure(ctypes.Structure):
_pack_ = 2
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16),
('c', ctypes.c_uint8),
('d', ctypes.c_uint16),
('e', ctypes.c_uint32),
('f', ctypes.c_uint32),
('g', ctypes.c_uint8)
]
expected = np.dtype(dict(
formats=[np.uint8, np.uint16, np.uint8, np.uint16, np.uint32, np.uint32, np.uint8],
offsets=[0, 2, 4, 6, 8, 12, 16],
names=['a', 'b', 'c', 'd', 'e', 'f', 'g'],
itemsize=18
))
self.check(PackedStructure, expected)
def test_big_endian_structure_packed(self):
class BigEndStruct(ctypes.BigEndianStructure):
_fields_ = [
('one', ctypes.c_uint8),
('two', ctypes.c_uint32)
]
_pack_ = 1
expected = np.dtype([('one', 'u1'), ('two', '>u4')])
self.check(BigEndStruct, expected)
def test_little_endian_structure_packed(self):
class LittleEndStruct(ctypes.LittleEndianStructure):
_fields_ = [
('one', ctypes.c_uint8),
('two', ctypes.c_uint32)
]
_pack_ = 1
expected = np.dtype([('one', 'u1'), ('two', '<u4')])
self.check(LittleEndStruct, expected)
def test_little_endian_structure(self):
class PaddedStruct(ctypes.LittleEndianStructure):
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16)
]
expected = np.dtype([
('a', '<B'),
('b', '<H')
], align=True)
self.check(PaddedStruct, expected)
def test_big_endian_structure(self):
class PaddedStruct(ctypes.BigEndianStructure):
_fields_ = [
('a', ctypes.c_uint8),
('b', ctypes.c_uint16)
]
expected = np.dtype([
('a', '>B'),
('b', '>H')
], align=True)
self.check(PaddedStruct, expected)
def test_simple_endian_types(self):
self.check(ctypes.c_uint16.__ctype_le__, np.dtype('<u2'))
self.check(ctypes.c_uint16.__ctype_be__, np.dtype('>u2'))
self.check(ctypes.c_uint8.__ctype_le__, np.dtype('u1'))
self.check(ctypes.c_uint8.__ctype_be__, np.dtype('u1'))
all_types = set(np.typecodes['All'])
all_pairs = permutations(all_types, 2)
@pytest.mark.parametrize("pair", all_pairs)
def test_pairs(self, pair):
"""
Check that np.dtype('x,y') matches [np.dtype('x'), np.dtype('y')]
Example: np.dtype('d,I') -> dtype([('f0', '<f8'), ('f1', '<u4')])
"""
pair_type = np.dtype('{},{}'.format(*pair))
expected = np.dtype([('f0', pair[0]), ('f1', pair[1])])
assert_equal(pair_type, expected)
class TestUserDType:
@pytest.mark.leaks_references(reason="dynamically creates custom dtype.")
def test_custom_structured_dtype(self):
class mytype:
pass
blueprint = np.dtype([("field", object)])
dt = create_custom_field_dtype(blueprint, mytype, 0)
assert dt.type == mytype
assert np.dtype(mytype) == np.dtype("O")
if HAS_REFCOUNT:
o = object()
a = np.array([o], dtype=dt)
del a
assert sys.getrefcount(o) == 2
def test_custom_structured_dtype_errors(self):
class mytype:
pass
blueprint = np.dtype([("field", object)])
with pytest.raises(ValueError):
create_custom_field_dtype(blueprint, mytype, 1)
with pytest.raises(RuntimeError):
create_custom_field_dtype(blueprint, mytype, 2)
class TestClassGetItem:
def test_dtype(self) -> None:
alias = np.dtype[Any]
assert isinstance(alias, types.GenericAlias)
assert alias.__origin__ is np.dtype
@pytest.mark.parametrize("code", np.typecodes["All"])
def test_dtype_subclass(self, code: str) -> None:
cls = type(np.dtype(code))
alias = cls[Any]
assert isinstance(alias, types.GenericAlias)
assert alias.__origin__ is cls
@pytest.mark.parametrize("arg_len", range(4))
def test_subscript_tuple(self, arg_len: int) -> None:
arg_tup = (Any,) * arg_len
if arg_len == 1:
assert np.dtype[arg_tup]
else:
with pytest.raises(TypeError):
np.dtype[arg_tup]
def test_subscript_scalar(self) -> None:
assert np.dtype[Any]
def test_result_type_integers_and_unitless_timedelta64():
td = np.timedelta64(4)
result = np.result_type(0, td)
assert_dtype_equal(result, td.dtype)
def test_creating_dtype_with_dtype_class_errors():
with pytest.raises(TypeError, match="Cannot convert np.dtype into a"):
np.array(np.ones(10), dtype=np.dtype)
.\numpy\numpy\_core\tests\test_einsum.py
import itertools
import sys
import platform
import pytest
import numpy as np
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_almost_equal,
assert_raises, suppress_warnings, assert_raises_regex, assert_allclose
)
chars = 'abcdefghij'
sizes = np.array([2, 3, 4, 5, 4, 3, 2, 6, 5, 4, 3])
global_size_dict = dict(zip(chars, sizes))
class TestEinsum:
@pytest.mark.parametrize("do_opt", [True, False])
@pytest.mark.parametrize("einsum_fn", [np.einsum, np.einsum_path])
python
def test_einsum_errors(self, do_opt, einsum_fn):
assert_raises(ValueError, einsum_fn, optimize=do_opt)
assert_raises(ValueError, einsum_fn, "", optimize=do_opt)
assert_raises(TypeError, einsum_fn, 0, 0, optimize=do_opt)
assert_raises(TypeError, einsum_fn, *(None,)*63, optimize=do_opt)
assert_raises(ValueError, einsum_fn, "", 0, 0, optimize=do_opt)
assert_raises(ValueError, einsum_fn, ",", 0, [0], [0],
optimize=do_opt)
assert_raises(ValueError, einsum_fn, ",", [0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i", 0, optimize=do_opt)
assert_raises(ValueError, einsum_fn, "ij", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "...i", 0, optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i...j", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i...", 0, optimize=do_opt)
assert_raises(ValueError, einsum_fn, "ij...", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i..", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, ".i...", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "j->..j", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "j->.j...", [0, 0],
optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i%...", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "...j$", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i->&", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "i->ij", [0, 0], optimize=do_opt)
assert_raises(ValueError, einsum_fn, "ij->jij", [[0, 0], [0, 0]],
optimize=do_opt)
assert_raises(ValueError, einsum_fn, "ii",
np.arange(6).reshape(2, 3), optimize=do_opt)
assert_raises(ValueError, einsum_fn, "ii->i",
np.arange(6).reshape(2, 3), optimize=do_opt)
with assert_raises_regex(ValueError, "'b'"):
a = np.ones((3, 3, 4, 5, 6))
b = np.ones((3, 4, 5))
einsum_fn('aabcb,abc', a, b)
@pytest.mark.parametrize("do_opt", [True, False])
def test_einsum_specific_errors(self, do_opt):
assert_raises(TypeError, np.einsum, "", 0, out='test',
optimize=do_opt)
assert_raises(ValueError, np.einsum, "", 0, order='W',
optimize=do_opt)
assert_raises(ValueError, np.einsum, "", 0, casting='blah',
optimize=do_opt)
assert_raises(TypeError, np.einsum, "", 0, dtype='bad_data_type',
optimize=do_opt)
assert_raises(TypeError, np.einsum, "", 0, bad_arg=0, optimize=do_opt)
assert_raises(ValueError, np.einsum, "i", np.arange(6).reshape(2, 3),
optimize=do_opt)
assert_raises(ValueError, np.einsum, "i->i", [[0, 1], [0, 1]],
out=np.arange(4).reshape(2, 2), optimize=do_opt)
assert_raises(ValueError, np.einsum, "i->i",
np.arange(6).reshape(-1, 1), optimize=do_opt, order='d')
def test_einsum_object_errors(self):
class CustomException(Exception):
pass
class DestructoBox:
def __init__(self, value, destruct):
self._val = value
self._destruct = destruct
def __add__(self, other):
tmp = self._val + other._val
if tmp >= self._destruct:
raise CustomException
else:
self._val = tmp
return self
def __radd__(self, other):
if other == 0:
return self
else:
return self.__add__(other)
def __mul__(self, other):
tmp = self._val * other._val
if tmp >= self._destruct:
raise CustomException
else:
self._val = tmp
return self
def __rmul__(self, other):
if other == 0:
return self
else:
return self.__mul__(other)
a = np.array([DestructoBox(i, 5) for i in range(1, 10)],
dtype='object').reshape(3, 3)
assert_raises(CustomException, np.einsum, "ij->i", a)
b = np.array([DestructoBox(i, 100) for i in range(0, 27)],
dtype='object').reshape(3, 3, 3)
assert_raises(CustomException, np.einsum, "i...k->...", b)
b = np.array([DestructoBox(i, 55) for i in range(1, 4)],
dtype='object')
assert_raises(CustomException, np.einsum, "ij, j", a, b)
assert_raises(CustomException, np.einsum, "ij, jh", a, a)
assert_raises(CustomException, np.einsum, "ij->", a)
@np._no_nep50_warning()
def test_einsum_sums_int8(self):
self.check_einsum_sums('i1')
def test_einsum_sums_uint8(self):
self.check_einsum_sums('u1')
def test_einsum_sums_int16(self):
self.check_einsum_sums('i2')
def test_einsum_sums_uint16(self):
self.check_einsum_sums('u2')
def test_einsum_sums_int32(self):
self.check_einsum_sums('i4')
self.check_einsum_sums('i4', True)
def test_einsum_sums_uint32(self):
self.check_einsum_sums('u4')
self.check_einsum_sums('u4', True)
def test_einsum_sums_int64(self):
self.check_einsum_sums('i8')
def test_einsum_sums_uint64(self):
self.check_einsum_sums('u8')
def test_einsum_sums_float16(self):
self.check_einsum_sums('f2')
def test_einsum_sums_float32(self):
self.check_einsum_sums('f4')
def test_einsum_sums_float64(self):
self.check_einsum_sums('f8')
self.check_einsum_sums('f8', True)
def test_einsum_sums_longdouble(self):
self.check_einsum_sums(np.longdouble)
def test_einsum_sums_cfloat64(self):
self.check_einsum_sums('c8')
self.check_einsum_sums('c8', True)
def test_einsum_sums_cfloat128(self):
self.check_einsum_sums('c16')
def test_einsum_sums_clongdouble(self):
self.check_einsum_sums(np.clongdouble)
def test_einsum_sums_object(self):
self.check_einsum_sums('object')
self.check_einsum_sums('object', True)
def test_einsum_misc(self):
a = np.ones((1, 2))
b = np.ones((2, 2, 1))
assert_equal(np.einsum('ij...,j...->i...', a, b), [[[2], [2]]])
assert_equal(np.einsum('ij...,j...->i...', a, b, optimize=True), [[[2], [2]]])
assert_equal(np.einsum('ij...,j...->i...', a, b), [[[2], [2]]])
assert_equal(np.einsum('...i,...i', [1, 2, 3], [2, 3, 4]), 20)
assert_equal(np.einsum('...i,...i', [1, 2, 3], [2, 3, 4],
optimize='greedy'), 20)
a = np.ones((5, 12, 4, 2, 3), np.int64)
b = np.ones((5, 12, 11), np.int64)
assert_equal(np.einsum('ijklm,ijn,ijn->', a, b, b),
np.einsum('ijklm,ijn->', a, b))
assert_equal(np.einsum('ijklm,ijn,ijn->', a, b, b, optimize=True),
np.einsum('ijklm,ijn->', a, b, optimize=True))
a = np.arange(1, 3)
b = np.arange(1, 5).reshape(2, 2)
c = np.arange(1, 9).reshape(4, 2)
assert_equal(np.einsum('x,yx,zx->xzy', a, b, c),
[[[1, 3], [3, 9], [5, 15], [7, 21]],
[[8, 16], [16, 32], [24, 48], [32, 64]]])
assert_equal(np.einsum('x,yx,zx->xzy', a, b, c, optimize=True),
[[[1, 3], [3, 9], [5, 15], [7, 21]],
[[8, 16], [16, 32], [24, 48], [32, 64]]])
assert_equal(np.einsum('i,j', [1], [2], out=None), [[2]])
def test_object_loop(self):
class Mult:
def __mul__(self, other):
return 42
objMult = np.array([Mult()])
objNULL = np.ndarray(buffer=b'\0' * np.intp(0).itemsize, shape=1, dtype=object)
with pytest.raises(TypeError):
np.einsum("i,j", [1], objNULL)
with pytest.raises(TypeError):
np.einsum("i,j", objNULL, [1])
assert np.einsum("i,j", objMult, objMult) == 42
def test_subscript_range(self):
a = np.ones((2, 3))
b = np.ones((3, 4))
np.einsum(a, [0, 20], b, [20, 2], [0, 2], optimize=False)
np.einsum(a, [0, 27], b, [27, 2], [0, 2], optimize=False)
np.einsum(a, [0, 51], b, [51, 2], [0, 2], optimize=False)
assert_raises(ValueError, lambda: np.einsum(a, [0, 52], b, [52, 2], [0, 2], optimize=False))
assert_raises(ValueError, lambda: np.einsum(a, [-1, 5], b, [5, 2], [-1, 2], optimize=False))
def test_einsum_broadcast(self):
A = np.arange(2 * 3 * 4).reshape(2, 3, 4)
B = np.arange(3)
ref = np.einsum('ijk,j->ijk', A, B, optimize=False)
for opt in [True, False]:
assert_equal(np.einsum('ij...,j...->ij...', A, B, optimize=opt), ref)
assert_equal(np.einsum('ij...,...j->ij...', A, B, optimize=opt), ref)
assert_equal(np.einsum('ij...,j->ij...', A, B, optimize=opt), ref)
A = np.arange(12).reshape((4, 3))
B = np.arange(6).reshape((3, 2))
ref = np.einsum('ik,kj->ij', A, B, optimize=False)
for opt in [True, False]:
assert_equal(np.einsum('ik...,k...->i...', A, B, optimize=opt), ref)
assert_equal(np.einsum('ik...,...kj->i...j', A, B, optimize=opt), ref)
assert_equal(np.einsum('...k,kj', A, B, optimize=opt), ref)
assert_equal(np.einsum('ik,k...->i...', A, B, optimize=opt), ref)
dims = [2, 3, 4, 5]
a = np.arange(np.prod(dims)).reshape(dims)
v = np.arange(dims[2])
ref = np.einsum('ijkl,k->ijl', a, v, optimize=False)
for opt in [True, False]:
assert_equal(np.einsum('ijkl,k', a, v, optimize=opt), ref)
assert_equal(np.einsum('...kl,k', a, v, optimize=opt), ref)
assert_equal(np.einsum('...kl,k...', a, v, optimize=opt), ref)
J, K, M = 160, 160, 120
A = np.arange(J * K * M).reshape(1, 1, 1, J, K, M)
B = np.arange(J * K * M * 3).reshape(J, K, M, 3)
ref = np.einsum('...lmn,...lmno->...o', A, B, optimize=False)
for opt in [True, False]:
assert_equal(np.einsum('...lmn,lmno->...o', A, B, optimize=opt), ref)
def test_einsum_fixedstridebug(self):
A = np.arange(2 * 3).reshape(2, 3).astype(np.float32)
B = np.arange(2 * 3 * 2731).reshape(2, 3, 2731).astype(np.int16)
es = np.einsum('cl, cpx->lpx', A, B)
tp = np.tensordot(A, B, axes=(0, 0))
assert_equal(es, tp)
A = np.arange(3 * 3).reshape(3, 3).astype(np.float64)
B = np.arange(3 * 3 * 64 * 64).reshape(3, 3, 64, 64).astype(np.float32)
es = np.einsum('cl, cpxy->lpxy', A, B)
tp = np.tensordot(A, B, axes=(0, 0))
assert_equal(es, tp)
def test_einsum_fixed_collapsingbug(self):
x = np.random.normal(0, 1, (5, 5, 5, 5))
y1 = np.zeros((5, 5))
np.einsum('aabb->ab', x, out=y1)
idx = np.arange(5)
y2 = x[idx[:, None], idx[:, None], idx, idx]
assert_equal(y1, y2)
def test_einsum_failed_on_p9_and_s390x(self):
tensor = np.random.random_sample((10, 10, 10, 10))
x = np.einsum('ijij->', tensor)
y = tensor.trace(axis1=0, axis2=2).trace()
assert_allclose(x, y)
def test_einsum_all_contig_non_contig_output(self):
x = np.ones((5, 5))
out = np.ones(10)[::2]
correct_base = np.ones(10)
correct_base[::2] = 5
np.einsum('mi,mi,mi->m', x, x, x, out=out)
assert_array_equal(out.base, correct_base)
np.einsum('im,im,im->m', x, x, x, out=out)
assert_array_equal(out.base, correct_base)
out = np.ones((2, 2, 2))[..., 0]
correct_base = np.ones((2, 2, 2))
correct_base[..., 0] = 2
x = np.ones((2, 2), np.float32)
np.einsum('ij,jk->ik', x, x, out=out)
assert_array_equal(out.base, correct_base)
@pytest.mark.parametrize("dtype",
np.typecodes["AllFloat"] + np.typecodes["AllInteger"])
def test_different_paths(self, dtype):
dtype = np.dtype(dtype)
arr = (np.arange(7) + 0.5).astype(dtype)
scalar = np.array(2, dtype=dtype)
res = np.einsum('i->', arr)
assert res == arr.sum()
res = np.einsum('i,i->i', arr, arr)
assert_array_equal(res, arr * arr)
res = np.einsum('i,i->i', arr.repeat(2)[::2], arr.repeat(2)[::2])
assert_array_equal(res, arr * arr)
assert np.einsum('i,i->', arr, arr) == (arr * arr).sum()
out = np.ones(7, dtype=dtype)
res = np.einsum('i,->i', arr, dtype.type(2), out=out)
assert_array_equal(res, arr * dtype.type(2))
res = np.einsum(',i->i', scalar, arr)
assert_array_equal(res, arr * dtype.type(2))
res = np.einsum(',i->', scalar, arr)
assert res == np.einsum('i->', scalar * arr)
res = np.einsum('i,->', arr, scalar)
assert res == np.einsum('i->', scalar * arr)
arr = np.array([0.5, 0.5, 0.25, 4.5, 3.], dtype=dtype)
res = np.einsum('i,i,i->', arr, arr, arr)
assert_array_equal(res, (arr * arr * arr).sum())
res = np.einsum('i,i,i,i->', arr, arr, arr, arr)
assert_array_equal(res, (arr * arr * arr * arr).sum())
def test_small_boolean_arrays(self):
a = np.zeros((16, 1, 1), dtype=np.bool)[:2]
a[...] = True
out = np.zeros((16, 1, 1), dtype=np.bool)[:2]
tgt = np.ones((2, 1, 1), dtype=np.bool)
res = np.einsum('...ij,...jk->...ik', a, a, out=out)
assert_equal(res, tgt)
def test_out_is_res(self):
a = np.arange(9).reshape(3, 3)
res = np.einsum('...ij,...jk->...ik', a, a, out=a)
assert res is a
def optimize_compare(self, subscripts, operands=None):
if operands is None:
args = [subscripts]
terms = subscripts.split('->')[0].split(',')
for term in terms:
dims = [global_size_dict[x] for x in term]
args.append(np.random.rand(*dims))
else:
args = [subscripts] + operands
noopt = np.einsum(*args, optimize=False)
opt = np.einsum(*args, optimize='greedy')
assert_almost_equal(opt, noopt)
opt = np.einsum(*args, optimize='optimal')
assert_almost_equal(opt, noopt)
def test_hadamard_like_products(self):
self.optimize_compare('a,ab,abc->abc')
self.optimize_compare('a,b,ab->ab')
def test_index_transformations(self):
self.optimize_compare('ea,fb,gc,hd,abcd->efgh')
self.optimize_compare('ea,fb,abcd,gc,hd->efgh')
self.optimize_compare('abcd,ea,fb,gc,hd->efgh')
def test_complex(self):
self.optimize_compare('acdf,jbje,gihb,hfac,gfac,gifabc,hfac')
self.optimize_compare('acdf,jbje,gihb,hfac,gfac,gifabc,hfac')
self.optimize_compare('cd,bdhe,aidb,hgca,gc,hgibcd,hgac')
self.optimize_compare('abhe,hidj,jgba,hiab,gab')
self.optimize_compare('bde,cdh,agdb,hica,ibd,hgicd,hiac')
self.optimize_compare('chd,bde,agbc,hiad,hgc,hgi,hiad')
self.optimize_compare('chd,bde,agbc,hiad,bdi,cgh,agdb')
self.optimize_compare('bdhe,acad,hiab,agac,hibd')
def test_collapse(self):
self.optimize_compare('ab,ab,c->')
self.optimize_compare('ab,ab,c->c')
self.optimize_compare('ab,ab,cd,cd->')
self.optimize_compare('ab,ab,cd,cd->ac')
self.optimize_compare('ab,ab,cd,cd->cd')
self.optimize_compare('ab,ab,cd,cd,ef,ef->')
def test_expand(self):
self.optimize_compare('ab,cd,ef->abcdef')
self.optimize_compare('ab,cd,ef->acdf')
self.optimize_compare('ab,cd,de->abcde')
self.optimize_compare('ab,cd,de->be')
self.optimize_compare('ab,bcd,cd->abcd')
self.optimize_compare('ab,bcd,cd->abd')
def test_edge_cases(self):
self.optimize_compare('eb,cb,fb->cef')
self.optimize_compare('dd,fb,be,cdb->cef')
self.optimize_compare('bca,cdb,dbf,afc->')
self.optimize_compare('dcc,fce,ea,dbf->ab')
self.optimize_compare('fdf,cdd,ccd,afe->ae')
self.optimize_compare('abcd,ad')
self.optimize_compare('ed,fcd,ff,bcf->be')
self.optimize_compare('baa,dcf,af,cde->be')
self.optimize_compare('bd,db,eac->ace')
self.optimize_compare('fff,fae,bef,def->abd')
self.optimize_compare('efc,dbc,acf,fd->abe')
self.optimize_compare('ba,ac,da->bcd')
def test_inner_product(self):
self.optimize_compare('ab,ab')
self.optimize_compare('ab,ba')
self.optimize_compare('abc,abc')
self.optimize_compare('abc,bac')
self.optimize_compare('abc,cba')
def test_random_cases(self):
self.optimize_compare('aab,fa,df,ecc->bde')
self.optimize_compare('ecb,fef,bad,ed->ac')
self.optimize_compare('bcf,bbb,fbf,fc->')
self.optimize_compare('bb,ff,be->e')
self.optimize_compare('bcb,bb,fc,fff->')
self.optimize_compare('fbb,dfd,fc,fc->')
self.optimize_compare('afd,ba,cc,dc->bf')
self.optimize_compare('adb,bc,fa,cfc->d')
self.optimize_compare('bbd,bda,fc,db->acf')
self.optimize_compare('dba,ead,cad->bce')
self.optimize_compare('aef,fbc,dca->bde')
def test_combined_views_mapping(self):
a = np.arange(9).reshape(1, 1, 3, 1, 3)
b = np.einsum('bbcdc->d', a)
assert_equal(b, [12])
def test_broadcasting_dot_cases(self):
a = np.random.rand(1, 5, 4)
b = np.random.rand(4, 6)
c = np.random.rand(5, 6)
d = np.random.rand(10)
self.optimize_compare('ijk,kl,jl', operands=[a, b, c])
self.optimize_compare('ijk,kl,jl,i->i', operands=[a, b, c, d])
e = np.random.rand(1, 1, 5, 4)
f = np.random.rand(7, 7)
self.optimize_compare('abjk,kl,jl', operands=[e, b, c])
self.optimize_compare('abjk,kl,jl,ab->ab', operands=[e, b, c, f])
g = np.arange(64).reshape(2, 4, 8)
self.optimize_compare('obk,ijk->ioj', operands=[g, g])
def test_output_order(self):
a = np.ones((2, 3, 5), order='F')
b = np.ones((4, 3), order='F')
for opt in [True, False]:
tmp = np.einsum('...ft,mf->...mt', a, b, order='a', optimize=opt)
assert_(tmp.flags.f_contiguous)
tmp = np.einsum('...ft,mf->...mt', a, b, order='f', optimize=opt)
assert_(tmp.flags.f_contiguous)
tmp = np.einsum('...ft,mf->...mt', a, b, order='c', optimize=opt)
assert_(tmp.flags.c_contiguous)
tmp = np.einsum('...ft,mf->...mt', a, b, order='k', optimize=opt)
assert_(tmp.flags.c_contiguous is False)
assert_(tmp.flags.f_contiguous is False)
tmp = np.einsum('...ft,mf->...mt', a, b, optimize=opt)
assert_(tmp.flags.c_contiguous is False)
assert_(tmp.flags.f_contiguous is False)
c = np.ones((4, 3), order='C')
for opt in [True, False]:
tmp = np.einsum('...ft,mf->...mt', a, c, order='a', optimize=opt)
assert_(tmp.flags.c_contiguous)
d = np.ones((2, 3, 5), order='C')
for opt in [True, False]:
tmp = np.einsum('...ft,mf->...mt', d, c, order='a', optimize=opt)
assert_(tmp.flags.c_contiguous)
class TestEinsumPath:
def build_operands(self, string, size_dict=global_size_dict):
operands = [string]
terms = string.split('->')[0].split(',')
for term in terms:
dims = [size_dict[x] for x in term]
operands.append(np.random.rand(*dims))
return operands
def assert_path_equal(self, comp, benchmark):
ret = (len(comp) == len(benchmark))
assert_(ret)
for pos in range(len(comp) - 1):
ret &= isinstance(comp[pos + 1], tuple)
ret &= (comp[pos + 1] == benchmark[pos + 1])
assert_(ret)
def test_memory_contraints(self):
outer_test = self.build_operands('a,b,c->abc')
path, path_str = np.einsum_path(*outer_test, optimize=('greedy', 0))
self.assert_path_equal(path, ['einsum_path', (0, 1, 2)])
path, path_str = np.einsum_path(*outer_test, optimize=('optimal', 0))
self.assert_path_equal(path, ['einsum_path', (0, 1, 2)])
long_test = self.build_operands('acdf,jbje,gihb,hfac')
path, path_str = np.einsum_path(*long_test, optimize=('greedy', 0))
self.assert_path_equal(path, ['einsum_path', (0, 1, 2, 3)])
path, path_str = np.einsum_path(*long_test, optimize=('optimal', 0))
self.assert_path_equal(path, ['einsum_path', (0, 1, 2, 3)])
def test_long_paths(self):
long_test1 = self.build_operands('acdf,jbje,gihb,hfac,gfac,gifabc,hfac')
path, path_str = np.einsum_path(*long_test1, optimize='greedy')
self.assert_path_equal(path, ['einsum_path',
(3, 6), (3, 4), (2, 4), (2, 3), (0, 2), (0, 1)])
path, path_str = np.einsum_path(*long_test1, optimize='optimal')
self.assert_path_equal(path, ['einsum_path',
(3, 6), (3, 4), (2, 4), (2, 3), (0, 2), (0, 1)])
long_test2 = self.build_operands('chd,bde,agbc,hiad,bdi,cgh,agdb')
path, path_str = np.einsum_path(*long_test2, optimize='greedy')
self.assert_path_equal(path, ['einsum_path',
(3, 4), (0, 3), (3, 4), (1, 3), (1, 2), (0, 1)])
path, path_str = np.einsum_path(*long_test2, optimize='optimal')
self.assert_path_equal(path, ['einsum_path',
(0, 5), (1, 4), (3, 4), (1, 3), (1, 2), (0, 1)])
def test_edge_paths(self):
edge_test1 = self.build_operands('eb,cb,fb->cef')
path, path_str = np.einsum_path(*edge_test1, optimize='greedy')
self.assert_path_equal(path, ['einsum_path', (0, 2), (0, 1)])
path, path_str = np.einsum_path(*edge_test1, optimize='optimal')
self.assert_path_equal(path, ['einsum_path', (0, 2), (0, 1)])
edge_test2 = self.build_operands('dd,fb,be,cdb->cef')
path, path_str = np.einsum_path(*edge_test2, optimize='greedy')
self.assert_path_equal(path, ['einsum_path', (0, 3), (0, 1), (0, 1)])
path, path_str = np.einsum_path(*edge_test2, optimize='optimal')
self.assert_path_equal(path, ['einsum_path', (0, 3), (0, 1), (0, 1)])
edge_test3 = self.build_operands('bca,cdb,dbf,afc->')
path, path_str = np.einsum_path(*edge_test3, optimize='greedy')
self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 2), (0, 1)])
path, path_str = np.einsum_path(*edge_test3, optimize='optimal')
self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 2), (0, 1)])
edge_test4 = self.build_operands('dcc,fce,ea,dbf->ab')
path, path_str = np.einsum_path(*edge_test4, optimize='greedy')
self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 1), (0, 1)])
path, path_str = np.einsum_path(*edge_test4, optimize='optimal')
self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 2), (0, 1)])
edge_test4 = self.build_operands('a,ac,ab,ad,cd,bd,bc->',
size_dict={"a": 20, "b": 20, "c": 20, "d": 20})
path, path_str = np.einsum_path(*edge_test4, optimize='greedy')
self.assert_path_equal(path, ['einsum_path', (0, 1), (0, 1, 2, 3, 4, 5)])
path, path_str = np.einsum_path(*edge_test4, optimize='optimal')
self.assert_path_equal(path, ['einsum_path', (0, 1), (0, 1, 2, 3, 4, 5)])
def test_path_type_input(self):
path_test = self.build_operands('dcc,fce,ea,dbf->ab')
path, path_str = np.einsum_path(*path_test, optimize=False)
self.assert_path_equal(path, ['einsum_path', (0, 1, 2, 3)])
path, path_str = np.einsum_path(*path_test, optimize=True)
self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 1), (0, 1)])
exp_path = ['einsum_path', (0, 2), (0, 2), (0, 1)]
path, path_str = np.einsum_path(*path_test, optimize=exp_path)
self.assert_path_equal(path, exp_path)
noopt = np.einsum(*path_test, optimize=False)
opt = np.einsum(*path_test, optimize=exp_path)
assert_almost_equal(noopt, opt)
def test_path_type_input_internal_trace(self):
path_test = self.build_operands('cab,cdd->ab')
exp_path = ['einsum_path', (1,), (0, 1)]
path, path_str = np.einsum_path(*path_test, optimize=exp_path)
self.assert_path_equal(path, exp_path)
noopt = np.einsum(*path_test, optimize=False)
opt = np.einsum(*path_test, optimize=exp_path)
assert_almost_equal(noopt, opt)
def test_path_type_input_invalid(self):
path_test = self.build_operands('ab,bc,cd,de->ae')
exp_path = ['einsum_path', (2, 3), (0, 1)]
assert_raises(RuntimeError, np.einsum, *path_test, optimize=exp_path)
assert_raises(
RuntimeError, np.einsum_path, *path_test, optimize=exp_path)
path_test = self.build_operands('a,a,a->a')
exp_path = ['einsum_path', (1,), (0, 1)]
assert_raises(RuntimeError, np.einsum, *path_test, optimize=exp_path)
assert_raises(
RuntimeError, np.einsum_path, *path_test, optimize=exp_path)
def test_spaces(self):
arr = np.array([[1]])
for sp in itertools.product(['', ' '], repeat=4):
np.einsum('{}...a{}->{}...a{}'.format(*sp), arr)
def test_overlap():
a = np.arange(9, dtype=int).reshape(3, 3)
b = np.arange(9, dtype=int).reshape(3, 3)
d = np.dot(a, b)
c = np.einsum('ij,jk->ik', a, b)
assert_equal(c, d)
c = np.einsum('ij,jk->ik', a, b, out=b)
assert_equal(c, d)