ndtypes 0.2.0dev5 → 0.2.0dev6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +12 -0
  3. data/Rakefile +8 -0
  4. data/ext/ruby_ndtypes/GPATH +0 -0
  5. data/ext/ruby_ndtypes/GRTAGS +0 -0
  6. data/ext/ruby_ndtypes/GTAGS +0 -0
  7. data/ext/ruby_ndtypes/extconf.rb +1 -1
  8. data/ext/ruby_ndtypes/include/ndtypes.h +231 -122
  9. data/ext/ruby_ndtypes/include/ruby_ndtypes.h +1 -1
  10. data/ext/ruby_ndtypes/lib/libndtypes.a +0 -0
  11. data/ext/ruby_ndtypes/lib/libndtypes.so.0.2.0dev3 +0 -0
  12. data/ext/ruby_ndtypes/ndtypes/Makefile +87 -0
  13. data/ext/ruby_ndtypes/ndtypes/config.h +68 -0
  14. data/ext/ruby_ndtypes/ndtypes/config.log +477 -0
  15. data/ext/ruby_ndtypes/ndtypes/config.status +1027 -0
  16. data/ext/ruby_ndtypes/ndtypes/doc/_static/style.css +7 -0
  17. data/ext/ruby_ndtypes/ndtypes/doc/_templates/layout.html +2 -0
  18. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +40 -4
  19. data/ext/ruby_ndtypes/ndtypes/doc/images/xndlogo.png +0 -0
  20. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +1 -1
  21. data/ext/ruby_ndtypes/ndtypes/doc/requirements.txt +2 -0
  22. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile +287 -0
  23. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +20 -4
  24. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +22 -3
  25. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +1 -1
  26. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.o +0 -0
  27. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.o +0 -0
  28. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile +73 -0
  29. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +246 -229
  30. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +15 -11
  31. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.o +0 -0
  32. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +38 -28
  33. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +91 -91
  34. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +1 -1
  35. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +4 -3
  36. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.o +0 -0
  37. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +8 -7
  38. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.o +0 -0
  39. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +2 -2
  40. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.o +0 -0
  41. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.o +0 -0
  42. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +263 -182
  43. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.o +0 -0
  44. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.o +0 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +67 -7
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.o +0 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +1112 -1000
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +69 -58
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.o +0 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +150 -99
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +185 -15
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.o +0 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +301 -276
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +1 -1
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +9 -4
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.o +0 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.a +0 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so +1 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0 +1 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0.2.0dev3 +0 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +729 -228
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.o +0 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +768 -403
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h +1002 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +231 -122
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.o +0 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +176 -84
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +26 -14
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.o +0 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +57 -35
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.o +0 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.c +420 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.o +0 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +8 -8
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +1 -1
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.o +0 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile +48 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +200 -116
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.o +0 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +46 -4
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.o +0 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +58 -27
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +1 -1
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.o +0 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +3 -5
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +12 -4
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.o +0 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile +55 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +8 -8
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +5 -5
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +274 -172
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +24 -4
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +2 -2
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +14 -14
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +32 -30
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +37 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +36 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +16 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +5 -5
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +706 -253
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_unify.c +132 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.c +703 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.o +0 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +335 -127
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.o +0 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +2 -2
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.o +0 -0
  108. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +88 -71
  109. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +0 -1
  110. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +10 -13
  111. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +395 -314
  112. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.a +0 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so +1 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0 +1 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0.2.0dev3 +0 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/ndtypes.h +1002 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +15 -33
  118. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +340 -132
  119. data/ext/ruby_ndtypes/ndtypes/setup.py +11 -2
  120. data/ext/ruby_ndtypes/ruby_ndtypes.c +364 -241
  121. data/ext/ruby_ndtypes/ruby_ndtypes.h +1 -1
  122. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +0 -1
  123. data/lib/ndtypes.rb +11 -0
  124. data/lib/ndtypes/version.rb +2 -2
  125. data/lib/ruby_ndtypes.so +0 -0
  126. data/ndtypes.gemspec +3 -0
  127. data/spec/ndtypes_spec.rb +6 -0
  128. metadata +98 -4
  129. data/ext/ruby_ndtypes/gc_guard.c +0 -36
  130. data/ext/ruby_ndtypes/gc_guard.h +0 -12
@@ -51,13 +51,11 @@ extern "C" {
51
51
 
52
52
  typedef struct {
53
53
  PyObject_HEAD
54
- PyObject *rbuf; /* resource buffer */
55
- ndt_t *ndt; /* type */
54
+ Py_hash_t hash;
55
+ const ndt_t *ndt;
56
56
  } NdtObject;
57
57
 
58
58
  #define NDT(v) (((NdtObject *)v)->ndt)
59
- #define RBUF(v) (((NdtObject *)v)->rbuf)
60
- #define RBUF_NDT_META(v) (((ResourceBufferObject *)(((NdtObject *)v)->rbuf))->m)
61
59
 
62
60
 
63
61
  /****************************************************************************/
@@ -72,42 +70,32 @@ typedef struct {
72
70
  #define Ndt_Check_RETURN int
73
71
  #define Ndt_Check_ARGS (const PyObject *)
74
72
 
75
- #define CONST_NDT_INDEX 2
76
- #define CONST_NDT_RETURN const ndt_t *
77
- #define CONST_NDT_ARGS (const PyObject *)
78
-
79
- #define Ndt_SetError_INDEX 3
73
+ #define Ndt_SetError_INDEX 2
80
74
  #define Ndt_SetError_RETURN PyObject *
81
75
  #define Ndt_SetError_ARGS (ndt_context_t *)
82
76
 
83
- #define Ndt_CopySubtree_INDEX 4
84
- #define Ndt_CopySubtree_RETURN PyObject *
85
- #define Ndt_CopySubtree_ARGS (const PyObject *, const ndt_t *)
86
-
87
- #define Ndt_MoveSubtree_INDEX 5
88
- #define Ndt_MoveSubtree_RETURN PyObject *
89
- #define Ndt_MoveSubtree_ARGS (const PyObject *, ndt_t *)
90
-
91
- #define Ndt_FromType_INDEX 6
77
+ #define Ndt_FromType_INDEX 3
92
78
  #define Ndt_FromType_RETURN PyObject *
93
- #define Ndt_FromType_ARGS (ndt_t *)
79
+ #define Ndt_FromType_ARGS (const ndt_t *)
94
80
 
95
- #define Ndt_FromObject_INDEX 7
81
+ #define Ndt_FromObject_INDEX 4
96
82
  #define Ndt_FromObject_RETURN PyObject *
97
83
  #define Ndt_FromObject_ARGS (PyObject *)
98
84
 
99
- #define NDTYPES_MAX_API 8
85
+ #define Ndt_FromOffsetsAndDtype_INDEX 5
86
+ #define Ndt_FromOffsetsAndDtype_RETURN PyObject *
87
+ #define Ndt_FromOffsetsAndDtype_ARGS (PyObject *offsets, bool *opt, const ndt_t *dtype)
88
+
89
+ #define NDTYPES_MAX_API 6
100
90
 
101
91
 
102
92
  #ifdef NDTYPES_MODULE
103
93
  static Ndt_CheckExact_RETURN Ndt_CheckExact Ndt_CheckExact_ARGS;
104
94
  static Ndt_Check_RETURN Ndt_Check Ndt_Check_ARGS;
105
- static CONST_NDT_RETURN CONST_NDT CONST_NDT_ARGS;
106
95
  static Ndt_SetError_RETURN Ndt_SetError Ndt_SetError_ARGS;
107
- static Ndt_CopySubtree_RETURN Ndt_CopySubtree Ndt_CopySubtree_ARGS;
108
- static Ndt_MoveSubtree_RETURN Ndt_MoveSubtree Ndt_MoveSubtree_ARGS;
109
96
  static Ndt_FromType_RETURN Ndt_FromType Ndt_FromType_ARGS;
110
97
  static Ndt_FromObject_RETURN Ndt_FromObject Ndt_FromObject_ARGS;
98
+ static Ndt_FromOffsetsAndDtype_RETURN Ndt_FromOffsetsAndDtype Ndt_FromOffsetsAndDtype_ARGS;
111
99
  #else
112
100
  static void **_ndtypes_api;
113
101
 
@@ -117,24 +105,18 @@ static void **_ndtypes_api;
117
105
  #define Ndt_Check \
118
106
  (*(Ndt_Check_RETURN (*)Ndt_Check_ARGS) _ndtypes_api[Ndt_Check_INDEX])
119
107
 
120
- #define CONST_NDT \
121
- (*(CONST_NDT_RETURN (*)CONST_NDT_ARGS) _ndtypes_api[CONST_NDT_INDEX])
122
-
123
108
  #define Ndt_SetError \
124
109
  (*(Ndt_SetError_RETURN (*)Ndt_SetError_ARGS) _ndtypes_api[Ndt_SetError_INDEX])
125
110
 
126
- #define Ndt_CopySubtree \
127
- (*(Ndt_CopySubtree_RETURN (*)Ndt_CopySubtree_ARGS) _ndtypes_api[Ndt_CopySubtree_INDEX])
128
-
129
- #define Ndt_MoveSubtree \
130
- (*(Ndt_MoveSubtree_RETURN (*)Ndt_MoveSubtree_ARGS) _ndtypes_api[Ndt_MoveSubtree_INDEX])
131
-
132
111
  #define Ndt_FromType \
133
112
  (*(Ndt_FromType_RETURN (*)Ndt_FromType_ARGS) _ndtypes_api[Ndt_FromType_INDEX])
134
113
 
135
114
  #define Ndt_FromObject \
136
115
  (*(Ndt_FromObject_RETURN (*)Ndt_FromObject_ARGS) _ndtypes_api[Ndt_FromObject_INDEX])
137
116
 
117
+ #define Ndt_FromOffsetsAndDtype \
118
+ (*(Ndt_FromOffsetsAndDtype_RETURN (*)Ndt_FromOffsetsAndDtype_ARGS) _ndtypes_api[Ndt_FromOffsetsAndDtype_INDEX])
119
+
138
120
  static int
139
121
  import_ndtypes(void)
140
122
  {
@@ -81,6 +81,7 @@ class TestModule(unittest.TestCase):
81
81
 
82
82
  self.assertFalse(t.is_f_contiguous())
83
83
  self.assertFalse(t.is_c_contiguous())
84
+ self.assertFalse(t.is_var_contiguous())
84
85
 
85
86
  def test_module_common_fields(self):
86
87
  t = ndt("SomeNamespace:: 2 * 3 * float64")
@@ -113,6 +114,7 @@ class TestFunction(unittest.TestCase):
113
114
 
114
115
  self.assertFalse(t.is_c_contiguous())
115
116
  self.assertFalse(t.is_f_contiguous())
117
+ self.assertFalse(t.is_var_contiguous())
116
118
 
117
119
  def test_function_common_fields(self):
118
120
  t = ndt("(10 * float64, string) -> float64")
@@ -145,6 +147,7 @@ class TestVoid(unittest.TestCase):
145
147
 
146
148
  self.assertFalse(t.is_c_contiguous())
147
149
  self.assertFalse(t.is_f_contiguous())
150
+ self.assertFalse(t.is_var_contiguous())
148
151
 
149
152
  def test_void_exceptions(self):
150
153
  # Void can only be used as a function return type.
@@ -167,6 +170,7 @@ class TestAny(unittest.TestCase):
167
170
 
168
171
  self.assertFalse(t.is_c_contiguous())
169
172
  self.assertFalse(t.is_f_contiguous())
173
+ self.assertFalse(t.is_var_contiguous())
170
174
 
171
175
  def test_any_common_fields(self):
172
176
  t = ndt("Any")
@@ -198,14 +202,17 @@ class TestFixedDim(unittest.TestCase):
198
202
 
199
203
  self.assertTrue(t.is_c_contiguous())
200
204
  self.assertFalse(t.is_f_contiguous())
205
+ self.assertFalse(t.is_var_contiguous())
201
206
 
202
207
  t = ndt("20 * complex128")
203
208
  self.assertTrue(t.is_c_contiguous())
204
209
  self.assertTrue(t.is_f_contiguous())
210
+ self.assertFalse(t.is_var_contiguous())
205
211
 
206
212
  t = ndt("1 * 10 * complex128")
207
213
  self.assertTrue(t.is_c_contiguous())
208
214
  self.assertTrue(t.is_f_contiguous())
215
+ self.assertFalse(t.is_var_contiguous())
209
216
 
210
217
  def test_fixed_dim_common_fields(self):
211
218
  dt = "{a: complex64, b: string}"
@@ -291,6 +298,32 @@ class TestFixedDim(unittest.TestCase):
291
298
  self.assertEqual(t.datasize, c_datasize(t))
292
299
  self.assertTrue(verify_datasize(t))
293
300
 
301
+ def test_fixed_dim_at(self):
302
+
303
+ for dims in ("2 * 3 * ", "0 * 1 * "):
304
+ t = ndt(dims + "int8")
305
+
306
+ u = t.at(0)
307
+ self.assertEqual(u, ndt(dims + "int8"))
308
+
309
+ u = t.at(1)
310
+ self.assertEqual(u, ndt(dims[4:] + "int8"))
311
+
312
+ u = t.at(2)
313
+ self.assertEqual(u, ndt("int8"))
314
+
315
+ u = t.at(0, dtype="int64")
316
+ self.assertEqual(u, ndt(dims + "int64"))
317
+
318
+ u = t.at(1, dtype="int64")
319
+ self.assertEqual(u, ndt(dims[4:] + "int64"))
320
+
321
+ u = t.at(2, dtype="int64")
322
+ self.assertEqual(u, ndt("int64"))
323
+
324
+ self.assertRaises(ValueError, t.at, -1)
325
+ self.assertRaises(ValueError, t.at, -3)
326
+
294
327
 
295
328
  class TestFortran(unittest.TestCase):
296
329
 
@@ -308,14 +341,17 @@ class TestFortran(unittest.TestCase):
308
341
 
309
342
  self.assertFalse(t.is_c_contiguous())
310
343
  self.assertTrue(t.is_f_contiguous())
344
+ self.assertFalse(t.is_var_contiguous())
311
345
 
312
346
  t = ndt("!20 * complex128")
313
347
  self.assertTrue(t.is_c_contiguous())
314
348
  self.assertTrue(t.is_f_contiguous())
349
+ self.assertFalse(t.is_var_contiguous())
315
350
 
316
351
  t = ndt("!1 * 10 * uint8")
317
352
  self.assertTrue(t.is_c_contiguous())
318
353
  self.assertTrue(t.is_f_contiguous())
354
+ self.assertFalse(t.is_var_contiguous())
319
355
 
320
356
  def test_fortran_common_fields(self):
321
357
  dt = "{a: complex64, b: string}"
@@ -398,6 +434,32 @@ class TestFortran(unittest.TestCase):
398
434
  s = "!fixed(shape=2, step=-20) * uint8"
399
435
  self.assertRaises(TypeError, ndt, s)
400
436
 
437
+ def test_fortran_at(self):
438
+
439
+ for dims in ("2 * 3 * ", "0 * 1 * "):
440
+ t = ndt("!" + dims + "int8")
441
+
442
+ u = t.at(0)
443
+ self.assertEqual(u, ndt(dims + "int8"))
444
+
445
+ u = t.at(1)
446
+ self.assertEqual(u, ndt(dims[4:] + "int8"))
447
+
448
+ u = t.at(2)
449
+ self.assertEqual(u, ndt("int8"))
450
+
451
+ u = t.at(0, dtype="int64")
452
+ self.assertEqual(u, ndt(dims + "int64"))
453
+
454
+ u = t.at(1, dtype="int64")
455
+ self.assertEqual(u, ndt(dims[4:] + "int64"))
456
+
457
+ u = t.at(2, dtype="int64")
458
+ self.assertEqual(u, ndt("int64"))
459
+
460
+ self.assertRaises(ValueError, t.at, -1)
461
+ self.assertRaises(ValueError, t.at, -3)
462
+
401
463
 
402
464
  class TestVarDim(unittest.TestCase):
403
465
 
@@ -416,6 +478,7 @@ class TestVarDim(unittest.TestCase):
416
478
 
417
479
  self.assertFalse(t.is_c_contiguous())
418
480
  self.assertFalse(t.is_f_contiguous())
481
+ self.assertTrue(t.is_var_contiguous())
419
482
 
420
483
  def test_var_dim_common_fields(self):
421
484
  dt = "{a: complex64, b: string}"
@@ -445,12 +508,6 @@ class TestVarDim(unittest.TestCase):
445
508
  # Too many dimensions.
446
509
  self.assertRaises(TypeError, ndt, "var * " * (MAX_DIM + 1) + "float64")
447
510
 
448
- # Nested var is disallowed.
449
- self.assertRaises(TypeError, ndt, "2 * {a: var * complex128}")
450
- self.assertRaises(TypeError, ndt, "var * {a: var * complex128}")
451
- self.assertRaises(TypeError, ndt, "var * ref(var * string)")
452
- self.assertRaises(TypeError, ndt, "var * SomeConstr(var * string)")
453
-
454
511
  def test_var_dim_external_offsets(self):
455
512
  # Invalid offsets.
456
513
  self.assertRaises(TypeError, ndt, "int8", [""])
@@ -478,9 +535,6 @@ class TestVarDim(unittest.TestCase):
478
535
  self.assertRaises(ValueError, ndt, "N * int8", [[0, 2], [0, 10, 20]])
479
536
  self.assertRaises(ValueError, ndt, "var * int8", [[0, 2], [0, 10, 20]])
480
537
 
481
- # Mixing external and internal offsets.
482
- self.assertRaises(TypeError, ndt, "var(offsets=[0,2,10]) * int8", [[0, 1], [0, 2]])
483
-
484
538
 
485
539
  class TestSymbolicDim(unittest.TestCase):
486
540
 
@@ -499,6 +553,7 @@ class TestSymbolicDim(unittest.TestCase):
499
553
 
500
554
  self.assertFalse(t.is_c_contiguous())
501
555
  self.assertFalse(t.is_f_contiguous())
556
+ self.assertFalse(t.is_var_contiguous())
502
557
 
503
558
  def test_symbolic_dim_common_fields(self):
504
559
  dt = "{a: complex64, b: string}"
@@ -506,12 +561,12 @@ class TestSymbolicDim(unittest.TestCase):
506
561
  check_serialize(self, t)
507
562
  dtype = ndt(dt)
508
563
 
509
- self.assertRaises(TypeError, t, 'ndim')
510
- self.assertRaises(TypeError, t, 'itemsize')
511
- self.assertRaises(TypeError, t, 'align')
564
+ self.assertRaises(TypeError, getattr, t, 'ndim')
565
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
566
+ self.assertRaises(TypeError, getattr, t, 'align')
512
567
 
513
- self.assertRaises(TypeError, t, 'shape')
514
- self.assertRaises(TypeError, t, 'strides')
568
+ self.assertRaises(TypeError, getattr, t, 'shape')
569
+ self.assertRaises(TypeError, getattr, t, 'strides')
515
570
 
516
571
 
517
572
  class TestEllipsisDim(unittest.TestCase):
@@ -531,6 +586,7 @@ class TestEllipsisDim(unittest.TestCase):
531
586
 
532
587
  self.assertFalse(t.is_c_contiguous())
533
588
  self.assertFalse(t.is_f_contiguous())
589
+ self.assertFalse(t.is_var_contiguous())
534
590
 
535
591
  def test_ellipsis_dim_common_fields(self):
536
592
  dt = "{a: complex64, b: string}"
@@ -538,12 +594,51 @@ class TestEllipsisDim(unittest.TestCase):
538
594
  check_serialize(self, t)
539
595
  dtype = ndt(dt)
540
596
 
541
- self.assertRaises(TypeError, t, 'ndim')
542
- self.assertRaises(TypeError, t, 'itemsize')
543
- self.assertRaises(TypeError, t, 'align')
597
+ self.assertRaises(TypeError, getattr, t, 'ndim')
598
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
599
+ self.assertRaises(TypeError, getattr, t, 'align')
544
600
 
545
- self.assertRaises(TypeError, t, 'shape')
546
- self.assertRaises(TypeError, t, 'strides')
601
+ self.assertRaises(TypeError, getattr, t, 'shape')
602
+ self.assertRaises(TypeError, getattr, t, 'strides')
603
+
604
+ class TestArray(unittest.TestCase):
605
+
606
+ def test_array_predicates(self):
607
+ t = ndt("array of complex128")
608
+ check_serialize(self, t)
609
+
610
+ self.assertFalse(t.isabstract())
611
+ self.assertFalse(t.iscomplex())
612
+ self.assertTrue(t.isconcrete())
613
+ self.assertFalse(t.isfloat())
614
+ self.assertFalse(t.isoptional())
615
+ self.assertFalse(t.isscalar())
616
+ self.assertFalse(t.issigned())
617
+ self.assertFalse(t.isunsigned())
618
+
619
+ self.assertFalse(t.is_c_contiguous())
620
+ self.assertFalse(t.is_f_contiguous())
621
+
622
+ def test_array_dim_common_fields(self):
623
+ dt = "{a: complex64, b: float64}"
624
+ t = ndt("array of %s" % dt)
625
+ check_serialize(self, t)
626
+ dtype = ndt(dt)
627
+
628
+ # The flexible array counts as a dtype.
629
+ self.assertEqual(t.ndim, 1)
630
+
631
+ self.assertRaises(TypeError, getattr, t, 'shape')
632
+ self.assertRaises(TypeError, getattr, t, 'strides')
633
+
634
+ if not HAVE_32_BIT_LINUX:
635
+ self.assertEqual(t.itemsize, dtype.itemsize)
636
+ self.assertEqual(t.align, dtype.align)
637
+
638
+ def test_array_invariants(self):
639
+ # Mixing array with fixed/var dimensions is disallowed.
640
+ self.assertRaises(TypeError, ndt, "array of 2 * int64")
641
+ self.assertRaises(TypeError, ndt, "array of var * int64")
547
642
 
548
643
 
549
644
  class TestTuple(unittest.TestCase):
@@ -564,6 +659,7 @@ class TestTuple(unittest.TestCase):
564
659
 
565
660
  self.assertTrue(t.is_c_contiguous())
566
661
  self.assertTrue(t.is_f_contiguous())
662
+ self.assertTrue(t.is_var_contiguous())
567
663
 
568
664
  for s in ["(Any)", "(int64, N * M * uint8)", "(string, Float)"]:
569
665
  t = ndt(s)
@@ -580,6 +676,7 @@ class TestTuple(unittest.TestCase):
580
676
 
581
677
  self.assertFalse(t.is_c_contiguous())
582
678
  self.assertFalse(t.is_f_contiguous())
679
+ self.assertFalse(t.is_var_contiguous())
583
680
 
584
681
  def test_tuple_common_fields(self):
585
682
  f = "{a: complex64, b: string}"
@@ -592,8 +689,8 @@ class TestTuple(unittest.TestCase):
592
689
  self.assertEqual(t.itemsize, 2 * field.itemsize)
593
690
  self.assertEqual(t.align, field.align)
594
691
 
595
- self.assertRaises(TypeError, t, 'shape')
596
- self.assertRaises(TypeError, t, 'strides')
692
+ self.assertEqual(t.shape, ())
693
+ self.assertEqual(t.strides, ())
597
694
 
598
695
 
599
696
  class TestRecord(unittest.TestCase):
@@ -614,6 +711,7 @@ class TestRecord(unittest.TestCase):
614
711
 
615
712
  self.assertTrue(t.is_c_contiguous())
616
713
  self.assertTrue(t.is_f_contiguous())
714
+ self.assertTrue(t.is_var_contiguous())
617
715
 
618
716
  for s in ["{a: Any, b: Complex}", "{x: N * M * T}"]:
619
717
  t = ndt(s)
@@ -630,6 +728,7 @@ class TestRecord(unittest.TestCase):
630
728
 
631
729
  self.assertFalse(t.is_c_contiguous())
632
730
  self.assertFalse(t.is_f_contiguous())
731
+ self.assertFalse(t.is_var_contiguous())
633
732
 
634
733
  def test_record_common_fields(self):
635
734
  f = "{a: complex64, b: string}"
@@ -642,8 +741,63 @@ class TestRecord(unittest.TestCase):
642
741
  self.assertEqual(t.itemsize, 3 * field.itemsize)
643
742
  self.assertEqual(t.align, field.align)
644
743
 
645
- self.assertRaises(TypeError, t, 'shape')
646
- self.assertRaises(TypeError, t, 'strides')
744
+ self.assertEqual(t.shape, ())
745
+ self.assertEqual(t.strides, ())
746
+
747
+
748
+ class TestUnion(unittest.TestCase):
749
+
750
+ def test_union_predicates(self):
751
+ for s in ["[A of int64 | B of bytes]", "[X of string | Y of uint8]"]:
752
+ t = ndt(s)
753
+ check_serialize(self, t)
754
+
755
+ self.assertFalse(t.isabstract())
756
+ self.assertFalse(t.iscomplex())
757
+ self.assertTrue(t.isconcrete())
758
+ self.assertFalse(t.isfloat())
759
+ self.assertFalse(t.isoptional())
760
+ self.assertFalse(t.isscalar())
761
+ self.assertFalse(t.issigned())
762
+ self.assertFalse(t.isunsigned())
763
+
764
+ self.assertTrue(t.is_c_contiguous())
765
+ self.assertTrue(t.is_f_contiguous())
766
+ self.assertTrue(t.is_var_contiguous())
767
+
768
+ for s in ["[A of Any | B of Complex]", "[X of N * M * T]"]:
769
+ t = ndt(s)
770
+ check_serialize(self, t)
771
+
772
+ self.assertTrue(t.isabstract())
773
+ self.assertFalse(t.iscomplex())
774
+ self.assertFalse(t.isconcrete())
775
+ self.assertFalse(t.isfloat())
776
+ self.assertFalse(t.isoptional())
777
+ self.assertFalse(t.isscalar())
778
+ self.assertFalse(t.issigned())
779
+ self.assertFalse(t.isunsigned())
780
+
781
+ self.assertFalse(t.is_c_contiguous())
782
+ self.assertFalse(t.is_f_contiguous())
783
+ self.assertFalse(t.is_var_contiguous())
784
+
785
+ def test_union_common_fields(self):
786
+ f = "[A of uint64 | B of uint8]"
787
+ g = "[C of (uint64, uint64) | D of string]"
788
+ t = ndt("[X of %s | Y of %s]" % (f, g))
789
+ u = ndt("(uint64, uint64)")
790
+
791
+ check_serialize(self, t)
792
+
793
+ a = ndt(g)
794
+
795
+ self.assertEqual(t.ndim, 0)
796
+ self.assertEqual(t.itemsize, u.itemsize + 2)
797
+ self.assertEqual(t.align, 1)
798
+
799
+ self.assertEqual(t.shape, ())
800
+ self.assertEqual(t.strides, ())
647
801
 
648
802
 
649
803
  class TestRef(unittest.TestCase):
@@ -664,6 +818,7 @@ class TestRef(unittest.TestCase):
664
818
 
665
819
  self.assertTrue(t.is_c_contiguous())
666
820
  self.assertTrue(t.is_f_contiguous())
821
+ self.assertTrue(t.is_var_contiguous())
667
822
 
668
823
  for s in ["&Any", "&(int64, N * M * uint8)"]:
669
824
  t = ndt(s)
@@ -680,6 +835,7 @@ class TestRef(unittest.TestCase):
680
835
 
681
836
  self.assertFalse(t.is_c_contiguous())
682
837
  self.assertFalse(t.is_f_contiguous())
838
+ self.assertFalse(t.is_var_contiguous())
683
839
 
684
840
  def test_ref_common_fields(self):
685
841
  a = "{a: complex64, b: string}"
@@ -691,8 +847,8 @@ class TestRef(unittest.TestCase):
691
847
  self.assertEqual(t.itemsize, SIZEOF_PTR)
692
848
  self.assertEqual(t.align, SIZEOF_PTR)
693
849
 
694
- self.assertRaises(TypeError, t, 'shape')
695
- self.assertRaises(TypeError, t, 'strides')
850
+ self.assertEqual(t.shape, ())
851
+ self.assertEqual(t.strides, ())
696
852
 
697
853
 
698
854
  class TestConstr(unittest.TestCase):
@@ -713,6 +869,7 @@ class TestConstr(unittest.TestCase):
713
869
 
714
870
  self.assertTrue(t.is_c_contiguous())
715
871
  self.assertTrue(t.is_f_contiguous())
872
+ self.assertTrue(t.is_var_contiguous())
716
873
 
717
874
  def test_constr_common_fields(self):
718
875
  a = "{a: complex64, b: string}"
@@ -725,8 +882,8 @@ class TestConstr(unittest.TestCase):
725
882
  self.assertEqual(t.itemsize, arg.itemsize)
726
883
  self.assertEqual(t.align, arg.align)
727
884
 
728
- self.assertRaises(TypeError, t, 'shape')
729
- self.assertRaises(TypeError, t, 'strides')
885
+ self.assertEqual(t.shape, ())
886
+ self.assertEqual(t.strides, ())
730
887
 
731
888
 
732
889
  class TestNominal(unittest.TestCase):
@@ -757,6 +914,7 @@ class TestNominal(unittest.TestCase):
757
914
 
758
915
  self.assertTrue(t.is_c_contiguous())
759
916
  self.assertTrue(t.is_f_contiguous())
917
+ self.assertTrue(t.is_var_contiguous())
760
918
 
761
919
  def test_nominal_common_fields(self):
762
920
  t = ndt("some_t")
@@ -769,8 +927,8 @@ class TestNominal(unittest.TestCase):
769
927
  self.assertEqual(t.itemsize, 2 * 10 * dtype.itemsize)
770
928
  self.assertEqual(t.align, dtype.align)
771
929
 
772
- self.assertRaises(TypeError, t, 'shape')
773
- self.assertRaises(TypeError, t, 'strides')
930
+ self.assertEqual(t.shape, ())
931
+ self.assertEqual(t.strides, ())
774
932
 
775
933
  def test_nominal_exceptions(self):
776
934
  # not in the typedef table
@@ -797,17 +955,18 @@ class TestScalarKind(unittest.TestCase):
797
955
 
798
956
  self.assertFalse(t.is_c_contiguous())
799
957
  self.assertFalse(t.is_f_contiguous())
958
+ self.assertFalse(t.is_var_contiguous())
800
959
 
801
960
  def test_scalar_kind_common_fields(self):
802
961
  t = ndt("Scalar")
803
962
  check_serialize(self, t)
804
963
 
805
- self.assertRaises(TypeError, t, 'ndim')
806
- self.assertRaises(TypeError, t, 'itemsize')
807
- self.assertRaises(TypeError, t, 'align')
964
+ self.assertRaises(TypeError, getattr, t, 'ndim')
965
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
966
+ self.assertRaises(TypeError, getattr, t, 'align')
808
967
 
809
- self.assertRaises(TypeError, t, 'shape')
810
- self.assertRaises(TypeError, t, 'strides')
968
+ self.assertRaises(TypeError, getattr, t, 'shape')
969
+ self.assertRaises(TypeError, getattr, t, 'strides')
811
970
 
812
971
 
813
972
  class TestCategorical(unittest.TestCase):
@@ -832,6 +991,7 @@ class TestCategorical(unittest.TestCase):
832
991
 
833
992
  self.assertTrue(t.is_c_contiguous())
834
993
  self.assertTrue(t.is_f_contiguous())
994
+ self.assertTrue(t.is_var_contiguous())
835
995
 
836
996
  def test_categorical_common_fields(self):
837
997
  t = ndt("categorical(NA, 'something', 'must', 'be', 'done')")
@@ -842,8 +1002,8 @@ class TestCategorical(unittest.TestCase):
842
1002
  self.assertEqual(t.itemsize, 8)
843
1003
  self.assertEqual(t.align, 8)
844
1004
 
845
- self.assertRaises(TypeError, t, 'shape')
846
- self.assertRaises(TypeError, t, 'strides')
1005
+ self.assertEqual(t.shape, ())
1006
+ self.assertEqual(t.strides, ())
847
1007
 
848
1008
 
849
1009
  class TestFixedStringKind(unittest.TestCase):
@@ -863,16 +1023,17 @@ class TestFixedStringKind(unittest.TestCase):
863
1023
 
864
1024
  self.assertFalse(t.is_c_contiguous())
865
1025
  self.assertFalse(t.is_f_contiguous())
1026
+ self.assertFalse(t.is_var_contiguous())
866
1027
 
867
1028
  def test_fixed_string_kind_common_fields(self):
868
1029
  t = ndt("FixedString")
869
1030
 
870
- self.assertRaises(TypeError, t, 'ndim')
871
- self.assertRaises(TypeError, t, 'itemsize')
872
- self.assertRaises(TypeError, t, 'align')
1031
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1032
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1033
+ self.assertRaises(TypeError, getattr, t, 'align')
873
1034
 
874
- self.assertRaises(TypeError, t, 'shape')
875
- self.assertRaises(TypeError, t, 'strides')
1035
+ self.assertRaises(TypeError, getattr, t, 'shape')
1036
+ self.assertRaises(TypeError, getattr, t, 'strides')
876
1037
 
877
1038
 
878
1039
  class TestFixedString(unittest.TestCase):
@@ -892,6 +1053,7 @@ class TestFixedString(unittest.TestCase):
892
1053
 
893
1054
  self.assertTrue(t.is_c_contiguous())
894
1055
  self.assertTrue(t.is_f_contiguous())
1056
+ self.assertTrue(t.is_var_contiguous())
895
1057
 
896
1058
  def test_fixed_string_common_fields(self):
897
1059
  for encoding, codepoint_size in [
@@ -908,8 +1070,8 @@ class TestFixedString(unittest.TestCase):
908
1070
  self.assertEqual(t.itemsize, 20 * codepoint_size)
909
1071
  self.assertEqual(t.align, codepoint_size)
910
1072
 
911
- self.assertRaises(TypeError, t, 'shape')
912
- self.assertRaises(TypeError, t, 'strides')
1073
+ self.assertEqual(t.shape, ())
1074
+ self.assertEqual(t.strides, ())
913
1075
 
914
1076
 
915
1077
  class TestFixedBytesKind(unittest.TestCase):
@@ -929,16 +1091,17 @@ class TestFixedBytesKind(unittest.TestCase):
929
1091
 
930
1092
  self.assertFalse(t.is_c_contiguous())
931
1093
  self.assertFalse(t.is_f_contiguous())
1094
+ self.assertFalse(t.is_var_contiguous())
932
1095
 
933
1096
  def test_fixed_string_kind_common_fields(self):
934
1097
  t = ndt("FixedBytes")
935
1098
 
936
- self.assertRaises(TypeError, t, 'ndim')
937
- self.assertRaises(TypeError, t, 'itemsize')
938
- self.assertRaises(TypeError, t, 'align')
1099
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1100
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1101
+ self.assertRaises(TypeError, getattr, t, 'align')
939
1102
 
940
- self.assertRaises(TypeError, t, 'shape')
941
- self.assertRaises(TypeError, t, 'strides')
1103
+ self.assertRaises(TypeError, getattr, t, 'shape')
1104
+ self.assertRaises(TypeError, getattr, t, 'strides')
942
1105
 
943
1106
 
944
1107
  class TestFixedBytes(unittest.TestCase):
@@ -958,6 +1121,7 @@ class TestFixedBytes(unittest.TestCase):
958
1121
 
959
1122
  self.assertTrue(t.is_c_contiguous())
960
1123
  self.assertTrue(t.is_f_contiguous())
1124
+ self.assertTrue(t.is_var_contiguous())
961
1125
 
962
1126
  def test_fixed_bytes_common_fields(self):
963
1127
  for align in [1,2,4,8,16,32,64]:
@@ -970,8 +1134,8 @@ class TestFixedBytes(unittest.TestCase):
970
1134
  self.assertEqual(t.itemsize, 1024)
971
1135
  self.assertEqual(t.align, align)
972
1136
 
973
- self.assertRaises(TypeError, t, 'shape')
974
- self.assertRaises(TypeError, t, 'strides')
1137
+ self.assertEqual(t.shape, ())
1138
+ self.assertEqual(t.strides, ())
975
1139
 
976
1140
  def test_fixed_bytes_exceptions(self):
977
1141
  # Data size must be a multiple of align.
@@ -995,6 +1159,7 @@ class TestString(unittest.TestCase):
995
1159
 
996
1160
  self.assertTrue(t.is_c_contiguous())
997
1161
  self.assertTrue(t.is_f_contiguous())
1162
+ self.assertTrue(t.is_var_contiguous())
998
1163
 
999
1164
  def test_string_common_fields(self):
1000
1165
  t = ndt("string")
@@ -1003,8 +1168,8 @@ class TestString(unittest.TestCase):
1003
1168
  self.assertEqual(t.itemsize, SIZEOF_PTR)
1004
1169
  self.assertEqual(t.align, SIZEOF_PTR)
1005
1170
 
1006
- self.assertRaises(TypeError, t, 'shape')
1007
- self.assertRaises(TypeError, t, 'strides')
1171
+ self.assertEqual(t.shape, ())
1172
+ self.assertEqual(t.strides, ())
1008
1173
 
1009
1174
 
1010
1175
  class TestBytes(unittest.TestCase):
@@ -1024,6 +1189,7 @@ class TestBytes(unittest.TestCase):
1024
1189
 
1025
1190
  self.assertTrue(t.is_c_contiguous())
1026
1191
  self.assertTrue(t.is_f_contiguous())
1192
+ self.assertTrue(t.is_var_contiguous())
1027
1193
 
1028
1194
  def test_bytes_common_fields(self):
1029
1195
  t = ndt("bytes")
@@ -1033,8 +1199,8 @@ class TestBytes(unittest.TestCase):
1033
1199
  self.assertEqual(t.itemsize, 16)
1034
1200
  self.assertEqual(t.align, 8)
1035
1201
 
1036
- self.assertRaises(TypeError, t, 'shape')
1037
- self.assertRaises(TypeError, t, 'strides')
1202
+ self.assertEqual(t.shape, ())
1203
+ self.assertEqual(t.strides, ())
1038
1204
 
1039
1205
 
1040
1206
  class TestChar(unittest.TestCase):
@@ -1054,6 +1220,7 @@ class TestChar(unittest.TestCase):
1054
1220
 
1055
1221
  self.assertTrue(t.is_c_contiguous())
1056
1222
  self.assertTrue(t.is_f_contiguous())
1223
+ self.assertTrue(t.is_var_contiguous())
1057
1224
 
1058
1225
  def test_char_common_fields(self):
1059
1226
  t = ndt("char('utf32')")
@@ -1063,8 +1230,8 @@ class TestChar(unittest.TestCase):
1063
1230
  self.assertEqual(t.itemsize, 4)
1064
1231
  self.assertEqual(t.align, 4)
1065
1232
 
1066
- self.assertRaises(TypeError, t, 'shape')
1067
- self.assertRaises(TypeError, t, 'strides')
1233
+ self.assertEqual(t.shape, ())
1234
+ self.assertEqual(t.strides, ())
1068
1235
 
1069
1236
 
1070
1237
  class TestBool(unittest.TestCase):
@@ -1084,6 +1251,7 @@ class TestBool(unittest.TestCase):
1084
1251
 
1085
1252
  self.assertTrue(t.is_c_contiguous())
1086
1253
  self.assertTrue(t.is_f_contiguous())
1254
+ self.assertTrue(t.is_var_contiguous())
1087
1255
 
1088
1256
  def test_bool_common_fields(self):
1089
1257
  t = ndt("bool")
@@ -1092,8 +1260,8 @@ class TestBool(unittest.TestCase):
1092
1260
  self.assertEqual(t.itemsize, 1)
1093
1261
  self.assertEqual(t.align, 1)
1094
1262
 
1095
- self.assertRaises(TypeError, t, 'shape')
1096
- self.assertRaises(TypeError, t, 'strides')
1263
+ self.assertEqual(t.shape, ())
1264
+ self.assertEqual(t.strides, ())
1097
1265
 
1098
1266
 
1099
1267
  class TestSignedKind(unittest.TestCase):
@@ -1113,16 +1281,17 @@ class TestSignedKind(unittest.TestCase):
1113
1281
 
1114
1282
  self.assertFalse(t.is_c_contiguous())
1115
1283
  self.assertFalse(t.is_f_contiguous())
1284
+ self.assertFalse(t.is_var_contiguous())
1116
1285
 
1117
1286
  def test_signed_kind_common_fields(self):
1118
1287
  t = ndt("Signed")
1119
1288
 
1120
- self.assertRaises(TypeError, t, 'ndim')
1121
- self.assertRaises(TypeError, t, 'itemsize')
1122
- self.assertRaises(TypeError, t, 'align')
1289
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1290
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1291
+ self.assertRaises(TypeError, getattr, t, 'align')
1123
1292
 
1124
- self.assertRaises(TypeError, t, 'shape')
1125
- self.assertRaises(TypeError, t, 'strides')
1293
+ self.assertRaises(TypeError, getattr, t, 'shape')
1294
+ self.assertRaises(TypeError, getattr, t, 'strides')
1126
1295
 
1127
1296
 
1128
1297
  class TestSigned(unittest.TestCase):
@@ -1145,6 +1314,7 @@ class TestSigned(unittest.TestCase):
1145
1314
 
1146
1315
  self.assertTrue(t.is_c_contiguous())
1147
1316
  self.assertTrue(t.is_f_contiguous())
1317
+ self.assertTrue(t.is_var_contiguous())
1148
1318
 
1149
1319
  def test_signed_common_fields(self):
1150
1320
  for s, itemsize in [
@@ -1160,8 +1330,8 @@ class TestSigned(unittest.TestCase):
1160
1330
  self.assertEqual(t.itemsize, itemsize)
1161
1331
  self.assertEqual(t.align, itemsize)
1162
1332
 
1163
- self.assertRaises(TypeError, t, 'shape')
1164
- self.assertRaises(TypeError, t, 'shape')
1333
+ self.assertEqual(t.shape, ())
1334
+ self.assertEqual(t.strides, ())
1165
1335
 
1166
1336
 
1167
1337
  class TestUnsignedKind(unittest.TestCase):
@@ -1181,16 +1351,17 @@ class TestUnsignedKind(unittest.TestCase):
1181
1351
 
1182
1352
  self.assertFalse(t.is_c_contiguous())
1183
1353
  self.assertFalse(t.is_f_contiguous())
1354
+ self.assertFalse(t.is_var_contiguous())
1184
1355
 
1185
1356
  def test_unsigned_kind_common_fields(self):
1186
1357
  t = ndt("Unsigned")
1187
1358
 
1188
- self.assertRaises(TypeError, t, 'ndim')
1189
- self.assertRaises(TypeError, t, 'itemsize')
1190
- self.assertRaises(TypeError, t, 'align')
1359
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1360
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1361
+ self.assertRaises(TypeError, getattr, t, 'align')
1191
1362
 
1192
- self.assertRaises(TypeError, t, 'shape')
1193
- self.assertRaises(TypeError, t, 'strides')
1363
+ self.assertRaises(TypeError, getattr, t, 'shape')
1364
+ self.assertRaises(TypeError, getattr, t, 'strides')
1194
1365
 
1195
1366
 
1196
1367
  class TestUnsigned(unittest.TestCase):
@@ -1213,6 +1384,7 @@ class TestUnsigned(unittest.TestCase):
1213
1384
 
1214
1385
  self.assertTrue(t.is_c_contiguous())
1215
1386
  self.assertTrue(t.is_f_contiguous())
1387
+ self.assertTrue(t.is_var_contiguous())
1216
1388
 
1217
1389
  def test_unsigned_common_fields(self):
1218
1390
  for s, itemsize in [
@@ -1228,8 +1400,8 @@ class TestUnsigned(unittest.TestCase):
1228
1400
  self.assertEqual(t.itemsize, itemsize)
1229
1401
  self.assertEqual(t.align, itemsize)
1230
1402
 
1231
- self.assertRaises(TypeError, t, 'shape')
1232
- self.assertRaises(TypeError, t, 'shape')
1403
+ self.assertEqual(t.shape, ())
1404
+ self.assertEqual(t.strides, ())
1233
1405
 
1234
1406
 
1235
1407
  class TestFloatKind(unittest.TestCase):
@@ -1249,25 +1421,24 @@ class TestFloatKind(unittest.TestCase):
1249
1421
 
1250
1422
  self.assertFalse(t.is_c_contiguous())
1251
1423
  self.assertFalse(t.is_f_contiguous())
1424
+ self.assertFalse(t.is_var_contiguous())
1252
1425
 
1253
1426
  def test_float_kind_common_fields(self):
1254
1427
  t = ndt("Float")
1255
1428
  check_serialize(self, t)
1256
1429
 
1257
- self.assertRaises(TypeError, t, 'ndim')
1258
- self.assertRaises(TypeError, t, 'itemsize')
1259
- self.assertRaises(TypeError, t, 'align')
1430
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1431
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1432
+ self.assertRaises(TypeError, getattr, t, 'align')
1260
1433
 
1261
- self.assertRaises(TypeError, t, 'shape')
1262
- self.assertRaises(TypeError, t, 'strides')
1434
+ self.assertRaises(TypeError, getattr, t, 'shape')
1435
+ self.assertRaises(TypeError, getattr, t, 'strides')
1263
1436
 
1264
1437
 
1265
1438
  class TestFloat(unittest.TestCase):
1266
1439
 
1267
1440
  def test_float_predicates(self):
1268
- _float = ['float32', 'float64']
1269
- if HAVE_PYTHON_36:
1270
- _float.insert(0, 'float16')
1441
+ _float = ['bfloat16', 'float16', 'float32', 'float64']
1271
1442
 
1272
1443
  for s in _float:
1273
1444
  t = ndt(s)
@@ -1284,11 +1455,10 @@ class TestFloat(unittest.TestCase):
1284
1455
 
1285
1456
  self.assertTrue(t.is_c_contiguous())
1286
1457
  self.assertTrue(t.is_f_contiguous())
1458
+ self.assertTrue(t.is_var_contiguous())
1287
1459
 
1288
1460
  def test_float_common_fields(self):
1289
- _float = [('float32', 4), ('float64', 8)]
1290
- if HAVE_PYTHON_36:
1291
- _float.insert(0, ('float16', 2))
1461
+ _float = [('bfloat16', 2), ('float16', 2), ('float32', 4), ('float64', 8)]
1292
1462
 
1293
1463
  for s, itemsize in _float:
1294
1464
  t = ndt(s)
@@ -1298,8 +1468,8 @@ class TestFloat(unittest.TestCase):
1298
1468
  self.assertEqual(t.itemsize, itemsize)
1299
1469
  self.assertEqual(t.align, itemsize)
1300
1470
 
1301
- self.assertRaises(TypeError, t, 'shape')
1302
- self.assertRaises(TypeError, t, 'shape')
1471
+ self.assertEqual(t.shape, ())
1472
+ self.assertEqual(t.strides, ())
1303
1473
 
1304
1474
 
1305
1475
  class TestComplexKind(unittest.TestCase):
@@ -1319,24 +1489,23 @@ class TestComplexKind(unittest.TestCase):
1319
1489
 
1320
1490
  self.assertFalse(t.is_c_contiguous())
1321
1491
  self.assertFalse(t.is_f_contiguous())
1492
+ self.assertFalse(t.is_var_contiguous())
1322
1493
 
1323
1494
  def test_complex_kind_common_fields(self):
1324
1495
  t = ndt("Complex")
1325
1496
 
1326
- self.assertRaises(TypeError, t, 'ndim')
1327
- self.assertRaises(TypeError, t, 'itemsize')
1328
- self.assertRaises(TypeError, t, 'align')
1497
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1498
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1499
+ self.assertRaises(TypeError, getattr, t, 'align')
1329
1500
 
1330
- self.assertRaises(TypeError, t, 'shape')
1331
- self.assertRaises(TypeError, t, 'strides')
1501
+ self.assertRaises(TypeError, getattr, t, 'shape')
1502
+ self.assertRaises(TypeError, getattr, t, 'strides')
1332
1503
 
1333
1504
 
1334
1505
  class TestComplex(unittest.TestCase):
1335
1506
 
1336
1507
  def test_complex_predicates(self):
1337
- _complex = ['complex64', 'complex128']
1338
- if HAVE_PYTHON_36:
1339
- _complex.insert(0, 'complex32')
1508
+ _complex = ['bcomplex32', 'complex32', 'complex64', 'complex128']
1340
1509
 
1341
1510
  for s in _complex:
1342
1511
  t = ndt(s)
@@ -1353,11 +1522,10 @@ class TestComplex(unittest.TestCase):
1353
1522
 
1354
1523
  self.assertTrue(t.is_c_contiguous())
1355
1524
  self.assertTrue(t.is_f_contiguous())
1525
+ self.assertTrue(t.is_var_contiguous())
1356
1526
 
1357
1527
  def test_complex_common_fields(self):
1358
- _complex = [('complex64', 8), ('complex128', 16)]
1359
- if HAVE_PYTHON_36:
1360
- _complex.insert(0, ('complex32', 4))
1528
+ _complex = [('bcomplex32', 4), ('complex32', 4), ('complex64', 8), ('complex128', 16)]
1361
1529
 
1362
1530
  for s, itemsize in _complex:
1363
1531
  t = ndt(s)
@@ -1367,8 +1535,8 @@ class TestComplex(unittest.TestCase):
1367
1535
  self.assertEqual(t.itemsize, itemsize)
1368
1536
  self.assertEqual(t.align, itemsize // 2)
1369
1537
 
1370
- self.assertRaises(TypeError, t, 'shape')
1371
- self.assertRaises(TypeError, t, 'shape')
1538
+ self.assertEqual(t.shape, ())
1539
+ self.assertEqual(t.strides, ())
1372
1540
 
1373
1541
 
1374
1542
  class TestTypevar(unittest.TestCase):
@@ -1388,16 +1556,17 @@ class TestTypevar(unittest.TestCase):
1388
1556
 
1389
1557
  self.assertFalse(t.is_c_contiguous())
1390
1558
  self.assertFalse(t.is_f_contiguous())
1559
+ self.assertFalse(t.is_var_contiguous())
1391
1560
 
1392
1561
  def test_typevar_common_fields(self):
1393
1562
  t = ndt("T")
1394
1563
 
1395
- self.assertRaises(TypeError, t, 'ndim')
1396
- self.assertRaises(TypeError, t, 'itemsize')
1397
- self.assertRaises(TypeError, t, 'align')
1564
+ self.assertRaises(TypeError, getattr, t, 'ndim')
1565
+ self.assertRaises(TypeError, getattr, t, 'itemsize')
1566
+ self.assertRaises(TypeError, getattr, t, 'align')
1398
1567
 
1399
- self.assertRaises(TypeError, t, 'shape')
1400
- self.assertRaises(TypeError, t, 'strides')
1568
+ self.assertRaises(TypeError, getattr, t, 'shape')
1569
+ self.assertRaises(TypeError, getattr, t, 'strides')
1401
1570
 
1402
1571
 
1403
1572
  class TestCopy(unittest.TestCase):
@@ -1450,7 +1619,7 @@ class TestBufferProtocol(unittest.TestCase):
1450
1619
  ("(2,19)T{<b:a:xxxQ:b:}", 12, 4),
1451
1620
  ("(31,221)T{<b:a:xxxxxxxQ:b:}", 16, 8),
1452
1621
  ("(2,3,10)T{<b:a:xxxxxxxxxxxxxxxQ:b:xxxxxxxx}", 32, 16),
1453
- ("(2,10)T{=L:a:(2,3)D:b:}", 100, 1)]
1622
+ ("(2,10)T{=L:a:(2,3)Zd:b:}", 100, 1)]
1454
1623
 
1455
1624
  test_error_cases = [
1456
1625
  # empty shape (scalars are not arrays in datashape)
@@ -1524,13 +1693,10 @@ class TestBufferProtocol(unittest.TestCase):
1524
1693
  'c', 'b', 'B',
1525
1694
  'h', 'i', 'l', 'q',
1526
1695
  'H', 'I', 'L', 'Q',
1527
- 'f', 'd']
1696
+ 'e', 'f', 'd']
1528
1697
 
1529
1698
  native = ['n', 'N']
1530
1699
 
1531
- if HAVE_PYTHON_36:
1532
- standard += ['e']
1533
-
1534
1700
  for fmt in standard:
1535
1701
  for modifier in ['', '@', '=', '<', '>', '!']:
1536
1702
  f = modifier + fmt
@@ -1553,17 +1719,16 @@ class TestBufferProtocol(unittest.TestCase):
1553
1719
  self.assertRaises(ValueError, ndt.from_format, f)
1554
1720
  self.assertRaises(struct.error, struct.Struct, f)
1555
1721
 
1556
- if HAVE_PYTHON_36:
1557
- # complex32
1558
- fmt = 'E'
1559
- for modifier in ['', '@', '=', '<', '>', '!']:
1560
- f = modifier + fmt
1561
- t = ndt.from_format(f)
1562
- if not HAVE_32_BIT_LINUX:
1563
- self.assertEqual(t.itemsize, 4)
1722
+ # complex32
1723
+ fmt = 'Ze'
1724
+ for modifier in ['', '@', '=', '<', '>', '!']:
1725
+ f = modifier + fmt
1726
+ t = ndt.from_format(f)
1727
+ if not HAVE_32_BIT_LINUX:
1728
+ self.assertEqual(t.itemsize, 4)
1564
1729
 
1565
1730
  # complex64
1566
- fmt = 'F'
1731
+ fmt = 'Zf'
1567
1732
  for modifier in ['', '@', '=', '<', '>', '!']:
1568
1733
  f = modifier + fmt
1569
1734
  t = ndt.from_format(f)
@@ -1571,7 +1736,7 @@ class TestBufferProtocol(unittest.TestCase):
1571
1736
  self.assertEqual(t.itemsize, 8)
1572
1737
 
1573
1738
  # complex128
1574
- fmt = 'D'
1739
+ fmt = 'Zd'
1575
1740
  for modifier in ['', '@', '=', '<', '>', '!']:
1576
1741
  f = modifier + fmt
1577
1742
  t = ndt.from_format(f)
@@ -1703,6 +1868,38 @@ class TestMatch(unittest.TestCase):
1703
1868
  self.assertFalse(p.match(c))
1704
1869
 
1705
1870
 
1871
+ class TestUnify(unittest.TestCase):
1872
+
1873
+ def test_unify(self):
1874
+
1875
+ t = ndt("2 * 3 * float32")
1876
+ u = ndt("2 * 3 * float32")
1877
+ w = t.unify(u)
1878
+ self.assertEqual(w, ndt("2 * 3 * float32"))
1879
+
1880
+ t = ndt("2 * 3 * float32")
1881
+ u = ndt("2 * 3 * ?float64")
1882
+ w = t.unify(u)
1883
+ self.assertEqual(w, ndt("2 * 3 * ?float64"))
1884
+
1885
+ t = ndt("2 * 3 * (?Any, int64)")
1886
+ u = ndt("2 * 3 * (float64, Any)")
1887
+ w = t.unify(u)
1888
+ self.assertEqual(w, ndt("2 * 3 * (?float64, int64)"))
1889
+
1890
+ t = ndt("var(offsets=[0,2]) * var(offsets=[0,3,10]) * (int64, complex128)")
1891
+ u = ndt("var(offsets=[0,2]) * var(offsets=[0,3,10]) * ?(int8, complex64)")
1892
+ w = t.unify(u)
1893
+ del t
1894
+ del u
1895
+ gc.collect()
1896
+ self.assertEqual(w, ndt("var(offsets=[0,2]) * var(offsets=[0,3,10]) * ?(int64, complex128)"))
1897
+
1898
+ x = copy(w)
1899
+ del(w)
1900
+ self.assertEqual(x, ndt("var(offsets=[0,2]) * var(offsets=[0,3,10]) * ?(int64, complex128)"))
1901
+
1902
+
1706
1903
  class TestApply(unittest.TestCase):
1707
1904
 
1708
1905
  def test_apply(self):
@@ -1714,13 +1911,14 @@ class TestApply(unittest.TestCase):
1714
1911
 
1715
1912
 
1716
1913
  # Argument types:
1717
- in_types = [ndt("20 * 2 * 3 * int64"), ndt("20 * 3 * 4 * int64")]
1914
+ types = [ndt("20 * 2 * 3 * int64"), ndt("20 * 3 * 4 * int64")]
1718
1915
 
1719
- spec = sig.apply(in_types)
1720
- self.assertEqual(spec.sig, sig)
1721
- self.assertEqual(spec.in_types, in_types)
1722
- self.assertSequenceEqual(spec.out_types, [ndt("20 * 2 * 4 * float64")])
1916
+ spec = sig.apply(*types)
1723
1917
  self.assertEqual(spec.outer_dims, 1)
1918
+ self.assertEqual(spec.nin, 2)
1919
+ self.assertEqual(spec.nout, 1)
1920
+ self.assertEqual(spec.nargs, 3)
1921
+ self.assertEqual(spec.types, types + [ndt("20 * 2 * 4 * float64")])
1724
1922
 
1725
1923
  def test_apply_error(self):
1726
1924
 
@@ -1731,8 +1929,8 @@ class TestApply(unittest.TestCase):
1731
1929
  ["20 * 2 * 100 * int64", "20 * 3 * 4 * int64"]]
1732
1930
 
1733
1931
  for l in lst:
1734
- in_types = [ndt(x) for x in l]
1735
- self.assertRaises(TypeError, sig.apply, in_types)
1932
+ types = [ndt(x) for x in l]
1933
+ self.assertRaises(TypeError, sig.apply, types)
1736
1934
 
1737
1935
 
1738
1936
  def from_shape_strides(shape, strides):
@@ -1745,12 +1943,19 @@ class TestBroadcast(unittest.TestCase):
1745
1943
 
1746
1944
  def test_broadcast(self):
1747
1945
 
1748
- for c in BROADCAST_TEST_CASES:
1749
- spec = c.sig.apply(c.in_types)
1946
+ for d in BROADCAST_TEST_CASES:
1947
+ sig, args, kwargs, expected = d.values()
1948
+ spec = sig.apply(*args, out=kwargs)
1949
+
1950
+ msg = str(sig)
1750
1951
 
1751
- self.assertEqual(len(spec), len(c))
1752
- for v, u in zip(spec, c):
1753
- self.assertEqual(v, u)
1952
+ self.assertEqual(len(spec), len(expected), msg=msg)
1953
+ self.assertEqual(spec.flags, expected.flags, msg=msg)
1954
+ self.assertEqual(spec.outer_dims, expected.outer_dims, msg=msg)
1955
+ self.assertEqual(spec.nin, expected.nin, msg=msg)
1956
+ self.assertEqual(spec.nout, expected.nout, msg=msg)
1957
+ self.assertEqual(spec.nargs, expected.nargs, msg=msg)
1958
+ self.assertEqual(spec.types, expected.types, msg=msg)
1754
1959
 
1755
1960
  def test_against_numpy(self):
1756
1961
 
@@ -1788,8 +1993,8 @@ class TestBroadcast(unittest.TestCase):
1788
1993
 
1789
1994
  t = from_shape_strides(xshape, xstrides)
1790
1995
  u = from_shape_strides(yshape, ystrides)
1791
- spec = sig.apply([t, u])
1792
- tt, uu = spec.in_broadcast
1996
+ spec = sig.apply(t, u)
1997
+ tt, uu = spec.types[:2]
1793
1998
 
1794
1999
  self.assertEqual(tt.shape, xx.shape)
1795
2000
  self.assertEqual(uu.shape, yy.shape)
@@ -1916,8 +2121,10 @@ ALL_TESTS = [
1916
2121
  TestVarDim,
1917
2122
  TestSymbolicDim,
1918
2123
  TestEllipsisDim,
2124
+ TestArray,
1919
2125
  TestTuple,
1920
2126
  TestRecord,
2127
+ TestUnion,
1921
2128
  TestRef,
1922
2129
  TestConstr,
1923
2130
  TestNominal,
@@ -1945,6 +2152,7 @@ ALL_TESTS = [
1945
2152
  TestConstruction,
1946
2153
  TestError,
1947
2154
  TestMatch,
2155
+ TestUnify,
1948
2156
  TestApply,
1949
2157
  TestBroadcast,
1950
2158
  TestTypedef,