163 PyObject *key(0), *value(0);
168 while (PyDict_Next(dictionary, &pos, &key, &value)) {
171 if (PyLong_Check(value)) {
172 if (PyBool_Check(value)) {
173 params.
add(skey,
bool(PyLong_AsLong(value)));
175 params.
add(skey,
int(PyLong_AsLong(value)));
177 }
else if (PyFloat_Check(value)) {
178 params.
add(skey, PyFloat_AsDouble(value));
179 }
else if (PyUnicode_Check(value)) {
181 }
else if (PyList_Check(value)) {
183 if (PyList_Size(value) > 0) {
184 auto vec0{PyList_GetItem(value, 0)};
186 if (PyLong_Check(vec0)) {
187 std::vector<int> vals;
189 for (
auto j{0}; j < PyList_Size(value); j++)
190 vals.push_back(PyLong_AsLong(PyList_GetItem(value, j)));
192 params.
add(skey, vals);
194 }
else if (PyFloat_Check(vec0)) {
195 std::vector<double> vals;
197 for (
auto j{0}; j < PyList_Size(value); j++)
198 vals.push_back(PyFloat_AsDouble(PyList_GetItem(value, j)));
200 params.
add(skey, vals);
202 }
else if (PyUnicode_Check(vec0)) {
203 std::vector<std::string> vals;
204 for (Py_ssize_t j = 0; j < PyList_Size(value); j++) {
205 PyObject* elem = PyList_GetItem(value, j);
209 params.
add(skey, vals);
210 }
else if (PyList_Check(vec0)) {
212 if (PyList_Size(vec0) > 0) {
213 auto vecvec0{PyList_GetItem(vec0, 0)};
214 if (PyLong_Check(vecvec0)) {
215 std::vector<std::vector<int>> vals;
216 for (
auto j{0}; j < PyList_Size(value); j++) {
217 auto subvec{PyList_GetItem(value, j)};
218 std::vector<int> subvals;
219 for (
auto k{0}; k < PyList_Size(subvec); k++) {
220 subvals.push_back(PyLong_AsLong(PyList_GetItem(subvec, k)));
222 vals.push_back(subvals);
224 params.
add(skey, vals);
225 }
else if (PyFloat_Check(vecvec0)) {
226 std::vector<std::vector<double>> vals;
227 for (
auto j{0}; j < PyList_Size(value); j++) {
228 auto subvec{PyList_GetItem(value, j)};
229 std::vector<double> subvals;
230 for (
auto k{0}; k < PyList_Size(subvec); k++) {
232 PyFloat_AsDouble(PyList_GetItem(subvec, k)));
234 vals.push_back(subvals);
236 params.
add(skey, vals);
237 }
else if (PyUnicode_Check(vecvec0)) {
238 std::vector<std::vector<std::string>> vals;
239 for (
auto j{0}; j < PyList_Size(value); j++) {
240 auto subvec{PyList_GetItem(value, j)};
241 std::vector<std::string> subvals;
242 for (
auto k{0}; k < PyList_Size(subvec); k++) {
243 subvals.push_back(
getPyString(PyList_GetItem(subvec, k)));
245 vals.push_back(subvals);
247 params.
add(skey, vals);
248 }
else if (PyList_Check(vecvec0)) {
249 EXCEPTION_RAISE(
"BadConf",
250 "A python list with dimension greater than 2 is "
254 std::vector<std::vector<framework::config::Parameters>> vals;
255 for (
auto j{0}; j < PyList_Size(value); j++) {
256 auto subvec{PyList_GetItem(value, j)};
257 std::vector<framework::config::Parameters> subvals;
258 for (
auto k{0}; k < PyList_Size(subvec); k++) {
259 subvals.emplace_back(
getMembers(PyList_GetItem(subvec, k)));
261 vals.push_back(subvals);
263 params.
add(skey, vals);
271 std::vector<framework::config::Parameters> vals;
272 for (
auto j{0}; j < PyList_Size(value); ++j) {
273 auto elem{PyList_GetItem(value, j)};
276 params.
add(skey, vals);
292Parameters run(
const std::string& root_object,
const std::string& pythonScript,
293 char* args[],
int nargs) {
299 std::unique_ptr<FILE, int (*)(FILE*)> fp{fopen(pythonScript.c_str(),
"r"),
301 if (fp.get() == NULL) {
302 EXCEPTION_RAISE(
"ConfigDNE",
303 "Passed config script '" + pythonScript +
304 "' is not accessible.\n"
305 " Did you make a typo in the path to the script?\n"
306 " Are you referencing a directory that is not "
307 "mounted to the container?");
316 wchar_t** targs =
new wchar_t*[nargs + 1];
317 targs[0] = Py_DecodeLocale(pythonScript.c_str(), NULL);
318 for (
int i = 0; i < nargs; i++) targs[i + 1] = Py_DecodeLocale(args[i], NULL);
320#if DEV_IMAGE_MAJOR < 5
322 Py_SetProgramName(targs[0]);
332 PySys_SetArgvEx(nargs + 1, targs, 1);
336 PyConfig_InitPythonConfig(&config);
338 config.parse_argv = 0;
345 status = PyConfig_SetString(&config, &config.program_name, targs[0]);
346 if (PyStatus_Exception(status)) {
347 PyConfig_Clear(&config);
348 Py_ExitStatusException(status);
349 EXCEPTION_RAISE(
"PyConfigInit",
350 "Unable to set the program name in the python config.");
353 status = PyConfig_SetArgv(&config, nargs + 1, targs);
354 if (PyStatus_Exception(status)) {
355 PyConfig_Clear(&config);
356 Py_ExitStatusException(status);
357 EXCEPTION_RAISE(
"PyConfigInit",
358 "Unable to set argv for the python config.");
361 status = PyConfig_Read(&config);
362 if (PyStatus_Exception(status)) {
363 PyConfig_Clear(&config);
364 Py_ExitStatusException(status);
365 EXCEPTION_RAISE(
"PyConfigInit",
"Unable to read the python config.");
368 status = Py_InitializeFromConfig(&config);
369 if (PyStatus_Exception(status)) {
370 PyConfig_Clear(&config);
371 Py_ExitStatusException(status);
373 EXCEPTION_RAISE(
"PyConfigInit",
374 "Unable to initilize the python interpreter.");
377 PyConfig_Clear(&config);
380 if (PyRun_SimpleFile(fp.get(), pythonScript.c_str()) != 0) {
384 EXCEPTION_RAISE(
"Python",
"Execution of python script failed.");
389 for (
int i = 0; i < nargs + 1; i++) PyMem_RawFree(targs[i]);
396 PyObject* py_root_obj = PyImport_ImportModule(
"__main__");
400 EXCEPTION_RAISE(
"Python",
401 "I don't know what happened. This should never happen.");
409 std::stringstream root_obj_ss{root_object};
410 while (std::getline(root_obj_ss, attr,
'.')) {
411 PyObject* one_level_down =
412 PyObject_GetAttrString(py_root_obj, attr.c_str());
413 if (one_level_down == 0) {
415 EXCEPTION_RAISE(
"Python",
"Unable to find python object '" + attr +
"'.");
417 Py_DECREF(py_root_obj);
418 py_root_obj = one_level_down;
422 if (py_root_obj == Py_None) {
425 EXCEPTION_RAISE(
"Python",
426 "Root configuration object " + root_object +
427 " not defined. This object is required to run.");
441 Py_DECREF(py_root_obj);
443 if (Py_FinalizeEx() < 0) {
445 EXCEPTION_RAISE(
"Python",
446 "I wasn't able to close up the python interpreter!");
449 return configuration;