xnd 0.2.0dev3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +3 -0
- data/History.md +0 -0
- data/README.md +7 -0
- data/Rakefile +135 -0
- data/ext/ruby_xnd/extconf.rb +70 -0
- data/ext/ruby_xnd/float_pack_unpack.c +277 -0
- data/ext/ruby_xnd/float_pack_unpack.h +39 -0
- data/ext/ruby_xnd/gc_guard.c +36 -0
- data/ext/ruby_xnd/gc_guard.h +12 -0
- data/ext/ruby_xnd/include/xnd.h +449 -0
- data/ext/ruby_xnd/lib/libxnd.a +0 -0
- data/ext/ruby_xnd/lib/libxnd.so +1 -0
- data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
- data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
- data/ext/ruby_xnd/memory_block_object.c +32 -0
- data/ext/ruby_xnd/memory_block_object.h +33 -0
- data/ext/ruby_xnd/ruby_xnd.c +1953 -0
- data/ext/ruby_xnd/ruby_xnd.h +61 -0
- data/ext/ruby_xnd/ruby_xnd_internal.h +85 -0
- data/ext/ruby_xnd/util.h +170 -0
- data/ext/ruby_xnd/xnd/AUTHORS.txt +5 -0
- data/ext/ruby_xnd/xnd/INSTALL.txt +134 -0
- data/ext/ruby_xnd/xnd/LICENSE.txt +29 -0
- data/ext/ruby_xnd/xnd/MANIFEST.in +3 -0
- data/ext/ruby_xnd/xnd/Makefile.in +80 -0
- data/ext/ruby_xnd/xnd/README.rst +44 -0
- data/ext/ruby_xnd/xnd/config.guess +1530 -0
- data/ext/ruby_xnd/xnd/config.h.in +22 -0
- data/ext/ruby_xnd/xnd/config.sub +1782 -0
- data/ext/ruby_xnd/xnd/configure +4867 -0
- data/ext/ruby_xnd/xnd/configure.ac +164 -0
- data/ext/ruby_xnd/xnd/doc/Makefile +14 -0
- data/ext/ruby_xnd/xnd/doc/_static/copybutton.js +66 -0
- data/ext/ruby_xnd/xnd/doc/conf.py +26 -0
- data/ext/ruby_xnd/xnd/doc/index.rst +44 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/data-structures.rst +186 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/functions.rst +148 -0
- data/ext/ruby_xnd/xnd/doc/libxnd/index.rst +25 -0
- data/ext/ruby_xnd/xnd/doc/releases/index.rst +34 -0
- data/ext/ruby_xnd/xnd/doc/xnd/align-pack.rst +96 -0
- data/ext/ruby_xnd/xnd/doc/xnd/buffer-protocol.rst +42 -0
- data/ext/ruby_xnd/xnd/doc/xnd/index.rst +30 -0
- data/ext/ruby_xnd/xnd/doc/xnd/quickstart.rst +62 -0
- data/ext/ruby_xnd/xnd/doc/xnd/types.rst +674 -0
- data/ext/ruby_xnd/xnd/install-sh +527 -0
- data/ext/ruby_xnd/xnd/libxnd/Makefile.in +102 -0
- data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +112 -0
- data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +345 -0
- data/ext/ruby_xnd/xnd/libxnd/contrib.h +313 -0
- data/ext/ruby_xnd/xnd/libxnd/copy.c +944 -0
- data/ext/ruby_xnd/xnd/libxnd/equal.c +1216 -0
- data/ext/ruby_xnd/xnd/libxnd/inline.h +154 -0
- data/ext/ruby_xnd/xnd/libxnd/overflow.h +147 -0
- data/ext/ruby_xnd/xnd/libxnd/split.c +286 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.in +39 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/Makefile.vc +44 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/README.txt +2 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/runtest.c +101 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/test.h +48 -0
- data/ext/ruby_xnd/xnd/libxnd/tests/test_fixed.c +108 -0
- data/ext/ruby_xnd/xnd/libxnd/xnd.c +1304 -0
- data/ext/ruby_xnd/xnd/libxnd/xnd.h +449 -0
- data/ext/ruby_xnd/xnd/python/test_xnd.py +3144 -0
- data/ext/ruby_xnd/xnd/python/xnd/__init__.py +290 -0
- data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +2822 -0
- data/ext/ruby_xnd/xnd/python/xnd/contrib/pretty.py +850 -0
- data/ext/ruby_xnd/xnd/python/xnd/docstrings.h +129 -0
- data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +200 -0
- data/ext/ruby_xnd/xnd/python/xnd/util.h +182 -0
- data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +1121 -0
- data/ext/ruby_xnd/xnd/python/xnd_support.py +106 -0
- data/ext/ruby_xnd/xnd/setup.py +303 -0
- data/ext/ruby_xnd/xnd/vcbuild/INSTALL.txt +42 -0
- data/ext/ruby_xnd/xnd/vcbuild/runtest32.bat +16 -0
- data/ext/ruby_xnd/xnd/vcbuild/runtest64.bat +14 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcbuild32.bat +29 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcbuild64.bat +29 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcclean.bat +13 -0
- data/ext/ruby_xnd/xnd/vcbuild/vcdistclean.bat +14 -0
- data/lib/ruby_xnd.so +0 -0
- data/lib/xnd.rb +306 -0
- data/lib/xnd/monkeys.rb +29 -0
- data/lib/xnd/version.rb +6 -0
- data/spec/debug_spec.rb +9 -0
- data/spec/gc_guard_spec.rb +10 -0
- data/spec/leakcheck.rb +9 -0
- data/spec/spec_helper.rb +877 -0
- data/spec/type_inference_spec.rb +81 -0
- data/spec/xnd_spec.rb +2921 -0
- data/xnd.gemspec +47 -0
- 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)
|