From 95c039ed6c08ab5f057c0d8cb84e309707a77097 Mon Sep 17 00:00:00 2001 From: Benjamin Maier Date: Tue, 11 Feb 2020 15:21:45 +0100 Subject: [PATCH] Fix legacy setting of python dicts where not set keys are set to zero when transforming to list --- core/src/control/python_config.tpp | 2 +- core/src/utility/python_utility_convert.tpp | 71 +++++++++++++++++++++ testing/unit_testing/src/1_rank/poisson.cpp | 2 +- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/core/src/control/python_config.tpp b/core/src/control/python_config.tpp index 00e7dc051..5cc24ed16 100644 --- a/core/src/control/python_config.tpp +++ b/core/src/control/python_config.tpp @@ -83,7 +83,7 @@ getOptionVector(std::string keyString, int nEntries, std::vector &values) con values.resize(nEntries, T{0.0}); return; } - values = PythonUtility::convertFromPython>::get(pyLocalValues); + values = PythonUtility::convertFromPython>::get(pyLocalValues, T{0.0}); if (values.size() < nEntries) { LOG(WARNING) << pathString << "[\"" << keyString << "\"]: given vector has only " << values.size() << " entries, fill with 0's to size " diff --git a/core/src/utility/python_utility_convert.tpp b/core/src/utility/python_utility_convert.tpp index e92c70b01..aca224374 100644 --- a/core/src/utility/python_utility_convert.tpp +++ b/core/src/utility/python_utility_convert.tpp @@ -777,6 +777,77 @@ struct PythonUtility::convertFromPython> return defaultValue; } + //! convert a python object to its corresponding c type, with type checking + static std::vector get(PyObject *object, ValueType defaultValue) + { + // start critical section for python API calls + // PythonUtility::GlobalInterpreterLock lock; + + std::vector result; + assert(object != nullptr); + if (PyList_Check(object)) + { + int nEntries = (int)PyList_Size(object); + result.resize(nEntries); + + for (int i = 0; i < nEntries; i++) + { + result[i] = PythonUtility::convertFromPython::get(PyList_GetItem(object, (Py_ssize_t)i)); + } + return result; + } + else if (PyTuple_Check(object)) + { + int nEntries = PyTuple_Size(object); + result.resize(nEntries + 1); + + for (int i = 0; i < nEntries; i++) + { + result[i] = PythonUtility::convertFromPython::get(PyTuple_GetItem(object, (Py_ssize_t)i)); + } + return result; + } + else if (PyDict_Check(object)) + { + PyObject *itemList = PyDict_Items(object); + + for (int itemListIndex = 0; itemListIndex < PyList_Size(itemList); itemListIndex++) + { + PyObject *tuple = PyList_GetItem(itemList, (Py_ssize_t)itemListIndex); + PyObject *pyKey = PyTuple_GetItem(tuple, (Py_ssize_t)0); + PyObject *pyValue = PyTuple_GetItem(tuple, (Py_ssize_t)1); + + int key = convertFromPython::get(pyKey); + + if (key >= 0) + { + if (key >= result.size()) + result.resize(key + 1, defaultValue); + result[key] = convertFromPython::get(pyValue); + } + } + return result; + } + else if (object == Py_None) + { + // object is None, this means empty list + return result; + } + else + { + ValueType valueDouble = PythonUtility::convertFromPython::get(object); + + result.resize(1); + result[0] = valueDouble; + + return result; + } + +#ifndef __PGI + return std::vector(); +#endif + } + //! convert a python object to its corresponding c type, with type checking, if conversion is not possible use trivial default value (0 or 0.0 or "") static std::vector get(PyObject *object) { diff --git a/testing/unit_testing/src/1_rank/poisson.cpp b/testing/unit_testing/src/1_rank/poisson.cpp index 9f46a86ad..6a927f72c 100644 --- a/testing/unit_testing/src/1_rank/poisson.cpp +++ b/testing/unit_testing/src/1_rank/poisson.cpp @@ -505,7 +505,7 @@ config = { "FiniteElementMethod" : { "nElements": [4, 5], "physicalExtent": [1.0, 5.0/4.], - "rightHandSide": {4:0, 5:0, 2:5, 7:7.0, 3:9, "8":3, 0:1, 1:4, 6.0:5, "10":0}, + "rightHandSide": {2:5, 7:7.0, 3:9, "8":3, 0:1, 1:4, 6.0:5, "10":0}, "dirichletBoundaryConditions": {0:0}, "relativeTolerance": 1e-15, },