173 PyObject *key(0), *value(0);
178 while (PyDict_Next(dictionary, &pos, &key, &value)) {
181 if (PyLong_Check(value)) {
182 if (PyBool_Check(value)) {
183 params.
add(skey,
bool(PyLong_AsLong(value)));
185 params.
add(skey,
int(PyLong_AsLong(value)));
187 }
else if (PyFloat_Check(value)) {
188 params.
add(skey, PyFloat_AsDouble(value));
189 }
else if (PyUnicode_Check(value)) {
191 }
else if (PyList_Check(value)) {
193 if (PyList_Size(value) > 0) {
194 auto vec0{PyList_GetItem(value, 0)};
196 if (PyLong_Check(vec0)) {
197 std::vector<int> vals;
199 for (
auto j{0}; j < PyList_Size(value); j++)
200 vals.push_back(PyLong_AsLong(PyList_GetItem(value, j)));
202 params.
add(skey, vals);
204 }
else if (PyFloat_Check(vec0)) {
205 std::vector<double> vals;
207 for (
auto j{0}; j < PyList_Size(value); j++)
208 vals.push_back(PyFloat_AsDouble(PyList_GetItem(value, j)));
210 params.
add(skey, vals);
212 }
else if (PyUnicode_Check(vec0)) {
213 std::vector<std::string> vals;
214 for (Py_ssize_t j = 0; j < PyList_Size(value); j++) {
215 PyObject* elem = PyList_GetItem(value, j);
219 params.
add(skey, vals);
220 }
else if (PyList_Check(vec0)) {
222 if (PyList_Size(vec0) > 0) {
223 auto vecvec0{PyList_GetItem(vec0, 0)};
224 if (PyLong_Check(vecvec0)) {
225 std::vector<std::vector<int>> vals;
226 for (
auto j{0}; j < PyList_Size(value); j++) {
227 auto subvec{PyList_GetItem(value, j)};
228 std::vector<int> subvals;
229 for (
auto k{0}; k < PyList_Size(subvec); k++) {
230 subvals.push_back(PyLong_AsLong(PyList_GetItem(subvec, k)));
232 vals.push_back(subvals);
234 params.
add(skey, vals);
235 }
else if (PyFloat_Check(vecvec0)) {
236 std::vector<std::vector<double>> vals;
237 for (
auto j{0}; j < PyList_Size(value); j++) {
238 auto subvec{PyList_GetItem(value, j)};
239 std::vector<double> subvals;
240 for (
auto k{0}; k < PyList_Size(subvec); k++) {
242 PyFloat_AsDouble(PyList_GetItem(subvec, k)));
244 vals.push_back(subvals);
246 params.
add(skey, vals);
247 }
else if (PyUnicode_Check(vecvec0)) {
248 std::vector<std::vector<std::string>> vals;
249 for (
auto j{0}; j < PyList_Size(value); j++) {
250 auto subvec{PyList_GetItem(value, j)};
251 std::vector<std::string> subvals;
252 for (
auto k{0}; k < PyList_Size(subvec); k++) {
253 subvals.push_back(
getPyString(PyList_GetItem(subvec, k)));
255 vals.push_back(subvals);
257 params.
add(skey, vals);
258 }
else if (PyList_Check(vecvec0)) {
259 EXCEPTION_RAISE(
"BadConf",
260 "A python list with dimension greater than 2 is "
264 std::vector<std::vector<framework::config::Parameters>> vals;
265 for (
auto j{0}; j < PyList_Size(value); j++) {
266 auto subvec{PyList_GetItem(value, j)};
267 std::vector<framework::config::Parameters> subvals;
268 for (
auto k{0}; k < PyList_Size(subvec); k++) {
269 subvals.emplace_back(
getMembers(PyList_GetItem(subvec, k)));
271 vals.push_back(subvals);
273 params.
add(skey, vals);
281 std::vector<framework::config::Parameters> vals;
282 for (
auto j{0}; j < PyList_Size(value); ++j) {
283 auto elem{PyList_GetItem(value, j)};
286 params.
add(skey, vals);
302Parameters run(
const std::string& root_object,
const std::string& pythonScript,
303 char* args[],
int nargs) {
309 std::unique_ptr<FILE, int (*)(FILE*)> fp{fopen(pythonScript.c_str(),
"r"),
311 if (fp.get() == NULL) {
312 EXCEPTION_RAISE(
"ConfigDNE",
313 "Passed config script '" + pythonScript +
314 "' is not accessible.\n"
315 " Did you make a typo in the path to the script?\n"
316 " Are you referencing a directory that is not "
317 "mounted to the container?");
326 wchar_t** targs =
new wchar_t*[nargs + 1];
327 targs[0] = Py_DecodeLocale(pythonScript.c_str(), NULL);
328 for (
int i = 0; i < nargs; i++) targs[i + 1] = Py_DecodeLocale(args[i], NULL);
330#if DEV_IMAGE_MAJOR < 5
332 Py_SetProgramName(targs[0]);
342 PySys_SetArgvEx(nargs + 1, targs, 1);
346 PyConfig_InitPythonConfig(&config);
348 config.parse_argv = 0;
355 status = PyConfig_SetString(&config, &config.program_name, targs[0]);
356 if (PyStatus_Exception(status)) {
357 PyConfig_Clear(&config);
358 Py_ExitStatusException(status);
359 EXCEPTION_RAISE(
"PyConfigInit",
360 "Unable to set the program name in the python config.");
363 status = PyConfig_SetArgv(&config, nargs + 1, targs);
364 if (PyStatus_Exception(status)) {
365 PyConfig_Clear(&config);
366 Py_ExitStatusException(status);
367 EXCEPTION_RAISE(
"PyConfigInit",
368 "Unable to set argv for the python config.");
371 status = PyConfig_Read(&config);
372 if (PyStatus_Exception(status)) {
373 PyConfig_Clear(&config);
374 Py_ExitStatusException(status);
375 EXCEPTION_RAISE(
"PyConfigInit",
"Unable to read the python config.");
378 status = Py_InitializeFromConfig(&config);
379 if (PyStatus_Exception(status)) {
380 PyConfig_Clear(&config);
381 Py_ExitStatusException(status);
383 EXCEPTION_RAISE(
"PyConfigInit",
384 "Unable to initilize the python interpreter.");
387 PyConfig_Clear(&config);
390 if (PyRun_SimpleFile(fp.get(), pythonScript.c_str()) != 0) {
394 EXCEPTION_RAISE(
"Python",
"Execution of python script failed.");
399 for (
int i = 0; i < nargs + 1; i++) PyMem_RawFree(targs[i]);
406 PyObject* py_root_obj = PyImport_ImportModule(
"__main__");
410 EXCEPTION_RAISE(
"Python",
411 "I don't know what happened. This should never happen.");
419 std::stringstream root_obj_ss{root_object};
420 while (std::getline(root_obj_ss, attr,
'.')) {
421 PyObject* one_level_down =
422 PyObject_GetAttrString(py_root_obj, attr.c_str());
423 if (one_level_down == 0) {
425 EXCEPTION_RAISE(
"Python",
"Unable to find python object '" + attr +
"'.");
427 Py_DECREF(py_root_obj);
428 py_root_obj = one_level_down;
432 if (py_root_obj == Py_None) {
435 EXCEPTION_RAISE(
"Python",
436 "Root configuration object " + root_object +
437 " not defined. This object is required to run.");
451 Py_DECREF(py_root_obj);
453 if (Py_FinalizeEx() < 0) {
455 EXCEPTION_RAISE(
"Python",
456 "I wasn't able to close up the python interpreter!");
459 return configuration;