171 PyObject *key(0), *value(0);
176 while (PyDict_Next(dictionary, &pos, &key, &value)) {
179 if (PyLong_Check(value)) {
180 if (PyBool_Check(value)) {
181 params.
add(skey,
bool(PyLong_AsLong(value)));
183 params.
add(skey,
int(PyLong_AsLong(value)));
185 }
else if (PyFloat_Check(value)) {
186 params.
add(skey, PyFloat_AsDouble(value));
187 }
else if (PyUnicode_Check(value)) {
189 }
else if (PyList_Check(value)) {
191 if (PyList_Size(value) > 0) {
192 auto vec0{PyList_GetItem(value, 0)};
194 if (PyLong_Check(vec0)) {
195 std::vector<int> vals;
197 for (
auto j{0}; j < PyList_Size(value); j++)
198 vals.push_back(PyLong_AsLong(PyList_GetItem(value, j)));
200 params.
add(skey, vals);
202 }
else if (PyFloat_Check(vec0)) {
203 std::vector<double> vals;
205 for (
auto j{0}; j < PyList_Size(value); j++)
206 vals.push_back(PyFloat_AsDouble(PyList_GetItem(value, j)));
208 params.
add(skey, vals);
210 }
else if (PyUnicode_Check(vec0)) {
211 std::vector<std::string> vals;
212 for (Py_ssize_t j = 0; j < PyList_Size(value); j++) {
213 PyObject* elem = PyList_GetItem(value, j);
217 params.
add(skey, vals);
218 }
else if (PyList_Check(vec0)) {
220 if (PyList_Size(vec0) > 0) {
221 auto vecvec0{PyList_GetItem(vec0, 0)};
222 if (PyLong_Check(vecvec0)) {
223 std::vector<std::vector<int>> vals;
224 for (
auto j{0}; j < PyList_Size(value); j++) {
225 auto subvec{PyList_GetItem(value, j)};
226 std::vector<int> subvals;
227 for (
auto k{0}; k < PyList_Size(subvec); k++) {
228 subvals.push_back(PyLong_AsLong(PyList_GetItem(subvec, k)));
230 vals.push_back(subvals);
232 params.
add(skey, vals);
233 }
else if (PyFloat_Check(vecvec0)) {
234 std::vector<std::vector<double>> vals;
235 for (
auto j{0}; j < PyList_Size(value); j++) {
236 auto subvec{PyList_GetItem(value, j)};
237 std::vector<double> subvals;
238 for (
auto k{0}; k < PyList_Size(subvec); k++) {
240 PyFloat_AsDouble(PyList_GetItem(subvec, k)));
242 vals.push_back(subvals);
244 params.
add(skey, vals);
245 }
else if (PyUnicode_Check(vecvec0)) {
246 std::vector<std::vector<std::string>> vals;
247 for (
auto j{0}; j < PyList_Size(value); j++) {
248 auto subvec{PyList_GetItem(value, j)};
249 std::vector<std::string> subvals;
250 for (
auto k{0}; k < PyList_Size(subvec); k++) {
251 subvals.push_back(
getPyString(PyList_GetItem(subvec, k)));
253 vals.push_back(subvals);
255 params.
add(skey, vals);
256 }
else if (PyList_Check(vecvec0)) {
257 EXCEPTION_RAISE(
"BadConf",
258 "A python list with dimension greater than 2 is "
262 std::vector<std::vector<framework::config::Parameters>> vals;
263 for (
auto j{0}; j < PyList_Size(value); j++) {
264 auto subvec{PyList_GetItem(value, j)};
265 std::vector<framework::config::Parameters> subvals;
266 for (
auto k{0}; k < PyList_Size(subvec); k++) {
267 subvals.emplace_back(
getMembers(PyList_GetItem(subvec, k)));
269 vals.push_back(subvals);
271 params.
add(skey, vals);
279 std::vector<framework::config::Parameters> vals;
280 for (
auto j{0}; j < PyList_Size(value); ++j) {
281 auto elem{PyList_GetItem(value, j)};
284 params.
add(skey, vals);
300Parameters run(
const std::string& root_object,
const std::string& pythonScript,
301 char* args[],
int nargs) {
307 std::unique_ptr<FILE, int (*)(FILE*)> fp{fopen(pythonScript.c_str(),
"r"),
309 if (fp.get() == NULL) {
310 EXCEPTION_RAISE(
"ConfigDNE",
311 "Passed config script '" + pythonScript +
312 "' is not accessible.\n"
313 " Did you make a typo in the path to the script?\n"
314 " Are you referencing a directory that is not "
315 "mounted to the container?");
324 wchar_t** targs =
new wchar_t*[nargs + 1];
325 targs[0] = Py_DecodeLocale(pythonScript.c_str(), NULL);
326 for (
int i = 0; i < nargs; i++) targs[i + 1] = Py_DecodeLocale(args[i], NULL);
328#if DEV_IMAGE_MAJOR < 5
330 Py_SetProgramName(targs[0]);
340 PySys_SetArgvEx(nargs + 1, targs, 1);
344 PyConfig_InitPythonConfig(&config);
346 config.parse_argv = 0;
353 status = PyConfig_SetString(&config, &config.program_name, targs[0]);
354 if (PyStatus_Exception(status)) {
355 PyConfig_Clear(&config);
356 Py_ExitStatusException(status);
357 EXCEPTION_RAISE(
"PyConfigInit",
358 "Unable to set the program name in the python config.");
361 status = PyConfig_SetArgv(&config, nargs + 1, targs);
362 if (PyStatus_Exception(status)) {
363 PyConfig_Clear(&config);
364 Py_ExitStatusException(status);
365 EXCEPTION_RAISE(
"PyConfigInit",
366 "Unable to set argv for the python config.");
369 status = PyConfig_Read(&config);
370 if (PyStatus_Exception(status)) {
371 PyConfig_Clear(&config);
372 Py_ExitStatusException(status);
373 EXCEPTION_RAISE(
"PyConfigInit",
"Unable to read the python config.");
376 status = Py_InitializeFromConfig(&config);
377 if (PyStatus_Exception(status)) {
378 PyConfig_Clear(&config);
379 Py_ExitStatusException(status);
381 EXCEPTION_RAISE(
"PyConfigInit",
382 "Unable to initilize the python interpreter.");
385 PyConfig_Clear(&config);
388 if (PyRun_SimpleFile(fp.get(), pythonScript.c_str()) != 0) {
392 EXCEPTION_RAISE(
"Python",
"Execution of python script failed.");
397 for (
int i = 0; i < nargs + 1; i++) PyMem_RawFree(targs[i]);
404 PyObject* py_root_obj = PyImport_ImportModule(
"__main__");
408 EXCEPTION_RAISE(
"Python",
409 "I don't know what happened. This should never happen.");
417 std::stringstream root_obj_ss{root_object};
418 while (std::getline(root_obj_ss, attr,
'.')) {
419 PyObject* one_level_down =
420 PyObject_GetAttrString(py_root_obj, attr.c_str());
421 if (one_level_down == 0) {
423 EXCEPTION_RAISE(
"Python",
"Unable to find python object '" + attr +
"'.");
425 Py_DECREF(py_root_obj);
426 py_root_obj = one_level_down;
430 if (py_root_obj == Py_None) {
433 EXCEPTION_RAISE(
"Python",
434 "Root configuration object " + root_object +
435 " not defined. This object is required to run.");
449 Py_DECREF(py_root_obj);
451 if (Py_FinalizeEx() < 0) {
453 EXCEPTION_RAISE(
"Python",
454 "I wasn't able to close up the python interpreter!");
457 return configuration;