Skip to content
This repository was archived by the owner on Jun 27, 2025. It is now read-only.

Commit 5182bba

Browse files
authored
Merge pull request #21 from static-frame/20/non-unique-dt64
Correct insertion of dt64
2 parents 2ba4073 + 2147da0 commit 5182bba

File tree

2 files changed

+33
-22
lines changed

2 files changed

+33
-22
lines changed

arraymap.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,13 +1440,14 @@ insert_int(
14401440
FAMObject *self,
14411441
npy_int64 key,
14421442
Py_ssize_t keys_pos,
1443-
Py_hash_t hash)
1443+
Py_hash_t hash,
1444+
KeysArrayType kat)
14441445
{
14451446
if (hash == -1) {
14461447
hash = int_to_hash(key);
14471448
}
14481449
// table position is not dependent on keys_pos
1449-
Py_ssize_t table_pos = lookup_hash_int(self, key, hash, self->keys_array_type);
1450+
Py_ssize_t table_pos = lookup_hash_int(self, key, hash, kat);
14501451
if (table_pos < 0) {
14511452
return -1;
14521453
}
@@ -1470,12 +1471,13 @@ insert_uint(
14701471
FAMObject *self,
14711472
npy_uint64 key,
14721473
Py_ssize_t keys_pos,
1473-
Py_hash_t hash)
1474+
Py_hash_t hash,
1475+
KeysArrayType kat)
14741476
{
14751477
if (hash == -1) {
14761478
hash = uint_to_hash(key);
14771479
}
1478-
Py_ssize_t table_pos = lookup_hash_uint(self, key, hash, self->keys_array_type);
1480+
Py_ssize_t table_pos = lookup_hash_uint(self, key, hash, kat);
14791481

14801482
if (table_pos < 0) {
14811483
return -1;
@@ -1500,13 +1502,14 @@ insert_double(
15001502
FAMObject *self,
15011503
npy_double key,
15021504
Py_ssize_t keys_pos,
1503-
Py_hash_t hash)
1505+
Py_hash_t hash,
1506+
KeysArrayType kat)
15041507
{
15051508
if (hash == -1) {
15061509
hash = double_to_hash(key);
15071510
}
15081511
// table position is not dependent on keys_pos
1509-
Py_ssize_t table_pos = lookup_hash_double(self, key, hash, self->keys_array_type);
1512+
Py_ssize_t table_pos = lookup_hash_double(self, key, hash, kat);
15101513

15111514
if (table_pos < 0) {
15121515
return -1;
@@ -2381,13 +2384,13 @@ fam_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
23812384

23822385

23832386
// This macro can be used with integer and floating point NumPy types, given an `npy_type` and a specialized `insert_func`. Uses context of `fam_init` to get `fam`, `contiguous`, `a`, `keys_size`, and `i`. An optional `post_deref` function can be supplied to transform extracted values before calling the appropriate insert function.
2384-
# define INSERT_SCALARS(npy_type, insert_func, post_deref) \
2387+
# define INSERT_SCALARS(npy_type, insert_func, kat, post_deref) \
23852388
{ \
23862389
if (contiguous) { \
23872390
npy_type* b = (npy_type*)PyArray_DATA(a); \
23882391
npy_type* b_end = b + keys_size; \
23892392
while (b < b_end) { \
2390-
if (insert_func(fam, post_deref(*b), i, -1)) { \
2393+
if (insert_func(fam, post_deref(*b), i, -1, kat)) { \
23912394
goto error; \
23922395
} \
23932396
b++; \
@@ -2399,7 +2402,8 @@ fam_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
23992402
if (insert_func(fam, \
24002403
post_deref(*(npy_type*)PyArray_GETPTR1(a, i)),\
24012404
i, \
2402-
-1)) { \
2405+
-1, \
2406+
kat)) { \
24032407
goto error; \
24042408
} \
24052409
} \
@@ -2513,7 +2517,7 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
25132517
}
25142518
keys_size = PyList_GET_SIZE(keys);
25152519
}
2516-
assert(keys_array_type >= 0);
2520+
25172521
fam->keys = keys;
25182522
fam->keys_array_type = keys_array_type;
25192523
fam->keys_size = keys_size;
@@ -2530,37 +2534,37 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
25302534
int contiguous = PyArray_IS_C_CONTIGUOUS(a);
25312535
switch (keys_array_type) {
25322536
case KAT_INT64:
2533-
INSERT_SCALARS(npy_int64, insert_int,);
2537+
INSERT_SCALARS(npy_int64, insert_int, keys_array_type,);
25342538
break;
25352539
case KAT_INT32:
2536-
INSERT_SCALARS(npy_int32, insert_int,);
2540+
INSERT_SCALARS(npy_int32, insert_int, keys_array_type,);
25372541
break;
25382542
case KAT_INT16:
2539-
INSERT_SCALARS(npy_int16, insert_int,);
2543+
INSERT_SCALARS(npy_int16, insert_int, keys_array_type,);
25402544
break;
25412545
case KAT_INT8:
2542-
INSERT_SCALARS(npy_int8, insert_int,);
2546+
INSERT_SCALARS(npy_int8, insert_int, keys_array_type,);
25432547
break;
25442548
case KAT_UINT64:
2545-
INSERT_SCALARS(npy_uint64, insert_uint,);
2549+
INSERT_SCALARS(npy_uint64, insert_uint, keys_array_type,);
25462550
break;
25472551
case KAT_UINT32:
2548-
INSERT_SCALARS(npy_uint32, insert_uint,);
2552+
INSERT_SCALARS(npy_uint32, insert_uint, keys_array_type,);
25492553
break;
25502554
case KAT_UINT16:
2551-
INSERT_SCALARS(npy_uint16, insert_uint,);
2555+
INSERT_SCALARS(npy_uint16, insert_uint, keys_array_type,);
25522556
break;
25532557
case KAT_UINT8:
2554-
INSERT_SCALARS(npy_uint8, insert_uint,);
2558+
INSERT_SCALARS(npy_uint8, insert_uint, keys_array_type,);
25552559
break;
25562560
case KAT_FLOAT64:
2557-
INSERT_SCALARS(npy_double, insert_double,);
2561+
INSERT_SCALARS(npy_double, insert_double, keys_array_type,);
25582562
break;
25592563
case KAT_FLOAT32:
2560-
INSERT_SCALARS(npy_float, insert_double,);
2564+
INSERT_SCALARS(npy_float, insert_double, keys_array_type,);
25612565
break;
25622566
case KAT_FLOAT16:
2563-
INSERT_SCALARS(npy_half, insert_double, npy_half_to_double);
2567+
INSERT_SCALARS(npy_half, insert_double, keys_array_type, npy_half_to_double);
25642568
break;
25652569
case KAT_UNICODE: {
25662570
// Over allocate buffer by 1 so there is room for null at end. This buffer is only used in lookup();
@@ -2587,7 +2591,7 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
25872591
case KAT_DTps:
25882592
case KAT_DTfs:
25892593
case KAT_DTas:
2590-
INSERT_SCALARS(npy_int64, insert_int,);
2594+
INSERT_SCALARS(npy_int64, insert_int, KAT_INT64,);
25912595
break;
25922596
default:
25932597
return -1;

test/test_unit.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ def test_fam_constructor_array_dt64_c():
153153
assert len(fam) == 2
154154

155155

156+
def test_fam_constructor_array_dt64_d():
157+
a1 = np.array(("2023-05", "2023-05"), dtype=np.datetime64)
158+
a1.flags.writeable = False
159+
with pytest.raises(NonUniqueError):
160+
fam = FrozenAutoMap(a1)
161+
162+
156163
# ------------------------------------------------------------------------------
157164

158165

0 commit comments

Comments
 (0)