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,90 @@ 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 )) {
173
+
174
+ #if PY_MAJOR_VERSION >= 3
175
+
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" );
182
+ #endif
183
+
184
+ #else
185
+ Py_SetProgramName ("android_python" );
186
+ #endif
187
+
188
+ if (dir_exists (python_bundle_dir )) {
178
189
LOGP ("_python_bundle dir exists" );
179
- snprintf (paths , 256 ,
180
- "%s/stdlib.zip:%s/modules" ,
181
- python_bundle_dir , python_bundle_dir );
182
190
183
- LOGP ( "calculated paths to be..." ) ;
184
- LOGP ( paths ) ;
191
+ wchar_t wchar_zip_path [ 256 ] ;
192
+ wchar_t wchar_modules_path [ 256 ] ;
185
193
186
- #if PY_MAJOR_VERSION >= 3
194
+ swprintf (wchar_zip_path , 256 , L"%s/stdlib.zip" , python_bundle_dir );
195
+ swprintf (wchar_modules_path , 256 , L"%s/modules" , python_bundle_dir );
196
+
197
+ LOGP ("Appending module search paths:" );
198
+
199
+ #if PY_MAJOR_VERSION >= 3
200
+ #if PY_MINOR_VERSION >= P4A_MIN_VER
201
+ config .module_search_paths_set = 1 ;
202
+ PyWideStringList_Append (& config .module_search_paths , wchar_zip_path );
203
+ PyWideStringList_Append (& config .module_search_paths , wchar_modules_path );
204
+ LOGP ("YES FUCKER 1" );
205
+ #else
206
+ char paths [512 ];
207
+ snprintf (paths , 512 , "%s/stdlib.zip:%s/modules" , python_bundle_dir , python_bundle_dir );
187
208
wchar_t * wchar_paths = Py_DecodeLocale (paths , NULL );
188
209
Py_SetPath (wchar_paths );
189
210
#endif
211
+ #endif
212
+
213
+ LOGP ("set wchar paths..." );
214
+ } else {
215
+ LOGP ("_python_bundle does not exist...this not looks good, all python"
216
+ " recipes should have this folder, should we expect a crash soon?" );
217
+ }
218
+
219
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= P4A_MIN_VER
220
+ PyStatus status = Py_InitializeFromConfig (& config );
221
+ if (PyStatus_Exception (status )) {
222
+ LOGP ("Python initialization failed: %s" );
223
+ LOGP (status .err_msg );
224
+ Py_ExitStatusException (status ); // this will exit the program with error
225
+ } else {
226
+ LOGP ("Python initialized successfully using Py_InitializeFromConfig." );
227
+ }
228
+ #else
229
+ Py_Initialize ();
230
+ LOGP ("Python initialized using legacy Py_Initialize()." );
231
+ #endif
190
232
191
- LOGP ("set wchar paths..." );
192
- } 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?" );
195
- }
196
233
197
- Py_Initialize ();
198
234
LOGP ("Initialized python" );
199
235
200
- /* ensure threads will work.
201
- */
202
- LOGP ("AND: Init threads" );
203
- PyEval_InitThreads ();
236
+ /* < 3.9 requires explicit GIL initialization
237
+ * 3.9+ PyEval_InitThreads() is deprecated and unnecessary
238
+ */
239
+ #if PY_VERSION_HEX < 0x03090000
240
+ LOGP ("Initializing threads (required for Python < 3.9)" );
241
+ PyEval_InitThreads ();
242
+ #endif
204
243
205
244
#if PY_MAJOR_VERSION < 3
206
245
initandroidembed ();
207
246
#endif
208
247
209
- PyRun_SimpleString ("import androidembed\nandroidembed.log('testing python "
210
- "print redirection')" );
248
+ PyRun_SimpleString (
249
+ "import sys;print(sys.path)"
250
+ );
251
+
252
+ PyRun_SimpleString (
253
+ "import androidembed\n"
254
+ "androidembed.log('testing python print redirection')"
255
+
256
+ );
211
257
212
258
/* inject our bootstrap code to redirect python stdin/stdout
213
259
* replace sys.path with our path
@@ -325,20 +371,6 @@ int main(int argc, char *argv[]) {
325
371
326
372
LOGP ("Python for android ended." );
327
373
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
374
343
375
/* This should never actually be reached, but we'll leave the clean-up
344
376
* here just to be safe.
0 commit comments