8000 MAINT: Move np.dtype.name.__get__ to python · numpy/numpy@5cba7ca · GitHub
[go: up one dir, main page]

Skip to content

Commit 5cba7ca

Browse files
committed
MAINT: Move np.dtype.name.__get__ to python
This shares a lot of code with part of `dtype.__repr__`, and it's helpful to get it all in one place. This fixes possible but unlikely segfaults if `PyUString_ConcatAndDel` fails.
1 parent 371cc4d commit 5cba7ca

File tree

2 files changed

+40
-66
lines changed

2 files changed

+40
-66
lines changed

numpy/core/_dtype.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,14 @@ def _byte_order_str(dtype):
161161

162162

163163
def _datetime_metadata_str(dtype):
164-
# This is a hack since the data is not exposed to python in any other way
165-
return dtype.name[dtype.name.rfind('['):]
164+
# TODO: this duplicates the C append_metastr_to_string
165+
unit, count = np.datetime_data(dtype)
166+
if unit == 'generic':
167+
return ''
168+
elif count == 1:
169+
return '[{}]'.format(unit)
170+
else:
171+
return '[{}{}]'.format(count, unit)
166172

167173

168174
def _struct_dict_str(dtype, includealignedflag):
@@ -292,3 +298,26 @@ def _struct_repr(dtype):
292298
return s
293299

294300

301+
def _name_get(dtype):
302+
# provides dtype.name.__get__
303+
304+
if dtype.isbuiltin == 2:
305+
# user dtypes don't promise to do anything special
306+
return dtype.type.__name__
307+
308+
# Builtin classes are documented as returning a "bit name"
309+
name = dtype.type.__name__
310+
311+
# handle bool_, str_, etc
312+
if name[-1] == '_':
313+
name = name[:-1]
314+
315+
# append bit counts to str, unicode, and void
316+
if np.issubdtype(dtype, np.flexible) and not _isunsized(dtype):
317+
name += "{}".format(dtype.itemsize * 8)
318+
319+
# append metadata to datetimes
320+
elif dtype.type in (np.datetime64, np.timedelta64):
321+
name += _datetime_metadata_str(dtype)
322+
323+
return name

numpy/core/src/multiarray/descriptor.c

Lines changed: 9 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,72 +1859,17 @@ arraydescr_protocol_typestr_get(PyArray_Descr *self)
18591859
}
18601860

18611861
static PyObject *
1862-
arraydescr_typename_get(PyArray_Descr *self)
1862+
arraydescr_name_get(PyArray_Descr *self)
18631863
{
1864-
static const char np_prefix[] = "numpy.";
1865-
const int np_prefix_len = sizeof(np_prefix) - 1;
1866-
PyTypeObject *typeobj = self->typeobj;
1864+
/* let python handle this */
1865+
PyObject *_numpy_dtype;
18671866
PyObject *res;
1868-
char *s;
1869-
int len;
1870-
int prefix_len;
1871-
int suffix_len;
1872-
1873-
if (PyTypeNum_ISUSERDEF(self->type_num)) {
1874-
s = strrchr(typeobj->tp_name, '.');
1875-
if (s == NULL) {
1876-
res = PyUString_FromString(typeobj->tp_name);
1877-
}
1878-
else {
1879-
res = PyUString_FromStringAndSize(s + 1, strlen(s) - 1);
1880-
}
1881-
return res;
1882-
}
1883-
else {
1884-
/*
1885-
* NumPy type or subclass
1886-
*
1887-
* res is derived from typeobj->tp_name with the following rules:
1888-
* - if starts with "numpy.", that prefix is removed
1889-
* - if ends with "_", that suffix is removed
1890-
*/
1891-
len = strlen(typeobj->tp_name);
1892-
1893-
if (! strncmp(typeobj->tp_name, np_prefix, np_prefix_len)) {
1894-
prefix_len = np_prefix_len;
1895-
}
1896-
else {
1897-
prefix_len = 0;
1898-
}
1899-
1900-
if (typeobj->tp_name[len - 1] == '_') {
1901-
suffix_len = 1;
1902-
}
1903-
else {
1904-
suffix_len = 0;
1905-
}
1906-
1907-
len -= prefix_len;
1908-
len -= suffix_len;
1909-
res = PyUString_FromStringAndSize(typeobj->tp_name+prefix_len, len);
1910-
}
1911-
if (PyTypeNum_ISFLEXIBLE(self->type_num) && !PyDataType_ISUNSIZED(self)) {
1912-
PyObject *p;
1913-
p = PyUString_FromFormat("%d", self->elsize * 8);
1914-
PyUString_ConcatAndDel(&res, p);
1915-
}
1916-
if (PyDataType_ISDATETIME(self)) {
1917-
PyArray_DatetimeMetaData *meta;
1918-
1919-
meta = get_datetime_metadata_from_dtype(self);
1920-
if (meta == NULL) {
1921-
Py_DECREF(res);
1922-
return NULL;
1923-
}
1924-
1925-
res = append_metastr_to_string(meta, 0, res);
1867+
_numpy_dtype = PyImport_ImportModule("numpy.core._dtype");
1868+
if (_numpy_dtype == NULL) {
1869+
return NULL;
19261870
}
1927-
1871+
res = PyObject_CallMethod(_numpy_dtype, "_name_get", "O", self);
1872+
Py_DECREF(_numpy_dtype);
19281873
return res;
19291874
}
19301875

@@ -2218,7 +2163,7 @@ static PyGetSetDef arraydescr_getsets[] = {
22182163
(getter)arraydescr_protocol_typestr_get,
22192164
NULL, NULL, NULL},
22202165
{"name",
2221-
(getter)arraydescr_typename_get,
2166+
(getter)arraydescr_name_get,
22222167
NULL, NULL, NULL},
22232168
{"base",
22242169
(getter)arraydescr_base_get,

0 commit comments

Comments
 (0)
0