Enable kpythonpluginfactory to build for Python 3 as well. Should be
upstreamed after more testing.
Note: It is OK for the Python and Python3 versions to have the same name
because of the version specific ABI tags in Python 3 so files and the fact
that Python 3 interpreters will search for those first.
Copyright (C) 2012 Barry A. Warsaw <barry@python.org>
old
|
new
|
|
29 | 29 | #include <kcomponentdata.h> |
30 | 30 | #include <kdebug.h> |
31 | 31 | |
| 32 | #if PY_MAJOR_VERSION >= 3 |
| 33 | #define PY3 |
| 34 | #endif |
| 35 | |
32 | 36 | /* |
33 | 37 | This implements a plugin factory for running Python plugins. It also |
34 | 38 | supports io-slaves with a kdemain() entry point. |
… |
… |
int kdemain( int argc, char **argv ) |
347 | 351 | PyObject *pModule; |
348 | 352 | char *protocol = argv[1]; |
349 | 353 | |
| 354 | #ifdef PY3 |
| 355 | /* Python 3 requires wchar_t*s for its Py_SetProgramName() and |
| 356 | PySys_SetArgv() calls. Python 2 uses the typical char*s. This is |
| 357 | probably not the best way to do it, but the algorithm is based on |
| 358 | Python 3's main(). |
| 359 | */ |
| 360 | wchar_t **program_args = (wchar_t **)PyMem_Malloc( |
| 361 | sizeof(wchar_t *) * (argc + 1)); |
| 362 | char *old_locale; |
| 363 | const char *argv_i; |
| 364 | |
| 365 | if (!program_args) { |
| 366 | /* out of memory */ |
| 367 | Py_FatalError("out of memory"); |
| 368 | } |
| 369 | for (int i = 0; i < argc; i++) { |
| 370 | program_args[i] = (wchar_t *)PyMem_Malloc( |
| 371 | sizeof(wchar_t) * (strlen(argv[i]) + 1)); |
| 372 | if (!program_args[i]) { |
| 373 | Py_FatalError("out of memory"); |
| 374 | } |
| 375 | argv_i = argv[i]; |
| 376 | if (mbsrtowcs(program_args[i], &argv_i, strlen(argv[i]), NULL) < 0) { |
| 377 | /* The conversion failed. */ |
| 378 | Py_FatalError("conversion to wchar_t* failed"); |
| 379 | } |
| 380 | } |
| 381 | #else |
| 382 | char **program_args = argv; |
| 383 | #endif // PY3 |
| 384 | |
350 | 385 | kDebug() << "Python kioslave starting"; |
351 | 386 | KComponentData slave(protocol); |
352 | 387 | kDebug() << "Created KComponentData for protocol " << protocol; |
353 | 388 | |
354 | 389 | QLibrary *pyLib = LoadPythonLibrary(); |
355 | 390 | |
356 | | Py_SetProgramName(argv[0]); |
| 391 | Py_SetProgramName(program_args[0]); |
357 | 392 | Py_Initialize(); |
358 | 393 | |
359 | 394 | //PyEval_InitThreads(); |
360 | | PySys_SetArgv(1, argv); |
| 395 | PySys_SetArgv(1, program_args); |
361 | 396 | |
362 | 397 | QString completePath = KStandardDirs::locate("data", QString("kio_python/%1/%2.py").arg(protocol).arg(protocol)); |
363 | 398 | kDebug() << "Path to Python kioslace is " << completePath; |
… |
… |
int kdemain( int argc, char **argv ) |
388 | 423 | } |
389 | 424 | PyObject *pClass, *pArgs, *pArg1, *pArg2; |
390 | 425 | pArgs = PyTuple_New(2); |
391 | | pArg1 = PyString_FromString(argv[2]); |
392 | | pArg2 = PyString_FromString(argv[3]); |
| 426 | pArg1 = PyBytes_FromString(argv[2]); |
| 427 | pArg2 = PyBytes_FromString(argv[3]); |
393 | 428 | PyTuple_SetItem(pArgs, 0, pArg1); |
394 | 429 | PyTuple_SetItem(pArgs, 1, pArg2); |
395 | 430 | RunFunction(factoryFunction, pArgs); |