static void mywrite(const char* name, FILE* fp, const char* format, va_list va) noexcept { PyObject* file; PyObject* error_type, *error_value, *error_traceback; PyErr_Fetch(&error_type, &error_value, &error_traceback); file = PySys_GetObject(name); if (file == NULL || PyFile_AsFile(file) == fp) vfprintf(fp, format, va); else { char buffer[1001]; const int written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (PyFile_WriteString(buffer, file) != 0) { PyErr_Clear(); fputs(buffer, fp); } if (written < 0 || (size_t)written >= sizeof(buffer)) { const char* truncated = "... truncated"; if (PyFile_WriteString(truncated, file) != 0) { PyErr_Clear(); fputs(truncated, fp); } } } PyErr_Restore(error_type, error_value, error_traceback); }
static int __Pyx_Print(PyObject *arg_tuple, int newline) { PyObject *f; PyObject* v; int i; if (!(f = __Pyx_GetStdout())) return -1; for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) { if (PyFile_SoftSpace(f, 1)) { if (PyFile_WriteString(" ", f) < 0) return -1; } v = PyTuple_GET_ITEM(arg_tuple, i); if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) return -1; if (PyString_Check(v)) { char *s = PyString_AsString(v); Py_ssize_t len = PyString_Size(v); if (len > 0 && isspace(Py_CHARMASK(s[len-1])) && s[len-1] != ' ') PyFile_SoftSpace(f, 0); } } if (newline) { if (PyFile_WriteString("\n", f) < 0) return -1; PyFile_SoftSpace(f, 0); } return 0; }
static void print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) { int err = 0, res; PyObject *cause, *context; if (seen != NULL) { /* Exception chaining */ PyObject *value_id = PyLong_FromVoidPtr(value); if (value_id == NULL || PySet_Add(seen, value_id) == -1) PyErr_Clear(); else if (PyExceptionInstance_Check(value)) { PyObject *check_id = NULL; cause = PyException_GetCause(value); context = PyException_GetContext(value); if (cause) { check_id = PyLong_FromVoidPtr(cause); if (check_id == NULL) { res = -1; } else { res = PySet_Contains(seen, check_id); Py_DECREF(check_id); } if (res == -1) PyErr_Clear(); if (res == 0) { print_exception_recursive( f, cause, seen); err |= PyFile_WriteString( cause_message, f); } } else if (context && !((PyBaseExceptionObject *)value)->suppress_context) { check_id = PyLong_FromVoidPtr(context); if (check_id == NULL) { res = -1; } else { res = PySet_Contains(seen, check_id); Py_DECREF(check_id); } if (res == -1) PyErr_Clear(); if (res == 0) { print_exception_recursive( f, context, seen); err |= PyFile_WriteString( context_message, f); } } Py_XDECREF(context); Py_XDECREF(cause); } Py_XDECREF(value_id); } print_exception(f, value); if (err != 0) PyErr_Clear(); }
static void callback_error(const char* handler) { PyObject* sys_stderr; sys_stderr = PySys_GetObject("stderr"); if (sys_stderr) { PyFile_WriteString("*** ImageWin: error in ", sys_stderr); PyFile_WriteString((char*) handler, sys_stderr); PyFile_WriteString(":\n", sys_stderr); } PyErr_Print(); PyErr_Clear(); }
int PyTraceBack_Print(PyObject *v, PyObject *f) { int err; PyObject *limitv; long limit = PyTraceBack_LIMIT; if (v == NULL) return 0; if (!PyTraceBack_Check(v)) { PyErr_BadInternalCall(); return -1; } limitv = PySys_GetObject("tracebacklimit"); if (limitv && PyLong_Check(limitv)) { int overflow; limit = PyLong_AsLongAndOverflow(limitv, &overflow); if (overflow > 0) { limit = LONG_MAX; } else if (limit <= 0) { return 0; } } err = PyFile_WriteString("Traceback (most recent call last):\n", f); if (!err) err = tb_printinternal((PyTracebackObject *)v, f, limit); return err; }
static int __Pyx_PrintOne(PyObject *o) { PyObject *f; if (!(f = __Pyx_GetStdout())) return -1; if (PyFile_SoftSpace(f, 0)) { if (PyFile_WriteString(" ", f) < 0) return -1; } if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0) return -1; if (PyFile_WriteString("\n", f) < 0) return -1; return 0; /* the line below is just to avoid compiler * compiler warnings about unused functions */ return __Pyx_Print(NULL, 0); }
/* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void PyErr_WriteUnraisable(PyObject *obj) { PyObject *f, *t, *v, *tb; PyErr_Fetch(&t, &v, &tb); f = PySys_GetObject("stderr"); if (f != NULL) { PyFile_WriteString("Exception ", f); if (t) { PyObject* moduleName; char* className; assert(PyExceptionClass_Check(t)); className = PyExceptionClass_Name(t); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = PyObject_GetAttrString(t, "__module__"); if (moduleName == NULL) PyFile_WriteString("<unknown>", f); else { char* modstr = PyString_AsString(moduleName); if (modstr && strcmp(modstr, "exceptions") != 0) { PyFile_WriteString(modstr, f); PyFile_WriteString(".", f); } } if (className == NULL) PyFile_WriteString("<unknown>", f); else PyFile_WriteString(className, f); if (v && v != Py_None) { PyFile_WriteString(": ", f); PyFile_WriteObject(v, f, 0); } Py_XDECREF(moduleName); } PyFile_WriteString(" in ", f); PyFile_WriteObject(obj, f, 0); PyFile_WriteString(" ignored\n", f); PyErr_Clear(); /* Just in case */ } Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); }
static void show_warning(PyObject *filename, int lineno, PyObject *text, PyObject *category, PyObject *sourceline) { PyObject *f_stderr; PyObject *name; char lineno_str[128]; PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); name = PyObject_GetAttrString(category, "__name__"); if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ return; f_stderr = PySys_GetObject("stderr"); if (f_stderr == NULL) { fprintf(stderr, "lost sys.stderr\n"); Py_DECREF(name); return; } /* Print "filename:lineno: category: text\n" */ PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW); PyFile_WriteString(lineno_str, f_stderr); PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW); PyFile_WriteString(": ", f_stderr); PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW); PyFile_WriteString("\n", f_stderr); Py_XDECREF(name); /* Print " source_line\n" */ if (sourceline) { char *source_line_str = PyString_AS_STRING(sourceline); while (*source_line_str == ' ' || *source_line_str == '\t' || *source_line_str == '\014') source_line_str++; PyFile_WriteString(source_line_str, f_stderr); PyFile_WriteString("\n", f_stderr); } else _Py_DisplaySourceLine(f_stderr, PyString_AS_STRING(filename), lineno, 2); PyErr_Clear(); }
static int __Pyx_PrintNewline(void) { PyObject *f; if (!(f = __Pyx_GetStdout())) return -1; if (PyFile_WriteString("\n", f) < 0) return -1; PyFile_SoftSpace(f, 0); return 0; }
static void print_error_text(PyObject *f, int offset, const char *text) { char *nl; if (offset >= 0) { if (offset > 0 && offset == (int)strlen(text)) offset--; for (;;) { nl = strchr(text, '\n'); if (nl == NULL || nl-text >= offset) break; offset -= (int)(nl+1-text); text = nl+1; } while (*text == ' ' || *text == '\t') { text++; offset--; } } PyFile_WriteString(" ", f); PyFile_WriteString(text, f); if (*text == '\0' || text[strlen(text)-1] != '\n') PyFile_WriteString("\n", f); if (offset == -1) return; PyFile_WriteString(" ", f); offset--; while (offset > 0) { PyFile_WriteString(" ", f); offset--; } PyFile_WriteString("^\n", f); }
static void initsite(void) { PyObject *m, *f; m = PyImport_ImportModule("site"); if (m == NULL) { f = PySys_GetObject("stderr"); if (Py_VerboseFlag) { PyFile_WriteString( "'import site' failed; traceback:\n", f); PyErr_Print(); } else { PyFile_WriteString( "'import site' failed; use -v for traceback\n", f); PyErr_Clear(); } } else { Py_DECREF(m); } }
static void PrintError(char *msg, ...) { char buf[512]; PyObject *f = PySys_GetObject("stderr"); va_list marker; va_start(marker, msg); vsnprintf(buf, sizeof(buf), msg, marker); va_end(marker); if (f != NULL && f != Py_None) PyFile_WriteString(buf, f); PyErr_Print(); }
/* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void PyErr_WriteUnraisable(PyObject *obj) { PyObject *f, *t, *v, *tb; PyErr_Fetch(&t, &v, &tb); f = PySys_GetObject("stderr"); if (f != NULL) { PyFile_WriteString("Exception ", f); if (t) { PyFile_WriteObject(t, f, Py_PRINT_RAW); if (v && v != Py_None) { PyFile_WriteString(": ", f); PyFile_WriteObject(v, f, 0); } } PyFile_WriteString(" in ", f); PyFile_WriteObject(obj, f, 0); PyFile_WriteString(" ignored\n", f); PyErr_Clear(); /* Just in case */ } Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); }
void PyCom_StreamMessage(const char *pszMessageText) { #ifndef MS_WINCE OutputDebugStringA(pszMessageText); #else NKDbgPrintfW(pszMessageText); #endif // PySys_WriteStderr has an internal 1024 limit due to varargs. // weve already resolved them, so we gotta do it the hard way // We can't afford to screw with the Python exception state PyObject *typ, *val, *tb; PyErr_Fetch(&typ, &val, &tb); PyObject *pyfile = PySys_GetObject("stderr"); if (pyfile) if (PyFile_WriteString((char *)pszMessageText, pyfile)!=0) // eeek - Python error writing this error - write it to stdout. fprintf(stdout, "%s", pszMessageText); PyErr_Restore(typ, val, tb); }
static int __Pyx_PrintItem(PyObject *v) { PyObject *f; if (!(f = __Pyx_GetStdout())) return -1; if (PyFile_SoftSpace(f, 1)) { if (PyFile_WriteString(" ", f) < 0) return -1; } if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) return -1; if (PyString_Check(v)) { char *s = PyString_AsString(v); Py_ssize_t len = PyString_Size(v); if (len > 0 && isspace(Py_CHARMASK(s[len-1])) && s[len-1] != ' ') PyFile_SoftSpace(f, 0); } return 0; }
int PyTraceBack_Print(PyObject *v, PyObject *f) { int err; PyObject *limitv; long limit = PyTraceBack_LIMIT; if (v == NULL) return 0; if (!PyTraceBack_Check(v)) { PyErr_BadInternalCall(); return -1; } limitv = PySys_GetObject("tracebacklimit"); if (limitv) { PyObject *exc_type, *exc_value, *exc_tb; PyErr_Fetch(&exc_type, &exc_value, &exc_tb); limit = PyLong_AsLong(limitv); if (limit == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { limit = PyTraceBack_LIMIT; } else { Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); return 0; } } else if (limit <= 0) { limit = PyTraceBack_LIMIT; } PyErr_Restore(exc_type, exc_value, exc_tb); } err = PyFile_WriteString("Traceback (most recent call last):\n", f); if (!err) err = tb_printinternal((PyTracebackObject *)v, f, limit); return err; }
static void call_sys_exitfunc(void) { PyObject *exitfunc = PySys_GetObject("exitfunc"); if (exitfunc) { PyObject *res, *f; Py_INCREF(exitfunc); PySys_SetObject("exitfunc", (PyObject *)NULL); f = PySys_GetObject("stderr"); res = PyEval_CallObject(exitfunc, (PyObject *)NULL); if (res == NULL) { if (f) PyFile_WriteString("Error in sys.exitfunc:\n", f); PyErr_Print(); } Py_DECREF(exitfunc); } if (Py_FlushLine()) PyErr_Clear(); }
int PyTraceBack_Print(PyObject *v, PyObject *f) { int err; PyObject *limitv; int limit = 1000; if (v == NULL) return 0; if (!PyTraceBack_Check(v)) { PyErr_BadInternalCall(); return -1; } limitv = PySys_GetObject("tracebacklimit"); if (limitv && PyInt_Check(limitv)) { limit = PyInt_AsLong(limitv); if (limit <= 0) return 0; } err = PyFile_WriteString("Traceback (most recent call last):\n", f); if (!err) err = tb_printinternal((tracebackobject *)v, f, limit); return err; }
static void print_error_text(PyObject *f, int offset, PyObject *text_obj) { const char *text; const char *nl; text = PyUnicode_AsUTF8(text_obj); if (text == NULL) return; if (offset >= 0) { if (offset > 0 && (size_t)offset == strlen(text) && text[offset - 1] == '\n') offset--; for (;;) { nl = strchr(text, '\n'); if (nl == NULL || nl-text >= offset) break; offset -= (int)(nl+1-text); text = nl+1; } while (*text == ' ' || *text == '\t' || *text == '\f') { text++; offset--; } } PyFile_WriteString(" ", f); PyFile_WriteString(text, f); if (*text == '\0' || text[strlen(text)-1] != '\n') PyFile_WriteString("\n", f); if (offset == -1) return; PyFile_WriteString(" ", f); while (--offset > 0) PyFile_WriteString(" ", f); PyFile_WriteString("^\n", f); }
static int tb_displayline(PyObject *f, char *filename, int lineno, char *name) { int err = 0; FILE *xfp; char linebuf[2000]; int i; if (filename == NULL || name == NULL) return -1; #ifdef MPW /* This is needed by MPW's File and Line commands */ #define FMT " File \"%.500s\"; line %d # in %.500s\n" #else /* This is needed by Emacs' compile command */ #define FMT " File \"%.500s\", line %d, in %.500s\n" #endif xfp = fopen(filename, "r" PY_STDIOTEXTMODE); if (xfp == NULL) { /* Search tail of filename in sys.path before giving up */ PyObject *path; char *tail = strrchr(filename, SEP); if (tail == NULL) tail = filename; else tail++; path = PySys_GetObject("path"); if (path != NULL && PyList_Check(path)) { int npath = PyList_Size(path); size_t taillen = strlen(tail); char namebuf[MAXPATHLEN+1]; for (i = 0; i < npath; i++) { PyObject *v = PyList_GetItem(path, i); if (v == NULL) { PyErr_Clear(); break; } if (PyString_Check(v)) { size_t len; len = PyString_Size(v); if (len + 1 + taillen >= MAXPATHLEN) continue; /* Too long */ strcpy(namebuf, PyString_AsString(v)); if (strlen(namebuf) != len) continue; /* v contains '\0' */ if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; strcpy(namebuf+len, tail); xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE); if (xfp != NULL) { filename = namebuf; break; } } } } } PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name); err = PyFile_WriteString(linebuf, f); if (xfp == NULL || err != 0) return err; for (i = 0; i < lineno; i++) { char* pLastChar = &linebuf[sizeof(linebuf)-2]; do { *pLastChar = '\0'; if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, xfp, NULL) == NULL) break; /* fgets read *something*; if it didn't get as far as pLastChar, it must have found a newline or hit the end of the file; if pLastChar is \n, it obviously found a newline; else we haven't yet seen a newline, so must continue */ } while (*pLastChar != '\0' && *pLastChar != '\n'); } if (i == lineno) { char *p = linebuf; while (*p == ' ' || *p == '\t' || *p == '\014') p++; err = PyFile_WriteString(" ", f); if (err == 0) { err = PyFile_WriteString(p, f); if (err == 0 && strchr(p, '\n') == NULL) err = PyFile_WriteString("\n", f); } } fclose(xfp); return err; }
static void show_warning(PyObject *filename, int lineno, PyObject *text, PyObject *category, PyObject *sourceline) { PyObject *f_stderr; PyObject *name; char lineno_str[128]; _Py_IDENTIFIER(__name__); PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); name = _PyObject_GetAttrId(category, &PyId___name__); if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */ goto error; f_stderr = _PySys_GetObjectId(&PyId_stderr); if (f_stderr == NULL) { fprintf(stderr, "lost sys.stderr\n"); goto error; } /* Print "filename:lineno: category: text\n" */ if (PyFile_WriteObject(filename, f_stderr, Py_PRINT_RAW) < 0) goto error; if (PyFile_WriteString(lineno_str, f_stderr) < 0) goto error; if (PyFile_WriteObject(name, f_stderr, Py_PRINT_RAW) < 0) goto error; if (PyFile_WriteString(": ", f_stderr) < 0) goto error; if (PyFile_WriteObject(text, f_stderr, Py_PRINT_RAW) < 0) goto error; if (PyFile_WriteString("\n", f_stderr) < 0) goto error; Py_CLEAR(name); /* Print " source_line\n" */ if (sourceline) { int kind; void *data; Py_ssize_t i, len; Py_UCS4 ch; PyObject *truncated; if (PyUnicode_READY(sourceline) < 1) goto error; kind = PyUnicode_KIND(sourceline); data = PyUnicode_DATA(sourceline); len = PyUnicode_GET_LENGTH(sourceline); for (i=0; i<len; i++) { ch = PyUnicode_READ(kind, data, i); if (ch != ' ' && ch != '\t' && ch != '\014') break; } truncated = PyUnicode_Substring(sourceline, i, len); if (truncated == NULL) goto error; PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW); Py_DECREF(truncated); PyFile_WriteString("\n", f_stderr); } else { _Py_DisplaySourceLine(f_stderr, filename, lineno, 2); } error: Py_XDECREF(name); PyErr_Clear(); }
/* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void PyErr_WriteUnraisable(PyObject *obj) { _Py_IDENTIFIER(__module__); PyObject *f, *t, *v, *tb; PyObject *moduleName = NULL; char* className; PyErr_Fetch(&t, &v, &tb); f = _PySys_GetObjectId(&PyId_stderr); if (f == NULL || f == Py_None) goto done; if (obj) { if (PyFile_WriteString("Exception ignored in: ", f) < 0) goto done; if (PyFile_WriteObject(obj, f, 0) < 0) { PyErr_Clear(); if (PyFile_WriteString("<object repr() failed>", f) < 0) { goto done; } } if (PyFile_WriteString("\n", f) < 0) goto done; } if (PyTraceBack_Print(tb, f) < 0) goto done; if (!t) goto done; assert(PyExceptionClass_Check(t)); className = PyExceptionClass_Name(t); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = _PyObject_GetAttrId(t, &PyId___module__); if (moduleName == NULL) { PyErr_Clear(); if (PyFile_WriteString("<unknown>", f) < 0) goto done; } else { if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0) goto done; if (PyFile_WriteString(".", f) < 0) goto done; } } if (className == NULL) { if (PyFile_WriteString("<unknown>", f) < 0) goto done; } else { if (PyFile_WriteString(className, f) < 0) goto done; } if (v && v != Py_None) { if (PyFile_WriteString(": ", f) < 0) goto done; if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) { PyErr_Clear(); if (PyFile_WriteString("<exception str() failed>", f) < 0) { goto done; } } } if (PyFile_WriteString("\n", f) < 0) goto done; done: Py_XDECREF(moduleName); Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); PyErr_Clear(); /* Just in case */ }
/* int main(int argc, char **argv) { */ int main(int argc, char *argv[]) { char *env_argument = NULL; char *env_entrypoint = NULL; char *env_logname = NULL; char entrypoint[ENTRYPOINT_MAXLEN]; int ret = 0; FILE *fd; setenv("P4A_BOOTSTRAP", "SDL2", 1); // env var to identify p4a to applications LOGP("Initializing Python for Android"); env_argument = getenv("ANDROID_ARGUMENT"); setenv("ANDROID_APP_PATH", env_argument, 1); env_entrypoint = getenv("ANDROID_ENTRYPOINT"); env_logname = getenv("PYTHON_NAME"); if (!getenv("ANDROID_UNPACK")) { /* ANDROID_UNPACK currently isn't set in services */ setenv("ANDROID_UNPACK", env_argument, 1); } if (env_logname == NULL) { env_logname = "python"; setenv("PYTHON_NAME", "python", 1); } LOGP("Changing directory to the one provided by ANDROID_ARGUMENT"); LOGP(env_argument); chdir(env_argument); Py_SetProgramName(L"android_python"); #if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); #endif LOGP("Preparing to initialize python"); // Set up the python path char paths[256]; char crystax_python_dir[256]; snprintf(crystax_python_dir, 256, "%s/crystax_python", getenv("ANDROID_UNPACK")); char python_bundle_dir[256]; snprintf(python_bundle_dir, 256, "%s/_python_bundle", getenv("ANDROID_UNPACK")); if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) { if (dir_exists(crystax_python_dir)) { LOGP("crystax_python exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", crystax_python_dir, crystax_python_dir); } if (dir_exists(python_bundle_dir)) { LOGP("_python_bundle dir exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", python_bundle_dir, python_bundle_dir); } LOGP("calculated paths to be..."); LOGP(paths); #if PY_MAJOR_VERSION >= 3 wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); #else char *wchar_paths = paths; LOGP("Can't Py_SetPath in python2, so crystax python2 doesn't work yet"); exit(1); #endif LOGP("set wchar paths..."); } else { // We do not expect to see crystax_python any more, so no point // reminding the user about it. If it does exist, we'll have // logged it earlier. LOGP("_python_bundle does not exist"); } Py_Initialize(); #if PY_MAJOR_VERSION < 3 PySys_SetArgv(argc, argv); #endif LOGP("Initialized python"); /* ensure threads will work. */ LOGP("AND: Init threads"); PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 initandroidembed(); #endif PyRun_SimpleString("import androidembed\nandroidembed.log('testing python " "print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly */ LOGP("Setting up python from ANDROID_PRIVATE"); PyRun_SimpleString("private = posix.environ['ANDROID_APP_PATH']\n" "argument = posix.environ['ANDROID_ARGUMENT']\n" "sys.path[:] = [ \n" " private + '/lib/python27.zip', \n" " private + '/lib/python2.7/', \n" " private + '/lib/python2.7/lib-dynload/', \n" " private + '/lib/python2.7/site-packages/', \n" " argument ]\n"); } char add_site_packages_dir[256]; if (dir_exists(crystax_python_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", crystax_python_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } if (dir_exists(python_bundle_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", python_bundle_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( "class LogFile(object):\n" " def __init__(self):\n" " self.buffer = ''\n" " def write(self, s):\n" " s = self.buffer + s\n" " lines = s.split(\"\\n\")\n" " for l in lines[:-1]:\n" " androidembed.log(l)\n" " self.buffer = lines[-1]\n" " def flush(self):\n" " return\n" "sys.stdout = sys.stderr = LogFile()\n" "print('Android path', sys.path)\n" "import os\n" "print('os.environ is', os.environ)\n" "print('Android kivy bootstrap done. __name__ is', __name__)"); #if PY_MAJOR_VERSION < 3 PyRun_SimpleString("import site; print site.getsitepackages()\n"); #endif LOGP("AND: Ran string"); /* run it ! */ LOGP("Run user program, change dir and execute entrypoint"); /* Get the entrypoint, search the .pyo then .py */ char *dot = strrchr(env_entrypoint, '.'); if (dot <= 0) { LOGP("Invalid entrypoint, abort."); return -1; } if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) { LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN."); return -1; } if (!strcmp(dot, ".pyo")) { if (!file_exists(env_entrypoint)) { /* fallback on .py */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) - 1] = '\0'; LOGP(entrypoint); if (!file_exists(entrypoint)) { LOGP("Entrypoint not found (.pyo, fallback on .py), abort"); return -1; } } else { strcpy(entrypoint, env_entrypoint); } } else if (!strcmp(dot, ".py")) { /* if .py is passed, check the pyo version first */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) + 1] = '\0'; entrypoint[strlen(env_entrypoint)] = 'o'; if (!file_exists(entrypoint)) { /* fallback on pure python version */ if (!file_exists(env_entrypoint)) { LOGP("Entrypoint not found (.py), abort."); return -1; } strcpy(entrypoint, env_entrypoint); } } else { LOGP("Entrypoint have an invalid extension (must be .py or .pyo), abort."); return -1; } // LOGP("Entrypoint is:"); // LOGP(entrypoint); fd = fopen(entrypoint, "r"); if (fd == NULL) { LOGP("Open the entrypoint failed"); LOGP(entrypoint); return -1; } /* run python ! */ ret = PyRun_SimpleFile(fd, entrypoint); if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); if (PyFile_WriteString( "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ PyErr_Clear(); } /* close everything */ Py_Finalize(); fclose(fd); LOGP("Python for android ended."); return ret; }
/* int main(int argc, char **argv) { */ int main(int argc, char *argv[]) { char *env_argument = NULL; int ret = 0; FILE *fd; /* AND: Several filepaths are hardcoded here, these must be made configurable */ /* AND: P4A uses env vars...not sure what's best */ LOG("Initialize Python for Android"); /* env_argument = "/data/data/org.kivy.android/files"; */ env_argument = getenv("ANDROID_ARGUMENT"); /* setenv("ANDROID_APP_PATH", env_argument, 1); */ /* setenv("ANDROID_ARGUMENT", env_argument, 1); */ /* setenv("ANDROID_PRIVATE", env_argument, 1); */ /* setenv("ANDROID_APP_PATH", env_argument, 1); */ /* setenv("PYTHONHOME", env_argument, 1); */ /* setenv("PYTHONPATH", "/data/data/org.kivy.android/files:/data/data/org.kivy.android/files/lib", 1); */ /* LOG("AND: Set env vars"); */ /* LOG(argv[0]); */ /* LOG("AND: That was argv 0"); */ //setenv("PYTHONVERBOSE", "2", 1); LOG("Changing directory to the one provided by ANDROID_ARGUMENT"); LOG(env_argument); chdir(env_argument); Py_SetProgramName(L"android_python"); #if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); #endif LOG("Preparing to initialize python"); if (dir_exists("crystax_python/")) { LOG("crystax_python exists"); char paths[256]; snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument); /* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */ LOG("calculated paths to be..."); LOG(paths); #if PY_MAJOR_VERSION >= 3 wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); #else char* wchar_paths = paths; LOG("Can't Py_SetPath in python2, so crystax python2 doesn't work yet"); exit(1); #endif LOG("set wchar paths..."); } else { LOG("crystax_python does not exist");} Py_Initialize(); #if PY_MAJOR_VERSION < 3 PySys_SetArgv(argc, argv); #endif LOG("Initialized python"); /* ensure threads will work. */ LOG("AND: Init threads"); PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 initandroidembed(); #endif PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly */ LOG("Setting up python from ANDROID_PRIVATE"); PyRun_SimpleString( "private = posix.environ['ANDROID_PRIVATE']\n" \ "argument = posix.environ['ANDROID_ARGUMENT']\n" \ "sys.path[:] = [ \n" \ " private + '/lib/python27.zip', \n" \ " private + '/lib/python2.7/', \n" \ " private + '/lib/python2.7/lib-dynload/', \n" \ " private + '/lib/python2.7/site-packages/', \n" \ " argument ]\n"); } if (dir_exists("crystax_python")) { char add_site_packages_dir[256]; snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", env_argument); PyRun_SimpleString( "import sys\n" \ "sys.argv = ['notaninterpreterreally']\n" \ "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( "class LogFile(object):\n" \ " def __init__(self):\n" \ " self.buffer = ''\n" \ " def write(self, s):\n" \ " s = self.buffer + s\n" \ " lines = s.split(\"\\n\")\n" \ " for l in lines[:-1]:\n" \ " androidembed.log(l)\n" \ " self.buffer = lines[-1]\n" \ " def flush(self):\n" \ " return\n" \ "sys.stdout = sys.stderr = LogFile()\n" \ "print('Android path', sys.path)\n" \ "import os\n" \ "print('os.environ is', os.environ)\n" \ "print('Android kivy bootstrap done. __name__ is', __name__)"); /* PyRun_SimpleString( */ /* "import sys, posix\n" \ */ /* "private = posix.environ['ANDROID_PRIVATE']\n" \ */ /* "argument = posix.environ['ANDROID_ARGUMENT']\n" \ */ /* "sys.path[:] = [ \n" \ */ /* " private + '/lib/python27.zip', \n" \ */ /* " private + '/lib/python2.7/', \n" \ */ /* " private + '/lib/python2.7/lib-dynload/', \n" \ */ /* " private + '/lib/python2.7/site-packages/', \n" \ */ /* " argument ]\n" \ */ /* "import androidembed\n" \ */ /* "class LogFile(object):\n" \ */ /* " def __init__(self):\n" \ */ /* " self.buffer = ''\n" \ */ /* " def write(self, s):\n" \ */ /* " s = self.buffer + s\n" \ */ /* " lines = s.split(\"\\n\")\n" \ */ /* " for l in lines[:-1]:\n" \ */ /* " androidembed.log(l)\n" \ */ /* " self.buffer = lines[-1]\n" \ */ /* " def flush(self):\n" \ */ /* " return\n" \ */ /* "sys.stdout = sys.stderr = LogFile()\n" \ */ /* "import site; print site.getsitepackages()\n"\ */ /* "print 'Android path', sys.path\n" \ */ /* "print 'Android kivy bootstrap done. __name__ is', __name__"); */ LOG("AND: Ran string"); /* run it ! */ LOG("Run user program, change dir and execute main.py"); /* search the initial main.py */ char *main_py = "main.pyo"; if ( file_exists(main_py) == 0 ) { if ( file_exists("main.py") ) main_py = "main.py"; else main_py = NULL; } if ( main_py == NULL ) { LOG("No main.pyo / main.py found."); return -1; } fd = fopen(main_py, "r"); if ( fd == NULL ) { LOG("Open the main.py(o) failed"); return -1; } /* run python ! */ ret = PyRun_SimpleFile(fd, main_py); if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ PyErr_Clear(); } /* close everything */ Py_Finalize(); fclose(fd); LOG("Python for android ended."); return ret; }
void PyErr_PrintEx(int set_sys_last_vars) { int err = 0; PyObject *exception, *v, *tb, *f; PyErr_Fetch(&exception, &v, &tb); PyErr_NormalizeException(&exception, &v, &tb); if (exception == NULL) return; if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); if (v == NULL || v == Py_None) Py_Exit(0); if (PyInstance_Check(v)) { /* we expect the error code to be store in the `code' attribute */ PyObject *code = PyObject_GetAttrString(v, "code"); if (code) { Py_DECREF(v); v = code; if (v == Py_None) Py_Exit(0); } /* if we failed to dig out the "code" attribute, then just let the else clause below print the error */ } if (PyInt_Check(v)) Py_Exit((int)PyInt_AsLong(v)); else { /* OK to use real stderr here */ PyObject_Print(v, stderr, Py_PRINT_RAW); fprintf(stderr, "\n"); Py_Exit(1); } } if (set_sys_last_vars) { PySys_SetObject("last_type", exception); PySys_SetObject("last_value", v); PySys_SetObject("last_traceback", tb); } f = PySys_GetObject("stderr"); if (f == NULL) fprintf(stderr, "lost sys.stderr\n"); else { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); err = PyTraceBack_Print(tb, f); if (err == 0 && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) { PyObject *message; char *filename, *text; int lineno, offset; if (!parse_syntax_error(v, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { char buf[10]; PyFile_WriteString(" File \"", f); if (filename == NULL) PyFile_WriteString("<string>", f); else PyFile_WriteString(filename, f); PyFile_WriteString("\", line ", f); sprintf(buf, "%d", lineno); PyFile_WriteString(buf, f); PyFile_WriteString("\n", f); if (text != NULL) { char *nl; if (offset > 0 && offset == (int)strlen(text)) offset--; for (;;) { nl = strchr(text, '\n'); if (nl == NULL || nl-text >= offset) break; offset -= (nl+1-text); text = nl+1; } while (*text == ' ' || *text == '\t') { text++; offset--; } PyFile_WriteString(" ", f); PyFile_WriteString(text, f); if (*text == '\0' || text[strlen(text)-1] != '\n') PyFile_WriteString("\n", f); PyFile_WriteString(" ", f); offset--; while (offset > 0) { PyFile_WriteString(" ", f); offset--; } PyFile_WriteString("^\n", f); } Py_INCREF(message); Py_DECREF(v); v = message; /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else if (PyClass_Check(exception)) { PyClassObject* exc = (PyClassObject*)exception; PyObject* className = exc->cl_name; PyObject* moduleName = PyDict_GetItemString(exc->cl_dict, "__module__"); if (moduleName == NULL) err = PyFile_WriteString("<unknown>", f); else { char* modstr = PyString_AsString(moduleName); if (modstr && strcmp(modstr, "exceptions")) { err = PyFile_WriteString(modstr, f); err += PyFile_WriteString(".", f); } } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteObject(className, f, Py_PRINT_RAW); } } else err = PyFile_WriteObject(exception, f, Py_PRINT_RAW); if (err == 0) { if (v != NULL && v != Py_None) { PyObject *s = PyObject_Str(v); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) err = -1; else if (!PyString_Check(s) || PyString_GET_SIZE(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } } if (err == 0) err = PyFile_WriteString("\n", f); } Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
/* int main(int argc, char **argv) { */ int main(int argc, char *argv[]) { char *env_argument = NULL; char *env_entrypoint = NULL; char *env_logname = NULL; char entrypoint[ENTRYPOINT_MAXLEN]; int ret = 0; FILE *fd; LOGP("Initializing Python for Android"); // Set a couple of built-in environment vars: setenv("P4A_BOOTSTRAP", bootstrap_name, 1); // env var to identify p4a to applications env_argument = getenv("ANDROID_ARGUMENT"); setenv("ANDROID_APP_PATH", env_argument, 1); env_entrypoint = getenv("ANDROID_ENTRYPOINT"); env_logname = getenv("PYTHON_NAME"); if (!getenv("ANDROID_UNPACK")) { /* ANDROID_UNPACK currently isn't set in services */ setenv("ANDROID_UNPACK", env_argument, 1); } if (env_logname == NULL) { env_logname = "python"; setenv("PYTHON_NAME", "python", 1); } // Set additional file-provided environment vars: LOGP("Setting additional env vars from p4a_env_vars.txt"); char env_file_path[256]; snprintf(env_file_path, sizeof(env_file_path), "%s/p4a_env_vars.txt", getenv("ANDROID_UNPACK")); FILE *env_file_fd = fopen(env_file_path, "r"); if (env_file_fd) { char* line = NULL; size_t len = 0; while (getline(&line, &len, env_file_fd) != -1) { if (strlen(line) > 0) { char *eqsubstr = strstr(line, "="); if (eqsubstr) { size_t eq_pos = eqsubstr - line; // Extract name: char env_name[256]; strncpy(env_name, line, sizeof(env_name)); env_name[eq_pos] = '\0'; // Extract value (with line break removed: char env_value[256]; strncpy(env_value, (char*)(line + eq_pos + 1), sizeof(env_value)); if (strlen(env_value) > 0 && env_value[strlen(env_value)-1] == '\n') { env_value[strlen(env_value)-1] = '\0'; if (strlen(env_value) > 0 && env_value[strlen(env_value)-1] == '\r') { // Also remove windows line breaks (\r\n) env_value[strlen(env_value)-1] = '\0'; } } // Set value: setenv(env_name, env_value, 1); } } } fclose(env_file_fd); } else { LOGP("Warning: no p4a_env_vars.txt found / failed to open!"); } LOGP("Changing directory to the one provided by ANDROID_ARGUMENT"); LOGP(env_argument); chdir(env_argument); #if PY_MAJOR_VERSION < 3 Py_NoSiteFlag=1; #endif #if PY_MAJOR_VERSION < 3 Py_SetProgramName("android_python"); #else Py_SetProgramName(L"android_python"); #endif #if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); #endif LOGP("Preparing to initialize python"); // Set up the python path char paths[256]; char crystax_python_dir[256]; snprintf(crystax_python_dir, 256, "%s/crystax_python", getenv("ANDROID_UNPACK")); char python_bundle_dir[256]; snprintf(python_bundle_dir, 256, "%s/_python_bundle", getenv("ANDROID_UNPACK")); if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) { if (dir_exists(crystax_python_dir)) { LOGP("crystax_python exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", crystax_python_dir, crystax_python_dir); } if (dir_exists(python_bundle_dir)) { LOGP("_python_bundle dir exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", python_bundle_dir, python_bundle_dir); } LOGP("calculated paths to be..."); LOGP(paths); #if PY_MAJOR_VERSION >= 3 wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); #endif LOGP("set wchar paths..."); } else { // We do not expect to see crystax_python any more, so no point // reminding the user about it. If it does exist, we'll have // logged it earlier. LOGP("_python_bundle does not exist"); } Py_Initialize(); #if PY_MAJOR_VERSION < 3 // Can't Py_SetPath in python2 but we can set PySys_SetPath, which must // be applied after Py_Initialize rather than before like Py_SetPath #if PY_MICRO_VERSION >= 15 // Only for python native-build PySys_SetPath(paths); #endif PySys_SetArgv(argc, argv); #endif LOGP("Initialized python"); /* ensure threads will work. */ LOGP("AND: Init threads"); PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 initandroidembed(); #endif PyRun_SimpleString("import androidembed\nandroidembed.log('testing python " "print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly. * This is only the case if we are using the python2legacy recipe */ LOGP("Setting up python from ANDROID_APP_PATH"); PyRun_SimpleString("private = posix.environ['ANDROID_APP_PATH']\n" "argument = posix.environ['ANDROID_ARGUMENT']\n" "sys.path[:] = [ \n" " private + '/lib/python27.zip', \n" " private + '/lib/python2.7/', \n" " private + '/lib/python2.7/lib-dynload/', \n" " private + '/lib/python2.7/site-packages/', \n" " argument ]\n"); } char add_site_packages_dir[256]; if (dir_exists(crystax_python_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", crystax_python_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } if (dir_exists(python_bundle_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", python_bundle_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( "class LogFile(object):\n" " def __init__(self):\n" " self.buffer = ''\n" " def write(self, s):\n" " s = self.buffer + s\n" " lines = s.split(\"\\n\")\n" " for l in lines[:-1]:\n" " androidembed.log(l)\n" " self.buffer = lines[-1]\n" " def flush(self):\n" " return\n" "sys.stdout = sys.stderr = LogFile()\n" "print('Android path', sys.path)\n" "import os\n" "print('os.environ is', os.environ)\n" "print('Android kivy bootstrap done. __name__ is', __name__)"); #if PY_MAJOR_VERSION < 3 PyRun_SimpleString("import site; print site.getsitepackages()\n"); #endif LOGP("AND: Ran string"); /* run it ! */ LOGP("Run user program, change dir and execute entrypoint"); /* Get the entrypoint, search the .pyo then .py */ char *dot = strrchr(env_entrypoint, '.'); #if PY_MAJOR_VERSION > 2 char *ext = ".pyc"; #else char *ext = ".pyo"; #endif if (dot <= 0) { LOGP("Invalid entrypoint, abort."); return -1; } if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) { LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN."); return -1; } if (!strcmp(dot, ext)) { if (!file_exists(env_entrypoint)) { /* fallback on .py */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) - 1] = '\0'; LOGP(entrypoint); if (!file_exists(entrypoint)) { LOGP("Entrypoint not found (.pyc/.pyo, fallback on .py), abort"); return -1; } } else { strcpy(entrypoint, env_entrypoint); } } else if (!strcmp(dot, ".py")) { /* if .py is passed, check the pyo version first */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) + 1] = '\0'; #if PY_MAJOR_VERSION > 2 entrypoint[strlen(env_entrypoint)] = 'c'; #else entrypoint[strlen(env_entrypoint)] = 'o'; #endif if (!file_exists(entrypoint)) { /* fallback on pure python version */ if (!file_exists(env_entrypoint)) { LOGP("Entrypoint not found (.py), abort."); return -1; } strcpy(entrypoint, env_entrypoint); } } else { LOGP("Entrypoint have an invalid extension (must be .py or .pyc/.pyo), abort."); return -1; } // LOGP("Entrypoint is:"); // LOGP(entrypoint); fd = fopen(entrypoint, "r"); if (fd == NULL) { LOGP("Open the entrypoint failed"); LOGP(entrypoint); return -1; } /* run python ! */ ret = PyRun_SimpleFile(fd, entrypoint); fclose(fd); if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); if (PyFile_WriteString( "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ PyErr_Clear(); } LOGP("Python for android ended."); /* Shut down: since regular shutdown causes issues sometimes (seems to be an incomplete shutdown breaking next launch) we'll use sys.exit(ret) to shutdown, since that one works. Reference discussion: https://github.com/kivy/kivy/pull/6107#issue-246120816 */ char terminatecmd[256]; snprintf( terminatecmd, sizeof(terminatecmd), "import sys; sys.exit(%d)\n", ret ); PyRun_SimpleString(terminatecmd); /* This should never actually be reached, but we'll leave the clean-up * here just to be safe. */ #if PY_MAJOR_VERSION < 3 Py_Finalize(); LOGP("Unexpectedly reached Py_FinalizeEx(), but was successful."); #else if (Py_FinalizeEx() != 0) // properly check success on Python 3 LOGP("Unexpectedly reached Py_FinalizeEx(), and got error!"); else LOGP("Unexpectedly reached Py_FinalizeEx(), but was successful."); #endif return ret; }
void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { int err = 0; PyObject *f = PySys_GetObject("stderr"); Py_INCREF(value); if (f == NULL) fprintf(stderr, "lost sys.stderr\n"); else { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && PyObject_HasAttrString(value, "print_file_and_line")) { PyObject *message; const char *filename, *text; int lineno, offset; if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { char buf[10]; PyFile_WriteString(" File \"", f); if (filename == NULL) PyFile_WriteString("<string>", f); else PyFile_WriteString(filename, f); PyFile_WriteString("\", line ", f); PyOS_snprintf(buf, sizeof(buf), "%d", lineno); PyFile_WriteString(buf, f); PyFile_WriteString("\n", f); if (text != NULL) print_error_text(f, offset, text); Py_DECREF(value); value = message; /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else if (PyExceptionClass_Check(exception)) { PyObject* moduleName; char* className = PyExceptionClass_Name(exception); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = PyObject_GetAttrString(exception, "__module__"); if (moduleName == NULL) err = PyFile_WriteString("<unknown>", f); else { char* modstr = PyString_AsString(moduleName); if (modstr && strcmp(modstr, "exceptions")) { err = PyFile_WriteString(modstr, f); err += PyFile_WriteString(".", f); } Py_DECREF(moduleName); } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteString(className, f); } } else err = PyFile_WriteObject(exception, f, Py_PRINT_RAW); if (err == 0 && (value != Py_None)) { PyObject *s = PyObject_Str(value); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) err = -1; else if (!PyString_Check(s) || PyString_GET_SIZE(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } if (err == 0) err = PyFile_WriteString("\n", f); } Py_DECREF(value); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
static void print_exception(PyObject *f, PyObject *value) { int err = 0; PyObject *type, *tb; _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); err += PyFile_WriteString(" found\n", f); if (err) PyErr_Clear(); return; } Py_INCREF(value); fflush(stdout); type = (PyObject *) Py_TYPE(value); tb = PyException_GetTraceback(value); if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && _PyObject_HasAttrId(value, &PyId_print_file_and_line)) { PyObject *message, *filename, *text; int lineno, offset; if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { PyObject *line; Py_DECREF(value); value = message; line = PyUnicode_FromFormat(" File \"%U\", line %d\n", filename, lineno); Py_DECREF(filename); if (line != NULL) { PyFile_WriteObject(line, f, Py_PRINT_RAW); Py_DECREF(line); } if (text != NULL) { print_error_text(f, offset, text); Py_DECREF(text); } /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else { PyObject* moduleName; const char *className; _Py_IDENTIFIER(__module__); assert(PyExceptionClass_Check(type)); className = PyExceptionClass_Name(type); if (className != NULL) { const char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = _PyObject_GetAttrId(type, &PyId___module__); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { Py_XDECREF(moduleName); err = PyFile_WriteString("<unknown>", f); } else { if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f); } Py_DECREF(moduleName); } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteString(className, f); } } if (err == 0 && (value != Py_None)) { PyObject *s = PyObject_Str(value); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) { PyErr_Clear(); err = -1; PyFile_WriteString(": <exception str() failed>", f); } else if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } /* try to write a newline in any case */ if (err < 0) { PyErr_Clear(); } err += PyFile_WriteString("\n", f); Py_XDECREF(tb); Py_DECREF(value); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
static void green_dealloc(PyGreenlet* self) { PyObject *error_type, *error_value, *error_traceback; #ifdef GREENLET_USE_GC PyObject_GC_UnTrack((PyObject *)self); Py_TRASHCAN_SAFE_BEGIN(self); #endif /* GREENLET_USE_GC */ if (PyGreenlet_ACTIVE(self) && self->run_info != NULL && !PyGreenlet_MAIN(self)) { /* Hacks hacks hacks copied from instance_dealloc() */ /* Temporarily resurrect the greenlet. */ assert(Py_REFCNT(self) == 0); Py_REFCNT(self) = 1; /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); if (kill_greenlet(self) < 0) { PyErr_WriteUnraisable((PyObject*) self); /* XXX what else should we do? */ } /* Check for no resurrection must be done while we keep * our internal reference, otherwise PyFile_WriteObject * causes recursion if using Py_INCREF/Py_DECREF */ if (Py_REFCNT(self) == 1 && PyGreenlet_ACTIVE(self)) { /* Not resurrected, but still not dead! XXX what else should we do? we complain. */ PyObject* f = PySys_GetObject("stderr"); Py_INCREF(self); /* leak! */ if (f != NULL) { PyFile_WriteString("GreenletExit did not kill ", f); PyFile_WriteObject((PyObject*) self, f, 0); PyFile_WriteString("\n", f); } } /* Restore the saved exception. */ PyErr_Restore(error_type, error_value, error_traceback); /* Undo the temporary resurrection; can't use DECREF here, * it would cause a recursive call. */ assert(Py_REFCNT(self) > 0); if (--Py_REFCNT(self) != 0) { /* Resurrected! */ Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference((PyObject*) self); Py_REFCNT(self) = refcnt; #ifdef GREENLET_USE_GC PyObject_GC_Track((PyObject *)self); #endif _Py_DEC_REFTOTAL; #ifdef COUNT_ALLOCS --Py_TYPE(self)->tp_frees; --Py_TYPE(self)->tp_allocs; #endif /* COUNT_ALLOCS */ goto green_dealloc_end; } } if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_CLEAR(self->parent); Py_CLEAR(self->run_info); Py_CLEAR(self->exc_type); Py_CLEAR(self->exc_value); Py_CLEAR(self->exc_traceback); Py_CLEAR(self->dict); Py_TYPE(self)->tp_free((PyObject*) self); green_dealloc_end: #ifdef GREENLET_USE_GC Py_TRASHCAN_SAFE_END(self); #endif /* GREENLET_USE_GC */ return; }
int _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) { int err = 0; int fd; int i; char *found_encoding; char *encoding; PyObject *io; PyObject *binary; PyObject *fob = NULL; PyObject *lineobj = NULL; PyObject *res; char buf[MAXPATHLEN+1]; int kind; void *data; /* open the file */ if (filename == NULL) return 0; io = PyImport_ImportModuleNoBlock("io"); if (io == NULL) return -1; binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb"); if (binary == NULL) { PyErr_Clear(); binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); if (binary == NULL) { Py_DECREF(io); return -1; } } /* use the right encoding to decode the file as unicode */ fd = PyObject_AsFileDescriptor(binary); if (fd < 0) { Py_DECREF(io); Py_DECREF(binary); return 0; } found_encoding = PyTokenizer_FindEncodingFilename(fd, filename); if (found_encoding == NULL) PyErr_Clear(); encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; /* Reset position */ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { Py_DECREF(io); Py_DECREF(binary); PyMem_FREE(found_encoding); return 0; } fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); Py_DECREF(io); Py_DECREF(binary); PyMem_FREE(found_encoding); if (fob == NULL) { PyErr_Clear(); return 0; } /* get the line number lineno */ for (i = 0; i < lineno; i++) { Py_XDECREF(lineobj); lineobj = PyFile_GetLine(fob, -1); if (!lineobj) { err = -1; break; } } res = _PyObject_CallMethodId(fob, &PyId_close, ""); if (res) Py_DECREF(res); else PyErr_Clear(); Py_DECREF(fob); if (!lineobj || !PyUnicode_Check(lineobj)) { Py_XDECREF(lineobj); return err; } /* remove the indentation of the line */ kind = PyUnicode_KIND(lineobj); data = PyUnicode_DATA(lineobj); for (i=0; i < PyUnicode_GET_LENGTH(lineobj); i++) { Py_UCS4 ch = PyUnicode_READ(kind, data, i); if (ch != ' ' && ch != '\t' && ch != '\014') break; } if (i) { PyObject *truncated; truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj)); if (truncated) { Py_DECREF(lineobj); lineobj = truncated; } else { PyErr_Clear(); } } /* Write some spaces before the line */ strcpy(buf, " "); assert (strlen(buf) == 10); while (indent > 0) { if (indent < 10) buf[indent] = '\0'; err = PyFile_WriteString(buf, f); if (err != 0) break; indent -= 10; } /* finally display the line */ if (err == 0) err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW); Py_DECREF(lineobj); if (err == 0) err = PyFile_WriteString("\n", f); return err; }