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

Commit fd0b79d

Browse files
authored
Merge pull request #34 from static-frame/33/np2
NumPy 2 support
2 parents 9af0392 + 11d1f63 commit fd0b79d

10 files changed

+26
-48
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ jobs:
4848
matrix:
4949
os: ${{ fromJson(needs.matrix_config.outputs.matrix_os) }}
5050
python:
51-
- {minor: 8, req_build: 'requirements-build-3_08.txt', req_test: 'requirements-dev-3_08.txt'}
5251
- {minor: 9, req_build: 'requirements-build-3_11.txt', req_test: 'requirements-dev-3_11.txt'}
5352
- {minor: 10, req_build: 'requirements-build-3_11.txt', req_test: 'requirements-dev-3_11.txt'}
5453
- {minor: 11, req_build: 'requirements-build-3_11.txt', req_test: 'requirements-dev-3_11.txt'}
@@ -63,7 +62,7 @@ jobs:
6362
- run: echo '::add-matcher::.github/problem-matchers/msvc.json'
6463
if: startsWith(matrix.os, 'windows-')
6564

66-
- uses: pypa/cibuildwheel@v2.16.2
65+
- uses: pypa/cibuildwheel@v2.18.0
6766
if: matrix.os != 'macos-13-xlarge'
6867
with:
6968
output-dir: dist
@@ -77,7 +76,7 @@ jobs:
7776

7877
- run: pip install pipx
7978
if: matrix.os == 'macos-13-xlarge'
80-
- uses: pypa/cibuildwheel@v2.16.2
79+
- uses: pypa/cibuildwheel@v2.18.0
8180
if: matrix.os == 'macos-13-xlarge'
8281
with:
8382
output-dir: dist

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ Dependencies
2828

2929
ArrayMap requires the following:
3030

31-
- Python >= 3.8
32-
- NumPy >= 1.18.5
31+
- Python >= 3.9
32+
- NumPy >= 1.19.5
3333

3434

3535

arraymap.c

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ typedef enum KeysArrayType{
8686
NPY_DATETIMEUNIT
8787
dt_unit_from_array(PyArrayObject* a) {
8888
// This is based on get_datetime_metadata_from_dtype in the NumPy source, but that function is private. This does not check that the dytpe is of the appropriate type.
89-
PyArray_DatetimeMetaData* dma = &(((PyArray_DatetimeDTypeMetaData *)PyArray_DESCR(a)->c_metadata)->meta);
89+
PyArray_Descr* dt = PyArray_DESCR(a); // borrowed ref
90+
PyArray_DatetimeMetaData* dma = &(((PyArray_DatetimeDTypeMetaData *)PyDataType_C_METADATA(dt))->meta);
9091
return dma->base;
9192
}
9293

@@ -451,7 +452,6 @@ typedef struct FAMIObject {
451452
Py_ssize_t index; // current index state, mutated in-place
452453
} FAMIObject;
453454

454-
455455
static void
456456
fami_dealloc(FAMIObject *self)
457457
{
@@ -550,7 +550,6 @@ static PyTypeObject FAMIType = {
550550
.tp_name = "arraymap.FrozenAutoMapIterator",
551551
};
552552

553-
554553
static PyObject *
555554
fami_new(FAMObject *fam, ViewKind kind, bool reversed)
556555
{
@@ -601,27 +600,23 @@ name(PyObject *left, PyObject *right) \
601600
return result; \
602601
}
603602

604-
605603
FAMV_SET_OP(famv_and, And)
606604
FAMV_SET_OP(famv_or, Or)
607605
FAMV_SET_OP(famv_subtract, Subtract)
608606
FAMV_SET_OP(famv_xor, Xor)
609607

610608
# undef FAMV_SET_OP
611609

612-
613610
static PyNumberMethods famv_as_number = {
614611
.nb_and = (binaryfunc) famv_and,
615612
.nb_or = (binaryfunc) famv_or,
616613
.nb_subtract = (binaryfunc) famv_subtract,
617614
.nb_xor = (binaryfunc) famv_xor,
618615
};
619616

620-
621617
static int fam_contains(FAMObject *, PyObject *);
622618
static PyObject *famv_fami_new(FAMVObject *);
623619

624-
625620
static int
626621
famv_contains(FAMVObject *self, PyObject *other)
627622
{
@@ -637,41 +632,35 @@ famv_contains(FAMVObject *self, PyObject *other)
637632
return result;
638633
}
639634

640-
641635
static PySequenceMethods famv_as_sequence = {
642636
.sq_contains = (objobjproc) famv_contains,
643637
};
644638

645-
646639
static void
647640
famv_dealloc(FAMVObject *self)
648641
{
649642
Py_DECREF(self->fam);
650643
PyObject_Del((PyObject *)self);
651644
}
652645

653-
654646
static PyObject *
655647
famv_fami_new(FAMVObject *self)
656648
{
657649
return fami_new(self->fam, self->kind, false);
658650
}
659651

660-
661652
static PyObject *
662653
famv_length_hint(FAMVObject *self)
663654
{
664655
return PyLong_FromSsize_t(self->fam->keys_size);
665656
}
666657

667-
668658
static PyObject *
669659
famv_reversed(FAMVObject *self)
670660
{
671661
return fami_new(self->fam, self->kind, true);
672662
}
673663

674-
675664
static PyObject *
676665
famv_isdisjoint(FAMVObject *self, PyObject *other)
677666
{
@@ -684,7 +673,6 @@ famv_isdisjoint(FAMVObject *self, PyObject *other)
684673
return PyBool_FromLong(result);
685674
}
686675

687-
688676
static PyObject *
689677
famv_richcompare(FAMVObject *self, PyObject *other, int op)
690678
{
@@ -703,15 +691,13 @@ famv_richcompare(FAMVObject *self, PyObject *other, int op)
703691
return result;
704692
}
705693

706-
707694
static PyMethodDef famv_methods[] = {
708695
{"__length_hint__", (PyCFunction) famv_length_hint, METH_NOARGS, NULL},
709696
{"__reversed__", (PyCFunction) famv_reversed, METH_NOARGS, NULL},
710697
{"isdisjoint", (PyCFunction) famv_isdisjoint, METH_O, NULL},
711698
{NULL},
712699
};
713700

714-
715701
static PyTypeObject FAMVType = {
716702
PyVarObject_HEAD_INIT(NULL, 0)
717703
.tp_as_number = &famv_as_number,
@@ -724,7 +710,6 @@ static PyTypeObject FAMVType = {
724710
.tp_richcompare = (richcmpfunc) famv_richcompare,
725711
};
726712

727-
728713
static PyObject *
729714
famv_new(FAMObject *fam, ViewKind kind)
730715
{
@@ -941,7 +926,7 @@ lookup_hash_unicode(
941926
Py_ssize_t table_pos = hash & mask;
942927

943928
PyArrayObject *a = (PyArrayObject *)self->keys;
944-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize / UCS4_SIZE;
929+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a) / UCS4_SIZE;
945930
Py_ssize_t cmp_bytes = Py_MIN(key_size, dt_size) * UCS4_SIZE;
946931

947932
Py_hash_t h = 0;
@@ -983,7 +968,7 @@ lookup_hash_string(
983968
Py_ssize_t table_pos = hash & mask;
984969

985970
PyArrayObject *a = (PyArrayObject *)self->keys;
986-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize;
971+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a);
987972
Py_ssize_t cmp_bytes = Py_MIN(key_size, dt_size);
988973

989974
Py_hash_t h = 0;
@@ -1284,7 +1269,7 @@ lookup_unicode(FAMObject *self, PyObject* key) {
12841269
return -1;
12851270
}
12861271
PyArrayObject *a = (PyArrayObject *)self->keys;
1287-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize / UCS4_SIZE;
1272+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a) / UCS4_SIZE;
12881273
// if the key_size is greater than the dtype size of the array, we know there cannot be a match
12891274
Py_ssize_t k_size = PyUnicode_GetLength(key);
12901275
if (k_size > dt_size) {
@@ -1305,7 +1290,7 @@ lookup_string(FAMObject *self, PyObject* key) {
13051290
return -1;
13061291
}
13071292
PyArrayObject *a = (PyArrayObject *)self->keys;
1308-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize;
1293+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a);
13091294
Py_ssize_t k_size = PyBytes_GET_SIZE(key);
13101295
if (k_size > dt_size) {
13111296
return -1;
@@ -1650,7 +1635,7 @@ copy_to_new(PyTypeObject *cls, FAMObject *self, FAMObject *new)
16501635
new->key_buffer = NULL;
16511636
if (new->keys_array_type == KAT_UNICODE) {
16521637
PyArrayObject *a = (PyArrayObject *)new->keys;
1653-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize / UCS4_SIZE;
1638+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a) / UCS4_SIZE;
16541639
new->key_buffer = (Py_UCS4*)PyMem_Malloc((dt_size+1) * UCS4_SIZE);
16551640
}
16561641

@@ -1831,7 +1816,7 @@ get(FAMObject *self, PyObject *key, PyObject *missing) {
18311816
# define GET_ALL_FLEXIBLE(char_type, get_end_func, lookup_func, hash_func, to_obj_func) \
18321817
{ \
18331818
char_type* v; \
1834-
Py_ssize_t dt_size = PyArray_DESCR(key_array)->elsize / sizeof(char_type);\
1819+
Py_ssize_t dt_size = PyArray_ITEMSIZE(key_array) / sizeof(char_type);\
18351820
Py_ssize_t k_size; \
18361821
for (; i < key_size; i++) { \
18371822
v = (char_type*)PyArray_GETPTR1(key_array, i); \
@@ -2019,7 +2004,7 @@ fam_get_all(FAMObject *self, PyObject *key) {
20192004
# define GET_ANY_FLEXIBLE(char_type, get_end_func, lookup_func, hash_func) \
20202005
{ \
20212006
char_type* v; \
2022-
Py_ssize_t dt_size = PyArray_DESCR(key_array)->elsize / sizeof(char_type);\
2007+
Py_ssize_t dt_size = PyArray_ITEMSIZE(key_array) / sizeof(char_type);\
20232008
Py_ssize_t k_size; \
20242009
for (; i < key_size; i++) { \
20252010
v = (char_type*)PyArray_GETPTR1(key_array, i); \
@@ -2539,13 +2524,13 @@ fam_init(PyObject *self, PyObject *args, PyObject *kwargs)
25392524
break;
25402525
case KAT_UNICODE: {
25412526
// Over allocate buffer by 1 so there is room for null at end. This buffer is only used in lookup();
2542-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize / UCS4_SIZE;
2527+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a) / UCS4_SIZE;
25432528
fam->key_buffer = (Py_UCS4*)PyMem_Malloc((dt_size+1) * UCS4_SIZE);
25442529
INSERT_FLEXIBLE(Py_UCS4, insert_unicode, ucs4_get_end_p);
25452530
break;
25462531
}
25472532
case KAT_STRING: {
2548-
Py_ssize_t dt_size = PyArray_DESCR(a)->elsize;
2533+
Py_ssize_t dt_size = PyArray_ITEMSIZE(a);
25492534
INSERT_FLEXIBLE(char, insert_string, char_get_end_p);
25502535
break;
25512536
}

requirements-build-3_08.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

requirements-build-3_11.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
numpy==1.23.5
1+
numpy==2.0.0

requirements-build-3_12.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
numpy==1.26.2
1+
numpy==2.0.0
22
setuptools==69.*

requirements-dev-3_08.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

requirements-dev-3_11.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
black==22.3.0
1+
black==24.4.2
22
hypothesis==6.70.0
3-
invoke==1.7.1
3+
invoke==2.2.0
44
pytest==7.1.2
55
tzdata==2022.1
6-
numpy==1.23.5
6+
numpy==1.23.5

requirements-dev-3_12.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
black==22.3.0
1+
black==24.4.2
22
hypothesis==6.70.0
33
invoke==2.2.0
44
pytest==7.1.2

setup.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
with open("README.rst") as file:
1010
LONG_DESCRIPTION = file.read()
1111

12+
1213
def get_ext_dir(*components: tp.Iterable[str]) -> tp.Sequence[str]:
1314
dirs = []
1415
for sp in site.getsitepackages():
@@ -17,11 +18,12 @@ def get_ext_dir(*components: tp.Iterable[str]) -> tp.Sequence[str]:
1718
dirs.append(fp)
1819
return dirs
1920

21+
2022
extension = setuptools.Extension(
2123
"arraymap",
2224
["arraymap.c"],
23-
include_dirs=get_ext_dir("numpy", "core", "include"),
24-
library_dirs=get_ext_dir("numpy", "core", "lib"),
25+
include_dirs=get_ext_dir("numpy", "_core", "include"),
26+
library_dirs=get_ext_dir("numpy", "_core", "lib"),
2527
define_macros=[("AM_VERSION", AM_VERSION)],
2628
libraries=["npymath"],
2729
)
@@ -31,7 +33,7 @@ def get_ext_dir(*components: tp.Iterable[str]) -> tp.Sequence[str]:
3133
version=AM_VERSION,
3234
description="Dictionary-like lookup from NumPy array values to their integer positions",
3335
long_description=LONG_DESCRIPTION,
34-
python_requires=">=3.8.0",
36+
python_requires=">=3.9",
3537
install_requires=["numpy>=1.19.5"],
3638
url="https://github.com/static-frame/arraymap",
3739
author="Christopher Ariza, Brandt Bucher",
@@ -44,7 +46,6 @@ def get_ext_dir(*components: tp.Iterable[str]) -> tp.Sequence[str]:
4446
"Operating System :: MacOS :: MacOS X",
4547
"Operating System :: Microsoft :: Windows",
4648
"Operating System :: POSIX",
47-
"Programming Language :: Python :: 3.8",
4849
"Programming Language :: Python :: 3.9",
4950
"Programming Language :: Python :: 3.10",
5051
"Programming Language :: Python :: 3.11",

0 commit comments

Comments
 (0)