xnd 0.2.0dev3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +42 -0
  3. data/Gemfile +3 -0
  4. data/History.md +0 -0
  5. data/README.md +7 -0
  6. data/Rakefile +135 -0
  7. data/ext/ruby_xnd/extconf.rb +70 -0
  8. data/ext/ruby_xnd/float_pack_unpack.c +277 -0
  9. data/ext/ruby_xnd/float_pack_unpack.h +39 -0
  10. data/ext/ruby_xnd/gc_guard.c +36 -0
  11. data/ext/ruby_xnd/gc_guard.h +12 -0
  12. data/ext/ruby_xnd/include/xnd.h +449 -0
  13. data/ext/ruby_xnd/lib/libxnd.a +0 -0
  14. data/ext/ruby_xnd/lib/libxnd.so +1 -0
  15. data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
  16. data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
  17. data/ext/ruby_xnd/memory_block_object.c +32 -0
  18. data/ext/ruby_xnd/memory_block_object.h +33 -0
  19. data/ext/ruby_xnd/ruby_xnd.c +1953 -0
  20. data/ext/ruby_xnd/ruby_xnd.h +61 -0
  21. data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
  22. data/ext/ruby_xnd/util.h +170 -0
  23. data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
  24. data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
  25. data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
  26. data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
  27. data/ext/ruby_xnd/xnd/Makefile.in +80 -0
  28. data/ext/ruby_xnd/xnd/README.rst +44 -0
  29. data/ext/ruby_xnd/xnd/config.guess +1530 -0
  30. data/ext/ruby_xnd/xnd/config.h.in +22 -0
  31. data/ext/ruby_xnd/xnd/config.sub +1782 -0
  32. data/ext/ruby_xnd/xnd/configure +4867 -0
  33. data/ext/ruby_xnd/xnd/configure.ac +164 -0
  34. data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
  35. data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
  36. data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
  37. data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
  38. data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
  39. data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
  40. data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
  41. data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
  42. data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
  43. data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
  44. data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
  45. data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
  46. data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
  47. data/ext/ruby_xnd/xnd/install-sh +527 -0
  48. data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
  49. data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
  50. data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
  51. data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
  52. data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
  53. data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
  54. data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
  55. data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
  56. data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
  57. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
  58. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
  59. data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
  60. data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
  61. data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
  62. data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
  63. data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
  64. data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
  65. data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
  66. data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
  67. data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
  68. data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
  69. data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
  70. data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
  71. data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
  72. data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
  73. data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
  74. data/ext/ruby_xnd/xnd/setup.py +303 -0
  75. data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
  76. data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
  77. data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
  78. data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
  79. data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
  80. data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
  81. data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
  82. data/lib/ruby_xnd.so +0 -0
  83. data/lib/xnd.rb +306 -0
  84. data/lib/xnd/monkeys.rb +29 -0
  85. data/lib/xnd/version.rb +6 -0
  86. data/spec/debug_spec.rb +9 -0
  87. data/spec/gc_guard_spec.rb +10 -0
  88. data/spec/leakcheck.rb +9 -0
  89. data/spec/spec_helper.rb +877 -0
  90. data/spec/type_inference_spec.rb +81 -0
  91. data/spec/xnd_spec.rb +2921 -0
  92. data/xnd.gemspec +47 -0
  93. metadata +215 -0
@@ -0,0 +1,449 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #ifndef XND_H
35
+ #define XND_H
36
+
37
+
38
+ #include <stdlib.h>
39
+ #include <stdint.h>
40
+ #include <string.h>
41
+ #include <assert.h>
42
+ #include "ndtypes.h"
43
+
44
+
45
+ #ifdef _MSC_VER
46
+ #if defined (XND_EXPORT)
47
+ #define XND_API __declspec(dllexport)
48
+ #elif defined(XND_IMPORT)
49
+ #define XND_API __declspec(dllimport)
50
+ #else
51
+ #define XND_API
52
+ #endif
53
+ #else
54
+ #define XND_API
55
+ #endif
56
+
57
+
58
+ #if SIZE_MAX == UINT64_MAX
59
+ #define XND_SSIZE_MAX INT64_MAX
60
+ #elif SIZE_MAX == UINT32_MAX
61
+ #define XND_SSIZE_MAX INT32_MAX
62
+ #else
63
+ #error "unsupported platform: need 32-bit or 64-bit size_t"
64
+ #endif
65
+
66
+
67
+ /*
68
+ * Ownership flags: The library itself has no notion of how many exported
69
+ * views a master buffer has. The Python bindings for example use Pythons's
70
+ * reference counting to to keep track of exported memory blocks.
71
+ */
72
+ #define XND_OWN_TYPE 0x00000001U /* type pointer */
73
+ #define XND_OWN_DATA 0x00000002U /* data pointer */
74
+ #define XND_OWN_STRINGS 0x00000004U /* embedded string pointers */
75
+ #define XND_OWN_BYTES 0x00000008U /* embedded bytes pointers */
76
+ #define XND_OWN_POINTERS 0x00000010U /* embedded pointers */
77
+
78
+ #define XND_OWN_ALL (XND_OWN_TYPE | \
79
+ XND_OWN_DATA | \
80
+ XND_OWN_STRINGS | \
81
+ XND_OWN_BYTES | \
82
+ XND_OWN_POINTERS)
83
+
84
+ #define XND_OWN_EMBEDDED (XND_OWN_DATA | \
85
+ XND_OWN_STRINGS | \
86
+ XND_OWN_BYTES | \
87
+ XND_OWN_POINTERS)
88
+
89
+
90
+ /* Convenience macros to extract embedded values. */
91
+ #define XND_POINTER_DATA(ptr) (*((char **)ptr))
92
+ #define XND_BYTES_SIZE(ptr) (((ndt_bytes_t *)ptr)->size)
93
+ #define XND_BYTES_DATA(ptr) (((ndt_bytes_t *)ptr)->data)
94
+
95
+
96
+ /* Bitmap tree. */
97
+ typedef struct xnd_bitmap xnd_bitmap_t;
98
+
99
+ struct xnd_bitmap {
100
+ uint8_t *data; /* bitmap */
101
+ int64_t size; /* number of subtree bitmaps in the "next" array */
102
+ xnd_bitmap_t *next; /* array of bitmaps for subtrees */
103
+ };
104
+
105
+ /* Typed memory block, usually a view. */
106
+ typedef struct xnd {
107
+ xnd_bitmap_t bitmap; /* bitmap tree */
108
+ int64_t index; /* linear index for var dims */
109
+ const ndt_t *type; /* type of the data */
110
+ char *ptr; /* data */
111
+ } xnd_t;
112
+
113
+ /* Master memory block. */
114
+ typedef struct xnd_master {
115
+ uint32_t flags; /* ownership flags */
116
+ xnd_t master; /* typed memory */
117
+ } xnd_master_t;
118
+
119
+ /* Used in indexing and slicing. */
120
+ enum xnd_key { Index, FieldName, Slice };
121
+ typedef struct {
122
+ enum xnd_key tag;
123
+ union {
124
+ int64_t Index;
125
+ const char *FieldName;
126
+ ndt_slice_t Slice;
127
+ };
128
+ } xnd_index_t;
129
+
130
+
131
+ /* Unstable API: view with ownership tracking. */
132
+ typedef struct xnd_view {
133
+ uint32_t flags; /* flags that indicate resource ownership by the view */
134
+ const void *obj; /* object that holds shared resources */
135
+ xnd_t view; /* typed memory */
136
+ } xnd_view_t;
137
+
138
+
139
+ /*****************************************************************************/
140
+ /* Create xnd memory blocks */
141
+ /*****************************************************************************/
142
+
143
+ XND_API xnd_master_t *xnd_empty_from_string(const char *s, uint32_t flags, ndt_context_t *ctx);
144
+ XND_API xnd_master_t *xnd_empty_from_type(const ndt_t *t, uint32_t flags, ndt_context_t *ctx);
145
+ XND_API void xnd_del(xnd_master_t *x);
146
+
147
+ /* Create and delete pristine xnd_t buffers. */
148
+ XND_API xnd_master_t *xnd_from_xnd(xnd_t *src, uint32_t flags, ndt_context_t *ctx);
149
+ XND_API void xnd_del_buffer(xnd_t *x, uint32_t flags);
150
+
151
+
152
+ /*****************************************************************************/
153
+ /* Traverse xnd memory blocks */
154
+ /*****************************************************************************/
155
+
156
+ XND_API xnd_t xnd_subtree_index(const xnd_t *x, const int64_t *indices, int len,
157
+ ndt_context_t *ctx);
158
+
159
+ XND_API xnd_t xnd_subtree(const xnd_t *x, const xnd_index_t indices[], int len,
160
+ ndt_context_t *ctx);
161
+
162
+ XND_API xnd_t xnd_multikey(const xnd_t *x, const xnd_index_t indices[], int len,
163
+ ndt_context_t *ctx);
164
+
165
+ XND_API xnd_t xnd_subscript(const xnd_t *x, const xnd_index_t indices[], int len,
166
+ ndt_context_t *ctx);
167
+
168
+ XND_API xnd_t *xnd_split(const xnd_t *x, int64_t *n, int max_outer, ndt_context_t *ctx);
169
+
170
+ XND_API int xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx);
171
+ XND_API int xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx);
172
+
173
+ XND_API int xnd_copy(xnd_t *y, const xnd_t *x, uint32_t flags, ndt_context_t *ctx);
174
+
175
+
176
+ /*****************************************************************************/
177
+ /* Bitmaps */
178
+ /*****************************************************************************/
179
+
180
+ XND_API int xnd_bitmap_init(xnd_bitmap_t *b, const ndt_t *t, ndt_context_t *ctx);
181
+ XND_API void xnd_bitmap_clear(xnd_bitmap_t *b);
182
+ XND_API xnd_bitmap_t xnd_bitmap_next(const xnd_t *x, int64_t i, ndt_context_t *ctx);
183
+ XND_API void xnd_set_valid(xnd_t *x);
184
+ XND_API void xnd_set_na(xnd_t *x);
185
+ XND_API int xnd_is_valid(const xnd_t *x);
186
+ XND_API int xnd_is_na(const xnd_t *x);
187
+
188
+
189
+ /*****************************************************************************/
190
+ /* Error handling */
191
+ /*****************************************************************************/
192
+
193
+ XND_API extern const xnd_t xnd_error;
194
+ XND_API extern const xnd_bitmap_t xnd_bitmap_empty;
195
+
196
+
197
+ /*****************************************************************************/
198
+ /* Unstable API */
199
+ /*****************************************************************************/
200
+
201
+ XND_API extern const xnd_view_t xnd_view_error;
202
+
203
+ XND_API int xnd_view_err_occurred(const xnd_view_t *x);
204
+ XND_API void xnd_view_clear(xnd_view_t *x);
205
+ XND_API xnd_view_t xnd_view_from_xnd(const void *obj, const xnd_t *x);
206
+ XND_API xnd_view_t xnd_view_subscript(const xnd_view_t *x, const xnd_index_t indices[],
207
+ int len, ndt_context_t *ctx);
208
+
209
+
210
+
211
+ /*****************************************************************************/
212
+ /* Float format */
213
+ /*****************************************************************************/
214
+
215
+ XND_API int xnd_init_float(ndt_context_t *ctx);
216
+ XND_API bool xnd_float_is_little_endian(void);
217
+ XND_API bool xnd_float_is_big_endian(void);
218
+ XND_API bool xnd_double_is_little_endian(void);
219
+ XND_API bool xnd_double_is_big_endian(void);
220
+
221
+
222
+ /*****************************************************************************/
223
+ /* Static inline functions */
224
+ /*****************************************************************************/
225
+
226
+ /*
227
+ * This looks inefficient, but both gcc and clang clean up unused xnd_t members.
228
+ */
229
+ static inline int64_t
230
+ xnd_ndim(const xnd_t *x)
231
+ {
232
+ return x->type->ndim;
233
+ }
234
+
235
+ static inline xnd_t
236
+ xnd_fixed_dim_next(const xnd_t *x, const int64_t i)
237
+ {
238
+ const ndt_t *t = x->type;
239
+ const ndt_t *u = t->FixedDim.type;
240
+ const int64_t step = i * t->Concrete.FixedDim.step;
241
+ xnd_t next;
242
+
243
+ assert(t->tag == FixedDim);
244
+
245
+ next.bitmap = x->bitmap;
246
+ next.index = x->index + step;
247
+ next.type = u;
248
+ next.ptr = u->ndim==0 ? x->ptr + next.index * next.type->datasize : x->ptr;
249
+
250
+ return next;
251
+ }
252
+
253
+ static inline int64_t
254
+ xnd_fixed_shape(const xnd_t *x)
255
+ {
256
+ const ndt_t *t = x->type;
257
+ assert(t->tag == FixedDim);
258
+ return t->FixedDim.shape;
259
+ }
260
+
261
+ static inline int64_t
262
+ xnd_fixed_shape_at(const xnd_t *x, const int i)
263
+ {
264
+ const ndt_t *t = x->type;
265
+
266
+ assert(0 <= i && i < t->ndim);
267
+ assert(t->tag == FixedDim);
268
+
269
+ for (int k = 0; k < i; k++) {
270
+ t = t->FixedDim.type;
271
+ }
272
+ return t->FixedDim.shape;
273
+ }
274
+
275
+ static inline int64_t
276
+ xnd_fixed_stride(const xnd_t *x)
277
+ {
278
+ const ndt_t *t = x->type;
279
+ assert(t->tag == FixedDim);
280
+ return t->Concrete.FixedDim.step * t->Concrete.FixedDim.itemsize;
281
+ }
282
+
283
+ static inline char *
284
+ xnd_fixed_apply_index(const xnd_t *x)
285
+ {
286
+ assert(x->type->tag == FixedDim);
287
+ return x->ptr + x->index * x->type->Concrete.FixedDim.itemsize;
288
+ }
289
+
290
+ static inline xnd_t
291
+ xnd_var_dim_next(const xnd_t *x, const int64_t start, const int64_t step,
292
+ const int64_t i)
293
+ {
294
+ const ndt_t *t = x->type;
295
+ const ndt_t *u = t->VarDim.type;
296
+ xnd_t next;
297
+
298
+ next.bitmap = x->bitmap;
299
+ next.index = start + i * step;
300
+ next.type = u;
301
+ next.ptr = u->ndim==0 ? x->ptr + next.index * next.type->datasize : x->ptr;
302
+
303
+ return next;
304
+ }
305
+
306
+ static inline xnd_t
307
+ xnd_tuple_next(const xnd_t *x, const int64_t i, ndt_context_t *ctx)
308
+ {
309
+ const ndt_t *t = x->type;
310
+ xnd_t next;
311
+
312
+ next.bitmap = xnd_bitmap_next(x, i, ctx);
313
+ if (ndt_err_occurred(ctx)) {
314
+ return xnd_error;
315
+ }
316
+
317
+ next.index = 0;
318
+ next.type = t->Tuple.types[i];
319
+ next.ptr = x->ptr + t->Concrete.Tuple.offset[i];
320
+
321
+ return next;
322
+ }
323
+
324
+ static inline xnd_t
325
+ xnd_record_next(const xnd_t *x, const int64_t i, ndt_context_t *ctx)
326
+ {
327
+ const ndt_t *t = x->type;
328
+ xnd_t next;
329
+
330
+ next.bitmap = xnd_bitmap_next(x, i, ctx);
331
+ if (ndt_err_occurred(ctx)) {
332
+ return xnd_error;
333
+ }
334
+
335
+ next.index = 0;
336
+ next.type = t->Record.types[i];
337
+ next.ptr = x->ptr + t->Concrete.Record.offset[i];
338
+
339
+ return next;
340
+ }
341
+
342
+ static inline xnd_t
343
+ xnd_ref_next(const xnd_t *x, ndt_context_t *ctx)
344
+ {
345
+ const ndt_t *t = x->type;
346
+ xnd_t next;
347
+
348
+ next.bitmap = xnd_bitmap_next(x, 0, ctx);
349
+ if (ndt_err_occurred(ctx)) {
350
+ return xnd_error;
351
+ }
352
+
353
+ next.index = 0;
354
+ next.type = t->Ref.type;
355
+ next.ptr = XND_POINTER_DATA(x->ptr);
356
+
357
+ return next;
358
+ }
359
+
360
+ static inline xnd_t
361
+ xnd_constr_next(const xnd_t *x, ndt_context_t *ctx)
362
+ {
363
+ const ndt_t *t = x->type;
364
+ xnd_t next;
365
+
366
+ next.bitmap = xnd_bitmap_next(x, 0, ctx);
367
+ if (ndt_err_occurred(ctx)) {
368
+ return xnd_error;
369
+ }
370
+
371
+ next.index = 0;
372
+ next.type = t->Constr.type;
373
+ next.ptr = x->ptr;
374
+
375
+ return next;
376
+ }
377
+
378
+ static inline xnd_t
379
+ xnd_nominal_next(const xnd_t *x, ndt_context_t *ctx)
380
+ {
381
+ const ndt_t *t = x->type;
382
+ xnd_t next;
383
+
384
+ next.bitmap = xnd_bitmap_next(x, 0, ctx);
385
+ if (ndt_err_occurred(ctx)) {
386
+ return xnd_error;
387
+ }
388
+
389
+ next.index = 0;
390
+ next.type = t->Nominal.type;
391
+ next.ptr = x->ptr;
392
+
393
+ return next;
394
+ }
395
+
396
+ #if NDT_SYS_BIG_ENDIAN == 1
397
+ #define XND_REV_COND NDT_LITTLE_ENDIAN
398
+ #else
399
+ #define XND_REV_COND NDT_BIG_ENDIAN
400
+ #endif
401
+
402
+ static inline void
403
+ memcpy_rev(char *dest, const char *src, size_t size)
404
+ {
405
+ size_t i;
406
+
407
+ for (i = 0; i < size; i++) {
408
+ dest[i] = src[size-1-i];
409
+ }
410
+ }
411
+
412
+ static inline void
413
+ bcopy_swap(char *dest, const char *src, size_t size, uint32_t flags)
414
+ {
415
+ if (flags & XND_REV_COND) {
416
+ memcpy_rev(dest, src, size);
417
+ }
418
+ else {
419
+ memcpy(dest, src, size);
420
+ }
421
+ }
422
+
423
+ static inline int
424
+ le(uint32_t flags)
425
+ {
426
+ #if NDT_SYS_BIG_ENDIAN == 1
427
+ return flags & NDT_LITTLE_ENDIAN;
428
+ #else
429
+ return !(flags & NDT_BIG_ENDIAN);
430
+ #endif
431
+ }
432
+
433
+
434
+ #define PACK_SINGLE(ptr, src, type, flags) \
435
+ do { \
436
+ type _x; \
437
+ _x = (type)src; \
438
+ bcopy_swap(ptr, (const char *)&_x, sizeof _x, flags); \
439
+ } while (0)
440
+
441
+ #define UNPACK_SINGLE(dest, ptr, type, flags) \
442
+ do { \
443
+ type _x; \
444
+ bcopy_swap((char *)&_x, ptr, sizeof _x, flags); \
445
+ dest = _x; \
446
+ } while (0)
447
+
448
+
449
+ #endif /* XND_H */
@@ -0,0 +1,3144 @@
1
+ #
2
+ # BSD 3-Clause License
3
+ #
4
+ # Copyright (c) 2017-2018, plures
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ #
13
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ #
17
+ # 3. Neither the name of the copyright holder nor the names of its
18
+ # contributors may be used to endorse or promote products derived from
19
+ # this software without specific prior written permission.
20
+ #
21
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+
33
+ import sys, unittest, argparse
34
+ from math import isinf, isnan
35
+ from ndtypes import ndt, typedef
36
+ from xnd import xnd, XndEllipsis
37
+ from xnd._xnd import _test_view_subscript, _test_view_new
38
+ from xnd_support import *
39
+ from xnd_randvalue import *
40
+ from _testbuffer import ndarray, ND_WRITABLE
41
+
42
+
43
+ try:
44
+ import numpy as np
45
+ except ImportError:
46
+ np = None
47
+
48
+
49
+ SKIP_LONG = True
50
+ SKIP_BRUTE_FORCE = True
51
+
52
+
53
+ def check_buffer(x):
54
+ try:
55
+ y = memoryview(x)
56
+ except ValueError:
57
+ return
58
+ with memoryview(x) as y:
59
+ del x
60
+ y.tobytes()
61
+
62
+
63
+ class XndTestCase(unittest.TestCase):
64
+
65
+ def assertStrictEqual(self, x, y):
66
+ self.assertTrue(x.strict_equal(y))
67
+ self.assertEqual(x, y)
68
+
69
+ def assertNotStrictEqual(self, x, y):
70
+ self.assertFalse(x.strict_equal(y))
71
+ self.assertNotEqual(x, y)
72
+
73
+
74
+ class TestModule(XndTestCase):
75
+
76
+ def test_module(self):
77
+ test_cases = [
78
+ "Foo:: 2 * 3 * ?int64",
79
+ "Foo:: 10 * 2 * ?string",
80
+ "Bar:: !10 * 2 * {a: !2 * ?int64}",
81
+ "Quux:: {a: string, b: ?bytes}"
82
+ ]
83
+
84
+ for s in test_cases:
85
+ self.assertRaises(ValueError, xnd.empty, s)
86
+
87
+
88
+ class TestFunction(XndTestCase):
89
+
90
+ def test_function(self):
91
+ test_cases = [
92
+ "(2 * 3 * ?int64, complex128) -> (T, T)",
93
+ "(2 * 3 * ?int64, {a: float64, b: bytes}) -> bytes",
94
+ ]
95
+
96
+ for s in test_cases:
97
+ self.assertRaises(ValueError, xnd.empty, s)
98
+
99
+
100
+ class TestVoid(XndTestCase):
101
+
102
+ def test_void(self):
103
+ self.assertRaises(ValueError, xnd.empty, "void")
104
+ self.assertRaises(ValueError, xnd.empty, "10 * 2 * void")
105
+
106
+
107
+ class TestAny(XndTestCase):
108
+
109
+ def test_any(self):
110
+ test_cases = [
111
+ "Any",
112
+ "10 * 2 * Any",
113
+ "10 * N * int64",
114
+ "{a: string, b: Any}"
115
+ ]
116
+
117
+ for s in test_cases:
118
+ self.assertRaises(ValueError, xnd.empty, s)
119
+
120
+
121
+ class TestFixedDim(XndTestCase):
122
+
123
+ def test_fixed_dim_empty(self):
124
+ for v, s in DTYPE_EMPTY_TEST_CASES:
125
+ for vv, ss in [
126
+ (0 * [v], "0 * %s" % s),
127
+ (1 * [v], "1 * %s" % s),
128
+ (2 * [v], "2 * %s" % s),
129
+ (1000 * [v], "1000 * %s" % s),
130
+
131
+ (0 * [0 * [v]], "0 * 0 * %s" % s),
132
+ (0 * [1 * [v]], "0 * 1 * %s" % s),
133
+ (1 * [0 * [v]], "1 * 0 * %s" % s),
134
+
135
+ (1 * [1 * [v]], "1 * 1 * %s" % s),
136
+ (1 * [2 * [v]], "1 * 2 * %s" % s),
137
+ (2 * [1 * [v]], "2 * 1 * %s" % s),
138
+ (2 * [2 * [v]], "2 * 2 * %s" % s),
139
+ (2 * [3 * [v]], "2 * 3 * %s" % s),
140
+ (3 * [2 * [v]], "3 * 2 * %s" % s),
141
+ (3 * [40 * [v]], "3 * 40 * %s" % s) ]:
142
+
143
+ t = ndt(ss)
144
+ x = xnd.empty(ss)
145
+ self.assertEqual(x.type, t)
146
+ self.assertEqual(x.value, vv)
147
+ self.assertEqual(len(x), len(vv))
148
+
149
+ def test_fixed_dim_subscript(self):
150
+ test_cases = [
151
+ ([[11.12-2.3j, -1222+20e8j],
152
+ [complex("inf"), -0.00002j],
153
+ [0.201+1j, -1+1e301j]], "3 * 2 * complex128"),
154
+ ([[11.12-2.3j, None],
155
+ [complex("inf"), None],
156
+ [0.201+1j, -1+1e301j]], "3 * 2 * ?complex128")
157
+ ]
158
+
159
+ for v, s in test_cases:
160
+ nd = NDArray(v)
161
+ t = ndt(s)
162
+ x = xnd(v, type=t)
163
+ check_buffer(x)
164
+
165
+ for i in range(3):
166
+ self.assertEqual(x[i].value, nd[i])
167
+
168
+ for i in range(3):
169
+ for k in range(2):
170
+ self.assertEqual(x[i][k], nd[i][k])
171
+ self.assertEqual(x[i, k], nd[i][k])
172
+
173
+ self.assertEqual(x[:].value, nd[:])
174
+
175
+ for start in list(range(-3, 4)) + [None]:
176
+ for stop in list(range(-3, 4)) + [None]:
177
+ for step in list(range(-3, 0)) + list(range(1, 4)) + [None]:
178
+ s = slice(start, stop, step)
179
+ self.assertEqual(x[s].value, nd[s])
180
+ check_buffer(x[s])
181
+
182
+ self.assertEqual(x[:, 0].value, nd[:, 0])
183
+ self.assertEqual(x[:, 1].value, nd[:, 1])
184
+
185
+ def test_fixed_dim_assign(self):
186
+ ### Regular data ###
187
+ x = xnd.empty("2 * 4 * float64")
188
+ v = [[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]]
189
+
190
+ # Full slice
191
+ x[:] = v
192
+ self.assertEqual(x.value, v)
193
+
194
+ # Subarray
195
+ x[0] = v[0] = [1.2, -3e45, float("inf"), -322.25]
196
+ self.assertEqual(x.value, v)
197
+
198
+ x[1] = v[1] = [-11.25, 3.355e301, -0.000002, -5000.2]
199
+ self.assertEqual(x.value, v)
200
+
201
+ # Single values
202
+ for i in range(2):
203
+ for j in range(4):
204
+ x[i][j] = v[i][j] = 3.22 * i + j
205
+ self.assertEqual(x.value, v)
206
+
207
+ # Tuple indexing
208
+ for i in range(2):
209
+ for j in range(4):
210
+ x[i, j] = v[i][j] = -3.002e1 * i + j
211
+ self.assertEqual(x.value, v)
212
+
213
+
214
+ ### Optional data ###
215
+ x = xnd.empty("2 * 4 * ?float64")
216
+ v = [[10.0, None, 2.0, 100.12], [None, None, 6.0, 7.0]]
217
+
218
+ # Full slice
219
+ x[:] = v
220
+ self.assertEqual(x.value, v)
221
+
222
+ # Subarray
223
+ x[0] = v[0] = [None, 3e45, float("inf"), None]
224
+ self.assertEqual(x.value, v)
225
+
226
+ x[1] = v[1] = [-11.25, 3.355e301, -0.000002, None]
227
+ self.assertEqual(x.value, v)
228
+
229
+ # Single values
230
+ for i in range(2):
231
+ for j in range(4):
232
+ x[i][j] = v[i][j] = -325.99 * i + j
233
+ self.assertEqual(x.value, v)
234
+
235
+ # Tuple indexing
236
+ for i in range(2):
237
+ for j in range(4):
238
+ x[i, j] = v[i][j] = -8.33e1 * i + j
239
+ self.assertEqual(x.value, v)
240
+
241
+ @unittest.skipIf(sys.platform == "darwin",
242
+ "mach_vm_map message defeats the purpose of this test")
243
+ def test_fixed_dim_overflow(self):
244
+ # Type cannot be created.
245
+ s = "2147483648 * 2147483648 * 2 * uint8"
246
+ self.assertRaises(ValueError, xnd.empty, s)
247
+
248
+ if HAVE_64_BIT:
249
+ # Allocation fails.
250
+ s = "2147483648 * 2147483647 * 2 * uint8"
251
+ self.assertRaises(MemoryError, xnd.empty, s)
252
+ else:
253
+ # Allocation fails.
254
+ s = "32768 * 32768 * 2 * uint8"
255
+ self.assertRaises(MemoryError, xnd.empty, s)
256
+
257
+ def test_fixed_dim_richcompare(self):
258
+
259
+ x = xnd([1,2,3,4])
260
+
261
+ self.assertIs(x.__lt__(x), NotImplemented)
262
+ self.assertIs(x.__le__(x), NotImplemented)
263
+ self.assertIs(x.__gt__(x), NotImplemented)
264
+ self.assertIs(x.__ge__(x), NotImplemented)
265
+
266
+ self.assertStrictEqual(x, xnd([1,2,3,4]))
267
+
268
+ # Different shape and/or data.
269
+ self.assertNotStrictEqual(x, xnd([1,2,3,100]))
270
+ self.assertNotStrictEqual(x, xnd([1,2,3]))
271
+ self.assertNotStrictEqual(x, xnd([1,2,3,4,5]))
272
+
273
+ # Different shape.
274
+ self.assertNotStrictEqual(x, xnd([1,2,3]))
275
+ self.assertNotStrictEqual(x, xnd([[1,2,3,4]]))
276
+ self.assertNotStrictEqual(x, xnd([[1,2], [3,4]]))
277
+
278
+ # Simple multidimensional arrays.
279
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
280
+ y = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
281
+ self.assertStrictEqual(x, y)
282
+
283
+ for i in range(4):
284
+ for k in range(3):
285
+ v = y[i, k]
286
+ y[i, k] = 100
287
+ self.assertNotStrictEqual(x, y)
288
+ y[i, k] = v
289
+
290
+ # C <-> Fortran.
291
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
292
+ y = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="!4 * 3 * int64")
293
+ self.assertStrictEqual(x, y)
294
+
295
+ for i in range(4):
296
+ for k in range(3):
297
+ v = y[i, k]
298
+ y[i, k] = 100
299
+ self.assertNotStrictEqual(x, y)
300
+ y[i, k] = v
301
+
302
+ # Slices.
303
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
304
+ y = xnd([[1,2,3], [7,8,9]], type="!2 * 3 * int64")
305
+ self.assertStrictEqual(x[::2], y)
306
+
307
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
308
+ y = xnd([1,4,7,10])
309
+ self.assertStrictEqual(x[:, 0], y)
310
+
311
+ # Test corner cases and many dtypes.
312
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
313
+ for vv, tt, uu in [
314
+ (0 * [v], "0 * %s" % t, "0 * %s" % u),
315
+ (0 * [0 * [v]], "0 * 0 * %s" % t, "0 * 0 * %s" % u),
316
+ (0 * [1 * [v]], "0 * 1 * %s" % t, "0 * 1 * %s" % u),
317
+ (1 * [0 * [v]], "1 * 0 * %s" % t, "1 * 0 * %s" % u)]:
318
+
319
+ ttt = ndt(tt)
320
+
321
+ x = xnd(vv, type=ttt)
322
+ y = xnd(vv, type=ttt)
323
+ self.assertStrictEqual(x, y)
324
+
325
+ if u is not None:
326
+ uuu = ndt(uu)
327
+ y = xnd(vv, type=uuu)
328
+ self.assertStrictEqual(x, y)
329
+
330
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
331
+ for vv, tt, uu, indices in [
332
+ (1 * [v], "1 * %s" % t, "1 * %s" % u, (0,)),
333
+ (2 * [v], "2 * %s" % t, "2 * %s" % u, (1,)),
334
+ (1000 * [v], "1000 * %s" % t, "1000 * %s" % u, (961,)),
335
+
336
+ (1 * [1 * [v]], "1 * 1 * %s" % t, "1 * 1 * %s" % u, (0, 0)),
337
+ (1 * [2 * [v]], "1 * 2 * %s" % t, "1 * 2 * %s" % u, (0, 1)),
338
+ (2 * [1 * [v]], "2 * 1 * %s" % t, "2 * 1 * %s" % u, (1, 0)),
339
+ (2 * [2 * [v]], "2 * 2 * %s" % t, "2 * 2 * %s" % u, (1, 1)),
340
+ (2 * [3 * [v]], "2 * 3 * %s" % t, "2 * 3 * %s" % u, (1, 2)),
341
+ (3 * [2 * [v]], "3 * 2 * %s" % t, "3 * 2 * %s" % u, (2, 1)),
342
+ (3 * [40 * [v]], "3 * 40 * %s" % t, "3 * 40 * %s" % u, (1, 32))]:
343
+
344
+ ttt = ndt(tt)
345
+ uuu = ndt(uu)
346
+
347
+ x = xnd(vv, type=ttt)
348
+
349
+ y = xnd(vv, type=ttt)
350
+ if eq:
351
+ self.assertStrictEqual(x, y)
352
+ else:
353
+ self.assertNotStrictEqual(x, y)
354
+
355
+ if u is not None:
356
+ y = xnd(vv, type=uuu)
357
+ if eq:
358
+ self.assertStrictEqual(x, y)
359
+ else:
360
+ self.assertNotStrictEqual(x, y)
361
+
362
+ if w is not None:
363
+ y = xnd(vv, type=ttt)
364
+ y[indices] = w
365
+ self.assertNotStrictEqual(x, y)
366
+
367
+ y = xnd(vv, type=uuu)
368
+ y[indices] = w
369
+ self.assertNotStrictEqual(x, y)
370
+
371
+
372
+ class TestFortran(XndTestCase):
373
+
374
+ def test_fortran_empty(self):
375
+ for v, s in DTYPE_EMPTY_TEST_CASES:
376
+ for vv, ss in [
377
+ (0 * [v], "!0 * %s" % s),
378
+ (1 * [v], "!1 * %s" % s),
379
+ (2 * [v], "!2 * %s" % s),
380
+ (1000 * [v], "!1000 * %s" % s),
381
+
382
+ (0 * [0 * [v]], "!0 * 0 * %s" % s),
383
+ (0 * [1 * [v]], "!0 * 1 * %s" % s),
384
+ (1 * [0 * [v]], "!1 * 0 * %s" % s),
385
+
386
+ (1 * [1 * [v]], "!1 * 1 * %s" % s),
387
+ (1 * [2 * [v]], "!1 * 2 * %s" % s),
388
+ (2 * [1 * [v]], "!2 * 1 * %s" % s),
389
+ (2 * [2 * [v]], "!2 * 2 * %s" % s),
390
+ (2 * [3 * [v]], "!2 * 3 * %s" % s),
391
+ (3 * [2 * [v]], "!3 * 2 * %s" % s),
392
+ (3 * [40 * [v]], "!3 * 40 * %s" % s) ]:
393
+
394
+ t = ndt(ss)
395
+ x = xnd.empty(ss)
396
+ self.assertEqual(x.type, t)
397
+ self.assertEqual(x.value, vv)
398
+ self.assertEqual(len(x), len(vv))
399
+
400
+ def test_fortran_subscript(self):
401
+ test_cases = [
402
+ ([[11.12-2.3j, -1222+20e8j],
403
+ [complex("inf"), -0.00002j],
404
+ [0.201+1j, -1+1e301j]], "!3 * 2 * complex128"),
405
+ ([[11.12-2.3j, None],
406
+ [complex("inf"), None],
407
+ [0.201+1j, -1+1e301j]], "!3 * 2 * ?complex128")
408
+ ]
409
+
410
+ for v, s in test_cases:
411
+ nd = NDArray(v)
412
+ t = ndt(s)
413
+ x = xnd(v, type=t)
414
+ check_buffer(x)
415
+
416
+ for i in range(3):
417
+ self.assertEqual(x[i].value, nd[i])
418
+
419
+ for i in range(3):
420
+ for k in range(2):
421
+ self.assertEqual(x[i][k], nd[i][k])
422
+ self.assertEqual(x[i, k], nd[i][k])
423
+
424
+ self.assertEqual(x[:].value, nd[:])
425
+
426
+ for start in list(range(-3, 4)) + [None]:
427
+ for stop in list(range(-3, 4)) + [None]:
428
+ for step in list(range(-3, 0)) + list(range(1, 4)) + [None]:
429
+ s = slice(start, stop, step)
430
+ self.assertEqual(x[s].value, nd[s])
431
+ check_buffer(x[s])
432
+
433
+ self.assertEqual(x[:, 0].value, nd[:, 0])
434
+ self.assertEqual(x[:, 1].value, nd[:, 1])
435
+
436
+ def test_fortran_assign(self):
437
+ ### Regular data ###
438
+ x = xnd.empty("!2 * 4 * float64")
439
+ v = [[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]]
440
+
441
+ # Full slice
442
+ x[:] = v
443
+ self.assertEqual(x.value, v)
444
+
445
+ # Subarray
446
+ x[0] = v[0] = [1.2, -3e45, float("inf"), -322.25]
447
+ self.assertEqual(x.value, v)
448
+
449
+ x[1] = v[1] = [-11.25, 3.355e301, -0.000002, -5000.2]
450
+ self.assertEqual(x.value, v)
451
+
452
+ # Single values
453
+ for i in range(2):
454
+ for j in range(4):
455
+ x[i][j] = v[i][j] = 3.22 * i + j
456
+ self.assertEqual(x.value, v)
457
+
458
+ # Tuple indexing
459
+ for i in range(2):
460
+ for j in range(4):
461
+ x[i, j] = v[i][j] = -3.002e1 * i + j
462
+ self.assertEqual(x.value, v)
463
+
464
+
465
+ ### Optional data ###
466
+ x = xnd.empty("!2 * 4 * ?float64")
467
+ v = [[10.0, None, 2.0, 100.12], [None, None, 6.0, 7.0]]
468
+
469
+ # Full slice
470
+ x[:] = v
471
+ self.assertEqual(x.value, v)
472
+
473
+ # Subarray
474
+ x[0] = v[0] = [None, 3e45, float("inf"), None]
475
+ self.assertEqual(x.value, v)
476
+
477
+ x[1] = v[1] = [-11.25, 3.355e301, -0.000002, None]
478
+ self.assertEqual(x.value, v)
479
+
480
+ # Single values
481
+ for i in range(2):
482
+ for j in range(4):
483
+ x[i][j] = v[i][j] = -325.99 * i + j
484
+ self.assertEqual(x.value, v)
485
+
486
+ # Tuple indexing
487
+ for i in range(2):
488
+ for j in range(4):
489
+ x[i, j] = v[i][j] = -8.33e1 * i + j
490
+ self.assertEqual(x.value, v)
491
+
492
+ @unittest.skipIf(sys.platform == "darwin",
493
+ "mach_vm_map message defeats the purpose of this test")
494
+ def test_fortran_overflow(self):
495
+ # Type cannot be created.
496
+ s = "!2147483648 * 2147483648 * 2 * uint8"
497
+ self.assertRaises(ValueError, xnd.empty, s)
498
+
499
+ if HAVE_64_BIT:
500
+ # Allocation fails.
501
+ s = "!2147483648 * 2147483647 * 2 * uint8"
502
+ self.assertRaises(MemoryError, xnd.empty, s)
503
+ else:
504
+ # Allocation fails.
505
+ s = "!32768 * 32768 * 2 * uint8"
506
+ self.assertRaises(MemoryError, xnd.empty, s)
507
+
508
+ def test_fortran_richcompare(self):
509
+
510
+ x = xnd([1,2,3,4], type="!4 * int64")
511
+
512
+ self.assertIs(x.__lt__(x), NotImplemented)
513
+ self.assertIs(x.__le__(x), NotImplemented)
514
+ self.assertIs(x.__gt__(x), NotImplemented)
515
+ self.assertIs(x.__ge__(x), NotImplemented)
516
+
517
+ self.assertStrictEqual(x, xnd([1,2,3,4], type="!4 * int64"))
518
+
519
+ # Different shape and/or data.
520
+ self.assertNotStrictEqual(x, xnd([1,2,3,100], type="!4 * int64"))
521
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="!3 * int64"))
522
+ self.assertNotStrictEqual(x, xnd([1,2,3,4,5], type="!5 * int64"))
523
+
524
+ # Different shape.
525
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="!3 * int64"))
526
+ self.assertNotStrictEqual(x, xnd([[1,2,3,4]], type="!1 * 4 * int64"))
527
+ self.assertNotStrictEqual(x, xnd([[1,2], [3,4]], type="!2 * 2 * int64"))
528
+
529
+ # Simple multidimensional arrays.
530
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="!4 * 3 * int64")
531
+ y = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="!4 * 3 * int64")
532
+ self.assertStrictEqual(x, y)
533
+
534
+ for i in range(4):
535
+ for k in range(3):
536
+ v = y[i, k]
537
+ y[i, k] = 100
538
+ self.assertNotStrictEqual(x, y)
539
+ y[i, k] = v
540
+
541
+ # Fortran <-> C.
542
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="!4 * 3 * int64")
543
+ y = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
544
+ self.assertStrictEqual(x, y)
545
+
546
+ for i in range(4):
547
+ for k in range(3):
548
+ v = y[i, k]
549
+ y[i, k] = 100
550
+ self.assertNotStrictEqual(x, y)
551
+ y[i, k] = v
552
+
553
+ # Slices.
554
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="!4 * 3 * int64")
555
+ y = xnd([[1,2,3], [7,8,9]])
556
+ self.assertStrictEqual(x[::2], y)
557
+
558
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="!4 * 3 * int64")
559
+ y = xnd([1,4,7,10], type="!4 * int64")
560
+ self.assertStrictEqual(x[:, 0], y)
561
+
562
+ # Test corner cases and many dtypes.
563
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
564
+ for vv, tt, uu in [
565
+ (0 * [v], "!0 * %s" % t, "!0 * %s" % u),
566
+ (0 * [0 * [v]], "!0 * 0 * %s" % t, "!0 * 0 * %s" % u),
567
+ (0 * [1 * [v]], "!0 * 1 * %s" % t, "!0 * 1 * %s" % u),
568
+ (1 * [0 * [v]], "!1 * 0 * %s" % t, "!1 * 0 * %s" % u)]:
569
+
570
+ ttt = ndt(tt)
571
+
572
+ x = xnd(vv, type=ttt)
573
+ y = xnd(vv, type=ttt)
574
+ self.assertStrictEqual(x, y)
575
+
576
+ if u is not None:
577
+ uuu = ndt(uu)
578
+ y = xnd(vv, type=uuu)
579
+ self.assertStrictEqual(x, y)
580
+
581
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
582
+ for vv, tt, uu, indices in [
583
+ (1 * [v], "!1 * %s" % t, "!1 * %s" % u, (0,)),
584
+ (2 * [v], "!2 * %s" % t, "!2 * %s" % u, (1,)),
585
+ (1000 * [v], "!1000 * %s" % t, "!1000 * %s" % u, (961,)),
586
+
587
+ (1 * [1 * [v]], "!1 * 1 * %s" % t, "!1 * 1 * %s" % u, (0, 0)),
588
+ (1 * [2 * [v]], "!1 * 2 * %s" % t, "!1 * 2 * %s" % u, (0, 1)),
589
+ (2 * [1 * [v]], "!2 * 1 * %s" % t, "!2 * 1 * %s" % u, (1, 0)),
590
+ (2 * [2 * [v]], "!2 * 2 * %s" % t, "!2 * 2 * %s" % u, (1, 1)),
591
+ (2 * [3 * [v]], "!2 * 3 * %s" % t, "!2 * 3 * %s" % u, (1, 2)),
592
+ (3 * [2 * [v]], "!3 * 2 * %s" % t, "!3 * 2 * %s" % u, (2, 1)),
593
+ (3 * [40 * [v]], "!3 * 40 * %s" % t, "!3 * 40 * %s" % u, (1, 32))]:
594
+
595
+ ttt = ndt(tt)
596
+
597
+ x = xnd(vv, type=ttt)
598
+ y = xnd(vv, type=ttt)
599
+ if eq:
600
+ self.assertStrictEqual(x, y)
601
+ else:
602
+ self.assertNotStrictEqual(x, y)
603
+
604
+ if u is not None:
605
+ uuu = ndt(uu)
606
+ y = xnd(vv, type=uuu)
607
+ if eq:
608
+ self.assertStrictEqual(x, y)
609
+ else:
610
+ self.assertNotStrictEqual(x, y)
611
+
612
+ if w is not None:
613
+ y = xnd(vv, type=ttt)
614
+ y[indices] = w
615
+ self.assertNotStrictEqual(x, y)
616
+
617
+ y = xnd(vv, type=uuu)
618
+ y[indices] = w
619
+ self.assertNotStrictEqual(x, y)
620
+
621
+
622
+ class TestVarDim(XndTestCase):
623
+
624
+ def test_var_dim_empty(self):
625
+ for v, s in DTYPE_EMPTY_TEST_CASES:
626
+ for vv, ss in [
627
+ (0 * [v], "var(offsets=[0,0]) * %s" % s),
628
+ (1 * [v], "var(offsets=[0,1]) * %s" % s),
629
+ (2 * [v], "var(offsets=[0,2]) * %s" % s),
630
+ (1000 * [v], "var(offsets=[0,1000]) * %s" % s),
631
+
632
+ (1 * [0 * [v]], "var(offsets=[0,1]) * var(offsets=[0,0]) * %s" % s),
633
+
634
+ ([[v], []], "var(offsets=[0,2]) * var(offsets=[0,1,1]) * %s" % s),
635
+ ([[], [v]], "var(offsets=[0,2]) * var(offsets=[0,0,1]) * %s" % s),
636
+
637
+ ([[v], [v]], "var(offsets=[0,2]) * var(offsets=[0,1,2]) * %s" % s),
638
+ ([[v], 2 * [v], 5 * [v]], "var(offsets=[0,3]) * var(offsets=[0,1,3,8]) * %s" % s)]:
639
+
640
+ t = ndt(ss)
641
+ x = xnd.empty(ss)
642
+ self.assertEqual(x.type, t)
643
+ self.assertEqual(x.value, vv)
644
+ self.assertEqual(len(x), len(vv))
645
+
646
+ def test_var_dim_assign(self):
647
+ ### Regular data ###
648
+ x = xnd.empty("var(offsets=[0,2]) * var(offsets=[0,2,5]) * float64")
649
+ v = [[0.0, 1.0], [2.0, 3.0, 4.0]]
650
+
651
+ # Full slice assignment
652
+ x[:] = v
653
+ self.assertEqual(x.value, v)
654
+
655
+ # Subarray assignment
656
+ x[0] = v[0] = [1.2, 2.5]
657
+ self.assertEqual(x.value, v)
658
+
659
+ x[1] = v[1] = [1.2, 2.5, 3.99]
660
+ self.assertEqual(x.value, v)
661
+
662
+ # Individual value assignment
663
+ for i in range(2):
664
+ x[0][i] = v[0][i] = 100.0 * i
665
+ for i in range(3):
666
+ x[1][i] = v[1][i] = 200.0 * i
667
+ self.assertEqual(x.value, v)
668
+
669
+ # Tuple indexing assignment
670
+ for i in range(2):
671
+ x[0, i] = v[0][i] = 300.0 * i + 1.222
672
+ for i in range(3):
673
+ x[1, i] = v[1][i] = 400.0 * i + 1.333
674
+
675
+ # Optional data
676
+ x = xnd.empty("var(offsets=[0,2]) * var(offsets=[0,2,5]) * ?float64")
677
+ v = [[0.0, None], [None, 3.0, 4.0]]
678
+
679
+ # Full slice assignment
680
+ x[:] = v
681
+ self.assertEqual(x.value, v)
682
+
683
+ # Subarray assignment
684
+ x[0] = v[0] = [None, 2.0]
685
+ self.assertEqual(x.value, v)
686
+
687
+ x[1] = v[1] = [1.22214, None, 10.0]
688
+ self.assertEqual(x.value, v)
689
+
690
+ # Individual value assignment
691
+ for i in range(2):
692
+ x[0][i] = v[0][i] = 3.14 * i + 1.222
693
+ for i in range(3):
694
+ x[1][i] = v[1][i] = 23.333 * i
695
+ self.assertEqual(x.value, v)
696
+
697
+ # Tuple indexing assignment
698
+ for i in range(2):
699
+ x[0, i] = v[0][i] = -122.5 * i + 1.222
700
+ for i in range(3):
701
+ x[1, i] = v[1][i] = -3e22 * i
702
+ self.assertEqual(x.value, v)
703
+
704
+ def test_var_dim_overflow(self):
705
+ s = "var(offsets=[0, 2]) * var(offsets=[0, 1073741824, 2147483648]) * uint8"
706
+ self.assertRaises(ValueError, xnd.empty, s)
707
+
708
+ def test_var_dim_match(self):
709
+ def type_equal(t, u):
710
+ return t.match(u) and u.match(t)
711
+
712
+ x = xnd([0, 1, 2, 3, 4], type="var(offsets=[0,5]) * complex128")
713
+ sig = ndt("var... * complex128 -> var... * complex128")
714
+
715
+ spec = sig.apply([x.type])
716
+ self.assertTrue(type_equal(spec.out_types[0], x.type))
717
+
718
+ y = x[::-1]
719
+ spec = sig.apply([y.type])
720
+ self.assertTrue(type_equal(spec.out_types[0], y.type))
721
+
722
+ y = x[1:3:-1]
723
+ spec = sig.apply([y.type])
724
+ self.assertTrue(type_equal(spec.out_types[0], y.type))
725
+
726
+ sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
727
+ spec = sig.apply([x.type, x.type])
728
+ self.assertTrue(type_equal(spec.out_types[0], x.type))
729
+
730
+ y = x[::-1]
731
+ sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
732
+ spec = sig.apply([x.type, y.type])
733
+ self.assertTrue(type_equal(spec.out_types[0], x.type))
734
+
735
+ x = xnd([[0], [1, 2], [3, 4, 5]], dtype="complex128")
736
+ y = xnd([[3, 4, 5], [1, 2], [0]], dtype="complex128")
737
+ z = y[::-1]
738
+ sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
739
+ spec = sig.apply([x.type, z.type])
740
+ self.assertTrue(type_equal(spec.out_types[0], x.type))
741
+
742
+ x = xnd([[0], [1, 2], [3, 4, 5]], dtype="complex128")
743
+ y = xnd([[5, 4, 3], [2, 1], [0]], dtype="complex128")
744
+ z = y[::-1, ::-1]
745
+ sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
746
+ spec = sig.apply([x.type, z.type])
747
+ self.assertTrue(type_equal(spec.out_types[0], x.type))
748
+
749
+ def test_var_dim_richcompare(self):
750
+
751
+ x = xnd([1,2,3,4], type="var(offsets=[0,4]) * int64")
752
+
753
+ self.assertIs(x.__lt__(x), NotImplemented)
754
+ self.assertIs(x.__le__(x), NotImplemented)
755
+ self.assertIs(x.__gt__(x), NotImplemented)
756
+ self.assertIs(x.__ge__(x), NotImplemented)
757
+
758
+ self.assertStrictEqual(x, xnd([1,2,3,4], type="var(offsets=[0,4]) * int64"))
759
+
760
+ # Different shape and/or data.
761
+ self.assertNotStrictEqual(x, xnd([1,2,3,100], type="var(offsets=[0,4]) * int64"))
762
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="var(offsets=[0,3]) * int64"))
763
+ self.assertNotStrictEqual(x, xnd([1,2,3,4,5], type="var(offsets=[0,5]) * int64"))
764
+
765
+ # Different shape.
766
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="var(offsets=[0,3]) * int64"))
767
+ self.assertNotStrictEqual(x, xnd([[1,2,3,4]], type="var(offsets=[0,1]) * var(offsets=[0,4]) * int64"))
768
+ self.assertNotStrictEqual(x, xnd([[1,2], [3,4]], type="var(offsets=[0,2]) * var(offsets=[0,2,4]) * int64"))
769
+
770
+ # Simple multidimensional arrays.
771
+ x = xnd([[1], [2,3,4,5], [6,7], [8,9,10]])
772
+ y = xnd([[1], [2,3,4,5], [6,7], [8,9,10]])
773
+ self.assertStrictEqual(x, y)
774
+
775
+ for i, shape in zip(range(4), (1, 4, 2, 3)):
776
+ for k in range(shape):
777
+ v = y[i, k]
778
+ y[i, k] = 100
779
+ self.assertNotStrictEqual(x, y)
780
+ y[i, k] = v
781
+
782
+ y = xnd([[1], [2,3,5], [6,7], [8,9,10]])
783
+ self.assertNotStrictEqual(x, y)
784
+
785
+ # Slices.
786
+ x = xnd([[1], [4,5], [6,7,8], [9,10,11,12]])
787
+
788
+ y = xnd([[1], [6,7,8]])
789
+ self.assertStrictEqual(x[::2], y)
790
+
791
+ y = xnd([[9,10,11,12], [4,5]])
792
+ self.assertStrictEqual(x[::-2], y)
793
+
794
+ y = xnd([[12,11,10,9], [5,4]])
795
+ self.assertStrictEqual(x[::-2, ::-1], y)
796
+
797
+ # Test corner cases and many dtypes.
798
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
799
+ for vv, tt, uu in [
800
+ (0 * [v], "var(offsets=[0,0]) * %s" % t,
801
+ "var(offsets=[0,0]) * %s" % u),
802
+ (1 * [0 * [v]], "var(offsets=[0,1]) * var(offsets=[0,0]) * %s" % t,
803
+ "var(offsets=[0,1]) * var(offsets=[0,0]) * %s" % u)]:
804
+
805
+ ttt = ndt(tt)
806
+
807
+ x = xnd(vv, type=ttt)
808
+ y = xnd(vv, type=ttt)
809
+ self.assertStrictEqual(x, y)
810
+
811
+ if u is not None:
812
+ uuu = ndt(uu)
813
+ y = xnd(vv, type=uuu)
814
+ self.assertStrictEqual(x, y)
815
+
816
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
817
+ for vv, tt, uu, indices in [
818
+ (1 * [v], "var(offsets=[0,1]) * %s" % t, "var(offsets=[0,1]) * %s" % u, (0,)),
819
+ (2 * [v], "var(offsets=[0,2]) * %s" % t, "var(offsets=[0,2]) * %s" % u, (1,)),
820
+ (1000 * [v], "var(offsets=[0,1000]) * %s" % t, "var(offsets=[0,1000]) * %s" % u, (961,)),
821
+ ([[v], []], "var(offsets=[0,2]) * var(offsets=[0,1,1]) * %s" % t,
822
+ "var(offsets=[0,2]) * var(offsets=[0,1,1]) * %s" % u, (0, 0)),
823
+ ([[], [v]], "var(offsets=[0,2]) * var(offsets=[0,0,1]) * %s" % t,
824
+ "var(offsets=[0,2]) * var(offsets=[0,0,1]) * %s" % u, (1, 0)),
825
+ ([[v], [v]], "var(offsets=[0,2]) * var(offsets=[0,1,2]) * %s" % t,
826
+ "var(offsets=[0,2]) * var(offsets=[0,1,2]) * %s" % u, (1, 0)),
827
+ ([[v], 2 * [v], 5 * [v]], "var(offsets=[0,3]) * var(offsets=[0,1,3,8]) * %s" % t,
828
+ "var(offsets=[0,3]) * var(offsets=[0,1,3,8]) * %s" % u, (2, 3))]:
829
+
830
+ ttt = ndt(tt)
831
+
832
+ x = xnd(vv, type=ttt)
833
+ y = xnd(vv, type=ttt)
834
+ if eq:
835
+ self.assertStrictEqual(x, y)
836
+ else:
837
+ self.assertNotStrictEqual(x, y)
838
+
839
+ if u is not None:
840
+ uuu = ndt(uu)
841
+ y = xnd(vv, type=uuu)
842
+ if eq:
843
+ self.assertStrictEqual(x, y)
844
+ else:
845
+ self.assertNotStrictEqual(x, y)
846
+
847
+ if w is not None:
848
+ y = xnd(vv, type=ttt)
849
+ y[indices] = w
850
+ self.assertNotStrictEqual(x, y)
851
+
852
+ y = xnd(vv, type=uuu)
853
+ y[indices] = w
854
+ self.assertNotStrictEqual(x, y)
855
+
856
+
857
+ class TestSymbolicDim(XndTestCase):
858
+
859
+ def test_symbolic_dim_raise(self):
860
+ for _, s in DTYPE_EMPTY_TEST_CASES:
861
+ for err, ss in [
862
+ (ValueError, "N * %s" % s),
863
+ (ValueError, "10 * N * %s" % s),
864
+ (ValueError, "N * 10 * N * %s" % s),
865
+ (ValueError, "X * 10 * N * %s" % s)]:
866
+
867
+ t = ndt(ss)
868
+ self.assertRaises(err, xnd.empty, t)
869
+
870
+
871
+ class TestEllipsisDim(XndTestCase):
872
+
873
+ def test_ellipsis_dim_raise(self):
874
+ for _, s in DTYPE_EMPTY_TEST_CASES:
875
+ for err, ss in [
876
+ (ValueError, "... * %s" % s),
877
+ (ValueError, "Dims... * %s" % s),
878
+ (ValueError, "... * 10 * %s" % s),
879
+ (ValueError, "B... *2 * 3 * ref(%s)" % s),
880
+ (ValueError, "A... * 10 * Some(ref(%s))" % s),
881
+ (ValueError, "B... * 2 * 3 * Some(ref(ref(%s)))" % s)]:
882
+
883
+ t = ndt(ss)
884
+ self.assertRaises(err, xnd.empty, t)
885
+
886
+
887
+ class TestTuple(XndTestCase):
888
+
889
+ def test_tuple_empty(self):
890
+ for v, s in DTYPE_EMPTY_TEST_CASES:
891
+ for vv, ss in [
892
+ ((v,), "(%s)" % s),
893
+ (((v,),), "((%s))" % s),
894
+ ((((v,),),), "(((%s)))" % s),
895
+
896
+ ((0 * [v],), "(0 * %s)" % s),
897
+ (((0 * [v],),), "((0 * %s))" % s),
898
+ ((1 * [v],), "(1 * %s)" % s),
899
+ (((1 * [v],),), "((1 * %s))" % s),
900
+ ((3 * [v],), "(3 * %s)" % s),
901
+ (((3 * [v],),), "((3 * %s))" % s)]:
902
+
903
+ t = ndt(ss)
904
+ x = xnd.empty(ss)
905
+ self.assertEqual(x.type, t)
906
+ self.assertEqual(x.value, vv)
907
+ self.assertEqual(len(x), len(vv))
908
+
909
+ def test_tuple_assign(self):
910
+ ### Regular data ###
911
+ x = xnd.empty("(complex64, bytes, string)")
912
+ v = (1+20j, b"abc", "any")
913
+
914
+ x[0] = v[0]
915
+ x[1] = v[1]
916
+ x[2] = v[2]
917
+
918
+ self.assertEqual(x.value, v)
919
+
920
+ ### Optional data ###
921
+ x = xnd.empty("(complex64, ?bytes, ?string)")
922
+ v = (1+20j, None, "Some")
923
+
924
+ x[0] = v[0]
925
+ x[1] = v[1]
926
+ x[2] = v[2]
927
+ self.assertEqual(x.value, v)
928
+
929
+ v = (-2.5+125j, None, None)
930
+ x[0] = v[0]
931
+ x[1] = v[1]
932
+ x[2] = v[2]
933
+ self.assertEqual(x.value, v)
934
+
935
+ x = xnd([("a", 100, 10.5), ("a", 100, 10.5)])
936
+ x[0][1] = 20000000
937
+ self.assertEqual(x[0][1], 20000000)
938
+ self.assertEqual(x[0, 1], 20000000)
939
+
940
+ def test_tuple_overflow(self):
941
+ # Type cannot be created.
942
+ s = "(4611686018427387904 * uint8, 4611686018427387904 * uint8)"
943
+ self.assertRaises(ValueError, xnd.empty, s)
944
+
945
+ if HAVE_64_BIT:
946
+ # Allocation fails.
947
+ s = "(4611686018427387904 * uint8, 4611686018427387903 * uint8)"
948
+ self.assertRaises(MemoryError, xnd.empty, s)
949
+ else:
950
+ # Allocation fails.
951
+ s = "(1073741824 * uint8, 1073741823 * uint8)"
952
+ self.assertRaises(MemoryError, xnd.empty, s)
953
+
954
+ def test_tuple_optional_values(self):
955
+ lst = [(None, 1, 2), (3, None, 4), (5, 6, None)]
956
+ x = xnd(lst, dtype="(?int64, ?int64, ?int64)")
957
+ self.assertEqual(x.value, lst)
958
+
959
+ def test_tuple_richcompare(self):
960
+
961
+ # Simple tests.
962
+ x = xnd((1, 2.0, "3", b"123"))
963
+
964
+ self.assertIs(x.__lt__(x), NotImplemented)
965
+ self.assertIs(x.__le__(x), NotImplemented)
966
+ self.assertIs(x.__gt__(x), NotImplemented)
967
+ self.assertIs(x.__ge__(x), NotImplemented)
968
+
969
+ self.assertStrictEqual(x, xnd((1, 2.0, "3", b"123")))
970
+
971
+ self.assertNotStrictEqual(x, xnd((2, 2.0, "3", b"123")))
972
+ self.assertNotStrictEqual(x, xnd((1, 2.1, "3", b"123")))
973
+ self.assertNotStrictEqual(x, xnd((1, 2.0, "", b"123")))
974
+ self.assertNotStrictEqual(x, xnd((1, 2.0, "345", b"123")))
975
+ self.assertNotStrictEqual(x, xnd((1, 2.0, "3", b"")))
976
+ self.assertNotStrictEqual(x, xnd((1, 2.0, "3", b"12345")))
977
+
978
+ # Nested structures.
979
+ t = """
980
+ (uint8,
981
+ fixed_string(100, 'utf32'),
982
+ (complex128,
983
+ 2 * 3 * (fixed_bytes(size=64, align=32), bytes)),
984
+ ref(string))
985
+ """
986
+
987
+ v = (10,
988
+ "\U00001234\U00001001abc",
989
+ (12.1e244+3j,
990
+ [[(b"123", 10 * b"22"),
991
+ (b"123456", 10 * b"23"),
992
+ (b"123456789", 10 * b"24")],
993
+ [(b"1", b"a"),
994
+ (b"12", b"ab"),
995
+ (b"123", b"abc")]]),
996
+ "xyz")
997
+
998
+ x = xnd(v, type=t)
999
+ y = xnd(v, type=t)
1000
+ self.assertStrictEqual(x, y)
1001
+
1002
+ w = y[0].value
1003
+ y[0] = 11
1004
+ self.assertNotStrictEqual(x, y)
1005
+ y[0] = w
1006
+ self.assertStrictEqual(x, y)
1007
+
1008
+ w = y[1].value
1009
+ y[1] = "\U00001234\U00001001abx"
1010
+ self.assertNotStrictEqual(x, y)
1011
+ y[1] = w
1012
+ self.assertStrictEqual(x, y)
1013
+
1014
+ w = y[2,0].value
1015
+ y[2,0] = 12.1e244-3j
1016
+ self.assertNotStrictEqual(x, y)
1017
+ y[2,0] = w
1018
+ self.assertStrictEqual(x, y)
1019
+
1020
+ w = y[2,1,1,2,0].value
1021
+ y[2,1,1,2,0] = b"abc"
1022
+ self.assertNotStrictEqual(x, y)
1023
+ y[2,1,1,2,0] = w
1024
+ self.assertStrictEqual(x, y)
1025
+
1026
+ w = y[3].value
1027
+ y[3] = ""
1028
+ self.assertNotStrictEqual(x, y)
1029
+ y[3] = w
1030
+ self.assertStrictEqual(x, y)
1031
+
1032
+ # Test corner cases and many dtypes.
1033
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
1034
+ for vv, tt, uu in [
1035
+ ((0 * [v],), "(0 * %s)" % t, "(0 * %s)" % u),
1036
+ (((0 * [v],),), "((0 * %s))" % t, "((0 * %s))" % u)]:
1037
+
1038
+ ttt = ndt(tt)
1039
+
1040
+ x = xnd(vv, type=ttt)
1041
+ y = xnd(vv, type=ttt)
1042
+ self.assertStrictEqual(x, y)
1043
+
1044
+ if u is not None:
1045
+ uuu = ndt(uu)
1046
+ y = xnd(vv, type=uuu)
1047
+ self.assertStrictEqual(x, y)
1048
+
1049
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
1050
+ for vv, tt, uu, indices in [
1051
+ ((v,), "(%s)" % t, "(%s)" % u, (0,)),
1052
+ (((v,),), "((%s))" % t, "((%s))" % u, (0, 0)),
1053
+ ((((v,),),), "(((%s)))" % t, "(((%s)))" % u, (0, 0, 0)),
1054
+
1055
+ ((1 * [v],), "(1 * %s)" % t, "(1 * %s)" % u, (0, 0)),
1056
+ (((1 * [v],),), "((1 * %s))" % t, "((1 * %s))" % u, (0, 0, 0)),
1057
+ ((3 * [v],), "(3 * %s)" % t, "(3 * %s)" % u, (0, 2))]:
1058
+
1059
+ ttt = ndt(tt)
1060
+
1061
+ x = xnd(vv, type=ttt)
1062
+ y = xnd(vv, type=ttt)
1063
+ if eq:
1064
+ self.assertStrictEqual(x, y)
1065
+ else:
1066
+ self.assertNotStrictEqual(x, y)
1067
+
1068
+ if u is not None:
1069
+ uuu = ndt(uu)
1070
+ y = xnd(vv, type=uuu)
1071
+ if eq:
1072
+ self.assertStrictEqual(x, y)
1073
+ else:
1074
+ self.assertNotStrictEqual(x, y)
1075
+
1076
+ if w is not None:
1077
+ y = xnd(vv, type=ttt)
1078
+ y[indices] = w
1079
+ self.assertNotStrictEqual(x, y)
1080
+
1081
+ y = xnd(vv, type=uuu)
1082
+ y[indices] = w
1083
+ self.assertNotStrictEqual(x, y)
1084
+
1085
+
1086
+ class TestRecord(XndTestCase):
1087
+
1088
+ def test_record_empty(self):
1089
+ for v, s in DTYPE_EMPTY_TEST_CASES:
1090
+ for vv, ss in [
1091
+ ({'x': v}, "{x: %s}" % s),
1092
+ ({'x': {'y': v}}, "{x: {y: %s}}" % s),
1093
+
1094
+ ({'x': 0 * [v]}, "{x: 0 * %s}" % s),
1095
+ ({'x': {'y': 0 * [v]}}, "{x: {y: 0 * %s}}" % s),
1096
+ ({'x': 1 * [v]}, "{x: 1 * %s}" % s),
1097
+ ({'x': 3 * [v]}, "{x: 3 * %s}" % s)]:
1098
+
1099
+ t = ndt(ss)
1100
+ x = xnd.empty(ss)
1101
+ self.assertEqual(x.type, t)
1102
+ self.assertEqual(x.value, vv)
1103
+ self.assertEqual(len(x), len(vv))
1104
+
1105
+ def test_record_assign(self):
1106
+ ### Regular data ###
1107
+ x = xnd.empty("{x: complex64, y: bytes, z: string}")
1108
+ v = R['x': 1+20j, 'y': b"abc", 'z': "any"]
1109
+
1110
+ x['x'] = v['x']
1111
+ x['y'] = v['y']
1112
+ x['z'] = v['z']
1113
+
1114
+ self.assertEqual(x.value, v)
1115
+
1116
+ ### Optional data ###
1117
+ x = xnd.empty("{x: complex64, y: ?bytes, z: ?string}")
1118
+ v = R['x': 1+20j, 'y': None, 'z': "Some"]
1119
+
1120
+ x['x'] = v['x']
1121
+ x['y'] = v['y']
1122
+ x['z'] = v['z']
1123
+ self.assertEqual(x.value, v)
1124
+
1125
+ v = R['x': -2.5+125j, 'y': None, 'z': None]
1126
+ x['x'] = v['x']
1127
+ x['y'] = v['y']
1128
+ x['z'] = v['z']
1129
+ self.assertEqual(x.value, v)
1130
+
1131
+ x = xnd([R['x': "abc", 'y': 100, 'z': 10.5]])
1132
+ x[0][1] = 20000000
1133
+ self.assertEqual(x[0][1], 20000000)
1134
+ self.assertEqual(x[0, 1], 20000000)
1135
+
1136
+ def test_record_overflow(self):
1137
+ # Type cannot be created.
1138
+ s = "{a: 4611686018427387904 * uint8, b: 4611686018427387904 * uint8}"
1139
+ self.assertRaises(ValueError, xnd.empty, s)
1140
+
1141
+ if HAVE_64_BIT:
1142
+ # Allocation fails.
1143
+ s = "{a: 4611686018427387904 * uint8, b: 4611686018427387903 * uint8}"
1144
+ self.assertRaises(MemoryError, xnd.empty, s)
1145
+ else:
1146
+ # Allocation fails.
1147
+ s = "{a: 1073741824 * uint8, b: 1073741823 * uint8}"
1148
+ self.assertRaises(MemoryError, xnd.empty, s)
1149
+
1150
+ def test_record_optional_values(self):
1151
+ lst = [R['a': None, 'b': 2, 'c': 3], R['a': 4, 'b': None, 'c': 5],
1152
+ R['a': 5, 'b': 6, 'c': None]]
1153
+ x = xnd(lst, dtype="{a: ?int64, b: ?int64, c: ?int64}")
1154
+ self.assertEqual(x.value, lst)
1155
+
1156
+ def test_record_richcompare(self):
1157
+
1158
+ # Simple tests.
1159
+ x = xnd(R['a': 1, 'b': 2.0, 'c': "3", 'd': b"123"])
1160
+
1161
+ self.assertIs(x.__lt__(x), NotImplemented)
1162
+ self.assertIs(x.__le__(x), NotImplemented)
1163
+ self.assertIs(x.__gt__(x), NotImplemented)
1164
+ self.assertIs(x.__ge__(x), NotImplemented)
1165
+
1166
+ self.assertStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "3", 'd': b"123"]))
1167
+
1168
+ self.assertNotStrictEqual(x, xnd(R['z': 1, 'b': 2.0, 'c': "3", 'd': b"123"]))
1169
+ self.assertNotStrictEqual(x, xnd(R['a': 2, 'b': 2.0, 'c': "3", 'd': b"123"]))
1170
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.1, 'c': "3", 'd': b"123"]))
1171
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "", 'd': b"123"]))
1172
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "345", 'd': "123"]))
1173
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "3", 'd': b""]))
1174
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "3", 'd': b"12345"]))
1175
+
1176
+ # Nested structures.
1177
+ t = """
1178
+ {a: uint8,
1179
+ b: fixed_string(100, 'utf32'),
1180
+ c: {x: complex128,
1181
+ y: 2 * 3 * {v: fixed_bytes(size=64, align=32),
1182
+ u: bytes}},
1183
+ d: ref(string)}
1184
+ """
1185
+
1186
+ v = R['a': 10,
1187
+ 'b': "\U00001234\U00001001abc",
1188
+ 'c': R['x': 12.1e244+3j,
1189
+ 'y': [[R['v': b"123", 'u': 10 * b"22"],
1190
+ R['v': b"123456", 'u': 10 * b"23"],
1191
+ R['v': b"123456789", 'u': 10 * b"24"]],
1192
+ [R['v': b"1", 'u': b"a"],
1193
+ R['v': b"12", 'u': b"ab"],
1194
+ R['v': b"123", 'u': b"abc"]]]],
1195
+ 'd': "xyz"]
1196
+
1197
+ x = xnd(v, type=t)
1198
+ y = xnd(v, type=t)
1199
+ self.assertStrictEqual(x, y)
1200
+
1201
+ w = y[0].value
1202
+ y[0] = 11
1203
+ self.assertNotStrictEqual(x, y)
1204
+ y[0] = w
1205
+ self.assertStrictEqual(x, y)
1206
+
1207
+ w = y[1].value
1208
+ y[1] = "\U00001234\U00001001abx"
1209
+ self.assertNotStrictEqual(x, y)
1210
+ y[1] = w
1211
+ self.assertStrictEqual(x, y)
1212
+
1213
+ w = y[2,0].value
1214
+ y[2,0] = 12.1e244-3j
1215
+ self.assertNotStrictEqual(x, y)
1216
+ y[2,0] = w
1217
+ self.assertStrictEqual(x, y)
1218
+
1219
+ w = y[2,1,1,2,0].value
1220
+ y[2,1,1,2,0] = b"abc"
1221
+ self.assertNotStrictEqual(x, y)
1222
+ y[2,1,1,2,0] = w
1223
+ self.assertStrictEqual(x, y)
1224
+
1225
+ w = y[3].value
1226
+ y[3] = ""
1227
+ self.assertNotStrictEqual(x, y)
1228
+ y[3] = w
1229
+ self.assertStrictEqual(x, y)
1230
+
1231
+ # Test corner cases and many dtypes.
1232
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
1233
+ for vv, tt, uu in [
1234
+ ({'x': 0 * [v]}, "{x: 0 * %s}" % t, "{x: 0 * %s}" % u),
1235
+ ({'x': {'y': 0 * [v]}}, "{x: {y: 0 * %s}}" % t, "{x: {y: 0 * %s}}" % u)]:
1236
+
1237
+ ttt = ndt(tt)
1238
+
1239
+ x = xnd(vv, type=ttt)
1240
+
1241
+ y = xnd(vv, type=ttt)
1242
+ self.assertStrictEqual(x, y)
1243
+
1244
+ if u is not None:
1245
+ uuu = ndt(uu)
1246
+ y = xnd(vv, type=uuu)
1247
+ self.assertStrictEqual(x, y)
1248
+
1249
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
1250
+ for vv, tt, uu, indices in [
1251
+ ({'x': v}, "{x: %s}" % t, "{x: %s}" % u, (0,)),
1252
+ ({'x': {'y': v}}, "{x: {y: %s}}" % t, "{x: {y: %s}}" % u, (0, 0)),
1253
+ ({'x': 1 * [v]}, "{x: 1 * %s}" % t, "{x: 1 * %s}" % u, (0, 0)),
1254
+ ({'x': 3 * [v]}, "{x: 3 * %s}" % t, "{x: 3 * %s}" % u, (0, 2))]:
1255
+
1256
+ ttt = ndt(tt)
1257
+ uuu = ndt(uu)
1258
+
1259
+ x = xnd(vv, type=ttt)
1260
+
1261
+ y = xnd(vv, type=ttt)
1262
+ if eq:
1263
+ self.assertStrictEqual(x, y)
1264
+ else:
1265
+ self.assertNotStrictEqual(x, y)
1266
+
1267
+ if u is not None:
1268
+ y = xnd(vv, type=uuu)
1269
+ if eq:
1270
+ self.assertStrictEqual(x, y)
1271
+ else:
1272
+ self.assertNotStrictEqual(x, y)
1273
+
1274
+ if w is not None:
1275
+ y = xnd(vv, type=ttt)
1276
+ y[indices] = w
1277
+ self.assertNotStrictEqual(x, y)
1278
+
1279
+
1280
+ class TestRef(XndTestCase):
1281
+
1282
+ def test_ref_empty(self):
1283
+ for v, s in DTYPE_EMPTY_TEST_CASES:
1284
+ for vv, ss in [
1285
+ (v, "ref(%s)" % s),
1286
+ (v, "ref(ref(%s))" % s),
1287
+ (v, "ref(ref(ref(%s)))" % s),
1288
+
1289
+ (0 * [v], "ref(0 * %s)" % s),
1290
+ (0 * [v], "ref(ref(0 * %s))" % s),
1291
+ (0 * [v], "ref(ref(ref(0 * %s)))" % s),
1292
+ (1 * [v], "ref(1 * %s)" % s),
1293
+ (1 * [v], "ref(ref(1 * %s))" % s),
1294
+ (1 * [v], "ref(ref(ref(1 * %s)))" % s),
1295
+ (3 * [v], "ref(3 * %s)" % s),
1296
+ (3 * [v], "ref(ref(3 * %s))" % s),
1297
+ (3 * [v], "ref(ref(ref(3 * %s)))" % s)]:
1298
+
1299
+ t = ndt(ss)
1300
+ x = xnd.empty(ss)
1301
+ self.assertEqual(x.type, t)
1302
+ self.assertEqual(x.value, vv)
1303
+ assertEqualWithEx(self, len, x, vv)
1304
+
1305
+ def test_ref_empty_view(self):
1306
+ # If a ref is a dtype but contains an array itself, indexing should
1307
+ # return a view and not a Python value.
1308
+ inner = 4 * [5 * [0+0j]]
1309
+ x = xnd.empty("2 * 3 * ref(4 * 5 * complex128)")
1310
+
1311
+ y = x[1][2]
1312
+ self.assertIsInstance(y, xnd)
1313
+ self.assertEqual(y.value, inner)
1314
+
1315
+ y = x[1, 2]
1316
+ self.assertIsInstance(y, xnd)
1317
+ self.assertEqual(y.value, inner)
1318
+
1319
+ def test_ref_indexing(self):
1320
+ # If a ref is a dtype but contains an array itself, indexing through
1321
+ # the ref should work transparently.
1322
+ inner = [['a', 'b', 'c', 'd', 'e'],
1323
+ ['f', 'g', 'h', 'i', 'j'],
1324
+ ['k', 'l', 'm', 'n', 'o'],
1325
+ ['p', 'q', 'r', 's', 't']]
1326
+
1327
+ v = 2 * [3 * [inner]]
1328
+
1329
+ x = xnd(v, type="2 * 3 * ref(4 * 5 * string)")
1330
+
1331
+ for i in range(2):
1332
+ for j in range(3):
1333
+ for k in range(4):
1334
+ for l in range(5):
1335
+ self.assertEqual(x[i][j][k][l], inner[k][l])
1336
+ self.assertEqual(x[i, j, k, l], inner[k][l])
1337
+
1338
+ def test_ref_assign(self):
1339
+ # If a ref is a dtype but contains an array itself, assigning through
1340
+ # the ref should work transparently.
1341
+ inner = [['a', 'b', 'c', 'd', 'e'],
1342
+ ['f', 'g', 'h', 'i', 'j'],
1343
+ ['k', 'l', 'm', 'n', 'o'],
1344
+ ['p', 'q', 'r', 's', 't']]
1345
+
1346
+ v = 2 * [3 * [inner]]
1347
+
1348
+ x = xnd(v, type="2 * 3 * ref(4 * 5 * string)")
1349
+ for i in range(2):
1350
+ for j in range(3):
1351
+ for k in range(4):
1352
+ for l in range(5):
1353
+ x[i][j][k][l] = inner[k][l] = "%d" % (k * 5 + l)
1354
+
1355
+ self.assertEqual(x.value, v)
1356
+
1357
+ for i in range(2):
1358
+ for j in range(3):
1359
+ for k in range(4):
1360
+ for l in range(5):
1361
+ x[i, j, k, l] = inner[k][l] = "%d" % (k * 5 + l + 1)
1362
+
1363
+ self.assertEqual(x.value, v)
1364
+
1365
+ def test_ref_richcompare(self):
1366
+
1367
+ # Simple tests.
1368
+ x = xnd([1,2,3,4], type="ref(4 * float32)")
1369
+
1370
+ self.assertIs(x.__lt__(x), NotImplemented)
1371
+ self.assertIs(x.__le__(x), NotImplemented)
1372
+ self.assertIs(x.__gt__(x), NotImplemented)
1373
+ self.assertIs(x.__ge__(x), NotImplemented)
1374
+
1375
+ self.assertStrictEqual(x, xnd([1,2,3,4], type="ref(4 * float32)"))
1376
+
1377
+ self.assertNotStrictEqual(x, xnd([1,2,3,5], type="ref(4 * float32)"))
1378
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="ref(3 * float32)"))
1379
+ self.assertNotStrictEqual(x, xnd([1,2,3,4,5], type="ref(5 * float32)"))
1380
+
1381
+ # Test corner cases and many dtypes.
1382
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
1383
+ for vv, tt, uu in [
1384
+ (0 * [v], "ref(0 * %s)" % t, "ref(0 * %s)" % u),
1385
+ (0 * [v], "ref(ref(0 * %s))" % t, "ref(ref(0 * %s))" % u),
1386
+ (0 * [v], "ref(ref(ref(0 * %s)))" % t, "ref(ref(ref(0 * %s)))" % u)]:
1387
+
1388
+ ttt = ndt(tt)
1389
+
1390
+ x = xnd(vv, type=ttt)
1391
+
1392
+ y = xnd(vv, type=ttt)
1393
+ self.assertStrictEqual(x, y)
1394
+
1395
+ if u is not None:
1396
+ uuu = ndt(uu)
1397
+ y = xnd(vv, type=uuu)
1398
+ self.assertStrictEqual(x, y)
1399
+
1400
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
1401
+ for vv, tt, uu, indices in [
1402
+ (v, "ref(%s)" % t, "ref(%s)" % u, ()),
1403
+ (v, "ref(ref(%s))" % t, "ref(ref(%s))" % u, ()),
1404
+ (v, "ref(ref(ref(%s)))" % t, "ref(ref(ref(%s)))" % u, ()),
1405
+ (1 * [v], "ref(1 * %s)" % t, "ref(1 * %s)" % u, (0,)),
1406
+ (3 * [v], "ref(3 * %s)" % t, "ref(3 * %s)" % u, (2,))]:
1407
+
1408
+ ttt = ndt(tt)
1409
+ uuu = ndt(uu)
1410
+
1411
+ x = xnd(vv, type=ttt)
1412
+
1413
+ y = xnd(vv, type=ttt)
1414
+ if eq:
1415
+ self.assertStrictEqual(x, y)
1416
+ else:
1417
+ self.assertNotStrictEqual(x, y)
1418
+
1419
+ if u is not None:
1420
+ y = xnd(vv, type=uuu)
1421
+ if eq:
1422
+ self.assertStrictEqual(x, y)
1423
+ else:
1424
+ self.assertNotStrictEqual(x, y)
1425
+
1426
+ if w is not None:
1427
+ y = xnd(vv, type=ttt)
1428
+ y[indices] = w
1429
+ self.assertNotStrictEqual(x, y)
1430
+
1431
+
1432
+ class TestConstr(XndTestCase):
1433
+
1434
+ def test_constr_empty(self):
1435
+ for v, s in DTYPE_EMPTY_TEST_CASES:
1436
+ for vv, ss in [
1437
+ (v, "SomeConstr(%s)" % s),
1438
+ (v, "Just(Some(%s))" % s),
1439
+
1440
+ (0 * [v], "Some(0 * %s)" % s),
1441
+ (1 * [v], "Some(1 * %s)" % s),
1442
+ (3 * [v], "Maybe(3 * %s)" % s)]:
1443
+
1444
+ t = ndt(ss)
1445
+ x = xnd.empty(ss)
1446
+ self.assertEqual(x.type, t)
1447
+ self.assertEqual(x.value, vv)
1448
+ assertEqualWithEx(self, len, x, vv)
1449
+
1450
+ def test_constr_empty_view(self):
1451
+ # If a constr is a dtype but contains an array itself, indexing should
1452
+ # return a view and not a Python value.
1453
+ inner = 4 * [5 * [""]]
1454
+ x = xnd.empty("2 * 3 * InnerArray(4 * 5 * string)")
1455
+
1456
+ y = x[1][2]
1457
+ self.assertIsInstance(y, xnd)
1458
+ self.assertEqual(y.value, inner)
1459
+
1460
+ y = x[1, 2]
1461
+ self.assertIsInstance(y, xnd)
1462
+ self.assertEqual(y.value, inner)
1463
+
1464
+ def test_constr_indexing(self):
1465
+ # If a constr is a dtype but contains an array itself, indexing through
1466
+ # the constructor should work transparently.
1467
+ inner = [['a', 'b', 'c', 'd', 'e'],
1468
+ ['f', 'g', 'h', 'i', 'j'],
1469
+ ['k', 'l', 'm', 'n', 'o'],
1470
+ ['p', 'q', 'r', 's', 't']]
1471
+
1472
+ v = 2 * [3 * [inner]]
1473
+
1474
+ x = xnd(v, type="2 * 3 * InnerArray(4 * 5 * string)")
1475
+
1476
+ for i in range(2):
1477
+ for j in range(3):
1478
+ for k in range(4):
1479
+ for l in range(5):
1480
+ self.assertEqual(x[i][j][k][l], inner[k][l])
1481
+ self.assertEqual(x[i, j, k, l], inner[k][l])
1482
+
1483
+ def test_constr_assign(self):
1484
+ # If a constr is a dtype but contains an array itself, assigning through
1485
+ # the constructor should work transparently.
1486
+ inner = [['a', 'b', 'c', 'd', 'e'],
1487
+ ['f', 'g', 'h', 'i', 'j'],
1488
+ ['k', 'l', 'm', 'n', 'o'],
1489
+ ['p', 'q', 'r', 's', 't']]
1490
+
1491
+ v = 2 * [3 * [inner]]
1492
+
1493
+ x = xnd(v, type="2 * 3 * InnerArray(4 * 5 * string)")
1494
+
1495
+ for i in range(2):
1496
+ for j in range(3):
1497
+ for k in range(4):
1498
+ for l in range(5):
1499
+ x[i][j][k][l] = inner[k][l] = "%d" % (k * 5 + l)
1500
+
1501
+ self.assertEqual(x.value, v)
1502
+
1503
+ for i in range(2):
1504
+ for j in range(3):
1505
+ for k in range(4):
1506
+ for l in range(5):
1507
+ x[i][j][k][l] = inner[k][l] = "%d" % (k * 5 + l + 1)
1508
+
1509
+ self.assertEqual(x.value, v)
1510
+
1511
+ def test_constr_richcompare(self):
1512
+
1513
+ # Simple tests.
1514
+ x = xnd([1,2,3,4], type="A(4 * float32)")
1515
+
1516
+ self.assertIs(x.__lt__(x), NotImplemented)
1517
+ self.assertIs(x.__le__(x), NotImplemented)
1518
+ self.assertIs(x.__gt__(x), NotImplemented)
1519
+ self.assertIs(x.__ge__(x), NotImplemented)
1520
+
1521
+ self.assertStrictEqual(x, xnd([1,2,3,4], type="A(4 * float32)"))
1522
+
1523
+ self.assertNotStrictEqual(x, xnd([1,2,3,4], type="B(4 * float32)"))
1524
+ self.assertNotStrictEqual(x, xnd([1,2,3,5], type="A(4 * float32)"))
1525
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="A(3 * float32)"))
1526
+ self.assertNotStrictEqual(x, xnd([1,2,3,4,5], type="A(5 * float32)"))
1527
+
1528
+ # Test corner cases and many dtypes.
1529
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
1530
+ for vv, tt, uu in [
1531
+ (0 * [v], "A(0 * %s)" % t, "A(0 * %s)" % u),
1532
+ (0 * [v], "A(B(0 * %s))" % t, "A(B(0 * %s))" % u),
1533
+ (0 * [v], "A(B(C(0 * %s)))" % t, "A(B(C(0 * %s)))" % u)]:
1534
+
1535
+ ttt = ndt(tt)
1536
+
1537
+ x = xnd(vv, type=ttt)
1538
+ y = xnd(vv, type=ttt)
1539
+ self.assertStrictEqual(x, y)
1540
+
1541
+ if u is not None:
1542
+ uuu = ndt(uu)
1543
+ y = xnd(vv, type=uuu)
1544
+ self.assertStrictEqual(x, y)
1545
+
1546
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
1547
+ for vv, tt, uu, indices in [
1548
+ (v, "A(%s)" % t, "A(%s)" % u, ()),
1549
+ (v, "A(B(%s))" % t, "A(B(%s))" % u, ()),
1550
+ (v, "A(B(C(%s)))" % t, "A(B(C(%s)))" % u, ()),
1551
+ (1 * [v], "A(1 * %s)" % t, "A(1 * %s)" % u, (0,)),
1552
+ (3 * [v], "A(3 * %s)" % t, "A(3 * %s)" % u, (2,))]:
1553
+
1554
+ ttt = ndt(tt)
1555
+ uuu = ndt(uu)
1556
+
1557
+ x = xnd(vv, type=ttt)
1558
+
1559
+ y = xnd(vv, type=ttt)
1560
+ if eq:
1561
+ self.assertStrictEqual(x, y)
1562
+ else:
1563
+ self.assertNotStrictEqual(x, y)
1564
+
1565
+ if u is not None:
1566
+ y = xnd(vv, type=uuu)
1567
+ if eq:
1568
+ self.assertStrictEqual(x, y)
1569
+ else:
1570
+ self.assertNotStrictEqual(x, y)
1571
+
1572
+ if w is not None:
1573
+ y = xnd(vv, type=ttt)
1574
+ y[indices] = w
1575
+ self.assertNotStrictEqual(x, y)
1576
+
1577
+
1578
+ class TestNominal(XndTestCase):
1579
+
1580
+ def test_nominal_empty(self):
1581
+ c = 0
1582
+ for v, s in DTYPE_EMPTY_TEST_CASES:
1583
+ typedef("some%d" % c, s)
1584
+ typedef("just%d" % c, "some%d" %c)
1585
+
1586
+ for vv, ss in [
1587
+ (v, "some%d" % c),
1588
+ (v, "just%d" % c)]:
1589
+
1590
+ t = ndt(ss)
1591
+ x = xnd.empty(ss)
1592
+ self.assertEqual(x.type, t)
1593
+ self.assertEqual(x.value, vv)
1594
+ assertEqualWithEx(self, len, x, vv)
1595
+
1596
+ c += 1
1597
+
1598
+ def test_nominal_empty_view(self):
1599
+ # If a typedef is a dtype but contains an array itself, indexing should
1600
+ # return a view and not a Python value.
1601
+ typedef("inner_array", "4 * 5 * string")
1602
+ inner = 4 * [5 * [""]]
1603
+ x = xnd.empty("2 * 3 * inner_array")
1604
+
1605
+ y = x[1][2]
1606
+ self.assertIsInstance(y, xnd)
1607
+ self.assertEqual(y.value, inner)
1608
+
1609
+ y = x[1, 2]
1610
+ self.assertIsInstance(y, xnd)
1611
+ self.assertEqual(y.value, inner)
1612
+
1613
+ def test_nominal_indexing(self):
1614
+ # If a typedef is a dtype but contains an array itself, indexing through
1615
+ # the constructor should work transparently.
1616
+ typedef("inner", "4 * 5 * string")
1617
+ inner = [['a', 'b', 'c', 'd', 'e'],
1618
+ ['f', 'g', 'h', 'i', 'j'],
1619
+ ['k', 'l', 'm', 'n', 'o'],
1620
+ ['p', 'q', 'r', 's', 't']]
1621
+
1622
+ v = 2 * [3 * [inner]]
1623
+
1624
+ x = xnd(v, type="2 * 3 * inner")
1625
+
1626
+ for i in range(2):
1627
+ for j in range(3):
1628
+ for k in range(4):
1629
+ for l in range(5):
1630
+ self.assertEqual(x[i][j][k][l], inner[k][l])
1631
+ self.assertEqual(x[i, j, k, l], inner[k][l])
1632
+
1633
+ def test_nominal_assign(self):
1634
+ # If a typedef is a dtype but contains an array itself, assigning through
1635
+ # the constructor should work transparently.
1636
+ typedef("in", "4 * 5 * string")
1637
+ inner = [['a', 'b', 'c', 'd', 'e'],
1638
+ ['f', 'g', 'h', 'i', 'j'],
1639
+ ['k', 'l', 'm', 'n', 'o'],
1640
+ ['p', 'q', 'r', 's', 't']]
1641
+
1642
+ v = 2 * [3 * [inner]]
1643
+
1644
+ x = xnd(v, type="2 * 3 * in")
1645
+
1646
+ for i in range(2):
1647
+ for j in range(3):
1648
+ for k in range(4):
1649
+ for l in range(5):
1650
+ x[i][j][k][l] = inner[k][l] = "%d" % (k * 5 + l)
1651
+
1652
+ self.assertEqual(x.value, v)
1653
+
1654
+ for i in range(2):
1655
+ for j in range(3):
1656
+ for k in range(4):
1657
+ for l in range(5):
1658
+ x[i][j][k][l] = inner[k][l] = "%d" % (k * 5 + l + 1)
1659
+
1660
+ self.assertEqual(x.value, v)
1661
+
1662
+ def test_nominal_error(self):
1663
+ self.assertRaises(ValueError, xnd.empty, "undefined_t")
1664
+
1665
+ def test_nominal_richcompare(self):
1666
+
1667
+ typedef("some1000", "4 * float32")
1668
+ typedef("some1001", "4 * float32")
1669
+
1670
+ # Simple tests.
1671
+ x = xnd([1,2,3,4], type="some1000")
1672
+
1673
+ self.assertIs(x.__lt__(x), NotImplemented)
1674
+ self.assertIs(x.__le__(x), NotImplemented)
1675
+ self.assertIs(x.__gt__(x), NotImplemented)
1676
+ self.assertIs(x.__ge__(x), NotImplemented)
1677
+
1678
+ self.assertStrictEqual(x, xnd([1,2,3,4], type="some1000"))
1679
+
1680
+ self.assertNotStrictEqual(x, xnd([1,2,3,4], type="some1001"))
1681
+ self.assertNotStrictEqual(x, xnd([1,2,3,5], type="some1000"))
1682
+
1683
+
1684
+ class TestScalarKind(XndTestCase):
1685
+
1686
+ def test_scalar_kind(self):
1687
+ self.assertRaises(ValueError, xnd.empty, "Scalar")
1688
+
1689
+
1690
+ class TestCategorical(XndTestCase):
1691
+
1692
+ def test_categorical_empty(self):
1693
+ # Categorical values are stored as indices into the type's categories.
1694
+ # Since empty xnd objects are initialized to zero, the value of an
1695
+ # empty categorical entry is always the value of the first category.
1696
+ # This is safe, since categorical types must have at least one entry.
1697
+ r = R['a': "", 'b': 1.2]
1698
+ rt = "{a: string, b: categorical(1.2, 10.0, NA)}"
1699
+
1700
+ test_cases = [
1701
+ ("January", "categorical('January')"),
1702
+ ((None,), "(categorical(NA, 'January', 'August'))"),
1703
+ (10 * [2 * [1.2]], "10 * 2 * categorical(1.2, 10.0, NA)"),
1704
+ (10 * [2 * [100]], "10 * 2 * categorical(100, 'mixed')"),
1705
+ (10 * [2 * [r]], "10 * 2 * %s" % rt),
1706
+ ([2 * [r], 5 * [r], 3 * [r]], "var(offsets=[0,3]) * var(offsets=[0,2,7,10]) * %s" % rt)
1707
+ ]
1708
+
1709
+ for v, s in test_cases:
1710
+ t = ndt(s)
1711
+ x = xnd.empty(s)
1712
+ self.assertEqual(x.type, t)
1713
+ self.assertEqual(x.value, v)
1714
+
1715
+ def test_categorical_assign(self):
1716
+ s = """2 * categorical(
1717
+ NA, 'January', 'February', 'March', 'April', 'May', 'June',
1718
+ 'July', 'August', 'September', 'October', 'November', 'December'
1719
+ )
1720
+ """
1721
+
1722
+ x = xnd([None, None], type=s)
1723
+ x[0] = 'August'
1724
+ x[1] = 'December'
1725
+
1726
+ self.assertEqual(x.value, ['August', 'December'])
1727
+
1728
+ x[0] = None
1729
+ self.assertEqual(x.value, [None, 'December'])
1730
+
1731
+ def test_categorical_richcompare(self):
1732
+ t = "3 * categorical(NA, 'January', 'August')"
1733
+ x = xnd(['August', 'January', 'January'], type=t)
1734
+
1735
+ y = xnd(['August', 'January', 'January'], type=t)
1736
+ self.assertStrictEqual(x, y)
1737
+
1738
+ y = xnd(['August', 'January', 'August'], type=t)
1739
+ self.assertNotStrictEqual(x, y)
1740
+
1741
+ x = xnd(['August', None, 'August'], type=t)
1742
+ y = xnd(['August', None, 'August'], type=t)
1743
+ self.assertNotStrictEqual(x, y)
1744
+
1745
+
1746
+ class TestFixedStringKind(XndTestCase):
1747
+
1748
+ def test_fixed_string_kind(self):
1749
+ self.assertRaises(ValueError, xnd.empty, "FixedString")
1750
+
1751
+
1752
+ class TestFixedString(XndTestCase):
1753
+
1754
+ def test_fixed_string_empty(self):
1755
+ test_cases = [
1756
+ ("fixed_string(1)", ""),
1757
+ ("fixed_string(3)", 3 * ""),
1758
+ ("fixed_string(1, 'ascii')", ""),
1759
+ ("fixed_string(3, 'utf8')", 3 * ""),
1760
+ ("fixed_string(3, 'utf16')", 3 * ""),
1761
+ ("fixed_string(3, 'utf32')", 3 * ""),
1762
+ ("2 * fixed_string(3, 'utf32')", 2 * [3 * ""]),
1763
+ ]
1764
+
1765
+ for s, v in test_cases:
1766
+ t = ndt(s)
1767
+ x = xnd.empty(s)
1768
+ self.assertEqual(x.type, t)
1769
+ self.assertEqual(x.value, v)
1770
+
1771
+ def test_fixed_string(self):
1772
+ t = "2 * fixed_string(3, 'utf16')"
1773
+ v = ["\u1111\u2222\u3333", "\u1112\u2223\u3334"]
1774
+ x = xnd(v, type=t)
1775
+ self.assertEqual(x.value, v)
1776
+
1777
+
1778
+ t = "2 * fixed_string(3, 'utf32')"
1779
+ v = ["\U00011111\U00022222\U00033333", "\U00011112\U00022223\U00033334"]
1780
+ x = xnd(v, type=t)
1781
+ self.assertEqual(x.value, v)
1782
+
1783
+ def test_fixed_string_assign(self):
1784
+ t = "2 * fixed_string(3, 'utf32')"
1785
+ v = ["\U00011111\U00022222\U00033333", "\U00011112\U00022223\U00033334"]
1786
+ x = xnd(v, type=t)
1787
+
1788
+ x[0] = "a"
1789
+ self.assertEqual(x.value, ["a", "\U00011112\U00022223\U00033334"])
1790
+
1791
+ x[0] = "a\x00\x00"
1792
+ self.assertEqual(x.value, ["a", "\U00011112\U00022223\U00033334"])
1793
+
1794
+ x[1] = "b\x00c"
1795
+ self.assertEqual(x.value, ["a", "b\x00c"])
1796
+
1797
+ def test_fixed_string_overflow(self):
1798
+ # Type cannot be created.
1799
+ for s in ["fixed_string(9223372036854775808)",
1800
+ "fixed_string(4611686018427387904, 'utf16')",
1801
+ "fixed_string(2305843009213693952, 'utf32')"]:
1802
+ self.assertRaises(ValueError, xnd.empty, s)
1803
+
1804
+ if HAVE_64_BIT:
1805
+ # Allocation fails.
1806
+ s = "fixed_string(4611686018427387903, 'utf16')"
1807
+ self.assertRaises(MemoryError, xnd.empty, s)
1808
+ else:
1809
+ # Allocation fails.
1810
+ s = "fixed_string(1073741824, 'utf16')"
1811
+ self.assertRaises(MemoryError, xnd.empty, s)
1812
+
1813
+ def test_fixed_string_richcompare(self):
1814
+ test_cases = [
1815
+ ("fixed_string(1)", "", "x"),
1816
+ ("fixed_string(3)", 3 * "y", "yyz"),
1817
+ ("fixed_string(1, 'ascii')", "a", "b"),
1818
+ ("fixed_string(3, 'utf8')", 3 * "a", "abc"),
1819
+ ("fixed_string(3, 'utf16')", 3 * "\u1234", "\u1234\u1235\u1234"),
1820
+ ("fixed_string(3, 'utf32')", 3 * "\U00001234", "\U00001234\U00001234\U00001235"),
1821
+ ]
1822
+
1823
+ for t, v, w in test_cases:
1824
+ x = xnd(v, type=t)
1825
+ y = xnd(v, type=t)
1826
+ self.assertStrictEqual(x, y)
1827
+ y[()] = w
1828
+ self.assertNotStrictEqual(x, y)
1829
+
1830
+
1831
+ class TestFixedBytesKind(XndTestCase):
1832
+
1833
+ def test_fixed_bytes_kind(self):
1834
+ self.assertRaises(ValueError, xnd.empty, "FixedBytes")
1835
+
1836
+
1837
+ class TestFixedBytes(XndTestCase):
1838
+
1839
+ def test_fixed_bytes_empty(self):
1840
+ r = R['a': 3 * b'\x00', 'b': 10 * b'\x00']
1841
+
1842
+ test_cases = [
1843
+ (b'\x00', 'fixed_bytes(size=1)'),
1844
+ (100 * b'\x00', 'fixed_bytes(size=100)'),
1845
+ (4 * b'\x00', 'fixed_bytes(size=4, align=2)'),
1846
+ (128 * b'\x00', 'fixed_bytes(size=128, align=16)'),
1847
+ (r, '{a: fixed_bytes(size=3), b: fixed_bytes(size=10)}'),
1848
+ (2 * [3 * [r]], '2 * 3 * {a: fixed_bytes(size=3), b: fixed_bytes(size=10)}')
1849
+ ]
1850
+
1851
+ for v, s in test_cases:
1852
+ t = ndt(s)
1853
+ x = xnd.empty(s)
1854
+ self.assertEqual(x.type, t)
1855
+ self.assertEqual(x.value, v)
1856
+
1857
+ def test_fixed_bytes_assign(self):
1858
+ t = "2 * fixed_bytes(size=3, align=1)"
1859
+ v = [b"abc", b"123"]
1860
+ x = xnd(v, type=t)
1861
+
1862
+ x[0] = b"xyz"
1863
+ self.assertEqual(x.value, [b"xyz", b"123"])
1864
+
1865
+
1866
+ t = "2 * fixed_bytes(size=3, align=1)"
1867
+ v = [b"abc", b"123"]
1868
+ x = xnd(v, type=t)
1869
+
1870
+ x[0] = b"xyz"
1871
+ self.assertEqual(x.value, [b"xyz", b"123"])
1872
+
1873
+ def test_fixed_bytes_overflow(self):
1874
+ # Type cannot be created.
1875
+ s = "fixed_bytes(size=9223372036854775808)"
1876
+ self.assertRaises(ValueError, xnd.empty, s)
1877
+
1878
+ if HAVE_64_BIT:
1879
+ # Allocation fails.
1880
+ s = "fixed_bytes(size=9223372036854775807)"
1881
+ self.assertRaises(MemoryError, xnd.empty, s)
1882
+ else:
1883
+ # Allocation fails.
1884
+ s = "fixed_bytes(size=2147483648)"
1885
+ self.assertRaises(MemoryError, xnd.empty, s)
1886
+
1887
+ def test_fixed_bytes_richcompare(self):
1888
+ test_cases = [
1889
+ (b"a", "fixed_bytes(size=1)", b"b"),
1890
+ (100 * b"a", "fixed_bytes(size=100)", 99 * b"a" + b"b"),
1891
+ (4 * b"a", "fixed_bytes(size=4, align=2)", 2 * b"a" + 2 * b"b"),
1892
+ ]
1893
+
1894
+ for v, t, w in test_cases:
1895
+ x = xnd(v, type=t)
1896
+ y = xnd(v, type=t)
1897
+ self.assertStrictEqual(x, y)
1898
+ y[()] = w
1899
+ self.assertNotStrictEqual(x, y)
1900
+
1901
+ x = xnd(128 * b"a", type="fixed_bytes(size=128, align=16)")
1902
+ y = xnd(128 * b"a", type="fixed_bytes(size=128, align=4)")
1903
+ self.assertStrictEqual(x, y)
1904
+
1905
+ x = xnd(128 * b"a", type="fixed_bytes(size=128, align=16)")
1906
+ y = xnd(128 * b"a", type="fixed_bytes(size=128, align=4)")
1907
+ self.assertStrictEqual(x, y)
1908
+
1909
+
1910
+ class TestString(XndTestCase):
1911
+
1912
+ def test_string_empty(self):
1913
+ test_cases = [
1914
+ 'string',
1915
+ '(string)',
1916
+ '10 * 2 * string',
1917
+ '10 * 2 * (string, string)',
1918
+ '10 * 2 * {a: string, b: string}',
1919
+ 'var(offsets=[0,3]) * var(offsets=[0,2,7,10]) * {a: string, b: string}'
1920
+ ]
1921
+
1922
+ for s in test_cases:
1923
+ t = ndt(s)
1924
+ x = xnd.empty(s)
1925
+ self.assertEqual(x.type, t)
1926
+
1927
+ t = ndt('string')
1928
+ x = xnd.empty(t)
1929
+ self.assertEqual(x.type, t)
1930
+ self.assertEqual(x.value, '')
1931
+
1932
+ t = ndt('10 * string')
1933
+ x = xnd.empty(t)
1934
+ self.assertEqual(x.type, t)
1935
+ for i in range(10):
1936
+ self.assertEqual(x[i], '')
1937
+
1938
+ def test_string(self):
1939
+ t = '2 * {a: complex128, b: string}'
1940
+ x = xnd([R['a': 2+3j, 'b': "thisguy"], R['a': 1+4j, 'b': "thatguy"]], type=t)
1941
+
1942
+ self.assertEqual(x[0]['b'], "thisguy")
1943
+ self.assertEqual(x[1]['b'], "thatguy")
1944
+
1945
+ def test_string_assign(self):
1946
+ t = '2 * {a: complex128, b: string}'
1947
+ x = xnd([R['a': 2+3j, 'b': "thisguy"], R['a': 1+4j, 'b': "thatguy"]], type=t)
1948
+
1949
+ x[0] = R['a': 220j, 'b': 'y']
1950
+ x[1] = R['a': -12j, 'b': 'z']
1951
+ self.assertEqual(x.value, [R['a': 220j, 'b': 'y'], R['a': -12j, 'b': 'z']])
1952
+
1953
+ def test_string_richcompare(self):
1954
+
1955
+ x = xnd("abc")
1956
+
1957
+ self.assertStrictEqual(x, xnd("abc"))
1958
+ self.assertStrictEqual(x, xnd("abc\0\0"))
1959
+
1960
+ self.assertNotStrictEqual(x, xnd("acb"))
1961
+
1962
+
1963
+ class TestBytes(XndTestCase):
1964
+
1965
+ def test_bytes_empty(self):
1966
+ r = R['a': b'', 'b': b'']
1967
+
1968
+ test_cases = [
1969
+ (b'', 'bytes(align=16)'),
1970
+ ((b'',), '(bytes(align=32))'),
1971
+ (3 * [2 * [b'']], '3 * 2 * bytes'),
1972
+ (10 * [2 * [(b'', b'')]], '10 * 2 * (bytes, bytes)'),
1973
+ (10 * [2 * [r]], '10 * 2 * {a: bytes(align=32), b: bytes(align=1)}'),
1974
+ (10 * [2 * [r]], '10 * 2 * {a: bytes(align=1), b: bytes(align=32)}'),
1975
+ ([2 * [r], 5 * [r], 3 * [r]], 'var(offsets=[0,3]) * var(offsets=[0,2,7,10]) * {a: bytes(align=32), b: bytes}')
1976
+ ]
1977
+
1978
+ for v, s in test_cases:
1979
+ t = ndt(s)
1980
+ x = xnd.empty(s)
1981
+ self.assertEqual(x.type, t)
1982
+ self.assertEqual(x.value, v)
1983
+
1984
+ def test_bytes_assign(self):
1985
+ t = "2 * SomeByteArray(3 * bytes)"
1986
+ inner = [b'a', b'b', b'c']
1987
+ v = 2 * [inner]
1988
+
1989
+ x = xnd(v, type=t)
1990
+ for i in range(2):
1991
+ for k in range(3):
1992
+ x[i, k] = inner[k] = bytes(chr(ord('x') + k), "ascii")
1993
+
1994
+ self.assertEqual(x.value, v)
1995
+
1996
+
1997
+ class TestChar(XndTestCase):
1998
+
1999
+ def test_char(self):
2000
+ # Semantics need to be evaluated (we already have fixed_string
2001
+ # with different encodings).
2002
+ self.assertRaises(NotImplementedError, xnd.empty, "char('utf8')")
2003
+ self.assertRaises(NotImplementedError, xnd, 1, type="char('utf8')")
2004
+
2005
+
2006
+ class TestBool(XndTestCase):
2007
+
2008
+ def test_bool(self):
2009
+ # From bool.
2010
+ x = xnd(True, type="bool")
2011
+ self.assertIs(x.value, True)
2012
+
2013
+ x = xnd(False, type="bool")
2014
+ self.assertIs(x.value, False)
2015
+
2016
+ # From int.
2017
+ x = xnd(1, type="bool")
2018
+ self.assertIs(x.value, True)
2019
+
2020
+ x = xnd(0, type="bool")
2021
+ self.assertIs(x.value, False)
2022
+
2023
+ # From object (for numpy compat: np.bool([1,2,3]))
2024
+ x = xnd([1,2,3], type="bool")
2025
+ self.assertIs(x.value, True)
2026
+
2027
+ x = xnd(None, type="?bool")
2028
+ self.assertIs(x.value, None)
2029
+
2030
+ self.assertRaises(ValueError, xnd, None, type="bool")
2031
+
2032
+ # Test broken input.
2033
+ b = BoolMemoryError()
2034
+ self.assertRaises(MemoryError, xnd, b, type="bool")
2035
+
2036
+ # Test len.
2037
+ x = xnd(True, type="bool")
2038
+ self.assertRaises(TypeError, len, x)
2039
+
2040
+ def test_bool_richcompare(self):
2041
+
2042
+ self.assertStrictEqual(xnd(True), xnd(True))
2043
+ self.assertStrictEqual(xnd(False), xnd(False))
2044
+ self.assertNotStrictEqual(xnd(True), xnd(False))
2045
+ self.assertNotStrictEqual(xnd(False), xnd(True))
2046
+
2047
+
2048
+ class TestSignedKind(XndTestCase):
2049
+
2050
+ def test_signed_kind(self):
2051
+ self.assertRaises(ValueError, xnd.empty, "Signed")
2052
+
2053
+
2054
+ class TestSigned(XndTestCase):
2055
+
2056
+ def test_signed(self):
2057
+ # Test bounds.
2058
+ for n in (8, 16, 32, 64):
2059
+ t = "int%d" % n
2060
+
2061
+ v = -2**(n-1)
2062
+ x = xnd(v, type=t)
2063
+ self.assertEqual(x.value, v)
2064
+ self.assertRaises((ValueError, OverflowError), xnd, v-1, type=t)
2065
+
2066
+ v = 2**(n-1) - 1
2067
+ x = xnd(v, type=t)
2068
+ self.assertEqual(x.value, v)
2069
+ self.assertRaises((ValueError, OverflowError), xnd, v+1, type=t)
2070
+
2071
+ # Test index.
2072
+ i = Index()
2073
+ for n in (8, 16, 32, 64):
2074
+ t = "int%d" % n
2075
+ x = xnd(i, type=t)
2076
+ self.assertEqual(x.value, 10)
2077
+
2078
+ # Test broken input.
2079
+ for n in (8, 16, 32, 64):
2080
+ t = "int%d" % n
2081
+ i = IndexMemoryError()
2082
+ self.assertRaises(MemoryError, xnd, i, type=t)
2083
+ i = IndexTypeError()
2084
+ self.assertRaises(TypeError, xnd, i, type=t)
2085
+
2086
+ # Test len.
2087
+ x = xnd(10, type="int16")
2088
+ self.assertRaises(TypeError, len, x)
2089
+
2090
+ def test_signed_richcompare(self):
2091
+
2092
+ for t in "int8", "int16", "int32", "int64":
2093
+ self.assertStrictEqual(xnd(-10, type=t), xnd(-10, type=t))
2094
+ self.assertNotStrictEqual(xnd(-10, type=t), xnd(100, type=t))
2095
+
2096
+
2097
+ class TestUnsignedKind(XndTestCase):
2098
+
2099
+ def test_unsigned_kind(self):
2100
+ self.assertRaises(ValueError, xnd.empty, "Unsigned")
2101
+
2102
+
2103
+ class TestUnsigned(XndTestCase):
2104
+
2105
+ def test_unsigned(self):
2106
+ # Test bounds.
2107
+ for n in (8, 16, 32, 64):
2108
+ t = "uint%d" % n
2109
+
2110
+ v = 0
2111
+ x = xnd(v, type=t)
2112
+ self.assertEqual(x.value, v)
2113
+ self.assertRaises((ValueError, OverflowError), xnd, v-1, type=t)
2114
+
2115
+ v = 2**n - 1
2116
+ x = xnd(v, type=t)
2117
+ self.assertEqual(x.value, v)
2118
+ self.assertRaises((ValueError, OverflowError), xnd, v+1, type=t)
2119
+
2120
+ # Test index.
2121
+ i = Index()
2122
+ for n in (8, 16, 32, 64):
2123
+ t = "uint%d" % n
2124
+ x = xnd(i, type=t)
2125
+ self.assertEqual(x.value, 10)
2126
+
2127
+ # Test broken input.
2128
+ for n in (8, 16, 32, 64):
2129
+ t = "uint%d" % n
2130
+ i = IndexMemoryError()
2131
+ self.assertRaises(MemoryError, xnd, i, type=t)
2132
+ i = IndexTypeError()
2133
+ self.assertRaises(TypeError, xnd, i, type=t)
2134
+
2135
+ # Test len.
2136
+ x = xnd(10, type="uint64")
2137
+ self.assertRaises(TypeError, len, x)
2138
+
2139
+ def test_unsigned_richcompare(self):
2140
+
2141
+ for t in "uint8", "uint16", "uint32", "uint64":
2142
+ self.assertStrictEqual(xnd(10, type=t), xnd(10, type=t))
2143
+ self.assertNotStrictEqual(xnd(10, type=t), xnd(100, type=t))
2144
+
2145
+
2146
+ class TestFloatKind(XndTestCase):
2147
+
2148
+ def test_float_kind(self):
2149
+ self.assertRaises(ValueError, xnd.empty, "Float")
2150
+
2151
+
2152
+ class TestFloat(XndTestCase):
2153
+
2154
+ @requires_py36
2155
+ def test_float16(self):
2156
+ fromhex = float.fromhex
2157
+
2158
+ # Test creation and initialization of empty xnd objects.
2159
+ for value, type_string in EMPTY_TEST_CASES:
2160
+ ts = type_string % "float16"
2161
+ x = xnd.empty(ts)
2162
+ self.assertEqual(x.value, value)
2163
+ self.assertEqual(x.type, ndt(ts))
2164
+
2165
+ # Test bounds.
2166
+ DENORM_MIN = fromhex("0x1p-24")
2167
+ LOWEST = fromhex("-0x1.ffcp+15")
2168
+ MAX = fromhex("0x1.ffcp+15")
2169
+ INF = fromhex("0x1.ffep+15")
2170
+
2171
+ x = xnd(DENORM_MIN, type="float16")
2172
+ self.assertEqual(x.value, DENORM_MIN)
2173
+
2174
+ x = xnd(LOWEST, type="float16")
2175
+ self.assertEqual(x.value, LOWEST)
2176
+
2177
+ x = xnd(MAX, type="float16")
2178
+ self.assertEqual(x.value, MAX)
2179
+
2180
+ self.assertRaises(OverflowError, xnd, INF, type="float16")
2181
+ self.assertRaises(OverflowError, xnd, -INF, type="float16")
2182
+
2183
+ # Test special values.
2184
+ x = xnd(float("inf"), type="float16")
2185
+ self.assertTrue(isinf(x.value))
2186
+
2187
+ x = xnd(float("nan"), type="float16")
2188
+ self.assertTrue(isnan(x.value))
2189
+
2190
+ # Richcompare.
2191
+ self.assertStrictEqual(xnd(1.2e3, type="float16"), xnd(1.2e3, type="float16"))
2192
+ self.assertStrictEqual(xnd(float("inf"), type="float16"), xnd(float("inf"), type="float16"))
2193
+ self.assertStrictEqual(xnd(float("-inf"), type="float16"), xnd(float("-inf"), type="float16"))
2194
+
2195
+ self.assertNotStrictEqual(xnd(1.2e3, type="float16"), xnd(-1.2e3, type="float16"))
2196
+ self.assertNotStrictEqual(xnd(float("inf"), type="float16"), xnd(float("-inf"), type="float16"))
2197
+ self.assertNotStrictEqual(xnd(float("-inf"), type="float16"), xnd(float("inf"), type="float16"))
2198
+ self.assertNotStrictEqual(xnd(float("nan"), type="float16"), xnd(float("nan"), type="float16"))
2199
+
2200
+ def test_float32(self):
2201
+ fromhex = float.fromhex
2202
+
2203
+ # Test bounds.
2204
+ DENORM_MIN = fromhex("0x1p-149")
2205
+ LOWEST = fromhex("-0x1.fffffep+127")
2206
+ MAX = fromhex("0x1.fffffep+127")
2207
+ INF = fromhex("0x1.ffffffp+127")
2208
+
2209
+ x = xnd(DENORM_MIN, type="float32")
2210
+ self.assertEqual(x.value, DENORM_MIN)
2211
+
2212
+ x = xnd(LOWEST, type="float32")
2213
+ self.assertEqual(x.value, LOWEST)
2214
+
2215
+ x = xnd(MAX, type="float32")
2216
+ self.assertEqual(x.value, MAX)
2217
+
2218
+ self.assertRaises(OverflowError, xnd, INF, type="float32")
2219
+ self.assertRaises(OverflowError, xnd, -INF, type="float32")
2220
+
2221
+ # Test special values.
2222
+ x = xnd(float("inf"), type="float32")
2223
+ self.assertTrue(isinf(x.value))
2224
+
2225
+ x = xnd(float("nan"), type="float32")
2226
+ self.assertTrue(isnan(x.value))
2227
+
2228
+ # Richcompare.
2229
+ self.assertStrictEqual(xnd(1.2e7, type="float32"), xnd(1.2e7, type="float32"))
2230
+ self.assertStrictEqual(xnd(float("inf"), type="float32"), xnd(float("inf"), type="float32"))
2231
+ self.assertStrictEqual(xnd(float("-inf"), type="float32"), xnd(float("-inf"), type="float32"))
2232
+
2233
+ self.assertNotStrictEqual(xnd(1.2e7, type="float32"), xnd(-1.2e7, type="float32"))
2234
+ self.assertNotStrictEqual(xnd(float("inf"), type="float32"), xnd(float("-inf"), type="float32"))
2235
+ self.assertNotStrictEqual(xnd(float("-inf"), type="float32"), xnd(float("inf"), type="float32"))
2236
+ self.assertNotStrictEqual(xnd(float("nan"), type="float32"), xnd(float("nan"), type="float32"))
2237
+
2238
+ def test_float64(self):
2239
+ fromhex = float.fromhex
2240
+
2241
+ # Test bounds.
2242
+ DENORM_MIN = fromhex("0x0.0000000000001p-1022")
2243
+ LOWEST = fromhex("-0x1.fffffffffffffp+1023")
2244
+ MAX = fromhex("0x1.fffffffffffffp+1023")
2245
+
2246
+ x = xnd(DENORM_MIN, type="float64")
2247
+ self.assertEqual(x.value, DENORM_MIN)
2248
+
2249
+ x = xnd(LOWEST, type="float64")
2250
+ self.assertEqual(x.value, LOWEST)
2251
+
2252
+ x = xnd(MAX, type="float64")
2253
+ self.assertEqual(x.value, MAX)
2254
+
2255
+ # Test special values.
2256
+ x = xnd(float("inf"), type="float64")
2257
+ self.assertTrue(isinf(x.value))
2258
+
2259
+ x = xnd(float("nan"), type="float64")
2260
+ self.assertTrue(isnan(x.value))
2261
+
2262
+ # Richcompare.
2263
+ self.assertStrictEqual(xnd(1.2e7, type="float64"), xnd(1.2e7, type="float64"))
2264
+ self.assertStrictEqual(xnd(float("inf"), type="float64"), xnd(float("inf"), type="float64"))
2265
+ self.assertStrictEqual(xnd(float("-inf"), type="float64"), xnd(float("-inf"), type="float64"))
2266
+
2267
+ self.assertNotStrictEqual(xnd(1.2e7, type="float64"), xnd(-1.2e7, type="float64"))
2268
+ self.assertNotStrictEqual(xnd(float("inf"), type="float64"), xnd(float("-inf"), type="float64"))
2269
+ self.assertNotStrictEqual(xnd(float("-inf"), type="float64"), xnd(float("inf"), type="float64"))
2270
+ self.assertNotStrictEqual(xnd(float("nan"), type="float64"), xnd(float("nan"), type="float64"))
2271
+
2272
+
2273
+ class TestComplexKind(XndTestCase):
2274
+
2275
+ def test_complex_kind(self):
2276
+ self.assertRaises(ValueError, xnd.empty, "Complex")
2277
+
2278
+
2279
+ class TestComplex(XndTestCase):
2280
+
2281
+ @requires_py36
2282
+ def test_complex32(self):
2283
+ fromhex = float.fromhex
2284
+
2285
+ # Test creation and initialization of empty xnd objects.
2286
+ for value, type_string in EMPTY_TEST_CASES:
2287
+ ts = type_string % "complex32"
2288
+ x = xnd.empty(ts)
2289
+ self.assertEqual(x.value, value)
2290
+ self.assertEqual(x.type, ndt(ts))
2291
+
2292
+ # Test bounds.
2293
+ DENORM_MIN = fromhex("0x1p-24")
2294
+ LOWEST = fromhex("-0x1.ffcp+15")
2295
+ MAX = fromhex("0x1.ffcp+15")
2296
+ INF = fromhex("0x1.ffep+15")
2297
+
2298
+ v = complex(DENORM_MIN, DENORM_MIN)
2299
+ x = xnd(v, type="complex32")
2300
+ self.assertEqual(x.value, v)
2301
+
2302
+ v = complex(LOWEST, LOWEST)
2303
+ x = xnd(v, type="complex32")
2304
+ self.assertEqual(x.value, v)
2305
+
2306
+ v = complex(MAX, MAX)
2307
+ x = xnd(v, type="complex32")
2308
+ self.assertEqual(x.value, v)
2309
+
2310
+ v = complex(INF, INF)
2311
+ self.assertRaises(OverflowError, xnd, v, type="complex32")
2312
+
2313
+ v = complex(-INF, -INF)
2314
+ self.assertRaises(OverflowError, xnd, v, type="complex32")
2315
+
2316
+ # Test special values.
2317
+ x = xnd(complex("inf"), type="complex32")
2318
+ self.assertTrue(isinf(x.value.real))
2319
+ self.assertEqual(x.value.imag, 0.0)
2320
+
2321
+ x = xnd(complex("nan"), type="complex32")
2322
+ self.assertTrue(isnan(x.value.real))
2323
+ self.assertEqual(x.value.imag, 0.0)
2324
+
2325
+ # Richcompare.
2326
+ t = "complex32"
2327
+ c = [DENORM_MIN, LOWEST, MAX, float("inf"), float("-inf"), float("nan")]
2328
+ for r in c:
2329
+ for s in c:
2330
+ for i in c:
2331
+ for j in c:
2332
+ x = xnd(complex(r, i), type=t)
2333
+ y = xnd(complex(s, j), type=t)
2334
+ if r == s and i == j:
2335
+ self.assertStrictEqual(x, y)
2336
+ else:
2337
+ self.assertNotStrictEqual(x, y)
2338
+
2339
+ def test_complex64(self):
2340
+ fromhex = float.fromhex
2341
+
2342
+ # Test bounds.
2343
+ DENORM_MIN = fromhex("0x1p-149")
2344
+ LOWEST = fromhex("-0x1.fffffep+127")
2345
+ MAX = fromhex("0x1.fffffep+127")
2346
+ INF = fromhex("0x1.ffffffp+127")
2347
+
2348
+ v = complex(DENORM_MIN, DENORM_MIN)
2349
+ x = xnd(v, type="complex64")
2350
+ self.assertEqual(x.value, v)
2351
+
2352
+ v = complex(LOWEST, LOWEST)
2353
+ x = xnd(v, type="complex64")
2354
+ self.assertEqual(x.value, v)
2355
+
2356
+ v = complex(MAX, MAX)
2357
+ x = xnd(v, type="complex64")
2358
+ self.assertEqual(x.value, v)
2359
+
2360
+ v = complex(INF, INF)
2361
+ self.assertRaises(OverflowError, xnd, INF, type="complex64")
2362
+
2363
+ v = complex(-INF, -INF)
2364
+ self.assertRaises(OverflowError, xnd, -INF, type="complex64")
2365
+
2366
+ # Test special values.
2367
+ x = xnd(complex("inf"), type="complex64")
2368
+ self.assertTrue(isinf(x.value.real))
2369
+ self.assertEqual(x.value.imag, 0.0)
2370
+
2371
+ x = xnd(complex("nan"), type="complex64")
2372
+ self.assertTrue(isnan(x.value.real))
2373
+ self.assertEqual(x.value.imag, 0.0)
2374
+
2375
+ # Richcompare.
2376
+ t = "complex64"
2377
+ c = [DENORM_MIN, LOWEST, MAX, float("inf"), float("-inf"), float("nan")]
2378
+ for r in c:
2379
+ for s in c:
2380
+ for i in c:
2381
+ for j in c:
2382
+ x = xnd(complex(r, i), type=t)
2383
+ y = xnd(complex(s, j), type=t)
2384
+ if r == s and i == j:
2385
+ self.assertStrictEqual(x, y)
2386
+ else:
2387
+ self.assertNotStrictEqual(x, y)
2388
+
2389
+ def test_complex128(self):
2390
+ fromhex = float.fromhex
2391
+
2392
+ # Test bounds.
2393
+ DENORM_MIN = fromhex("0x0.0000000000001p-1022")
2394
+ LOWEST = fromhex("-0x1.fffffffffffffp+1023")
2395
+ MAX = fromhex("0x1.fffffffffffffp+1023")
2396
+
2397
+ v = complex(DENORM_MIN, DENORM_MIN)
2398
+ x = xnd(v, type="complex128")
2399
+ self.assertEqual(x.value, v)
2400
+
2401
+ v = complex(LOWEST, LOWEST)
2402
+ x = xnd(v, type="complex128")
2403
+ self.assertEqual(x.value, v)
2404
+
2405
+ v = complex(MAX, MAX)
2406
+ x = xnd(v, type="complex128")
2407
+ self.assertEqual(x.value, v)
2408
+
2409
+ # Test special values.
2410
+ x = xnd(complex("inf"), type="complex128")
2411
+ self.assertTrue(isinf(x.value.real))
2412
+ self.assertEqual(x.value.imag, 0.0)
2413
+
2414
+ x = xnd(complex("nan"), type="complex128")
2415
+ self.assertTrue(isnan(x.value.real))
2416
+ self.assertEqual(x.value.imag, 0.0)
2417
+
2418
+ # Richcompare.
2419
+ t = "complex128"
2420
+ c = [DENORM_MIN, LOWEST, MAX, float("inf"), float("-inf"), float("nan")]
2421
+ for r in c:
2422
+ for s in c:
2423
+ for i in c:
2424
+ for j in c:
2425
+ x = xnd(complex(r, i), type=t)
2426
+ y = xnd(complex(s, j), type=t)
2427
+ if r == s and i == j:
2428
+ self.assertStrictEqual(x, y)
2429
+ else:
2430
+ self.assertNotStrictEqual(x, y)
2431
+
2432
+
2433
+ class TestPrimitive(XndTestCase):
2434
+
2435
+ def test_primitive_empty(self):
2436
+ # Test creation and initialization of empty xnd objects.
2437
+
2438
+ for value, type_string in EMPTY_TEST_CASES:
2439
+ for p in PRIMITIVE:
2440
+ ts = type_string % p
2441
+ x = xnd.empty(ts)
2442
+ self.assertEqual(x.value, value)
2443
+ self.assertEqual(x.type, ndt(ts))
2444
+
2445
+
2446
+ class TestTypevar(XndTestCase):
2447
+
2448
+ def test_typevar(self):
2449
+ self.assertRaises(ValueError, xnd.empty, "T")
2450
+ self.assertRaises(ValueError, xnd.empty, "2 * 10 * T")
2451
+ self.assertRaises(ValueError, xnd.empty, "{a: 2 * 10 * T, b: bytes}")
2452
+
2453
+
2454
+ class TestTypeInference(XndTestCase):
2455
+
2456
+ def test_tuple(self):
2457
+ d = R['a': (2.0, b"bytes"), 'b': ("str", float('inf'))]
2458
+ typeof_d = "{a: (float64, bytes), b: (string, float64)}"
2459
+
2460
+ test_cases = [
2461
+ ((), "()"),
2462
+ (((),), "(())"),
2463
+ (((), ()), "((), ())"),
2464
+ ((((),), ()), "((()), ())"),
2465
+ ((((),), ((), ())), "((()), ((), ()))"),
2466
+ ((1, 2, 3), "(int64, int64, int64)"),
2467
+ ((1.0, 2, "str"), "(float64, int64, string)"),
2468
+ ((1.0, 2, ("str", b"bytes", d)),
2469
+ "(float64, int64, (string, bytes, %s))" % typeof_d)
2470
+ ]
2471
+
2472
+ for v, t in test_cases:
2473
+ x = xnd(v)
2474
+ self.assertEqual(x.type, ndt(t))
2475
+ self.assertEqual(x.value, v)
2476
+
2477
+ def test_record(self):
2478
+ d = R['a': (2.0, b"bytes"), 'b': ("str", float('inf'))]
2479
+ typeof_d = "{a: (float64, bytes), b: (string, float64)}"
2480
+
2481
+ test_cases = [
2482
+ ({}, "{}"),
2483
+ ({'x': {}}, "{x: {}}"),
2484
+ (R['x': {}, 'y': {}], "{x: {}, y: {}}"),
2485
+ (R['x': R['y': {}], 'z': {}], "{x: {y: {}}, z: {}}"),
2486
+ (R['x': R['y': {}], 'z': R['a': {}, 'b': {}]], "{x: {y: {}}, z: {a: {}, b: {}}}"),
2487
+ (d, typeof_d)
2488
+ ]
2489
+
2490
+ for v, t in test_cases:
2491
+ x = xnd(v)
2492
+ self.assertEqual(x.type, ndt(t))
2493
+ self.assertEqual(x.value, v)
2494
+
2495
+ def test_float64(self):
2496
+ d = R['a': 2.221e100, 'b': float('inf')]
2497
+ typeof_d = "{a: float64, b: float64}"
2498
+
2499
+ test_cases = [
2500
+ # 'float64' is the default dtype if there is no data at all.
2501
+ ([], "0 * float64"),
2502
+ ([[]], "1 * 0 * float64"),
2503
+ ([[], []], "2 * 0 * float64"),
2504
+ ([[[]], [[]]], "2 * 1 * 0 * float64"),
2505
+ ([[[]], [[], []]], "var(offsets=[0, 2]) * var(offsets=[0, 1, 3]) * var(offsets=[0, 0, 0, 0]) * float64"),
2506
+
2507
+ ([0.0], "1 * float64"),
2508
+ ([0.0, 1.2], "2 * float64"),
2509
+ ([[0.0], [1.2]], "2 * 1 * float64"),
2510
+
2511
+ (d, typeof_d),
2512
+ ([d] * 2, "2 * %s" % typeof_d),
2513
+ ([[d] * 2] * 10, "10 * 2 * %s" % typeof_d)
2514
+ ]
2515
+
2516
+ for v, t in test_cases:
2517
+ x = xnd(v)
2518
+ self.assertEqual(x.type, ndt(t))
2519
+ self.assertEqual(x.value, v)
2520
+
2521
+ def test_complex128(self):
2522
+ d = R['a': 3.123+10j, 'b': complex('inf')]
2523
+ typeof_d = "{a: complex128, b: complex128}"
2524
+
2525
+ test_cases = [
2526
+ ([1+3e300j], "1 * complex128"),
2527
+ ([-2.2-5j, 1.2-10j], "2 * complex128"),
2528
+ ([-2.2-5j, 1.2-10j, None], "3 * ?complex128"),
2529
+ ([[-1+3j], [-3+5j]], "2 * 1 * complex128"),
2530
+
2531
+ (d, typeof_d),
2532
+ ([d] * 2, "2 * %s" % typeof_d),
2533
+ ([[d] * 2] * 10, "10 * 2 * %s" % typeof_d)
2534
+ ]
2535
+
2536
+ for v, t in test_cases:
2537
+ x = xnd(v)
2538
+ self.assertEqual(x.type, ndt(t))
2539
+ self.assertEqual(x.value, v)
2540
+
2541
+ def test_int64(self):
2542
+ t = (1, -2, -3)
2543
+ typeof_t = "(int64, int64, int64)"
2544
+
2545
+ test_cases = [
2546
+ ([0], "1 * int64"),
2547
+ ([0, 1], "2 * int64"),
2548
+ ([[0], [1]], "2 * 1 * int64"),
2549
+
2550
+ (t, typeof_t),
2551
+ ([t] * 2, "2 * %s" % typeof_t),
2552
+ ([[t] * 2] * 10, "10 * 2 * %s" % typeof_t)
2553
+ ]
2554
+
2555
+ for v, t in test_cases:
2556
+ x = xnd(v)
2557
+ self.assertEqual(x.type, ndt(t))
2558
+ self.assertEqual(x.value, v)
2559
+
2560
+ def test_string(self):
2561
+ t = ("supererogatory", "exiguous")
2562
+ typeof_t = "(string, string)"
2563
+
2564
+ test_cases = [
2565
+ (["mov"], "1 * string"),
2566
+ (["mov", "$0"], "2 * string"),
2567
+ ([["cmp"], ["$0"]], "2 * 1 * string"),
2568
+
2569
+ (t, typeof_t),
2570
+ ([t] * 2, "2 * %s" % typeof_t),
2571
+ ([[t] * 2] * 10, "10 * 2 * %s" % typeof_t)
2572
+ ]
2573
+
2574
+ for v, t in test_cases:
2575
+ x = xnd(v)
2576
+ self.assertEqual(x.type, ndt(t))
2577
+ self.assertEqual(x.value, v)
2578
+
2579
+ def test_bytes(self):
2580
+ t = (b"lagrange", b"points")
2581
+ typeof_t = "(bytes, bytes)"
2582
+
2583
+ test_cases = [
2584
+ ([b"L1"], "1 * bytes"),
2585
+ ([b"L2", b"L3", b"L4"], "3 * bytes"),
2586
+ ([[b"L5"], [b"none"]], "2 * 1 * bytes"),
2587
+
2588
+ (t, typeof_t),
2589
+ ([t] * 2, "2 * %s" % typeof_t),
2590
+ ([[t] * 2] * 10, "10 * 2 * %s" % typeof_t)
2591
+ ]
2592
+
2593
+ for v, t in test_cases:
2594
+ x = xnd(v)
2595
+ self.assertEqual(x.type, ndt(t))
2596
+ self.assertEqual(x.value, v)
2597
+
2598
+ def test_optional(self):
2599
+ test_cases = [
2600
+ (None, "?float64"),
2601
+ ([None], "1 * ?float64"),
2602
+ ([None, None], "2 * ?float64"),
2603
+ ([None, 10], "2 * ?int64"),
2604
+ ([None, b'abc'], "2 * ?bytes"),
2605
+ ([None, 'abc'], "2 * ?string")
2606
+ ]
2607
+
2608
+ for v, t in test_cases:
2609
+ x = xnd(v)
2610
+ self.assertEqual(x.type, ndt(t))
2611
+ self.assertEqual(x.value, v)
2612
+
2613
+ # Optional dimensions are not implemented.
2614
+ not_implemented = [
2615
+ [None, []],
2616
+ [[], None],
2617
+ [None, [10]],
2618
+ [[None, [0, 1]], [[2, 3]]]
2619
+ ]
2620
+
2621
+ for v in not_implemented:
2622
+ self.assertRaises(NotImplementedError, xnd, v)
2623
+
2624
+
2625
+ class TestIndexing(XndTestCase):
2626
+
2627
+ def test_indexing(self):
2628
+ x = xnd([])
2629
+ self.assertRaises(IndexError, x.__getitem__, 0)
2630
+ self.assertRaises(IndexError, x.__getitem__, (0, 0))
2631
+
2632
+ x = xnd([0])
2633
+ self.assertEqual(x[0], 0)
2634
+
2635
+ self.assertRaises(IndexError, x.__getitem__, 1)
2636
+ self.assertRaises(IndexError, x.__getitem__, (0, 1))
2637
+
2638
+ x = xnd([[0,1,2], [3,4,5]])
2639
+ self.assertEqual(x[0,0], 0)
2640
+ self.assertEqual(x[0,1], 1)
2641
+ self.assertEqual(x[0,2], 2)
2642
+
2643
+ self.assertEqual(x[1,0], 3)
2644
+ self.assertEqual(x[1,1], 4)
2645
+ self.assertEqual(x[1,2], 5)
2646
+
2647
+ self.assertRaises(IndexError, x.__getitem__, (0, 3))
2648
+ self.assertRaises(IndexError, x.__getitem__, (2, 0))
2649
+
2650
+ t1 = (1.0, "capricious", (1, 2, 3))
2651
+ t2 = (2.0, "volatile", (4, 5, 6))
2652
+
2653
+ x = xnd([t1, t2])
2654
+ self.assertEqual(x[0].value, t1)
2655
+ self.assertEqual(x[1].value, t2)
2656
+
2657
+ self.assertEqual(x[0,0], 1.0)
2658
+ self.assertEqual(x[0,1], "capricious")
2659
+ self.assertEqual(x[0,2].value, (1, 2, 3))
2660
+
2661
+ self.assertEqual(x[1,0], 2.0)
2662
+ self.assertEqual(x[1,1], "volatile")
2663
+ self.assertEqual(x[1,2].value, (4, 5, 6))
2664
+
2665
+ def test_subview(self):
2666
+ # fixed
2667
+ x = xnd([["a", "b"], ["c", "d"]])
2668
+ self.assertEqual(x[0].value, ["a", "b"])
2669
+ self.assertEqual(x[1].value, ["c", "d"])
2670
+
2671
+ # var
2672
+ x = xnd([["a", "b"], ["x", "y", "z"]])
2673
+ self.assertEqual(x[0].value, ["a", "b"])
2674
+ self.assertEqual(x[1].value, ["x", "y", "z"])
2675
+
2676
+
2677
+ class TestSequence(XndTestCase):
2678
+
2679
+ def test_sequence(self):
2680
+ for v, s in DTYPE_EMPTY_TEST_CASES:
2681
+ for vv, ss in [
2682
+ (1 * [1 * [v]], "!1 * 1 * %s" % s),
2683
+ (1 * [2 * [v]], "!1 * 2 * %s" % s),
2684
+ (2 * [1 * [v]], "!2 * 1 * %s" % s),
2685
+ (2 * [2 * [v]], "2 * 2 * %s" % s),
2686
+ (2 * [3 * [v]], "2 * 3 * %s" % s),
2687
+ (3 * [2 * [v]], "3 * 2 * %s" % s)]:
2688
+
2689
+ x = xnd(vv, type=ss)
2690
+
2691
+ lst = [v for v in x]
2692
+
2693
+ for i, z in enumerate(x):
2694
+ self.assertEqual(z.value, lst[i].value)
2695
+
2696
+
2697
+ class TestAPI(XndTestCase):
2698
+
2699
+ def test_hash(self):
2700
+ x = xnd(1000)
2701
+ self.assertRaises(TypeError, hash, x)
2702
+
2703
+ x = xnd([1, 2, 3])
2704
+ self.assertRaises(TypeError, hash, x)
2705
+
2706
+ def test_short_value(self):
2707
+ x = xnd([1, 2])
2708
+ self.assertEqual(x.short_value(0), [])
2709
+ self.assertEqual(x.short_value(1), [XndEllipsis])
2710
+ self.assertEqual(x.short_value(2), [1, XndEllipsis])
2711
+ self.assertEqual(x.short_value(3), [1, 2])
2712
+ self.assertRaises(ValueError, x.short_value, -1)
2713
+
2714
+ x = xnd([[1, 2], [3]])
2715
+ self.assertEqual(x.short_value(0), [])
2716
+ self.assertEqual(x.short_value(1), [XndEllipsis])
2717
+ self.assertEqual(x.short_value(2), [[1, XndEllipsis], XndEllipsis])
2718
+ self.assertEqual(x.short_value(3), [[1, 2], [3]])
2719
+ self.assertRaises(ValueError, x.short_value, -1)
2720
+
2721
+ x = xnd((1, 2))
2722
+ self.assertEqual(x.short_value(0), ())
2723
+ self.assertEqual(x.short_value(1), (XndEllipsis,))
2724
+ self.assertEqual(x.short_value(2), (1, XndEllipsis))
2725
+ self.assertEqual(x.short_value(3), (1, 2))
2726
+ self.assertRaises(ValueError, x.short_value, -1)
2727
+
2728
+ x = xnd(R['a': 1, 'b': 2])
2729
+ self.assertEqual(x.short_value(0), {})
2730
+ self.assertEqual(x.short_value(1), {XndEllipsis: XndEllipsis})
2731
+ self.assertEqual(x.short_value(2), R['a': 1, XndEllipsis: XndEllipsis])
2732
+ self.assertEqual(x.short_value(3), R['a': 1, 'b': 2])
2733
+ self.assertRaises(ValueError, x.short_value, -1)
2734
+
2735
+
2736
+ class TestRepr(XndTestCase):
2737
+
2738
+ def test_repr(self):
2739
+ lst = 10 * [19 * [23 * [{'a': 100, 'b': "xyz", 'c': ['abc', 'uvw']}]]]
2740
+ x = xnd(lst)
2741
+ r = repr(x)
2742
+ self.assertLess(len(r), 100000)
2743
+
2744
+
2745
+ class TestBuffer(XndTestCase):
2746
+
2747
+ @unittest.skipIf(np is None, "numpy not found")
2748
+ def test_from_buffer(self):
2749
+ x = np.array([[[0,1,2],
2750
+ [3,4,5]],
2751
+ [[6,7,8],
2752
+ [9,10,11]]])
2753
+
2754
+ y = xnd.from_buffer(x)
2755
+ for i in range(2):
2756
+ for j in range(2):
2757
+ for k in range(3):
2758
+ self.assertEqual(y[i,j,k], x[i,j,k])
2759
+
2760
+ x = np.array([(1000, 400.25, 'abc'), (-23, -1e10, 'cba')],
2761
+ dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'S3')])
2762
+ y = xnd.from_buffer(x)
2763
+
2764
+ for i in range(2):
2765
+ for k in ['x', 'y', 'z']:
2766
+ self.assertEqual(y[i][k], x[i][k])
2767
+
2768
+ @unittest.skipIf(np is None, "numpy not found")
2769
+ def test_unsafe_from_buffer(self):
2770
+ x = np.array([[[0,1,2],
2771
+ [3,4,5]],
2772
+ [[6,7,8],
2773
+ [9,10,11]]], dtype="int64")
2774
+
2775
+ y = xnd.unsafe_from_data(obj=x, type="12 * int64")
2776
+ np.testing.assert_equal(y, x.reshape(12))
2777
+
2778
+ @unittest.skipIf(np is None, "numpy not found")
2779
+ def test_endian(self):
2780
+ standard = [
2781
+ '?',
2782
+ 'c', 'b', 'B',
2783
+ 'h', 'i', 'l', 'q',
2784
+ 'H', 'I', 'L', 'Q',
2785
+ 'f', 'd',
2786
+ ]
2787
+
2788
+ if HAVE_PYTHON_36:
2789
+ standard += 'e'
2790
+
2791
+ modifiers = ['', '<', '>']
2792
+
2793
+ for fmt in standard:
2794
+ for mod in modifiers:
2795
+ f = mod + fmt
2796
+ x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=f)
2797
+ y = xnd.from_buffer(x)
2798
+ for i in range(10):
2799
+ self.assertEqual(y[i], x[i])
2800
+
2801
+ # XXX T{>i:x:f:y:3s:z:} does not work.
2802
+ x = np.array([(1000, 400.25, 'abc'), (-23, -1e10, 'cba')],
2803
+ dtype=[('x', '<i4'), ('y', '>f4'), ('z', 'S3')])
2804
+ y = xnd.from_buffer(x)
2805
+
2806
+ for i in range(2):
2807
+ for k in ['x', 'y', 'z']:
2808
+ self.assertEqual(y[i][k], x[i][k])
2809
+
2810
+ def test_readonly(self):
2811
+ x = ndarray([1,2,3], shape=[3], format="L")
2812
+ y = xnd.from_buffer(x)
2813
+ self.assertRaises(TypeError, y.__setitem__, 0, 1000)
2814
+
2815
+ x = ndarray([1,2,3], shape=[3], format="L", flags=ND_WRITABLE)
2816
+ y = xnd.from_buffer(x)
2817
+ y[:] = [1000, 2000, 3000]
2818
+ self.assertEqual(x.tolist(), [1000, 2000, 3000])
2819
+
2820
+
2821
+ class TestSplit(XndTestCase):
2822
+
2823
+ def test_split(self):
2824
+ for _ in range(1):
2825
+ for lst in gen_fixed():
2826
+ x = xnd(lst)
2827
+ for n in range(1, 100):
2828
+ try:
2829
+ a = split_xnd(x, n)
2830
+ except ValueError:
2831
+ continue
2832
+ b = xnd.split(x, n)
2833
+ self.assertEqual(a, b)
2834
+
2835
+ def test_split_limit_outer(self):
2836
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
2837
+
2838
+ for lst in gen_fixed():
2839
+ x = xnd(lst)
2840
+ for n in range(1, 10):
2841
+ for m in range(x.type.ndim + 2):
2842
+ try:
2843
+ a = split_xnd(x, n, max_outer=m)
2844
+ except ValueError:
2845
+ continue
2846
+ b = xnd.split(x, n, max_outer=m)
2847
+ self.assertEqual(a, b)
2848
+
2849
+
2850
+ class TestView(XndTestCase):
2851
+
2852
+ def test_view_subscript(self):
2853
+ x = xnd([[1,2,3], [4,5,6]])
2854
+ y = _test_view_subscript(x, key=(0, 1))
2855
+ self.assertEqual(y, xnd(2))
2856
+
2857
+ x = xnd([[1,2,3], [4,5,6]])
2858
+ y = _test_view_subscript(x, key=(1, slice(None, None, -1)))
2859
+ self.assertEqual(y, xnd([6,5,4]))
2860
+
2861
+ def test_view_new(self):
2862
+ x = _test_view_new()
2863
+ self.assertEqual(x, xnd([1.1, 2.2, 3.3]))
2864
+
2865
+
2866
+ class TestSpec(XndTestCase):
2867
+
2868
+ def __init__(self, *, constr,
2869
+ values, value_generator,
2870
+ indices_generator, indices_generator_args):
2871
+ super().__init__()
2872
+ self.constr = constr
2873
+ self.values = values
2874
+ self.value_generator = value_generator
2875
+ self.indices_generator = indices_generator
2876
+ self.indices_generator_args = indices_generator_args
2877
+ self.indices_stack = [None] * 8
2878
+
2879
+ def log_err(self, value, depth):
2880
+ """Dump an error as a Python script for debugging."""
2881
+
2882
+ sys.stderr.write("\n\nfrom xnd import *\n")
2883
+ sys.stderr.write("from test_xnd import NDArray\n")
2884
+ sys.stderr.write("lst = %s\n\n" % value)
2885
+ sys.stderr.write("x0 = xnd(lst)\n")
2886
+ sys.stderr.write("y0 = NDArray(lst)\n" % value)
2887
+
2888
+ for i in range(depth+1):
2889
+ sys.stderr.write("x%d = x%d[%s]\n" % (i+1, i, itos(self.indices_stack[i])))
2890
+ sys.stderr.write("y%d = y%d[%s]\n" % (i+1, i, itos(self.indices_stack[i])))
2891
+
2892
+ sys.stderr.write("\n")
2893
+
2894
+ def run_single(self, nd, d, indices):
2895
+ """Run a single test case."""
2896
+
2897
+ self.assertEqual(len(nd), len(d))
2898
+
2899
+ nd_exception = None
2900
+ try:
2901
+ nd_result = nd[indices]
2902
+ except Exception as e:
2903
+ nd_exception = e
2904
+
2905
+ def_exception = None
2906
+ try:
2907
+ def_result = d[indices]
2908
+ except Exception as e:
2909
+ def_exception = e
2910
+
2911
+ if nd_exception or def_exception:
2912
+ if nd_exception is None and def_exception.__class__ is IndexError:
2913
+ # Example: type = 0 * 0 * int64
2914
+ if len(indices) <= nd.ndim:
2915
+ return None, None
2916
+
2917
+ self.assertIs(nd_exception.__class__, def_exception.__class__)
2918
+ return None, None
2919
+
2920
+ if isinstance(nd_result, xnd):
2921
+ nd_value = nd_result.value
2922
+ elif np is not None and isinstance(nd_result, np.ndarray):
2923
+ nd_value = nd_result.tolist()
2924
+ else:
2925
+ nd_value = nd_result
2926
+
2927
+ self.assertEqual(nd_value, def_result)
2928
+ return nd_result, def_result
2929
+
2930
+ def run(self):
2931
+ def check(nd, d, value, depth):
2932
+ if depth > 3: # adjust for longer tests
2933
+ return
2934
+
2935
+ g = self.indices_generator(*self.indices_generator_args)
2936
+
2937
+ for indices in g:
2938
+ self.indices_stack[depth] = indices
2939
+
2940
+ try:
2941
+ next_nd, next_d = self.run_single(nd, d, indices)
2942
+ except Exception as e:
2943
+ self.log_err(value, depth)
2944
+ raise e
2945
+
2946
+ if isinstance(next_d, list): # possibly None or scalar
2947
+ check(next_nd, next_d, value, depth+1)
2948
+
2949
+ for value in self.values:
2950
+ nd = self.constr(value)
2951
+ d = NDArray(value)
2952
+ check(nd, d, value, 0)
2953
+ check_buffer(nd)
2954
+
2955
+ for max_ndim in range(1, 5):
2956
+ for min_shape in (0, 1):
2957
+ for max_shape in range(1, 8):
2958
+ for value in self.value_generator(max_ndim, min_shape, max_shape):
2959
+ nd = self.constr(value)
2960
+ d = NDArray(value)
2961
+ check(nd, d, value, 0)
2962
+ check_buffer(nd)
2963
+
2964
+
2965
+ class LongIndexSliceTest(XndTestCase):
2966
+
2967
+ def test_subarray(self):
2968
+ # Multidimensional indexing
2969
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
2970
+
2971
+ t = TestSpec(constr=xnd,
2972
+ values=SUBSCRIPT_FIXED_TEST_CASES,
2973
+ value_generator=gen_fixed,
2974
+ indices_generator=genindices,
2975
+ indices_generator_args=())
2976
+ t.run()
2977
+
2978
+ t = TestSpec(constr=xnd,
2979
+ values=SUBSCRIPT_VAR_TEST_CASES,
2980
+ value_generator=gen_var,
2981
+ indices_generator=genindices,
2982
+ indices_generator_args=())
2983
+ t.run()
2984
+
2985
+ def test_slices(self):
2986
+ # Multidimensional slicing
2987
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
2988
+
2989
+ t = TestSpec(constr=xnd,
2990
+ values=SUBSCRIPT_FIXED_TEST_CASES,
2991
+ value_generator=gen_fixed,
2992
+ indices_generator=randslices,
2993
+ indices_generator_args=(3,))
2994
+ t.run()
2995
+
2996
+ t = TestSpec(constr=xnd,
2997
+ values=SUBSCRIPT_VAR_TEST_CASES,
2998
+ value_generator=gen_var,
2999
+ indices_generator=randslices,
3000
+ indices_generator_args=(3,))
3001
+ t.run()
3002
+
3003
+ def test_chained_indices_slices(self):
3004
+ # Multidimensional indexing and slicing, chained
3005
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
3006
+
3007
+ t = TestSpec(constr=xnd,
3008
+ values=SUBSCRIPT_FIXED_TEST_CASES,
3009
+ value_generator=gen_fixed,
3010
+ indices_generator=gen_indices_or_slices,
3011
+ indices_generator_args=())
3012
+ t.run()
3013
+
3014
+
3015
+ t = TestSpec(constr=xnd,
3016
+ values=SUBSCRIPT_VAR_TEST_CASES,
3017
+ value_generator=gen_var,
3018
+ indices_generator=gen_indices_or_slices,
3019
+ indices_generator_args=())
3020
+ t.run()
3021
+
3022
+ def test_fixed_mixed_indices_slices(self):
3023
+ # Multidimensional indexing and slicing, mixed
3024
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
3025
+
3026
+ t = TestSpec(constr=xnd,
3027
+ values=SUBSCRIPT_FIXED_TEST_CASES,
3028
+ value_generator=gen_fixed,
3029
+ indices_generator=mixed_indices,
3030
+ indices_generator_args=(3,))
3031
+ t.run()
3032
+
3033
+ def test_var_mixed_indices_slices(self):
3034
+ # Multidimensional indexing and slicing, mixed
3035
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
3036
+
3037
+ x = xnd([[1], [2, 3], [4, 5, 6]])
3038
+
3039
+ indices = (0, slice(0,1,1))
3040
+ self.assertRaises(IndexError, x.__getitem__, indices)
3041
+
3042
+ indices = (slice(0,1,1), 0)
3043
+ self.assertRaises(IndexError, x.__getitem__, indices)
3044
+
3045
+ def test_slices_brute_force(self):
3046
+ # Test all possible slices for the given ndim and shape
3047
+ skip_if(SKIP_BRUTE_FORCE, "use --all argument to enable these tests")
3048
+
3049
+ t = TestSpec(constr=xnd,
3050
+ values=SUBSCRIPT_FIXED_TEST_CASES,
3051
+ value_generator=gen_fixed,
3052
+ indices_generator=genslices_ndim,
3053
+ indices_generator_args=(3, [3,3,3]))
3054
+ t.run()
3055
+
3056
+ t = TestSpec(constr=xnd,
3057
+ values=SUBSCRIPT_VAR_TEST_CASES,
3058
+ value_generator=gen_var,
3059
+ indices_generator=genslices_ndim,
3060
+ indices_generator_args=(3, [3,3,3]))
3061
+ t.run()
3062
+
3063
+ @unittest.skipIf(np is None, "numpy not found")
3064
+ def test_array_definition(self):
3065
+ # Test the NDArray definition against NumPy
3066
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
3067
+
3068
+ t = TestSpec(constr=np.array,
3069
+ values=SUBSCRIPT_FIXED_TEST_CASES,
3070
+ value_generator=gen_fixed,
3071
+ indices_generator=mixed_indices,
3072
+ indices_generator_args=(3,))
3073
+ t.run()
3074
+
3075
+
3076
+ ALL_TESTS = [
3077
+ TestModule,
3078
+ TestFunction,
3079
+ TestVoid,
3080
+ TestAny,
3081
+ TestFixedDim,
3082
+ TestFortran,
3083
+ TestVarDim,
3084
+ TestSymbolicDim,
3085
+ TestEllipsisDim,
3086
+ TestTuple,
3087
+ TestRecord,
3088
+ TestRef,
3089
+ TestConstr,
3090
+ TestNominal,
3091
+ TestScalarKind,
3092
+ TestCategorical,
3093
+ TestFixedStringKind,
3094
+ TestFixedString,
3095
+ TestFixedBytesKind,
3096
+ TestFixedBytes,
3097
+ TestString,
3098
+ TestBytes,
3099
+ TestChar,
3100
+ TestBool,
3101
+ TestSignedKind,
3102
+ TestSigned,
3103
+ TestUnsignedKind,
3104
+ TestUnsigned,
3105
+ TestFloatKind,
3106
+ TestFloat,
3107
+ TestComplexKind,
3108
+ TestComplex,
3109
+ TestPrimitive,
3110
+ TestTypevar,
3111
+ TestTypeInference,
3112
+ TestIndexing,
3113
+ TestSequence,
3114
+ TestAPI,
3115
+ TestRepr,
3116
+ TestBuffer,
3117
+ TestSplit,
3118
+ TestView,
3119
+ LongIndexSliceTest,
3120
+ ]
3121
+
3122
+
3123
+ if __name__ == '__main__':
3124
+ parser = argparse.ArgumentParser()
3125
+ parser.add_argument("-f", "--failfast", action="store_true",
3126
+ help="stop the test run on first error")
3127
+ parser.add_argument('--long', action="store_true", help="run long slice tests")
3128
+ parser.add_argument('--all', action="store_true", help="run brute force tests")
3129
+ args = parser.parse_args()
3130
+ SKIP_LONG = not (args.long or args.all)
3131
+ SKIP_BRUTE_FORCE = not args.all
3132
+
3133
+ suite = unittest.TestSuite()
3134
+ loader = unittest.TestLoader()
3135
+
3136
+ for case in ALL_TESTS:
3137
+ s = loader.loadTestsFromTestCase(case)
3138
+ suite.addTest(s)
3139
+
3140
+ runner = unittest.TextTestRunner(failfast=args.failfast, verbosity=2)
3141
+ result = runner.run(suite)
3142
+ ret = not result.wasSuccessful()
3143
+
3144
+ sys.exit(ret)