Skip to content

Commit d34c656

Browse files
committed
array creation works
1 parent c6f0262 commit d34c656

File tree

3 files changed

+56
-23
lines changed

3 files changed

+56
-23
lines changed

asciidtype/asciidtype/scalar.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ def __init__(self, value, dtype):
66
self.value = value
77
self.dtype = dtype
88

9+
def __str__(self):
10+
return str(self.value)
11+
912
def __repr__(self):
10-
return f"{self.value}"
13+
return repr(self.value)

asciidtype/asciidtype/src/dtype.c

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,34 @@
44

55
PyTypeObject *ASCIIScalar_Type = NULL;
66

7-
static char *
7+
static PyObject *
88
get_value(PyObject *scalar)
99
{
10+
PyObject *ret_bytes = NULL;
1011
PyTypeObject *scalar_type = Py_TYPE(scalar);
11-
if (scalar_type != ASCIIScalar_Type) {
12-
PyErr_SetString(PyExc_TypeError,
13-
"Can only store ASCIIScalar in a ASCIIDType array.");
14-
return NULL;
12+
if (scalar_type == &PyUnicode_Type) {
13+
// attempt to decode as ASCII
14+
ret_bytes = PyUnicode_AsASCIIString(scalar);
15+
if (ret_bytes == NULL) {
16+
PyErr_SetString(
17+
PyExc_TypeError,
18+
"Can only store ASCII text in a ASCIIDType array.");
19+
}
1520
}
16-
17-
PyObject *value = PyObject_GetAttrString(scalar, "value");
18-
if (value == NULL) {
21+
else if (scalar_type != ASCIIScalar_Type) {
22+
PyErr_SetString(PyExc_TypeError,
23+
"Can only store ASCII text in a ASCIIDType array.");
1924
return NULL;
2025
}
21-
PyObject *res_bytes = PyUnicode_AsASCIIString(value);
22-
Py_DECREF(value);
23-
char *res = PyBytes_AsString(res_bytes);
24-
Py_DECREF(res_bytes);
25-
if (res == NULL) {
26-
return NULL;
26+
else {
27+
PyObject *value = PyObject_GetAttrString(scalar, "value");
28+
if (value == NULL) {
29+
return NULL;
30+
}
31+
ret_bytes = PyUnicode_AsASCIIString(value);
32+
Py_DECREF(value);
2733
}
28-
return res;
34+
return ret_bytes;
2935
}
3036

3137
/*
@@ -100,24 +106,39 @@ ascii_discover_descriptor_from_pyobject(PyArray_DTypeMeta *NPY_UNUSED(cls),
100106
static int
101107
asciidtype_setitem(ASCIIDTypeObject *descr, PyObject *obj, char *dataptr)
102108
{
103-
char *value = get_value(obj);
109+
PyObject *value = get_value(obj);
104110
if (value == NULL) {
105111
return -1;
106112
}
107113

108-
memcpy(dataptr, value, descr->size * sizeof(char)); // NOLINT
114+
Py_ssize_t len = PyBytes_Size(value);
115+
116+
size_t copysize;
117+
118+
if (len > descr->size) {
119+
copysize = descr->size;
120+
}
121+
else {
122+
copysize = len;
123+
}
124+
125+
char *char_value = PyBytes_AsString(value);
126+
127+
memcpy(dataptr, char_value, copysize * sizeof(char)); // NOLINT
128+
129+
for (int i = copysize; i < descr->size; i++) {
130+
dataptr[i] = '\0';
131+
}
132+
133+
Py_DECREF(value);
109134

110135
return 0;
111136
}
112137

113138
static PyObject *
114139
asciidtype_getitem(ASCIIDTypeObject *descr, char *dataptr)
115140
{
116-
char *val = NULL;
117-
/* get the value */
118-
memcpy(val, dataptr, descr->size * sizeof(char)); // NOLINT
119-
120-
PyObject *val_obj = PyUnicode_FromStringAndSize(val, descr->size);
141+
PyObject *val_obj = PyUnicode_FromString(dataptr);
121142
if (val_obj == NULL) {
122143
return NULL;
123144
}

asciidtype/tests/test_asciidtype.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import numpy as np
2+
13
from asciidtype import ASCIIDType, ASCIIScalar
24

35

@@ -9,3 +11,10 @@ def test_dtype_creation():
911
def test_scalar_creation():
1012
dtype = ASCIIDType(7)
1113
ASCIIScalar('string', dtype)
14+
15+
16+
def test_creation_with_explicit_dtype():
17+
dtype = ASCIIDType(7)
18+
arr = np.array(["hello", "this", "is", "an", "array"], dtype=dtype)
19+
assert repr(arr) == (
20+
"array(['hello', 'this', 'is', 'an', 'array'], dtype=ASCIIDType(7))")

0 commit comments

Comments
 (0)