xnd 0.2.0dev3

Sign up to get free protection for your applications and to get access to all the features.
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)