@@ -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-
12089PYBIND11_NAMESPACE_END (detail)
12190
12291/* * \rst
@@ -146,9 +115,64 @@ 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 [], detail::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 (detail::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_InitIsolatedConfig (&config);
153+ config.install_signal_handlers = init_signal_handlers ? 1 : 0 ;
154+
155+ PyStatus status = PyConfig_SetBytesArgv (&config, argc, const_cast <char *const *>(argv));
156+ if (PyStatus_Exception (status)) {
157+ // A failure here indicates a character-encoding failure or the python
158+ // interpreter out of memory. Give up.
159+ PyConfig_Clear (&config);
160+ throw std::runtime_error (PyStatus_IsError (status) ? status.err_msg
161+ : " Failed to prepare CPython" );
162+ }
163+ status = Py_InitializeFromConfig (&config);
164+ PyConfig_Clear (&config);
165+ if (PyStatus_Exception (status)) {
166+ throw std::runtime_error (PyStatus_IsError (status) ? status.err_msg
167+ : " Failed to init CPython" );
168+ }
169+ if (add_program_dir_to_path) {
170+ PyRun_SimpleString (" import sys, os.path; "
171+ " sys.path.insert(0, "
172+ " os.path.abspath(os.path.dirname(sys.argv[0])) "
173+ " if sys.argv and os.path.exists(sys.argv[0]) else '')" );
174+ }
175+ #endif
152176}
153177
154178/* * \rst
0 commit comments