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

Commit 8e15491

Browse files
authored
Merge pull request #4 from static-frame/3/init-seg-fault
Improvements to `fam_init` for generators that raise
2 parents 96015d5 + 6e2b6d4 commit 8e15491

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

arraymap.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,11 @@ lookup(FAMObject *self, PyObject *key) {
11891189

11901190
// Insert a key_pos, hash pair into the table. Assumes table already has appropriate size. When inserting a new itme, `hash` is -1, forcing a fresh hash to be computed here. Return 0 on success, -1 on error.
11911191
static int
1192-
insert_obj(FAMObject *self, PyObject *key, Py_ssize_t keys_pos, Py_hash_t hash)
1192+
insert_obj(
1193+
FAMObject *self,
1194+
PyObject *key,
1195+
Py_ssize_t keys_pos,
1196+
Py_hash_t hash)
11931197
{
11941198
if (hash == -1) {
11951199
hash = PyObject_Hash(key);
@@ -1819,6 +1823,9 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
18191823

18201824
if (!keys) {
18211825
keys = PyList_New(0);
1826+
if (!keys) {
1827+
return -1;
1828+
}
18221829
}
18231830
else if (PyObject_TypeCheck(keys, &FAMType)) {
18241831
// Use `keys` as old, `self` as new, and fill from old to new. This returns the same error codes as this function.
@@ -1831,6 +1838,8 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
18311838
return -1;
18321839
}
18331840
int array_t = PyArray_TYPE(a);
1841+
keys_size = PyArray_SIZE(a);
1842+
18341843
if (cls != &AMType &&
18351844
(PyTypeNum_ISINTEGER(array_t) // signed and unsigned
18361845
|| PyTypeNum_ISFLOAT(array_t)
@@ -1843,25 +1852,26 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
18431852
keys_array_type = at_to_kat(array_t);
18441853
Py_INCREF(keys);
18451854
}
1846-
else { // if an AutoMap or an array that we do not custom-hash, we create a list
1855+
else { // if an AutoMap or an array that we do not handle, create a list
18471856
if (array_t == NPY_DATETIME || array_t == NPY_TIMEDELTA){
18481857
keys = PySequence_List(keys); // force scalars
18491858
}
18501859
else {
18511860
keys = PyArray_ToList(a); // converts to objs
18521861
}
1862+
if (!keys) {
1863+
return -1;
1864+
}
18531865
}
1854-
keys_size = PyArray_SIZE(a);
18551866
}
18561867
else { // assume an arbitrary iterable
18571868
keys = PySequence_List(keys);
1869+
if (!keys) {
1870+
return -1;
1871+
}
18581872
keys_size = PyList_GET_SIZE(keys);
18591873
}
18601874

1861-
if (!keys) {
1862-
return -1;
1863-
}
1864-
18651875
fam->keys = keys;
18661876
fam->keys_array_type = keys_array_type;
18671877
fam->keys_size = keys_size;
@@ -1870,7 +1880,6 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
18701880

18711881
// NOTE: on itialization, grow_table() does not use keys
18721882
if (grow_table(fam, keys_size)) {
1873-
// assume `fam->keys` will be decrefed by the caller
18741883
return -1;
18751884
}
18761885
Py_ssize_t i = 0;

test/test_unit.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
from arraymap import FrozenAutoMap
99
from arraymap import NonUniqueError
1010

11+
1112
def test_version():
1213
import arraymap
14+
1315
assert isinstance(arraymap.__version__, str)
1416

1517

@@ -41,6 +43,20 @@ def test_fam_contains():
4143
# ------------------------------------------------------------------------------
4244

4345

46+
def test_fam_constructor_a():
47+
with pytest.raises(ZeroDivisionError):
48+
fam = FrozenAutoMap((x / 0 for x in range(3)))
49+
50+
51+
def test_fam_constructor_b():
52+
fam1 = FrozenAutoMap(range(3))
53+
fam2 = FrozenAutoMap(fam1)
54+
assert list(fam2), [0, 1, 2]
55+
56+
57+
# ------------------------------------------------------------------------------
58+
59+
4460
def test_fam_constructor_array_int_a1():
4561
a1 = np.array((10, 20, 30), dtype=np.int64)
4662
with pytest.raises(TypeError):

0 commit comments

Comments
 (0)