codekingpro/portable-devtools
115k
1import pytest
2
3import numpy as np
4from numpy._core.multiarray import _vec_string
5from numpy.testing import (
6 assert_,
7 assert_array_equal,
8 assert_equal,
9 assert_raises,
10 assert_raises_regex,
11)
12
13kw_unicode_true = {'unicode': True} # make 2to3 work properly
14kw_unicode_false = {'unicode': False}
15
16class TestBasic:
17 def test_from_object_array(self):
18 A = np.array([['abc', 2],
19 ['long ', '0123456789']], dtype='O')
20 B = np.char.array(A)
21 assert_equal(B.dtype.itemsize, 10)
22 assert_array_equal(B, [[b'abc', b'2'],
23 [b'long', b'0123456789']])
24
25 def test_from_object_array_unicode(self):
26 A = np.array([['abc', 'Sigma \u03a3'],
27 ['long ', '0123456789']], dtype='O')
28 assert_raises(ValueError, np.char.array, (A,))
29 B = np.char.array(A, **kw_unicode_true)
30 assert_equal(B.dtype.itemsize, 10 * np.array('a', 'U').dtype.itemsize)
31 assert_array_equal(B, [['abc', 'Sigma \u03a3'],
32 ['long', '0123456789']])
33
34 def test_from_string_array(self):
35 A = np.array([[b'abc', b'foo'],
36 [b'long ', b'0123456789']])
37 assert_equal(A.dtype.type, np.bytes_)
38 B = np.char.array(A)
39 assert_array_equal(B, A)
40 assert_equal(B.dtype, A.dtype)
41 assert_equal(B.shape, A.shape)
42 B[0, 0] = 'changed'
43 assert_(B[0, 0] != A[0, 0])
44 C = np.char.asarray(A)
45 assert_array_equal(C, A)
46 assert_equal(C.dtype, A.dtype)
47 C[0, 0] = 'changed again'
48 assert_(C[0, 0] != B[0, 0])
49 assert_(C[0, 0] == A[0, 0])
50
51 def test_from_unicode_array(self):
52 A = np.array([['abc', 'Sigma \u03a3'],
53 ['long ', '0123456789']])
54 assert_equal(A.dtype.type, np.str_)
55 B = np.char.array(A)
56 assert_array_equal(B, A)
57 assert_equal(B.dtype, A.dtype)
58 assert_equal(B.shape, A.shape)
59 B = np.char.array(A, **kw_unicode_true)
60 assert_array_equal(B, A)
61 assert_equal(B.dtype, A.dtype)
62 assert_equal(B.shape, A.shape)
63
64 def fail():
65 np.char.array(A, **kw_unicode_false)
66
67 assert_raises(UnicodeEncodeError, fail)
68
69 def test_unicode_upconvert(self):
70 A = np.char.array(['abc'])
71 B = np.char.array(['\u03a3'])
72 assert_(issubclass((A + B).dtype.type, np.str_))
73
74 def test_from_string(self):
75 A = np.char.array(b'abc')
76 assert_equal(len(A), 1)
77 assert_equal(len(A[0]), 3)
78 assert_(issubclass(A.dtype.type, np.bytes_))
79
80 def test_from_unicode(self):
81 A = np.char.array('\u03a3')
82 assert_equal(len(A), 1)
83 assert_equal(len(A[0]), 1)
84 assert_equal(A.itemsize, 4)
85 assert_(issubclass(A.dtype.type, np.str_))
86
87class TestVecString:
88 def test_non_existent_method(self):
89
90 def fail():
91 _vec_string('a', np.bytes_, 'bogus')
92
93 assert_raises(AttributeError, fail)
94
95 def test_non_string_array(self):
96
97 def fail():
98 _vec_string(1, np.bytes_, 'strip')
99
100 assert_raises(TypeError, fail)
101
102 def test_invalid_args_tuple(self):
103
104 def fail():
105 _vec_string(['a'], np.bytes_, 'strip', 1)
106
107 assert_raises(TypeError, fail)
108
109 def test_invalid_type_descr(self):
110
111 def fail():
112 _vec_string(['a'], 'BOGUS', 'strip')
113
114 assert_raises(TypeError, fail)
115
116 def test_invalid_function_args(self):
117
118 def fail():
119 _vec_string(['a'], np.bytes_, 'strip', (1,))
120
121 assert_raises(TypeError, fail)
122
123 def test_invalid_result_type(self):
124
125 def fail():
126 _vec_string(['a'], np.int_, 'strip')
127
128 assert_raises(TypeError, fail)
129
130 def test_broadcast_error(self):
131
132 def fail():
133 _vec_string([['abc', 'def']], np.int_, 'find', (['a', 'd', 'j'],))
134
135 assert_raises(ValueError, fail)
136
137class TestWhitespace:
138 def test1(self):
139 A = np.array([['abc ', '123 '],
140 ['789 ', 'xyz ']]).view(np.char.chararray)
141 B = np.array([['abc', '123'],
142 ['789', 'xyz']]).view(np.char.chararray)
143 assert_(np.all(A == B))
144 assert_(np.all(A >= B))
145 assert_(np.all(A <= B))
146 assert_(not np.any(A > B))
147 assert_(not np.any(A < B))
148 assert_(not np.any(A != B))
149
150class TestChar:
151 def test_it(self):
152 A = np.array('abc1', dtype='c').view(np.char.chararray)
153 assert_equal(A.shape, (4,))
154 assert_equal(A.upper()[:2].tobytes(), b'AB')
155
156class TestComparisons:
157 def A(self):
158 return np.array([['abc', 'abcc', '123'],
159 ['789', 'abc', 'xyz']]).view(np.char.chararray)
160
161 def B(self):
162 return np.array([['efg', 'efg', '123 '],
163 ['051', 'efgg', 'tuv']]).view(np.char.chararray)
164
165 def test_not_equal(self):
166 A, B = self.A(), self.B()
167 assert_array_equal((A != B),
168 [[True, True, False], [True, True, True]])
169
170 def test_equal(self):
171 A, B = self.A(), self.B()
172 assert_array_equal((A == B),
173 [[False, False, True], [False, False, False]])
174
175 def test_greater_equal(self):
176 A, B = self.A(), self.B()
177 assert_array_equal((A >= B),
178 [[False, False, True], [True, False, True]])
179
180 def test_less_equal(self):
181 A, B = self.A(), self.B()
182 assert_array_equal((A <= B),
183 [[True, True, True], [False, True, False]])
184
185 def test_greater(self):
186 A, B = self.A(), self.B()
187 assert_array_equal((A > B),
188 [[False, False, False], [True, False, True]])
189
190 def test_less(self):
191 A, B = self.A(), self.B()
192 assert_array_equal((A < B),
193 [[True, True, False], [False, True, False]])
194
195 def test_type(self):
196 A, B = self.A(), self.B()
197 out1 = np.char.equal(A, B)
198 out2 = np.char.equal('a', 'a')
199 assert_(isinstance(out1, np.ndarray))
200 assert_(isinstance(out2, np.ndarray))
201
202class TestComparisonsMixed1(TestComparisons):
203 """Ticket #1276"""
204
205 def B(self):
206 return np.array(
207 [['efg', 'efg', '123 '],
208 ['051', 'efgg', 'tuv']], np.str_).view(np.char.chararray)
209
210class TestComparisonsMixed2(TestComparisons):
211 """Ticket #1276"""
212
213 def A(self):
214 return np.array(
215 [['abc', 'abcc', '123'],
216 ['789', 'abc', 'xyz']], np.str_).view(np.char.chararray)
217
218class TestInformation:
219 def A(self):
220 return np.array([[' abc ', ''],
221 ['12345', 'MixedCase'],
222 ['123 \t 345 \0 ', 'UPPER']]) \
223 .view(np.char.chararray)
224
225 def B(self):
226 return np.array([[' \u03a3 ', ''],
227 ['12345', 'MixedCase'],
228 ['123 \t 345 \0 ', 'UPPER']]) \
229 .view(np.char.chararray)
230
231 def test_len(self):
232 A, B = self.A(), self.B()
233 assert_(issubclass(np.char.str_len(A).dtype.type, np.integer))
234 assert_array_equal(np.char.str_len(A), [[5, 0], [5, 9], [12, 5]])
235 assert_array_equal(np.char.str_len(B), [[3, 0], [5, 9], [12, 5]])
236
237 def test_count(self):
238 A, B = self.A(), self.B()
239 assert_(issubclass(A.count('').dtype.type, np.integer))
240 assert_array_equal(A.count('a'), [[1, 0], [0, 1], [0, 0]])
241 assert_array_equal(A.count('123'), [[0, 0], [1, 0], [1, 0]])
242 # Python doesn't seem to like counting NULL characters
243 assert_array_equal(A.count('a', 0, 2), [[1, 0], [0, 0], [0, 0]])
244 assert_array_equal(B.count('a'), [[0, 0], [0, 1], [0, 0]])
245 assert_array_equal(B.count('123'), [[0, 0], [1, 0], [1, 0]])
246
247 def test_endswith(self):
248 A = self.A()
249 assert_(issubclass(A.endswith('').dtype.type, np.bool))
250 assert_array_equal(A.endswith(' '), [[1, 0], [0, 0], [1, 0]])
251 assert_array_equal(A.endswith('3', 0, 3), [[0, 0], [1, 0], [1, 0]])
252
253 def fail():
254 A.endswith('3', 'fdjk')
255
256 assert_raises(TypeError, fail)
257
258 @pytest.mark.parametrize(
259 "dtype, encode",
260 [("U", str),
261 ("S", lambda x: x.encode('ascii')),
262 ])
263 def test_find(self, dtype, encode):
264 A = self.A().astype(dtype)
265 assert_(issubclass(A.find(encode('a')).dtype.type, np.integer))
266 assert_array_equal(A.find(encode('a')),
267 [[1, -1], [-1, 6], [-1, -1]])
268 assert_array_equal(A.find(encode('3')),
269 [[-1, -1], [2, -1], [2, -1]])
270 assert_array_equal(A.find(encode('a'), 0, 2),
271 [[1, -1], [-1, -1], [-1, -1]])
272 assert_array_equal(A.find([encode('1'), encode('P')]),
273 [[-1, -1], [0, -1], [0, 1]])
274 C = (np.array(['ABCDEFGHIJKLMNOPQRSTUVWXYZ',
275 '01234567890123456789012345'])
276 .view(np.char.chararray)).astype(dtype)
277 assert_array_equal(C.find(encode('M')), [12, -1])
278
279 def test_index(self):
280 A = self.A()
281
282 def fail():
283 A.index('a')
284
285 assert_raises(ValueError, fail)
286 assert_(np.char.index('abcba', 'b') == 1)
287 assert_(issubclass(np.char.index('abcba', 'b').dtype.type, np.integer))
288
289 def test_isalnum(self):
290 A = self.A()
291 assert_(issubclass(A.isalnum().dtype.type, np.bool))
292 assert_array_equal(A.isalnum(), [[False, False], [True, True], [False, True]])
293
294 def test_isalpha(self):
295 A = self.A()
296 assert_(issubclass(A.isalpha().dtype.type, np.bool))
297 assert_array_equal(A.isalpha(), [[False, False], [False, True], [False, True]])
298
299 def test_isdigit(self):
300 A = self.A()
301 assert_(issubclass(A.isdigit().dtype.type, np.bool))
302 assert_array_equal(A.isdigit(), [[False, False], [True, False], [False, False]])
303
304 def test_islower(self):
305 A = self.A()
306 assert_(issubclass(A.islower().dtype.type, np.bool))
307 assert_array_equal(A.islower(), [[True, False], [False, False], [False, False]])
308
309 def test_isspace(self):
310 A = self.A()
311 assert_(issubclass(A.isspace().dtype.type, np.bool))
312 assert_array_equal(A.isspace(), [[False, False], [False, False], [False, False]])
313
314 def test_istitle(self):
315 A = self.A()
316 assert_(issubclass(A.istitle().dtype.type, np.bool))
317 assert_array_equal(A.istitle(), [[False, False], [False, False], [False, False]])
318
319 def test_isupper(self):
320 A = self.A()
321 assert_(issubclass(A.isupper().dtype.type, np.bool))
322 assert_array_equal(A.isupper(), [[False, False], [False, False], [False, True]])
323
324 def test_rfind(self):
325 A = self.A()
326 assert_(issubclass(A.rfind('a').dtype.type, np.integer))
327 assert_array_equal(A.rfind('a'), [[1, -1], [-1, 6], [-1, -1]])
328 assert_array_equal(A.rfind('3'), [[-1, -1], [2, -1], [6, -1]])
329 assert_array_equal(A.rfind('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]])
330 assert_array_equal(A.rfind(['1', 'P']), [[-1, -1], [0, -1], [0, 2]])
331
332 def test_rindex(self):
333 A = self.A()
334
335 def fail():
336 A.rindex('a')
337
338 assert_raises(ValueError, fail)
339 assert_(np.char.rindex('abcba', 'b') == 3)
340 assert_(issubclass(np.char.rindex('abcba', 'b').dtype.type, np.integer))
341
342 def test_startswith(self):
343 A = self.A()
344 assert_(issubclass(A.startswith('').dtype.type, np.bool))
345 assert_array_equal(A.startswith(' '), [[1, 0], [0, 0], [0, 0]])
346 assert_array_equal(A.startswith('1', 0, 3), [[0, 0], [1, 0], [1, 0]])
347
348 def fail():
349 A.startswith('3', 'fdjk')
350
351 assert_raises(TypeError, fail)
352
353class TestMethods:
354 def A(self):
355 return np.array([[' abc ', ''],
356 ['12345', 'MixedCase'],
357 ['123 \t 345 \0 ', 'UPPER']],
358 dtype='S').view(np.char.chararray)
359
360 def B(self):
361 return np.array([[' \u03a3 ', ''],
362 ['12345', 'MixedCase'],
363 ['123 \t 345 \0 ', 'UPPER']]) \
364 .view(np.char.chararray)
365
366 def test_capitalize(self):
367 A, B = self.A(), self.B()
368 tgt = [[b' abc ', b''],
369 [b'12345', b'Mixedcase'],
370 [b'123 \t 345 \0 ', b'Upper']]
371 assert_(issubclass(A.capitalize().dtype.type, np.bytes_))
372 assert_array_equal(A.capitalize(), tgt)
373
374 tgt = [[' \u03c3 ', ''],
375 ['12345', 'Mixedcase'],
376 ['123 \t 345 \0 ', 'Upper']]
377 assert_(issubclass(B.capitalize().dtype.type, np.str_))
378 assert_array_equal(B.capitalize(), tgt)
379
380 def test_center(self):
381 A = self.A()
382 assert_(issubclass(A.center(10).dtype.type, np.bytes_))
383 C = A.center([10, 20])
384 assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
385
386 C = A.center(20, b'#')
387 assert_(np.all(C.startswith(b'#')))
388 assert_(np.all(C.endswith(b'#')))
389
390 C = np.char.center(b'FOO', [[10, 20], [15, 8]])
391 tgt = [[b' FOO ', b' FOO '],
392 [b' FOO ', b' FOO ']]
393 assert_(issubclass(C.dtype.type, np.bytes_))
394 assert_array_equal(C, tgt)
395
396 def test_decode(self):
397 A = np.char.array([b'\\u03a3'])
398 assert_(A.decode('unicode-escape')[0] == '\u03a3')
399
400 def test_encode(self):
401 B = self.B().encode('unicode_escape')
402 assert_(B[0][0] == ' \\u03a3 '.encode('latin1'))
403
404 def test_expandtabs(self):
405 T = self.A().expandtabs()
406 assert_(T[2, 0] == b'123 345 \0')
407
408 def test_join(self):
409 # NOTE: list(b'123') == [49, 50, 51]
410 # so that b','.join(b'123') results to an error on Py3
411 A0 = self.A().decode('ascii')
412
413 A = np.char.join([',', '#'], A0)
414 assert_(issubclass(A.dtype.type, np.str_))
415 tgt = np.array([[' ,a,b,c, ', ''],
416 ['1,2,3,4,5', 'M#i#x#e#d#C#a#s#e'],
417 ['1,2,3, ,\t, ,3,4,5, ,\x00, ', 'U#P#P#E#R']])
418 assert_array_equal(np.char.join([',', '#'], A0), tgt)
419
420 def test_ljust(self):
421 A = self.A()
422 assert_(issubclass(A.ljust(10).dtype.type, np.bytes_))
423
424 C = A.ljust([10, 20])
425 assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
426
427 C = A.ljust(20, b'#')
428 assert_array_equal(C.startswith(b'#'), [
429 [False, True], [False, False], [False, False]])
430 assert_(np.all(C.endswith(b'#')))
431
432 C = np.char.ljust(b'FOO', [[10, 20], [15, 8]])
433 tgt = [[b'FOO ', b'FOO '],
434 [b'FOO ', b'FOO ']]
435 assert_(issubclass(C.dtype.type, np.bytes_))
436 assert_array_equal(C, tgt)
437
438 def test_lower(self):
439 A, B = self.A(), self.B()
440 tgt = [[b' abc ', b''],
441 [b'12345', b'mixedcase'],
442 [b'123 \t 345 \0 ', b'upper']]
443 assert_(issubclass(A.lower().dtype.type, np.bytes_))
444 assert_array_equal(A.lower(), tgt)
445
446 tgt = [[' \u03c3 ', ''],
447 ['12345', 'mixedcase'],
448 ['123 \t 345 \0 ', 'upper']]
449 assert_(issubclass(B.lower().dtype.type, np.str_))
450 assert_array_equal(B.lower(), tgt)
451
452 def test_lstrip(self):
453 A, B = self.A(), self.B()
454 tgt = [[b'abc ', b''],
455 [b'12345', b'MixedCase'],
456 [b'123 \t 345 \0 ', b'UPPER']]
457 assert_(issubclass(A.lstrip().dtype.type, np.bytes_))
458 assert_array_equal(A.lstrip(), tgt)
459
460 tgt = [[b' abc', b''],
461 [b'2345', b'ixedCase'],
462 [b'23 \t 345 \x00', b'UPPER']]
463 assert_array_equal(A.lstrip([b'1', b'M']), tgt)
464
465 tgt = [['\u03a3 ', ''],
466 ['12345', 'MixedCase'],
467 ['123 \t 345 \0 ', 'UPPER']]
468 assert_(issubclass(B.lstrip().dtype.type, np.str_))
469 assert_array_equal(B.lstrip(), tgt)
470
471 def test_partition(self):
472 A = self.A()
473 P = A.partition([b'3', b'M'])
474 tgt = [[(b' abc ', b'', b''), (b'', b'', b'')],
475 [(b'12', b'3', b'45'), (b'', b'M', b'ixedCase')],
476 [(b'12', b'3', b' \t 345 \0 '), (b'UPPER', b'', b'')]]
477 assert_(issubclass(P.dtype.type, np.bytes_))
478 assert_array_equal(P, tgt)
479
480 def test_replace(self):
481 A = self.A()
482 R = A.replace([b'3', b'a'],
483 [b'##########', b'@'])
484 tgt = [[b' abc ', b''],
485 [b'12##########45', b'MixedC@se'],
486 [b'12########## \t ##########45 \x00 ', b'UPPER']]
487 assert_(issubclass(R.dtype.type, np.bytes_))
488 assert_array_equal(R, tgt)
489 # Test special cases that should just return the input array,
490 # since replacements are not possible or do nothing.
491 S1 = A.replace(b'A very long byte string, longer than A', b'')
492 assert_array_equal(S1, A)
493 S2 = A.replace(b'', b'')
494 assert_array_equal(S2, A)
495 S3 = A.replace(b'3', b'3')
496 assert_array_equal(S3, A)
497 S4 = A.replace(b'3', b'', count=0)
498 assert_array_equal(S4, A)
499
500 def test_replace_count_and_size(self):
501 a = np.array(['0123456789' * i for i in range(4)]
502 ).view(np.char.chararray)
503 r1 = a.replace('5', 'ABCDE')
504 assert r1.dtype.itemsize == (3 * 10 + 3 * 4) * 4
505 assert_array_equal(r1, np.array(['01234ABCDE6789' * i
506 for i in range(4)]))
507 r2 = a.replace('5', 'ABCDE', count=1)
508 assert r2.dtype.itemsize == (3 * 10 + 4) * 4
509 r3 = a.replace('5', 'ABCDE', count=0)
510 assert r3.dtype.itemsize == a.dtype.itemsize
511 assert_array_equal(r3, a)
512 # Negative values mean to replace all.
513 r4 = a.replace('5', 'ABCDE', count=-1)
514 assert r4.dtype.itemsize == (3 * 10 + 3 * 4) * 4
515 assert_array_equal(r4, r1)
516 # We can do count on an element-by-element basis.
517 r5 = a.replace('5', 'ABCDE', count=[-1, -1, -1, 1])
518 assert r5.dtype.itemsize == (3 * 10 + 4) * 4
519 assert_array_equal(r5, np.array(
520 ['01234ABCDE6789' * i for i in range(3)]
521 + ['01234ABCDE6789' + '0123456789' * 2]))
522
523 def test_replace_broadcasting(self):
524 a = np.array('0,0,0').view(np.char.chararray)
525 r1 = a.replace('0', '1', count=np.arange(3))
526 assert r1.dtype == a.dtype
527 assert_array_equal(r1, np.array(['0,0,0', '1,0,0', '1,1,0']))
528 r2 = a.replace('0', [['1'], ['2']], count=np.arange(1, 4))
529 assert_array_equal(r2, np.array([['1,0,0', '1,1,0', '1,1,1'],
530 ['2,0,0', '2,2,0', '2,2,2']]))
531 r3 = a.replace(['0', '0,0', '0,0,0'], 'X')
532 assert_array_equal(r3, np.array(['X,X,X', 'X,0', 'X']))
533
534 def test_rjust(self):
535 A = self.A()
536 assert_(issubclass(A.rjust(10).dtype.type, np.bytes_))
537
538 C = A.rjust([10, 20])
539 assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]])
540
541 C = A.rjust(20, b'#')
542 assert_(np.all(C.startswith(b'#')))
543 assert_array_equal(C.endswith(b'#'),
544 [[False, True], [False, False], [False, False]])
545
546 C = np.char.rjust(b'FOO', [[10, 20], [15, 8]])
547 tgt = [[b' FOO', b' FOO'],
548 [b' FOO', b' FOO']]
549 assert_(issubclass(C.dtype.type, np.bytes_))
550 assert_array_equal(C, tgt)
551
552 def test_rpartition(self):
553 A = self.A()
554 P = A.rpartition([b'3', b'M'])
555 tgt = [[(b'', b'', b' abc '), (b'', b'', b'')],
556 [(b'12', b'3', b'45'), (b'', b'M', b'ixedCase')],
557 [(b'123 \t ', b'3', b'45 \0 '), (b'', b'', b'UPPER')]]
558 assert_(issubclass(P.dtype.type, np.bytes_))
559 assert_array_equal(P, tgt)
560
561 def test_rsplit(self):
562 A = self.A().rsplit(b'3')
563 tgt = [[[b' abc '], [b'']],
564 [[b'12', b'45'], [b'MixedCase']],
565 [[b'12', b' \t ', b'45 \x00 '], [b'UPPER']]]
566 assert_(issubclass(A.dtype.type, np.object_))
567 assert_equal(A.tolist(), tgt)
568
569 def test_rstrip(self):
570 A, B = self.A(), self.B()
571 assert_(issubclass(A.rstrip().dtype.type, np.bytes_))
572
573 tgt = [[b' abc', b''],
574 [b'12345', b'MixedCase'],
575 [b'123 \t 345', b'UPPER']]
576 assert_array_equal(A.rstrip(), tgt)
577
578 tgt = [[b' abc ', b''],
579 [b'1234', b'MixedCase'],
580 [b'123 \t 345 \x00', b'UPP']
581 ]
582 assert_array_equal(A.rstrip([b'5', b'ER']), tgt)
583
584 tgt = [[' \u03a3', ''],
585 ['12345', 'MixedCase'],
586 ['123 \t 345', 'UPPER']]
587 assert_(issubclass(B.rstrip().dtype.type, np.str_))
588 assert_array_equal(B.rstrip(), tgt)
589
590 def test_strip(self):
591 A, B = self.A(), self.B()
592 tgt = [[b'abc', b''],
593 [b'12345', b'MixedCase'],
594 [b'123 \t 345', b'UPPER']]
595 assert_(issubclass(A.strip().dtype.type, np.bytes_))
596 assert_array_equal(A.strip(), tgt)
597
598 tgt = [[b' abc ', b''],
599 [b'234', b'ixedCas'],
600 [b'23 \t 345 \x00', b'UPP']]
601 assert_array_equal(A.strip([b'15', b'EReM']), tgt)
602
603 tgt = [['\u03a3', ''],
604 ['12345', 'MixedCase'],
605 ['123 \t 345', 'UPPER']]
606 assert_(issubclass(B.strip().dtype.type, np.str_))
607 assert_array_equal(B.strip(), tgt)
608
609 def test_split(self):
610 A = self.A().split(b'3')
611 tgt = [
612 [[b' abc '], [b'']],
613 [[b'12', b'45'], [b'MixedCase']],
614 [[b'12', b' \t ', b'45 \x00 '], [b'UPPER']]]
615 assert_(issubclass(A.dtype.type, np.object_))
616 assert_equal(A.tolist(), tgt)
617
618 def test_splitlines(self):
619 A = np.char.array(['abc\nfds\nwer']).splitlines()
620 assert_(issubclass(A.dtype.type, np.object_))
621 assert_(A.shape == (1,))
622 assert_(len(A[0]) == 3)
623
624 def test_swapcase(self):
625 A, B = self.A(), self.B()
626 tgt = [[b' ABC ', b''],
627 [b'12345', b'mIXEDcASE'],
628 [b'123 \t 345 \0 ', b'upper']]
629 assert_(issubclass(A.swapcase().dtype.type, np.bytes_))
630 assert_array_equal(A.swapcase(), tgt)
631
632 tgt = [[' \u03c3 ', ''],
633 ['12345', 'mIXEDcASE'],
634 ['123 \t 345 \0 ', 'upper']]
635 assert_(issubclass(B.swapcase().dtype.type, np.str_))
636 assert_array_equal(B.swapcase(), tgt)
637
638 def test_title(self):
639 A, B = self.A(), self.B()
640 tgt = [[b' Abc ', b''],
641 [b'12345', b'Mixedcase'],
642 [b'123 \t 345 \0 ', b'Upper']]
643 assert_(issubclass(A.title().dtype.type, np.bytes_))
644 assert_array_equal(A.title(), tgt)
645
646 tgt = [[' \u03a3 ', ''],
647 ['12345', 'Mixedcase'],
648 ['123 \t 345 \0 ', 'Upper']]
649 assert_(issubclass(B.title().dtype.type, np.str_))
650 assert_array_equal(B.title(), tgt)
651
652 def test_upper(self):
653 A, B = self.A(), self.B()
654 tgt = [[b' ABC ', b''],
655 [b'12345', b'MIXEDCASE'],
656 [b'123 \t 345 \0 ', b'UPPER']]
657 assert_(issubclass(A.upper().dtype.type, np.bytes_))
658 assert_array_equal(A.upper(), tgt)
659
660 tgt = [[' \u03a3 ', ''],
661 ['12345', 'MIXEDCASE'],
662 ['123 \t 345 \0 ', 'UPPER']]
663 assert_(issubclass(B.upper().dtype.type, np.str_))
664 assert_array_equal(B.upper(), tgt)
665
666 def test_isnumeric(self):
667 A, B = self.A(), self.B()
668
669 def fail():
670 A.isnumeric()
671
672 assert_raises(TypeError, fail)
673 assert_(issubclass(B.isnumeric().dtype.type, np.bool))
674 assert_array_equal(B.isnumeric(), [
675 [False, False], [True, False], [False, False]])
676
677 def test_isdecimal(self):
678 A, B = self.A(), self.B()
679
680 def fail():
681 A.isdecimal()
682
683 assert_raises(TypeError, fail)
684 assert_(issubclass(B.isdecimal().dtype.type, np.bool))
685 assert_array_equal(B.isdecimal(), [
686 [False, False], [True, False], [False, False]])
687
688class TestOperations:
689 def A(self):
690 return np.array([['abc', '123'],
691 ['789', 'xyz']]).view(np.char.chararray)
692
693 def B(self):
694 return np.array([['efg', '456'],
695 ['051', 'tuv']]).view(np.char.chararray)
696
697 def test_argsort(self):
698 arr = np.array(['abc'] * 4).view(np.char.chararray)
699 actual = arr.argsort(stable=True)
700 assert_array_equal(actual, [0, 1, 2, 3])
701
702 def test_add(self):
703 A, B = self.A(), self.B()
704 AB = np.array([['abcefg', '123456'],
705 ['789051', 'xyztuv']]).view(np.char.chararray)
706 assert_array_equal(AB, (A + B))
707 assert_(len((A + B)[0][0]) == 6)
708
709 def test_radd(self):
710 A = self.A()
711 QA = np.array([['qabc', 'q123'],
712 ['q789', 'qxyz']]).view(np.char.chararray)
713 assert_array_equal(QA, ('q' + A))
714
715 def test_mul(self):
716 A = self.A()
717 for r in (2, 3, 5, 7, 197):
718 Ar = np.array([[A[0, 0] * r, A[0, 1] * r],
719 [A[1, 0] * r, A[1, 1] * r]]).view(np.char.chararray)
720
721 assert_array_equal(Ar, (A * r))
722
723 for ob in [object(), 'qrs']:
724 with assert_raises_regex(ValueError,
725 'Can only multiply by integers'):
726 A * ob
727
728 def test_rmul(self):
729 A = self.A()
730 for r in (2, 3, 5, 7, 197):
731 Ar = np.array([[A[0, 0] * r, A[0, 1] * r],
732 [A[1, 0] * r, A[1, 1] * r]]).view(np.char.chararray)
733 assert_array_equal(Ar, (r * A))
734
735 for ob in [object(), 'qrs']:
736 with assert_raises_regex(ValueError,
737 'Can only multiply by integers'):
738 ob * A
739
740 def test_mod(self):
741 """Ticket #856"""
742 F = np.array([['%d', '%f'], ['%s', '%r']]).view(np.char.chararray)
743 C = np.array([[3, 7], [19, 1]], dtype=np.int64)
744 FC = np.array([['3', '7.000000'],
745 ['19', 'np.int64(1)']]).view(np.char.chararray)
746 assert_array_equal(FC, F % C)
747
748 A = np.array([['%.3f', '%d'], ['%s', '%r']]).view(np.char.chararray)
749 A1 = np.array([['1.000', '1'],
750 ['1', repr(np.array(1)[()])]]).view(np.char.chararray)
751 assert_array_equal(A1, (A % 1))
752
753 A2 = np.array([['1.000', '2'],
754 ['3', repr(np.array(4)[()])]]).view(np.char.chararray)
755 assert_array_equal(A2, (A % [[1, 2], [3, 4]]))
756
757 def test_rmod(self):
758 A = self.A()
759 assert_(f"{A}" == str(A))
760 assert_(f"{A!r}" == repr(A))
761
762 for ob in [42, object()]:
763 with assert_raises_regex(
764 TypeError, "unsupported operand type.* and 'chararray'"):
765 ob % A
766
767 def test_slice(self):
768 """Regression test for https://github.com/numpy/numpy/issues/5982"""
769
770 arr = np.array([['abc ', 'def '], ['geh ', 'ijk ']],
771 dtype='S4').view(np.char.chararray)
772 sl1 = arr[:]
773 assert_array_equal(sl1, arr)
774 assert_(sl1.base is arr)
775 assert_(sl1.base.base is arr.base)
776
777 sl2 = arr[:, :]
778 assert_array_equal(sl2, arr)
779 assert_(sl2.base is arr)
780 assert_(sl2.base.base is arr.base)
781
782 assert_(arr[0, 0] == b'abc')
783
784 @pytest.mark.parametrize('data', [['plate', ' ', 'shrimp'],
785 [b'retro', b' ', b'encabulator']])
786 def test_getitem_length_zero_item(self, data):
787 # Regression test for gh-26375.
788 a = np.char.array(data)
789 # a.dtype.type() will be an empty string or bytes instance.
790 # The equality test will fail if a[1] has the wrong type
791 # or does not have length 0.
792 assert_equal(a[1], a.dtype.type())
793
794class TestMethodsEmptyArray:
795 def test_encode(self):
796 res = np.char.encode(np.array([], dtype='U'))
797 assert_array_equal(res, [])
798 assert_(res.dtype.char == 'S')
799
800 def test_decode(self):
801 res = np.char.decode(np.array([], dtype='S'))
802 assert_array_equal(res, [])
803 assert_(res.dtype.char == 'U')
804
805 def test_decode_with_reshape(self):
806 res = np.char.decode(np.array([], dtype='S').reshape((1, 0, 1)))
807 assert_(res.shape == (1, 0, 1))
808
809class TestMethodsScalarValues:
810 def test_mod(self):
811 A = np.array([[' abc ', ''],
812 ['12345', 'MixedCase'],
813 ['123 \t 345 \0 ', 'UPPER']], dtype='S')
814 tgt = [[b'123 abc ', b'123'],
815 [b'12312345', b'123MixedCase'],
816 [b'123123 \t 345 \0 ', b'123UPPER']]
817 assert_array_equal(np.char.mod(b"123%s", A), tgt)
818
819 def test_decode(self):
820 bytestring = b'\x81\xc1\x81\xc1\x81\xc1'
821 assert_equal(np.char.decode(bytestring, encoding='cp037'),
822 'aAaAaA')
823
824 def test_encode(self):
825 unicode = 'aAaAaA'
826 assert_equal(np.char.encode(unicode, encoding='cp037'),
827 b'\x81\xc1\x81\xc1\x81\xc1')
828
829 def test_expandtabs(self):
830 s = "\tone level of indentation\n\t\ttwo levels of indentation"
831 assert_equal(
832 np.char.expandtabs(s, tabsize=2),
833 " one level of indentation\n two levels of indentation"
834 )
835
836 def test_join(self):
837 seps = np.array(['-', '_'])
838 assert_array_equal(np.char.join(seps, 'hello'),
839 ['h-e-l-l-o', 'h_e_l_l_o'])
840
841 def test_partition(self):
842 assert_equal(np.char.partition('This string', ' '),
843 ['This', ' ', 'string'])
844
845 def test_rpartition(self):
846 assert_equal(np.char.rpartition('This string here', ' '),
847 ['This string', ' ', 'here'])
848
849 def test_replace(self):
850 assert_equal(np.char.replace('Python is good', 'good', 'great'),
851 'Python is great')
852
853def test_empty_indexing():
854 """Regression test for ticket 1948."""
855 # Check that indexing a chararray with an empty list/array returns an
856 # empty chararray instead of a chararray with a single empty string in it.
857 s = np.char.chararray((4,))
858 assert_(s[[]].size == 0)
859 