31
31
#define ENTRYPOINT_MAXLEN 128
32
32
#define LOG (n , x ) __android_log_write(ANDROID_LOG_INFO, (n), (x))
33
33
#define LOGP (x ) LOG("python", (x))
34
+ #define P4A_MIN_VER 11
34
35
35
36
static PyObject * androidembed_log (PyObject * self , PyObject * args ) {
36
37
char * logstr = NULL ;
@@ -154,11 +155,6 @@ int main(int argc, char *argv[]) {
154
155
Py_NoSiteFlag = 1 ;
155
156
#endif
156
157
157
- #if PY_MAJOR_VERSION < 3
158
- Py_SetProgramName ("android_python" );
159
- #else
160
- Py_SetProgramName (L"android_python" );
161
- #endif
162
158
163
159
#if PY_MAJOR_VERSION >= 3
164
160
/* our logging module for android
@@ -174,40 +170,80 @@ int main(int argc, char *argv[]) {
174
170
char python_bundle_dir [256 ];
175
171
snprintf (python_bundle_dir , 256 ,
176
172
"%s/_python_bundle" , getenv ("ANDROID_UNPACK" ));
177
- if (dir_exists (python_bundle_dir )) {
178
- LOGP ("_python_bundle dir exists" );
179
- snprintf (paths , 256 ,
180
- "%s/stdlib.zip:%s/modules" ,
181
- python_bundle_dir , python_bundle_dir );
182
173
183
- LOGP ("calculated paths to be..." );
184
- LOGP (paths );
174
+ #if PY_MAJOR_VERSION >= 3
185
175
186
- #if PY_MAJOR_VERSION >= 3
187
- wchar_t * wchar_paths = Py_DecodeLocale (paths , NULL );
188
- Py_SetPath (wchar_paths );
176
+ #if PY_MINOR_VERSION >= P4A_MIN_VER
177
+ PyConfig config ;
178
+ PyConfig_InitPythonConfig (& config );
179
+ config .program_name = L"android_python" ;
180
+ #else
181
+ Py_SetProgramName (L"android_python" );
189
182
#endif
190
183
191
- LOGP ("set wchar paths..." );
184
+ #else
185
+ Py_SetProgramName ("android_python" );
186
+ #endif
187
+
188
+ if (dir_exists (python_bundle_dir )) {
189
+ LOGP ("_python_bundle dir exists" );
190
+
191
+ #if PY_MAJOR_VERSION >= 3
192
+ #if PY_MINOR_VERSION >= P4A_MIN_VER
193
+
194
+ wchar_t wchar_zip_path [256 ];
195
+ wchar_t wchar_modules_path [256 ];
196
+ swprintf (wchar_zip_path , 256 , L"%s/stdlib.zip" , python_bundle_dir );
197
+ swprintf (wchar_modules_path , 256 , L"%s/modules" , python_bundle_dir );
198
+
199
+ config .module_search_paths_set = 1 ;
200
+ PyWideStringList_Append (& config .module_search_paths , wchar_zip_path );
201
+ PyWideStringList_Append (& config .module_search_paths , wchar_modules_path );
202
+ #else
203
+ char paths [512 ];
204
+ snprintf (paths , 512 , "%s/stdlib.zip:%s/modules" , python_bundle_dir , python_bundle_dir );
205
+ wchar_t * wchar_paths = Py_DecodeLocale (paths , NULL );
206
+ Py_SetPath (wchar_paths );
207
+ #endif
208
+
209
+ #endif
210
+
211
+ LOGP ("set wchar paths..." );
192
212
} else {
193
- LOGP ("_python_bundle does not exist...this not looks good, all python"
194
- " recipes should have this folder, should we expect a crash soon?" );
213
+ LOGP ("_python_bundle does not exist...this not looks good, all python"
214
+ " recipes should have this folder, should we expect a crash soon?" );
195
215
}
196
216
197
- Py_Initialize ();
217
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= P4A_MIN_VER
218
+ PyStatus status = Py_InitializeFromConfig (& config );
219
+ if (PyStatus_Exception (status )) {
220
+ LOGP ("Python initialization failed:" );
221
+ LOGP (status .err_msg );
222
+ }
223
+ #else
224
+ Py_Initialize ();
225
+ LOGP ("Python initialized using legacy Py_Initialize()." );
226
+ #endif
227
+
198
228
LOGP ("Initialized python" );
199
229
200
- /* ensure threads will work.
201
- */
202
- LOGP ("AND: Init threads" );
203
- PyEval_InitThreads ();
230
+ /* < 3.9 requires explicit GIL initialization
231
+ * 3.9+ PyEval_InitThreads() is deprecated and unnecessary
232
+ */
233
+ #if PY_VERSION_HEX < 0x03090000
234
+ LOGP ("Initializing threads (required for Python < 3.9)" );
235
+ PyEval_InitThreads ();
236
+ #endif
204
237
205
238
#if PY_MAJOR_VERSION < 3
206
239
initandroidembed ();
207
240
#endif
208
241
209
- PyRun_SimpleString ("import androidembed\nandroidembed.log('testing python "
210
- "print redirection')" );
242
+ PyRun_SimpleString (
243
+ "import androidembed\n"
244
+ "androidembed.log('testing python print redirection')"
245
+
246
+ );
211
247
212
248
/* inject our bootstrap code to redirect python stdin/stdout
213
249
* replace sys.path with our path
@@ -325,20 +361,6 @@ int main(int argc, char *argv[]) {
325
361
326
362
LOGP ("Python for android ended." );
327
363
328
- /* Shut down: since regular shutdown causes issues sometimes
329
- (seems to be an incomplete shutdown breaking next launch)
330
- we'll use sys.exit(ret) to shutdown, since that one works.
331
-
332
- Reference discussion:
333
-
334
- https://github.com/kivy/kivy/pull/6107#issue-246120816
335
- */
336
- char terminatecmd [256 ];
337
- snprintf (
338
- terminatecmd , sizeof (terminatecmd ),
339
- "import sys; sys.exit(%d)\n" , ret
340
- );
341
- PyRun_SimpleString (terminatecmd );
342
364
343
365
/* This should never actually be reached, but we'll leave the clean-up
344
366
* here just to be safe.
0 commit comments