arraykit 0.7.0__tar.gz → 0.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {arraykit-0.7.0/arraykit.egg-info → arraykit-0.7.1}/PKG-INFO +1 -1
  2. {arraykit-0.7.0 → arraykit-0.7.1}/README.rst +9 -2
  3. {arraykit-0.7.0 → arraykit-0.7.1/arraykit.egg-info}/PKG-INFO +1 -1
  4. {arraykit-0.7.0 → arraykit-0.7.1}/setup.py +1 -1
  5. {arraykit-0.7.0 → arraykit-0.7.1}/src/__init__.py +2 -2
  6. {arraykit-0.7.0 → arraykit-0.7.1}/src/__init__.pyi +2 -2
  7. {arraykit-0.7.0 → arraykit-0.7.1}/src/_arraykit.c +102 -54
  8. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_util.py +56 -18
  9. {arraykit-0.7.0 → arraykit-0.7.1}/LICENSE.txt +0 -0
  10. {arraykit-0.7.0 → arraykit-0.7.1}/MANIFEST.in +0 -0
  11. {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/SOURCES.txt +0 -0
  12. {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/dependency_links.txt +0 -0
  13. {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/requires.txt +0 -0
  14. {arraykit-0.7.0 → arraykit-0.7.1}/arraykit.egg-info/top_level.txt +0 -0
  15. {arraykit-0.7.0 → arraykit-0.7.1}/setup.cfg +0 -0
  16. {arraykit-0.7.0 → arraykit-0.7.1}/src/py.typed +0 -0
  17. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_array_go.py +0 -0
  18. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_block_index.py +0 -0
  19. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_delimited_to_arrays.py +0 -0
  20. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_delimited_to_arrays_integration.py +0 -0
  21. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_delimited_to_arrays_property.py +0 -0
  22. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_nonzero_1d.py +0 -0
  23. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_nonzero_1d_property.py +0 -0
  24. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_pyi.py +0 -0
  25. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_split_after_count.py +0 -0
  26. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_tri_map.py +0 -0
  27. {arraykit-0.7.0 → arraykit-0.7.1}/test/test_type_discovery.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arraykit
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Array utilities for StaticFrame
5
5
  Home-page: https://github.com/static-frame/arraykit
6
6
  Author: Christopher Ariza, Brandt Bucher, Charles Burkland
@@ -37,12 +37,19 @@ ArrayKit requires the following:
37
37
  What is New in ArrayKit
38
38
  -------------------------
39
39
 
40
+
41
+ 0.7.1
42
+ ............
43
+
44
+ Extended ``array_to_tuple_array()`` and ``array_to_tuple_iter()`` to support 1D arrays.
45
+
46
+
40
47
  0.7.0
41
48
  ............
42
49
 
43
- Added ``array2d_to_array1d()``.
50
+ Added ``array_to_tuple_array()``.
44
51
 
45
- Added ``array2d_tuple_iter()``.
52
+ Added ``array_to_tuple_iter()``.
46
53
 
47
54
 
48
55
  0.6.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arraykit
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Array utilities for StaticFrame
5
5
  Home-page: https://github.com/static-frame/arraykit
6
6
  Author: Christopher Ariza, Brandt Bucher, Charles Burkland
@@ -5,7 +5,7 @@ from setuptools import Extension # type: ignore
5
5
  from setuptools import setup
6
6
  from pathlib import Path
7
7
 
8
- AK_VERSION = '0.7.0'
8
+ AK_VERSION = '0.7.1'
9
9
 
10
10
  def get_long_description() -> str:
11
11
  return '''The ArrayKit library provides utilities for creating and transforming NumPy arrays, implementing performance-critical StaticFrame operations as Python C extensions.
@@ -28,6 +28,6 @@ from ._arraykit import count_iteration as count_iteration
28
28
  from ._arraykit import first_true_1d as first_true_1d
29
29
  from ._arraykit import first_true_2d as first_true_2d
30
30
  from ._arraykit import slice_to_ascending_slice as slice_to_ascending_slice
31
- from ._arraykit import array2d_to_array1d as array2d_to_array1d
32
- from ._arraykit import array2d_tuple_iter as array2d_tuple_iter
31
+ from ._arraykit import array_to_tuple_array as array_to_tuple_array
32
+ from ._arraykit import array_to_tuple_iter as array_to_tuple_iter
33
33
  from ._arraykit import nonzero_1d as nonzero_1d
@@ -161,5 +161,5 @@ def first_true_1d(__array: np.ndarray, *, forward: bool) -> int: ...
161
161
  def first_true_2d(__array: np.ndarray, *, forward: bool, axis: int) -> np.ndarray: ...
162
162
  def nonzero_1d(__array: np.ndarray, /) -> np.ndarray: ...
163
163
  def slice_to_ascending_slice(__slice: slice, __size: int) -> slice: ...
164
- def array2d_to_array1d(__array: np.ndarray) -> np.ndarray: ...
165
- def array2d_tuple_iter(__array: np.ndarray) -> tp.Iterator[tp.Tuple[tp.Any, ...]]: ...
164
+ def array_to_tuple_array(__array: np.ndarray) -> np.ndarray: ...
165
+ def array_to_tuple_iter(__array: np.ndarray) -> tp.Iterator[tp.Tuple[tp.Any, ...]]: ...
@@ -3524,16 +3524,20 @@ array_deepcopy(PyObject *m, PyObject *args, PyObject *kwargs)
3524
3524
  }
3525
3525
 
3526
3526
  //------------------------------------------------------------------------------
3527
- // Given a 2D array, return a 1D object array of tuples.
3527
+ // Given a 1D or 2D array, return a 1D object array of tuples.
3528
3528
  static PyObject *
3529
- array2d_to_array1d(PyObject *Py_UNUSED(m), PyObject *a)
3529
+ array_to_tuple_array(PyObject *Py_UNUSED(m), PyObject *a)
3530
3530
  {
3531
- AK_CHECK_NUMPY_ARRAY_2D(a);
3531
+ AK_CHECK_NUMPY_ARRAY(a);
3532
3532
  PyArrayObject *input_array = (PyArrayObject *)a;
3533
+ int ndim = PyArray_NDIM(input_array);
3534
+ if (ndim != 1 && ndim != 2) {
3535
+ return PyErr_Format(PyExc_NotImplementedError,
3536
+ "Expected 1D or 2D array, not %i.",
3537
+ ndim);
3538
+ }
3533
3539
 
3534
3540
  npy_intp num_rows = PyArray_DIM(input_array, 0);
3535
- npy_intp num_cols = PyArray_DIM(input_array, 1);
3536
-
3537
3541
  npy_intp dims[] = {num_rows};
3538
3542
  // NOTE: this initializes values to NULL, not None
3539
3543
  PyObject* output = PyArray_SimpleNew(1, dims, NPY_OBJECT);
@@ -3545,26 +3549,46 @@ array2d_to_array1d(PyObject *Py_UNUSED(m), PyObject *a)
3545
3549
  PyObject** p = output_data;
3546
3550
  PyObject** p_end = p + num_rows;
3547
3551
  npy_intp i = 0;
3548
- npy_intp j;
3549
3552
  PyObject* tuple;
3550
3553
  PyObject* item;
3551
3554
 
3552
- while (p < p_end) {
3553
- tuple = PyTuple_New(num_cols);
3554
- if (tuple == NULL) {
3555
- goto error;
3555
+ if (ndim == 2) {
3556
+ npy_intp num_cols = PyArray_DIM(input_array, 1);
3557
+ npy_intp j;
3558
+ while (p < p_end) {
3559
+ tuple = PyTuple_New(num_cols);
3560
+ if (tuple == NULL) {
3561
+ goto error;
3562
+ }
3563
+ for (j = 0; j < num_cols; ++j) {
3564
+ // cannot assume input_array is contiguous
3565
+ item = PyArray_ToScalar(PyArray_GETPTR2(input_array, i, j), input_array);
3566
+ if (item == NULL) {
3567
+ Py_DECREF(tuple);
3568
+ goto error;
3569
+ }
3570
+ PyTuple_SET_ITEM(tuple, j, item); // steals reference to item
3571
+ }
3572
+ *p++ = tuple; // assign with new ref, no incr needed
3573
+ i++;
3556
3574
  }
3557
- for (j = 0; j < num_cols; ++j) {
3558
- // cannot assume input_array is contiguous
3559
- item = PyArray_ToScalar(PyArray_GETPTR2(input_array, i, j), input_array);
3575
+ }
3576
+ else { // ndim == 1
3577
+ while (p < p_end) {
3578
+ tuple = PyTuple_New(1);
3579
+ if (tuple == NULL) {
3580
+ goto error;
3581
+ }
3582
+ // scalar returned in is native PyObject from object arrays
3583
+ item = PyArray_ToScalar(PyArray_GETPTR1(input_array, i), input_array);
3560
3584
  if (item == NULL) {
3561
3585
  Py_DECREF(tuple);
3562
3586
  goto error;
3563
3587
  }
3564
- PyTuple_SET_ITEM(tuple, j, item); // steals reference to item
3588
+ PyTuple_SET_ITEM(tuple, 0, item); // steals reference to item
3589
+ *p++ = tuple; // assign with new ref, no incr needed
3590
+ i++;
3565
3591
  }
3566
- *p++ = tuple; // assign with new ref, no incr needed
3567
- i++;
3568
3592
  }
3569
3593
  PyArray_CLEARFLAGS((PyArrayObject *)output, NPY_ARRAY_WRITEABLE);
3570
3594
  return output;
@@ -3579,65 +3603,81 @@ error:
3579
3603
  }
3580
3604
 
3581
3605
  //------------------------------------------------------------------------------
3582
- // Array2DTuple Iterator
3606
+ // ArrayToTupleIterator
3583
3607
 
3584
- static PyTypeObject A2DTupleType;
3608
+ static PyTypeObject ATTType;
3585
3609
 
3586
- typedef struct A2DTupleObject {
3610
+ typedef struct ATTObject {
3587
3611
  PyObject_HEAD
3588
3612
  PyArrayObject* array;
3589
3613
  npy_intp num_rows;
3590
3614
  npy_intp num_cols;
3591
3615
  Py_ssize_t pos; // current index state, mutated in-place
3592
- } A2DTupleObject;
3616
+ } ATTObject;
3593
3617
 
3594
3618
  static PyObject *
3595
- A2DTuple_new(PyArrayObject* array,
3619
+ ATT_new(PyArrayObject* array,
3596
3620
  npy_intp num_rows,
3597
3621
  npy_intp num_cols) {
3598
- A2DTupleObject* a2dt = PyObject_New(A2DTupleObject, &A2DTupleType);
3622
+ ATTObject* a2dt = PyObject_New(ATTObject, &ATTType);
3599
3623
  if (!a2dt) {
3600
3624
  return NULL;
3601
3625
  }
3602
3626
  Py_INCREF((PyObject*)array);
3603
3627
  a2dt->array = array;
3604
3628
  a2dt->num_rows = num_rows;
3605
- a2dt->num_cols = num_cols;
3629
+ a2dt->num_cols = num_cols; // -1 for 1D array
3606
3630
  a2dt->pos = 0;
3607
3631
  return (PyObject *)a2dt;
3608
3632
  }
3609
3633
 
3610
3634
  static void
3611
- A2DTuple_dealloc(A2DTupleObject *self) {
3635
+ ATT_dealloc(ATTObject *self) {
3612
3636
  Py_DECREF((PyObject*)self->array);
3613
3637
  PyObject_Del((PyObject*)self);
3614
3638
  }
3615
3639
 
3616
3640
  static PyObject*
3617
- A2DTuple_iter(A2DTupleObject *self) {
3641
+ ATT_iter(ATTObject *self) {
3618
3642
  Py_INCREF(self);
3619
3643
  return (PyObject*)self;
3620
3644
  }
3621
3645
 
3622
3646
  static PyObject *
3623
- A2DTuple_iternext(A2DTupleObject *self) {
3647
+ ATT_iternext(ATTObject *self) {
3624
3648
  Py_ssize_t i = self->pos;
3625
3649
  if (i < self->num_rows) {
3626
3650
  npy_intp num_cols = self->num_cols;
3627
3651
  PyArrayObject* array = self->array;
3628
- PyObject* tuple = PyTuple_New(num_cols);
3629
3652
  PyObject* item;
3630
- if (tuple == NULL) {
3631
- return NULL;
3653
+ PyObject* tuple;
3654
+
3655
+ if (num_cols > -1) { // ndim == 2
3656
+ tuple = PyTuple_New(num_cols);
3657
+ if (tuple == NULL) {
3658
+ return NULL;
3659
+ }
3660
+ for (npy_intp j = 0; j < num_cols; ++j) {
3661
+ // cannot assume array is contiguous
3662
+ item = PyArray_ToScalar(PyArray_GETPTR2(array, i, j), array);
3663
+ if (item == NULL) {
3664
+ Py_DECREF(tuple);
3665
+ return NULL;
3666
+ }
3667
+ PyTuple_SET_ITEM(tuple, j, item); // steals reference to item
3668
+ }
3632
3669
  }
3633
- for (npy_intp j = 0; j < num_cols; ++j) {
3634
- // cannot assume array is contiguous
3635
- item = PyArray_ToScalar(PyArray_GETPTR2(array, i, j), array);
3670
+ else { // ndim == 1
3671
+ tuple = PyTuple_New(1);
3672
+ if (tuple == NULL) {
3673
+ return NULL;
3674
+ }
3675
+ item = PyArray_ToScalar(PyArray_GETPTR1(array, i), array);
3636
3676
  if (item == NULL) {
3637
3677
  Py_DECREF(tuple);
3638
3678
  return NULL;
3639
3679
  }
3640
- PyTuple_SET_ITEM(tuple, j, item); // steals reference to item
3680
+ PyTuple_SET_ITEM(tuple, 0, item); // steals reference to item
3641
3681
  }
3642
3682
  self->pos++;
3643
3683
  return tuple;
@@ -3646,44 +3686,52 @@ A2DTuple_iternext(A2DTupleObject *self) {
3646
3686
  }
3647
3687
 
3648
3688
  // static PyObject *
3649
- // A2DTuple_reversed(A2DTupleObject *self) {
3650
- // return A2DTuple_new(self->bi, !self->reversed);
3689
+ // ATT_reversed(ATTObject *self) {
3690
+ // return ATT_new(self->bi, !self->reversed);
3651
3691
  // }
3652
3692
 
3653
3693
  static PyObject *
3654
- A2DTuple_length_hint(A2DTupleObject *self) {
3694
+ ATT_length_hint(ATTObject *self) {
3655
3695
  Py_ssize_t len = Py_MAX(0, self->num_rows - self->pos);
3656
3696
  return PyLong_FromSsize_t(len);
3657
3697
  }
3658
3698
 
3659
- static PyMethodDef A2DTuple_methods[] = {
3660
- {"__length_hint__", (PyCFunction)A2DTuple_length_hint, METH_NOARGS, NULL},
3661
- // {"__reversed__", (PyCFunction)A2DTuple_reversed, METH_NOARGS, NULL},
3699
+ static PyMethodDef ATT_methods[] = {
3700
+ {"__length_hint__", (PyCFunction)ATT_length_hint, METH_NOARGS, NULL},
3701
+ // {"__reversed__", (PyCFunction)ATT_reversed, METH_NOARGS, NULL},
3662
3702
  {NULL},
3663
3703
  };
3664
3704
 
3665
- static PyTypeObject A2DTupleType = {
3705
+ static PyTypeObject ATTType = {
3666
3706
  PyVarObject_HEAD_INIT(NULL, 0)
3667
- .tp_basicsize = sizeof(A2DTupleObject),
3668
- .tp_dealloc = (destructor) A2DTuple_dealloc,
3669
- .tp_iter = (getiterfunc) A2DTuple_iter,
3670
- .tp_iternext = (iternextfunc) A2DTuple_iternext,
3671
- .tp_methods = A2DTuple_methods,
3672
- .tp_name = "arraykit.A2DTupleIterator",
3707
+ .tp_basicsize = sizeof(ATTObject),
3708
+ .tp_dealloc = (destructor) ATT_dealloc,
3709
+ .tp_iter = (getiterfunc) ATT_iter,
3710
+ .tp_iternext = (iternextfunc) ATT_iternext,
3711
+ .tp_methods = ATT_methods,
3712
+ .tp_name = "arraykit.ATTIterator",
3673
3713
  };
3674
3714
 
3675
3715
  // Given a 2D array, return an iterator of row tuples.
3676
3716
  static PyObject *
3677
- array2d_tuple_iter(PyObject *Py_UNUSED(m), PyObject *a)
3717
+ array_to_tuple_iter(PyObject *Py_UNUSED(m), PyObject *a)
3678
3718
  {
3679
- AK_CHECK_NUMPY_ARRAY_2D(a);
3680
- PyArrayObject* array = (PyArrayObject *)a;
3719
+ AK_CHECK_NUMPY_ARRAY(a);
3720
+ PyArrayObject *array = (PyArrayObject *)a;
3721
+ int ndim = PyArray_NDIM(array);
3722
+ if (ndim != 1 && ndim != 2) {
3723
+ return PyErr_Format(PyExc_NotImplementedError,
3724
+ "Expected 1D or 2D array, not %i.",
3725
+ ndim);
3726
+ }
3681
3727
  npy_intp num_rows = PyArray_DIM(array, 0);
3682
- npy_intp num_cols = PyArray_DIM(array, 1);
3683
- return A2DTuple_new(array, num_rows, num_cols);
3728
+ npy_intp num_cols = -1; // indicate 1d
3729
+ if (ndim == 2) {
3730
+ num_cols = PyArray_DIM(array, 1);
3731
+ }
3732
+ return ATT_new(array, num_rows, num_cols);
3684
3733
  }
3685
3734
 
3686
-
3687
3735
  //------------------------------------------------------------------------------
3688
3736
  // type resolution
3689
3737
 
@@ -7431,8 +7479,8 @@ static PyMethodDef arraykit_methods[] = {
7431
7479
  (PyCFunction)array_deepcopy,
7432
7480
  METH_VARARGS | METH_KEYWORDS,
7433
7481
  NULL},
7434
- {"array2d_to_array1d", array2d_to_array1d, METH_O, NULL},
7435
- {"array2d_tuple_iter", array2d_tuple_iter, METH_O, NULL},
7482
+ {"array_to_tuple_array", array_to_tuple_array, METH_O, NULL},
7483
+ {"array_to_tuple_iter", array_to_tuple_iter, METH_O, NULL},
7436
7484
  {"resolve_dtype", resolve_dtype, METH_VARARGS, NULL},
7437
7485
  {"resolve_dtype_iter", resolve_dtype_iter, METH_O, NULL},
7438
7486
  {"first_true_1d",
@@ -22,8 +22,8 @@ from arraykit import count_iteration
22
22
  from arraykit import first_true_1d
23
23
  from arraykit import first_true_2d
24
24
  from arraykit import slice_to_ascending_slice
25
- from arraykit import array2d_to_array1d
26
- from arraykit import array2d_tuple_iter
25
+ from arraykit import array_to_tuple_array
26
+ from arraykit import array_to_tuple_iter
27
27
 
28
28
  from performance.reference.util import get_new_indexers_and_screen_ak as get_new_indexers_and_screen_full
29
29
  from arraykit import get_new_indexers_and_screen
@@ -286,15 +286,35 @@ class TestUnit(unittest.TestCase):
286
286
  a2 = array_deepcopy(a1, ())
287
287
 
288
288
  #---------------------------------------------------------------------------
289
- def test_array2d_to_array1d_dummy(self) -> None:
289
+ def test_array2d_to_array1d_1d_a(self) -> None:
290
290
  a1 = np.arange(10)
291
- with self.assertRaises(NotImplementedError):
292
- # 1 dimensional
293
- _ = array2d_to_array1d(a1)
291
+ a2 = array_to_tuple_array(a1)
292
+ self.assertEqual(a2.tolist(), [(0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,)])
293
+
294
+ def test_array2d_to_array1d_1d_b(self) -> None:
295
+ a1 = np.array(['aaa', 'b', 'ccc'])
296
+ a2 = array_to_tuple_array(a1)
297
+ self.assertEqual(a2.tolist(), [('aaa',), ('b',), ('ccc',)])
298
+
299
+ def test_array2d_to_array1d_1d_c(self) -> None:
300
+ a1 = np.array([None, 'b', 30])
301
+ a2 = array_to_tuple_array(a1)
302
+ self.assertEqual(a2.tolist(), [(None,), ('b',), (30,)])
303
+
304
+ def test_array2d_to_array1d_1d_d(self) -> None:
305
+ a1 = np.array([('a', 10), ('b', 30), ('c', 5)], dtype=object)
306
+ a2 = array_to_tuple_array(a1)
307
+ self.assertEqual(a2.tolist(), [('a', 10), ('b', 30), ('c', 5)])
308
+
309
+ def test_array2d_to_array1d_1d_e(self) -> None:
310
+ a1 = np.array([True, False, True], dtype=object)
311
+ a2 = array_to_tuple_array(a1)
312
+ self.assertIs(a2[0][0].__class__, bool)
313
+ self.assertEqual(a2.tolist(), [(True,), (False,), (True,)])
294
314
 
295
315
  def test_array2d_to_array1d_b(self) -> None:
296
316
  a1 = np.arange(10, dtype=np.int64).reshape(5, 2)
297
- result = array2d_to_array1d(a1)
317
+ result = array_to_tuple_array(a1)
298
318
  assert isinstance(result[0], tuple)
299
319
  assert result[0] == (0, 1)
300
320
  self.assertIs(type(result[0][0]), np.int64)
@@ -304,35 +324,35 @@ class TestUnit(unittest.TestCase):
304
324
 
305
325
  def test_array2d_to_array1d_c(self) -> None:
306
326
  a1 = np.array([["a", "b"], ["ccc", "ddd"], ["ee", "ff"]])
307
- a2 = array2d_to_array1d(a1)
327
+ a2 = array_to_tuple_array(a1)
308
328
  self.assertEqual(a2.tolist(), [('a', 'b'), ('ccc', 'ddd'), ('ee', 'ff')])
309
329
 
310
330
  def test_array2d_to_array1d_d(self) -> None:
311
331
  a1 = np.array([[3, 5], [10, 20], [7, 2]], dtype=np.uint8)
312
- a2 = array2d_to_array1d(a1)
332
+ a2 = array_to_tuple_array(a1)
313
333
  self.assertEqual(a2.tolist(), [(3, 5), (10, 20), (7, 2)])
314
334
  self.assertIs(type(a2[0][0]), np.uint8)
315
335
 
316
336
  def test_array2d_to_array1d_e(self) -> None:
317
337
  a1 = np.arange(20, dtype=np.int64).reshape(4, 5)
318
- result = array2d_to_array1d(a1)
338
+ result = array_to_tuple_array(a1)
319
339
  self.assertEqual(result.tolist(), [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)])
320
340
 
321
341
  #---------------------------------------------------------------------------
322
342
  def test_array2d_tuple_iter_a(self) -> None:
323
343
  a1 = np.arange(20, dtype=np.int64).reshape(4, 5)
324
- result = list(array2d_tuple_iter(a1))
344
+ result = list(array_to_tuple_iter(a1))
325
345
  self.assertEqual(len(result), 4)
326
346
  self.assertEqual(result, [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)])
327
347
 
328
348
  def test_array2d_tuple_iter_b(self) -> None:
329
349
  a1 = np.arange(20, dtype=np.int64).reshape(10, 2)
330
- result = list(array2d_tuple_iter(a1))
350
+ result = list(array_to_tuple_iter(a1))
331
351
  self.assertEqual(result, [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11), (12, 13), (14, 15), (16, 17), (18, 19)])
332
352
 
333
353
  def test_array2d_tuple_iter_c(self) -> None:
334
354
  a1 = np.array([['aaa', 'bb'], ['c', 'dd'], ['ee', 'fffff']])
335
- it = array2d_tuple_iter(a1)
355
+ it = array_to_tuple_iter(a1)
336
356
  self.assertEqual(it.__length_hint__(), 3)
337
357
  self.assertEqual(next(it), ('aaa', 'bb'))
338
358
  self.assertEqual(it.__length_hint__(), 2)
@@ -345,20 +365,20 @@ class TestUnit(unittest.TestCase):
345
365
 
346
366
  def test_array2d_tuple_iter_d(self) -> None:
347
367
  a1 = np.array([['aaa', 'bb'], ['c', 'dd'], ['ee', 'fffff']])
348
- it = array2d_tuple_iter(a1)
368
+ it = array_to_tuple_iter(a1)
349
369
  # __reversed__ not implemented
350
370
  with self.assertRaises(TypeError):
351
371
  reversed(it)
352
372
 
353
373
  def test_array2d_tuple_iter_e(self) -> None:
354
374
  a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
355
- it = array2d_tuple_iter(a1)
375
+ it = array_to_tuple_iter(a1)
356
376
  del a1
357
377
  self.assertEqual(list(it), [(None, 'bb'), (None, 'dd'), (3, None)])
358
378
 
359
379
  def test_array2d_tuple_iter_f(self) -> None:
360
380
  a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
361
- it1 = array2d_tuple_iter(a1)
381
+ it1 = array_to_tuple_iter(a1)
362
382
  del a1
363
383
  it2 = iter(it1)
364
384
  self.assertEqual(list(it1), [(None, 'bb'), (None, 'dd'), (3, None)])
@@ -366,12 +386,30 @@ class TestUnit(unittest.TestCase):
366
386
 
367
387
  def test_array2d_tuple_iter_g(self) -> None:
368
388
  a1 = np.array([[None, 'bb'], [None, 'dd'], [3, None]])
369
- it1 = array2d_tuple_iter(a1)
370
- it2 = array2d_tuple_iter(a1)
389
+ it1 = array_to_tuple_iter(a1)
390
+ it2 = array_to_tuple_iter(a1)
371
391
  del a1
372
392
  self.assertEqual(list(it1), [(None, 'bb'), (None, 'dd'), (3, None)])
373
393
  self.assertEqual(list(it2), [(None, 'bb'), (None, 'dd'), (3, None)])
374
394
 
395
+ def test_array2d_tuple_iter_1d_a(self) -> None:
396
+ a1 = np.array(['bb', 'c', 'aaa'])
397
+ result = list(array_to_tuple_iter(a1))
398
+ self.assertEqual(len(result), 3)
399
+ self.assertEqual(result, [('bb',), ('c',), ('aaa',)])
400
+
401
+ def test_array2d_tuple_iter_1d_b(self) -> None:
402
+ a1 = np.array([20, -1, 8])
403
+ result = list(array_to_tuple_iter(a1))
404
+ self.assertEqual(len(result), 3)
405
+ self.assertEqual(result, [(20,), (-1,), (8,)])
406
+
407
+ def test_array2d_tuple_iter_1d_c(self) -> None:
408
+ a1 = np.array([('a', 4), ('c', -1), ('d', 8)], dtype=object)
409
+ result = list(array_to_tuple_iter(a1))
410
+ self.assertEqual(len(result), 3)
411
+ self.assertEqual(result, [('a', 4), ('c', -1), ('d', 8)])
412
+
375
413
  #---------------------------------------------------------------------------
376
414
 
377
415
  def test_isna_element_a(self) -> None:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes