|
3 | 3 | #include "FWCore/PythonParameterSet/interface/PyBind11ProcessDesc.h" |
4 | 4 | #include "FWCore/PythonParameterSet/src/initializePyBind11Module.h" |
5 | 5 | #include "FWCore/PythonParameterSet/interface/PyBind11Wrapper.h" |
| 6 | +#include "FWCore/Utilities/interface/Exception.h" |
6 | 7 | #include <pybind11/embed.h> |
7 | 8 | #include <pybind11/pybind11.h> |
8 | 9 |
|
| 10 | +#include <filesystem> |
9 | 11 | #include <sstream> |
10 | 12 | #include <iostream> |
11 | 13 |
|
@@ -36,20 +38,34 @@ PyBind11ProcessDesc::PyBind11ProcessDesc(std::string const& config, bool isFile, |
36 | 38 | : theProcessPSet(), theInterpreter(true) { |
37 | 39 | edm::python::initializePyBind11Module(); |
38 | 40 | prepareToRead(); |
39 | | - { |
40 | | - typedef std::unique_ptr<wchar_t[], decltype(&PyMem_RawFree)> WArgUPtr; |
41 | | - std::vector<WArgUPtr> v_argv; |
42 | | - std::vector<wchar_t*> vp_argv; |
43 | | - v_argv.reserve(args.size()); |
44 | | - vp_argv.reserve(args.size()); |
45 | | - for (size_t i = 0; i < args.size(); i++) { |
46 | | - v_argv.emplace_back(Py_DecodeLocale(args[i].c_str(), nullptr), &PyMem_RawFree); |
47 | | - vp_argv.emplace_back(v_argv.back().get()); |
48 | | - } |
49 | 41 |
|
50 | | - wchar_t** argvt = vp_argv.data(); |
| 42 | + // Acquire Python GIL before touching Python objects |
| 43 | + pybind11::gil_scoped_acquire acquire; |
| 44 | + |
| 45 | + try { |
| 46 | + // Import sys module |
| 47 | + pybind11::module_ sys = pybind11::module_::import("sys"); |
51 | 48 |
|
52 | | - PySys_SetArgv(args.size(), argvt); |
| 49 | + // set sys.argv safely |
| 50 | + pybind11::list pyargs; |
| 51 | + for (auto const& arg : args) { |
| 52 | + pyargs.append(arg); |
| 53 | + } |
| 54 | + sys.attr("argv") = pyargs; |
| 55 | + |
| 56 | + // emulate old implicit sys.path[0] update (PySys_SetArgv behaviour) |
| 57 | + if (!args.empty()) { |
| 58 | + std::string dir = std::filesystem::path(args[0]).parent_path().string(); |
| 59 | + if (dir.empty()) |
| 60 | + dir = "."; // fallback to current directory |
| 61 | + |
| 62 | + // insert dir at the front of sys.path |
| 63 | + pybind11::list sys_path = sys.attr("path"); |
| 64 | + sys_path.insert(0, dir); |
| 65 | + sys.attr("path") = sys_path; |
| 66 | + } |
| 67 | + } catch (const pybind11::error_already_set& e) { |
| 68 | + throw cms::Exception("PyBind11Error") << "Python error initializing PyBind11ProcessDesc: " << e.what(); |
53 | 69 | } |
54 | 70 | read(config, isFile); |
55 | 71 | } |
|
0 commit comments