@@ -86,37 +86,6 @@ inline wchar_t *widen_chars(const char *safe_arg) {
86
86
return widened_arg;
87
87
}
88
88
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
-
120
89
PYBIND11_NAMESPACE_END (detail)
121
90
122
91
/* * \rst
@@ -146,9 +115,64 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
146
115
pybind11_fail (" The interpreter is already running" );
147
116
}
148
117
118
+ #if PY_VERSION_HEX < 0x030B0000
119
+
149
120
Py_InitializeEx (init_signal_handlers ? 1 : 0 );
150
121
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
152
176
}
153
177
154
178
/* * \rst
0 commit comments