[Python] Test that AnyValue held types are correct

Remove tests for unhandled cases that are now handled
This commit is contained in:
Ray Speth
2021-04-20 14:59:41 -04:00
committed by Bryan W. Weber
parent ce57ed3166
commit 8de5bb4dc5
2 changed files with 51 additions and 63 deletions

View File

@@ -8,28 +8,33 @@ from cantera._cantera import _py_to_any_to_py
class TestPyToAnyValue(utilities.CanteraTest):
def check_conversion(self, value):
out = _py_to_any_to_py(value)
def check_conversion(self, value, check_type=None):
out, held_type = _py_to_any_to_py(value)
self.assertEqual(out, value)
if check_type is not None:
self.assertEqual(held_type, check_type)
def check_inexact_conversion(self, value):
out = _py_to_any_to_py(value)
def check_inexact_conversion(self, value, check_type=None):
out, held_type = _py_to_any_to_py(value)
if isinstance(value, np.ndarray):
self.assertEqual(out, value.tolist())
else:
self.assertEqual(out, list(value))
if check_type is not None:
self.assertEqual(held_type, check_type)
def check_raises(self, value, ee, regex):
with self.assertRaisesRegex(ee, regex):
_py_to_any_to_py(value)
def test_none(self):
# None is converted to []
out = _py_to_any_to_py(None)
self.assertEqual(out, [])
out, held_type = _py_to_any_to_py(None)
self.assertEqual(out, None)
self.assertEqual(held_type, "void")
def test_set(self):
self.check_raises({'a', 'b'}, NotImplementedError, "Python set")
# Sets are converted to lists
self.check_inexact_conversion({'a', 'b'}, 'vector<string>')
def test_empty_list(self):
self.check_conversion([])
@@ -41,89 +46,72 @@ class TestPyToAnyValue(utilities.CanteraTest):
self.check_conversion({})
def test_scalar_string(self):
self.check_conversion('spam')
self.check_conversion('spam', 'string')
def test_scalar_int(self):
self.check_conversion(3)
self.check_conversion(3, 'long int')
def test_scalar_float(self):
self.check_conversion(3.1415)
self.check_conversion(3.1415, 'double')
def test_scalar_bool(self):
self.check_conversion(True)
self.check_conversion(True, 'bool')
def test_list_string(self):
self.check_conversion(['spam', 'eggs'])
self.check_conversion(['spam', 'eggs'], 'vector<string>')
def test_list_int(self):
self.check_conversion([1, 2, 3])
self.check_conversion([1, 2, 3], 'vector<long int>')
def test_list_float(self):
self.check_conversion([1., 2., 3.])
self.check_conversion([1., 2., 3.], 'vector<double>')
def test_list_bool(self):
self.check_conversion([True, False])
self.check_conversion([True, False], 'vector<bool>')
def test_list_various(self):
self.check_conversion([True, 'spam', 3, 4., {'foo': 'bar'}])
self.check_conversion([True, 'spam', 3, 4., {'foo': 'bar'}],
'vector<AnyValue>')
def test_tuple(self):
self.check_inexact_conversion((True, 'spam', 3, 4.))
self.check_inexact_conversion((True, 'spam', 3, 4.), 'vector<AnyValue>')
def test_ndarray1(self):
self.check_inexact_conversion(np.random.randn(10))
self.check_inexact_conversion(np.random.randn(10), 'vector<double>')
def test_ndarray2(self):
self.check_inexact_conversion(np.random.randn(3, 2))
self.check_inexact_conversion(np.random.randn(3, 2), 'vector<vector<double>>')
def test_ndarray3(self):
self.check_raises(np.random.randn(3, 2, 4),
NotImplementedError, 'cannot process float')
# Each inner AnyValue holds a vector<vector<double>>
self.check_inexact_conversion(np.random.randn(3, 2, 4), 'vector<AnyValue>')
def test_nested_string(self):
self.check_conversion([['spam', 'eggs'], ['foo', 'bar']])
self.check_conversion([['spam', 'eggs'], ['foo', 'bar']],
'vector<vector<string>>')
def test_nested_int(self):
self.check_conversion([[1, 2, 3], [4, 5, 6]])
self.check_conversion([[1, 2, 3], [4, 5, 6]], 'vector<vector<long int>>')
def test_nested_float(self):
self.check_conversion([[1., 2., 3.], [4., 5., 6.]])
self.check_conversion([[1., 2., 3.], [4., 5., 6.]], 'vector<vector<double>>')
def test_nested_bool(self):
self.check_conversion([[True, False], [False, True]])
def test_raises_string(self):
self.check_raises([[['spam', 'eggs'], ['foo', 'bar']]],
NotImplementedError, 'cannot process string')
def test_raises_named(self):
self.check_raises({'abcd': [[['spam', 'eggs'], ['foo', 'bar']]]},
NotImplementedError, "with key 'abcd'")
def test_raises_int(self):
self.check_raises([[[1, 2, 3], [4, 5, 6]]],
NotImplementedError, 'cannot process integer')
def test_raises_float(self):
self.check_raises([[[1., 2., 3.], [4., 5., 6.]]],
NotImplementedError, 'cannot process float')
def test_raises_bool(self):
self.check_raises([[[True, False], [False, True]]],
NotImplementedError, 'cannot process boolean')
self.check_conversion([[True, False], [False, True]], 'vector<vector<bool>>')
def test_multi_dict(self):
vv = [{'a': [['spam', 'eggs'], ['foo', 'bar']], 'b': {'c': 4}}, {'d': 3}]
self.check_conversion(vv)
def test_inhomogeneous(self):
self.check_raises([[1, 2], ['a', 'b']], NotImplementedError, 'inhomogeneous')
def test_ragged(self):
self.check_raises([[1, 2, 3], [4]], NotImplementedError, 'ragged')
self.check_conversion(vv, 'vector<AnyMap>')
def test_dict(self):
self.check_conversion({'a': 1, 'b': 2., 'c': 'eggs', 'd': True})
self.check_conversion({'a': 1, 'b': 2., 'c': 'eggs', 'd': True}, 'AnyMap')
def test_nested_dict(self):
self.check_conversion({'a': 1, 'b': 2., 'c': {'d': 'eggs'}})
self.check_conversion({'a': 1, 'b': 2., 'c': {'d': 'eggs'}}, 'AnyMap')
def test_unconvertible(self):
class Foo: pass
self.check_raises(Foo(), ct.CanteraError, "Unable to convert")
def test_unconvertible2(self):
self.check_raises([3+4j, 1-2j], ct.CanteraError, "Unable to convert")

View File

@@ -130,7 +130,7 @@ cdef anymap_to_dict(CxxAnyMap& m):
return {pystr(item.first): anyvalue_to_python(item.first, item.second)
for item in m.ordered()}
cdef CxxAnyMap dict_to_anymap(data):
cdef CxxAnyMap dict_to_anymap(data) except *:
cdef CxxAnyMap m
for k, v in data.items():
m[stringify(k)] = python_to_anyvalue(v, k)
@@ -229,21 +229,21 @@ cdef CxxAnyValue python_to_anyvalue(item, name=None) except *:
elif item is None:
pass # None corresponds to "empty" AnyValue
elif name is not None:
raise CanteraError("Unable to convert item of type '{}'"
" with key '{}' to AnyValue".format(type(item), name))
raise CanteraError("Unable to convert item of type {!r}"
" with key {!r} to AnyValue".format(type(item), name))
else:
raise CanteraError("Unable to convert item of type '{}'"
raise CanteraError("Unable to convert item of type {!r}"
" to AnyValue".format(type(item)))
return v
# Helper functions for converting specific types to AnyValue
cdef vector[CxxAnyValue] list_to_anyvalue(data):
cdef vector[CxxAnyValue] list_to_anyvalue(data) except *:
cdef vector[CxxAnyValue] v
v.resize(len(data))
cdef size_t i
for i, item in enumerate(data):
v[i] = python_to_anyvalue(item, "<list item>")
v[i] = python_to_anyvalue(item)
return v
cdef vector[double] list_double_to_anyvalue(data):
@@ -278,7 +278,7 @@ cdef vector[string] list_string_to_anyvalue(data):
v[i] = stringify(item)
return v
cdef vector[CxxAnyMap] list_dict_to_anyvalue(data):
cdef vector[CxxAnyMap] list_dict_to_anyvalue(data) except *:
cdef vector[CxxAnyMap] v
v.resize(len(data))
cdef size_t i
@@ -330,4 +330,4 @@ def _py_to_any_to_py(dd):
# @internal used for testing purposes only
cdef string name = stringify("test")
cdef CxxAnyValue vv = python_to_anyvalue(dd)
return anyvalue_to_python(name, vv)
return anyvalue_to_python(name, vv), pystr(vv.type_str())