diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2020-04-17 14:30:49 +0100 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2020-04-17 16:38:03 +0100 |
commit | 9dac4d51713f14ab013ac68b9d72ee430d1f89e2 (patch) | |
tree | f203faf85246fea716646722cfd6fe0b360fb698 /numpy | |
parent | 52c9e6f2e3e72081576fc7f629fe3eb0c67b143b (diff) | |
download | numpy-9dac4d51713f14ab013ac68b9d72ee430d1f89e2.tar.gz |
TST: Add tests for the conversion utilities
This way we can test them without having to try and guess their behavior from the functions that use them.
This also makes a bit more apparently the inconsistencies between them.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/_multiarray_tests.c.src | 129 | ||||
-rw-r--r-- | numpy/core/tests/test_conversion_utils.py | 124 |
2 files changed, 253 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src index ec2928c8f..318559885 100644 --- a/numpy/core/src/multiarray/_multiarray_tests.c.src +++ b/numpy/core/src/multiarray/_multiarray_tests.c.src @@ -1938,6 +1938,114 @@ getset_numericops(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args)) return ret; } +static PyObject * +run_byteorder_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + char byteorder; + if (!PyArg_ParseTuple(args, "O&", PyArray_ByteorderConverter, &byteorder)) { + return NULL; + } + switch (byteorder) { + case NPY_BIG: return PyUnicode_FromString("NPY_BIG"); + case NPY_LITTLE: return PyUnicode_FromString("NPY_LITTLE"); + case NPY_NATIVE: return PyUnicode_FromString("NPY_NATIVE"); + case NPY_SWAP: return PyUnicode_FromString("NPY_SWAP"); + case NPY_IGNORE: return PyUnicode_FromString("NPY_IGNORE"); + } + return PyInt_FromLong(byteorder); +} + +static PyObject * +run_sortkind_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + NPY_SORTKIND kind; + if (!PyArg_ParseTuple(args, "O&", PyArray_SortkindConverter, &kind)) { + return NULL; + } + switch (kind) { + case NPY_QUICKSORT: return PyUnicode_FromString("NPY_QUICKSORT"); + case NPY_HEAPSORT: return PyUnicode_FromString("NPY_HEAPSORT"); + case NPY_STABLESORT: return PyUnicode_FromString("NPY_STABLESORT"); + } + return PyInt_FromLong(kind); +} + +static PyObject * +run_selectkind_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + NPY_SELECTKIND kind; + if (!PyArg_ParseTuple(args, "O&", PyArray_SelectkindConverter, &kind)) { + return NULL; + } + switch (kind) { + case NPY_INTROSELECT: return PyUnicode_FromString("NPY_INTROSELECT"); + } + return PyInt_FromLong(kind); +} + +static PyObject * +run_searchside_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + NPY_SEARCHSIDE side; + if (!PyArg_ParseTuple(args, "O&", PyArray_SearchsideConverter, &side)) { + return NULL; + } + switch (side) { + case NPY_SEARCHLEFT: return PyUnicode_FromString("NPY_SEARCHLEFT"); + case NPY_SEARCHRIGHT: return PyUnicode_FromString("NPY_SEARCHRIGHT"); + } + return PyInt_FromLong(side); +} + +static PyObject * +run_order_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + NPY_ORDER order; + if (!PyArg_ParseTuple(args, "O&", PyArray_OrderConverter, &order)) { + return NULL; + } + switch (order) { + case NPY_ANYORDER: return PyUnicode_FromString("NPY_ANYORDER"); + case NPY_CORDER: return PyUnicode_FromString("NPY_CORDER"); + case NPY_FORTRANORDER: return PyUnicode_FromString("NPY_FORTRANORDER"); + case NPY_KEEPORDER: return PyUnicode_FromString("NPY_KEEPORDER"); + } + return PyInt_FromLong(order); +} + +static PyObject * +run_clipmode_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + NPY_CLIPMODE mode; + if (!PyArg_ParseTuple(args, "O&", PyArray_ClipmodeConverter, &mode)) { + return NULL; + } + switch (mode) { + case NPY_CLIP: return PyUnicode_FromString("NPY_CLIP"); + case NPY_WRAP: return PyUnicode_FromString("NPY_WRAP"); + case NPY_RAISE: return PyUnicode_FromString("NPY_RAISE"); + } + return PyInt_FromLong(mode); +} + +static PyObject * +run_casting_converter(PyObject* NPY_UNUSED(self), PyObject *args) +{ + NPY_CASTING casting; + if (!PyArg_ParseTuple(args, "O&", PyArray_CastingConverter, &casting)) { + return NULL; + } + switch (casting) { + case NPY_NO_CASTING: return PyUnicode_FromString("NPY_NO_CASTING"); + case NPY_EQUIV_CASTING: return PyUnicode_FromString("NPY_EQUIV_CASTING"); + case NPY_SAFE_CASTING: return PyUnicode_FromString("NPY_SAFE_CASTING"); + case NPY_SAME_KIND_CASTING: return PyUnicode_FromString("NPY_SAME_KIND_CASTING"); + case NPY_UNSAFE_CASTING: return PyUnicode_FromString("NPY_UNSAFE_CASTING"); + } + return PyInt_FromLong(casting); +} + + static PyMethodDef Multiarray_TestsMethods[] = { {"IsPythonScalar", IsPythonScalar, @@ -2089,6 +2197,27 @@ static PyMethodDef Multiarray_TestsMethods[] = { {"get_struct_alignments", get_struct_alignments, METH_VARARGS, NULL}, + {"run_byteorder_converter", + run_byteorder_converter, + METH_VARARGS, NULL}, + {"run_sortkind_converter", + run_sortkind_converter, + METH_VARARGS, NULL}, + {"run_selectkind_converter", + run_selectkind_converter, + METH_VARARGS, NULL}, + {"run_searchside_converter", + run_searchside_converter, + METH_VARARGS, NULL}, + {"run_order_converter", + run_order_converter, + METH_VARARGS, NULL}, + {"run_clipmode_converter", + run_clipmode_converter, + METH_VARARGS, NULL}, + {"run_casting_converter", + run_casting_converter, + METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/numpy/core/tests/test_conversion_utils.py b/numpy/core/tests/test_conversion_utils.py new file mode 100644 index 000000000..9e80fdcbf --- /dev/null +++ b/numpy/core/tests/test_conversion_utils.py @@ -0,0 +1,124 @@ +""" +Tests for numpy/core/src/multiarray/conversion_utils.c +""" +import pytest + +import numpy as np +import numpy.core._multiarray_tests as mt + + +class StringConverterTestCase: + allow_bytes = True + case_insensitive = True + exact_match = False + + def _check(self, val, expected): + assert self.conv(val) == expected + + if self.allow_bytes: + assert self.conv(val.encode('ascii')) == expected + else: + with pytest.raises(TypeError): + self.conv(val.encode('ascii')) + + if len(val) != 1: + if self.exact_match: + with pytest.raises(ValueError): + self.conv(val[:1]) + else: + assert self.conv(val[:1]) == expected + + if self.case_insensitive: + if val != val.lower(): + assert self.conv(val.lower()) == expected + if val != val.upper(): + assert self.conv(val.upper()) == expected + else: + if val != val.lower(): + with pytest.raises(ValueError): + self.conv(val.lower()) + if val != val.upper(): + with pytest.raises(ValueError): + self.conv(val.upper()) + + +class TestByteorderConverter(StringConverterTestCase): + """ Tests of PyArray_ByteorderConverter """ + conv = mt.run_byteorder_converter + def test_valid(self): + for s in ['big', '>']: + self._check(s, 'NPY_BIG') + for s in ['little', '<']: + self._check(s, 'NPY_LITTLE') + for s in ['native', '=']: + self._check(s, 'NPY_NATIVE') + for s in ['ignore', '|']: + self._check(s, 'NPY_IGNORE') + for s in ['swap']: + self._check(s, 'NPY_SWAP') + + +class TestSortkindConverter(StringConverterTestCase): + """ Tests of PyArray_SortkindConverter """ + conv = mt.run_sortkind_converter + def test_valid(self): + self._check('quick', 'NPY_QUICKSORT') + self._check('heap', 'NPY_HEAPSORT') + self._check('merge', 'NPY_STABLESORT') # alias + self._check('stable', 'NPY_STABLESORT') + + +class TestSelectkindConverter(StringConverterTestCase): + """ Tests of PyArray_SelectkindConverter """ + conv = mt.run_selectkind_converter + case_insensitive = False + exact_match = True + + def test_valid(self): + self._check('introselect', 'NPY_INTROSELECT') + + +class TestSearchsideConverter(StringConverterTestCase): + """ Tests of PyArray_SearchsideConverter """ + conv = mt.run_searchside_converter + def test_valid(self): + self._check('left', 'NPY_SEARCHLEFT') + self._check('right', 'NPY_SEARCHRIGHT') + + +class TestOrderConverter(StringConverterTestCase): + """ Tests of PyArray_OrderConverter """ + conv = mt.run_order_converter + def test_valid(self): + self._check('c', 'NPY_CORDER') + self._check('f', 'NPY_FORTRANORDER') + self._check('a', 'NPY_ANYORDER') + self._check('k', 'NPY_KEEPORDER') + + +class TestClipmodeConverter(StringConverterTestCase): + """ Tests of PyArray_ClipmodeConverter """ + conv = mt.run_clipmode_converter + def test_valid(self): + self._check('clip', 'NPY_CLIP') + self._check('wrap', 'NPY_WRAP') + self._check('raise', 'NPY_RAISE') + + # integer values allowed here + assert self.conv(np.CLIP) == 'NPY_CLIP' + assert self.conv(np.WRAP) == 'NPY_WRAP' + assert self.conv(np.RAISE) == 'NPY_RAISE' + + +class TestCastingConverter(StringConverterTestCase): + """ Tests of PyArray_CastingConverter """ + conv = mt.run_casting_converter + case_insensitive = False + exact_match = True + + def test_valid(self): + self._check("no", "NPY_NO_CASTING") + self._check("equiv", "NPY_EQUIV_CASTING") + self._check("safe", "NPY_SAFE_CASTING") + self._check("same_kind", "NPY_SAME_KIND_CASTING") + self._check("unsafe", "NPY_UNSAFE_CASTING") |