Skip to content

Commit c4d14bc

Browse files
committed
fix: try using modern init for embedded interp
1 parent 574bd95 commit c4d14bc

File tree

2 files changed

+47
-33
lines changed

2 files changed

+47
-33
lines changed

include/pybind11/embed.h

+46-32
Original file line numberDiff line numberDiff line change
@@ -86,37 +86,6 @@ inline wchar_t *widen_chars(const char *safe_arg) {
8686
return widened_arg;
8787
}
8888

89-
/// Python 2.x/3.x-compatible version of `PySys_SetArgv`
90-
inline void set_interpreter_argv(int argc, const char *const *argv, bool add_program_dir_to_path) {
91-
// Before it was special-cased in python 3.8, passing an empty or null argv
92-
// caused a segfault, so we have to reimplement the special case ourselves.
93-
bool special_case = (argv == nullptr || argc <= 0);
94-
95-
const char *const empty_argv[]{"\0"};
96-
const char *const *safe_argv = special_case ? empty_argv : argv;
97-
if (special_case) {
98-
argc = 1;
99-
}
100-
101-
auto argv_size = static_cast<size_t>(argc);
102-
// SetArgv* on python 3 takes wchar_t, so we have to convert.
103-
std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
104-
std::vector<std::unique_ptr<wchar_t[], wide_char_arg_deleter>> widened_argv_entries;
105-
widened_argv_entries.reserve(argv_size);
106-
for (size_t ii = 0; ii < argv_size; ++ii) {
107-
widened_argv_entries.emplace_back(widen_chars(safe_argv[ii]));
108-
if (!widened_argv_entries.back()) {
109-
// A null here indicates a character-encoding failure or the python
110-
// interpreter out of memory. Give up.
111-
return;
112-
}
113-
widened_argv[ii] = widened_argv_entries.back().get();
114-
}
115-
116-
auto *pysys_argv = widened_argv.get();
117-
PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
118-
}
119-
12089
PYBIND11_NAMESPACE_END(detail)
12190

12291
/** \rst
@@ -146,9 +115,54 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
146115
pybind11_fail("The interpreter is already running");
147116
}
148117

118+
#if PY_VERSION_HEX < 0x030B0000
119+
149120
Py_InitializeEx(init_signal_handlers ? 1 : 0);
150121

151-
detail::set_interpreter_argv(argc, argv, add_program_dir_to_path);
122+
// Before it was special-cased in python 3.8, passing an empty or null argv
123+
// caused a segfault, so we have to reimplement the special case ourselves.
124+
bool special_case = (argv == nullptr || argc <= 0);
125+
126+
const char *const empty_argv[]{"\0"};
127+
const char *const *safe_argv = special_case ? empty_argv : argv;
128+
if (special_case) {
129+
argc = 1;
130+
}
131+
132+
auto argv_size = static_cast<size_t>(argc);
133+
// SetArgv* on python 3 takes wchar_t, so we have to convert.
134+
std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
135+
std::vector<std::unique_ptr<wchar_t[], wide_char_arg_deleter>> widened_argv_entries;
136+
widened_argv_entries.reserve(argv_size);
137+
for (size_t ii = 0; ii < argv_size; ++ii) {
138+
widened_argv_entries.emplace_back(widen_chars(safe_argv[ii]));
139+
if (!widened_argv_entries.back()) {
140+
// A null here indicates a character-encoding failure or the python
141+
// interpreter out of memory. Give up.
142+
return;
143+
}
144+
widened_argv[ii] = widened_argv_entries.back().get();
145+
}
146+
147+
auto *pysys_argv = widened_argv.get();
148+
149+
PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
150+
#else
151+
PyConfig config;
152+
PyConfig_InitPythonConfig(&config);
153+
config.safe_path = add_program_dir_to_path ? 0 : 1;
154+
config.install_signal_handlers = init_signal_handlers ? 1 : 0;
155+
156+
PyStatus status = PyConfig_SetBytesArgv(&config, argc, const_cast<char *const *>(argv));
157+
if (PyStatus_Exception(status)) {
158+
// A failure here indicates a character-encoding failure or the python
159+
// interpreter out of memory. Give up.
160+
PyConfig_Clear(&config);
161+
return;
162+
}
163+
Py_InitializeFromConfig(&config);
164+
PyConfig_Clear(&config);
165+
#endif
152166
}
153167

154168
/** \rst

tests/requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
build==0.7.0
1+
build==0.8.0
22
numpy==1.21.5; platform_python_implementation=="PyPy" and sys_platform=="linux" and python_version=="3.7"
33
numpy==1.19.3; platform_python_implementation!="PyPy" and python_version=="3.6"
44
numpy==1.21.5; platform_python_implementation!="PyPy" and python_version>="3.7" and python_version<"3.10"

0 commit comments

Comments
 (0)