summaryrefslogtreecommitdiffstats
path: root/Python/pythonrun.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r--Python/pythonrun.c1482
1 files changed, 388 insertions, 1094 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index dd32017..a2e1e74 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -11,10 +11,13 @@
#include "parsetok.h"
#include "errcode.h"
#include "code.h"
+#include "compile.h"
#include "symtable.h"
+#include "pyarena.h"
#include "ast.h"
+#include "eval.h"
#include "marshal.h"
-#include "osdefs.h"
+#include "abstract.h"
#ifdef HAVE_SIGNAL_H
#include <signal.h>
@@ -32,7 +35,6 @@
#ifdef MS_WINDOWS
#undef BYTE
#include "windows.h"
-#define PATH_MAX MAXPATHLEN
#endif
#ifndef Py_REF_DEBUG
@@ -47,32 +49,24 @@
extern "C" {
#endif
-extern wchar_t *Py_GetPath(void);
+extern char *Py_GetPath(void);
extern grammar _PyParser_Grammar; /* From graminit.c */
/* Forward */
-static void initmain(PyInterpreterState *interp);
-static int initfsencoding(PyInterpreterState *interp);
+static void initmain(void);
static void initsite(void);
-static int initstdio(void);
-static void flush_io(void);
static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
PyCompilerFlags *, PyArena *);
static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
PyCompilerFlags *);
static void err_input(perrdetail *);
-static void err_free(perrdetail *);
static void initsigs(void);
-static void call_py_exitfuncs(void);
static void wait_for_thread_shutdown(void);
+static void call_sys_exitfunc(void);
static void call_ll_exitfuncs(void);
-extern int _PyUnicode_Init(void);
+extern void _PyUnicode_Init(void);
extern void _PyUnicode_Fini(void);
-extern int _PyLong_Init(void);
-extern void PyLong_Fini(void);
-extern int _PyFaulthandler_Init(void);
-extern void _PyFaulthandler_Fini(void);
#ifdef WITH_THREAD
extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
@@ -81,7 +75,6 @@ extern void _PyGILState_Fini(void);
int Py_DebugFlag; /* Needed by parser.c */
int Py_VerboseFlag; /* Needed by import.c */
-int Py_QuietFlag; /* Needed by sysmodule.c */
int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */
int Py_NoSiteFlag; /* Suppress 'import site' */
@@ -89,13 +82,15 @@ int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */
int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */
int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
int Py_FrozenFlag; /* Needed by getpath.c */
+int Py_UnicodeFlag = 0; /* Needed by compile.c */
int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
+/* _XXX Py_QnewFlag should go away in 2.3. It's true iff -Qnew is passed,
+ on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
+ true divisions (which they will be in 2.3). */
+int _Py_QnewFlag = 0;
int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
-int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
-PyThreadState *_Py_Finalizing = NULL;
-
/* PyModule_GetWarningsModule is no longer necessary as of 2.6
since _warnings is builtin. This API should not be used. */
PyObject *
@@ -137,130 +132,32 @@ add_flag(int flag, const char *envs)
return flag;
}
-static char*
-get_codec_name(const char *encoding)
-{
- char *name_utf8, *name_str;
- PyObject *codec, *name = NULL;
- _Py_IDENTIFIER(name);
-
- codec = _PyCodec_Lookup(encoding);
- if (!codec)
- goto error;
-
- name = _PyObject_GetAttrId(codec, &PyId_name);
- Py_CLEAR(codec);
- if (!name)
- goto error;
-
- name_utf8 = _PyUnicode_AsString(name);
- if (name_utf8 == NULL)
- goto error;
- name_str = strdup(name_utf8);
- Py_DECREF(name);
- if (name_str == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- return name_str;
-
-error:
- Py_XDECREF(codec);
- Py_XDECREF(name);
- return NULL;
-}
-
-static char*
-get_locale_encoding(void)
-{
-#ifdef MS_WINDOWS
- char codepage[100];
- PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP());
- return get_codec_name(codepage);
-#elif defined(HAVE_LANGINFO_H) && defined(CODESET)
- char* codeset = nl_langinfo(CODESET);
- if (!codeset || codeset[0] == '\0') {
- PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty");
- return NULL;
- }
- return get_codec_name(codeset);
-#else
- PyErr_SetNone(PyExc_NotImplementedError);
- return NULL;
-#endif
-}
-
-static void
-import_init(PyInterpreterState *interp, PyObject *sysmod)
-{
- PyObject *importlib;
- PyObject *impmod;
- PyObject *sys_modules;
- PyObject *value;
-
- /* Import _importlib through its frozen version, _frozen_importlib. */
- if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
- Py_FatalError("Py_Initialize: can't import _frozen_importlib");
- }
- else if (Py_VerboseFlag) {
- PySys_FormatStderr("import _frozen_importlib # frozen\n");
- }
- importlib = PyImport_AddModule("_frozen_importlib");
- if (importlib == NULL) {
- Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from "
- "sys.modules");
- }
- interp->importlib = importlib;
- Py_INCREF(interp->importlib);
-
- /* Install _importlib as __import__ */
- impmod = PyInit_imp();
- if (impmod == NULL) {
- Py_FatalError("Py_Initialize: can't import imp");
- }
- else if (Py_VerboseFlag) {
- PySys_FormatStderr("import imp # builtin\n");
- }
- sys_modules = PyImport_GetModuleDict();
- if (Py_VerboseFlag) {
- PySys_FormatStderr("import sys # builtin\n");
- }
- if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) {
- Py_FatalError("Py_Initialize: can't save _imp to sys.modules");
- }
-
- value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod);
- if (value == NULL) {
- PyErr_Print();
- Py_FatalError("Py_Initialize: importlib install failed");
- }
- Py_DECREF(value);
- Py_DECREF(impmod);
-
- _PyImportZip_Init();
-}
-
-
void
-_Py_InitializeEx_Private(int install_sigs, int install_importlib)
+Py_InitializeEx(int install_sigs)
{
PyInterpreterState *interp;
PyThreadState *tstate;
- PyObject *bimod, *sysmod, *pstderr;
+ PyObject *bimod, *sysmod;
char *p;
+ char *icodeset = NULL; /* On Windows, input codeset may theoretically
+ differ from output codeset. */
+ char *codeset = NULL;
+ char *errors = NULL;
+ int free_codeset = 0;
+ int overridden = 0;
+ PyObject *sys_stream, *sys_isatty;
+#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
+ char *saved_locale, *loc_codeset;
+#endif
+#ifdef MS_WINDOWS
+ char ibuf[128];
+ char buf[128];
+#endif
extern void _Py_ReadyTypes(void);
if (initialized)
return;
initialized = 1;
- _Py_Finalizing = NULL;
-
-#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE)
- /* Set up the LC_CTYPE locale, so we can obtain
- the locale's charset without having to switch
- locales. */
- setlocale(LC_CTYPE, "");
-#endif
if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')
Py_DebugFlag = add_flag(Py_DebugFlag, p);
@@ -286,23 +183,14 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
Py_FatalError("Py_Initialize: can't make first thread");
(void) PyThreadState_Swap(tstate);
-#ifdef WITH_THREAD
- /* We can't call _PyEval_FiniThreads() in Py_Finalize because
- destroying the GIL might fail when it is being referenced from
- another running thread (see issue #9901).
- Instead we destroy the previously created GIL here, which ensures
- that we can call Py_Initialize / Py_Finalize multiple times. */
- _PyEval_FiniThreads();
-
- /* Auto-thread-state API */
- _PyGILState_Init(interp, tstate);
-#endif /* WITH_THREAD */
-
_Py_ReadyTypes();
if (!_PyFrame_Init())
Py_FatalError("Py_Initialize: can't init frames");
+ if (!_PyInt_Init())
+ Py_FatalError("Py_Initialize: can't init ints");
+
if (!_PyLong_Init())
Py_FatalError("Py_Initialize: can't init longs");
@@ -314,23 +202,23 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
interp->modules = PyDict_New();
if (interp->modules == NULL)
Py_FatalError("Py_Initialize: can't make modules dictionary");
+ interp->modules_reloading = PyDict_New();
+ if (interp->modules_reloading == NULL)
+ Py_FatalError("Py_Initialize: can't make modules_reloading dictionary");
+#ifdef Py_USING_UNICODE
/* Init Unicode implementation; relies on the codec registry */
- if (_PyUnicode_Init() < 0)
- Py_FatalError("Py_Initialize: can't initialize unicode");
+ _PyUnicode_Init();
+#endif
bimod = _PyBuiltin_Init();
if (bimod == NULL)
- Py_FatalError("Py_Initialize: can't initialize builtins modules");
- _PyImport_FixupBuiltin(bimod, "builtins");
+ Py_FatalError("Py_Initialize: can't initialize __builtin__");
interp->builtins = PyModule_GetDict(bimod);
if (interp->builtins == NULL)
Py_FatalError("Py_Initialize: can't initialize builtins dict");
Py_INCREF(interp->builtins);
- /* initialize builtin exceptions */
- _PyExc_Init(bimod);
-
sysmod = _PySys_Init();
if (sysmod == NULL)
Py_FatalError("Py_Initialize: can't initialize sys");
@@ -338,67 +226,149 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
if (interp->sysdict == NULL)
Py_FatalError("Py_Initialize: can't initialize sys dict");
Py_INCREF(interp->sysdict);
- _PyImport_FixupBuiltin(sysmod, "sys");
+ _PyImport_FixupExtension("sys", "sys");
PySys_SetPath(Py_GetPath());
PyDict_SetItemString(interp->sysdict, "modules",
interp->modules);
- /* Set up a preliminary stderr printer until we have enough
- infrastructure for the io module in place. */
- pstderr = PyFile_NewStdPrinter(fileno(stderr));
- if (pstderr == NULL)
- Py_FatalError("Py_Initialize: can't set preliminary stderr");
- PySys_SetObject("stderr", pstderr);
- PySys_SetObject("__stderr__", pstderr);
- Py_DECREF(pstderr);
-
_PyImport_Init();
- _PyImportHooks_Init();
-
- /* Initialize _warnings. */
- _PyWarnings_Init();
-
- if (!install_importlib)
- return;
-
- import_init(interp, sysmod);
-
- /* initialize the faulthandler module */
- if (_PyFaulthandler_Init())
- Py_FatalError("Py_Initialize: can't initialize faulthandler");
+ /* initialize builtin exceptions */
+ _PyExc_Init();
+ _PyImport_FixupExtension("exceptions", "exceptions");
- _PyTime_Init();
+ /* phase 2 of builtins */
+ _PyImport_FixupExtension("__builtin__", "__builtin__");
- if (initfsencoding(interp) < 0)
- Py_FatalError("Py_Initialize: unable to load the file system codec");
+ _PyImportHooks_Init();
if (install_sigs)
initsigs(); /* Signal handling stuff, including initintr() */
- initmain(interp); /* Module __main__ */
- if (initstdio() < 0)
- Py_FatalError(
- "Py_Initialize: can't initialize sys standard streams");
-
/* Initialize warnings. */
+ _PyWarnings_Init();
if (PySys_HasWarnOptions()) {
PyObject *warnings_module = PyImport_ImportModule("warnings");
- if (warnings_module == NULL) {
- fprintf(stderr, "'import warnings' failed; traceback:\n");
- PyErr_Print();
- }
+ if (!warnings_module)
+ PyErr_Clear();
Py_XDECREF(warnings_module);
}
+ initmain(); /* Module __main__ */
+
+ /* auto-thread-state API, if available */
+#ifdef WITH_THREAD
+ _PyGILState_Init(interp, tstate);
+#endif /* WITH_THREAD */
+
if (!Py_NoSiteFlag)
initsite(); /* Module site */
-}
-void
-Py_InitializeEx(int install_sigs)
-{
- _Py_InitializeEx_Private(install_sigs, 1);
+ if ((p = Py_GETENV("PYTHONIOENCODING")) && *p != '\0') {
+ p = icodeset = codeset = strdup(p);
+ free_codeset = 1;
+ errors = strchr(p, ':');
+ if (errors) {
+ *errors = '\0';
+ errors++;
+ }
+ overridden = 1;
+ }
+
+#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
+ /* On Unix, set the file system encoding according to the
+ user's preference, if the CODESET names a well-known
+ Python codec, and Py_FileSystemDefaultEncoding isn't
+ initialized by other means. Also set the encoding of
+ stdin and stdout if these are terminals, unless overridden. */
+
+ if (!overridden || !Py_FileSystemDefaultEncoding) {
+ saved_locale = strdup(setlocale(LC_CTYPE, NULL));
+ setlocale(LC_CTYPE, "");
+ loc_codeset = nl_langinfo(CODESET);
+ if (loc_codeset && *loc_codeset) {
+ PyObject *enc = PyCodec_Encoder(loc_codeset);
+ if (enc) {
+ loc_codeset = strdup(loc_codeset);
+ Py_DECREF(enc);
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+ PyErr_Clear();
+ loc_codeset = NULL;
+ } else {
+ PyErr_Print();
+ exit(1);
+ }
+ }
+ } else
+ loc_codeset = NULL;
+ setlocale(LC_CTYPE, saved_locale);
+ free(saved_locale);
+
+ if (!overridden) {
+ codeset = icodeset = loc_codeset;
+ free_codeset = 1;
+ }
+
+ /* Initialize Py_FileSystemDefaultEncoding from
+ locale even if PYTHONIOENCODING is set. */
+ if (!Py_FileSystemDefaultEncoding) {
+ Py_FileSystemDefaultEncoding = loc_codeset;
+ if (!overridden)
+ free_codeset = 0;
+ }
+ }
+#endif
+
+#ifdef MS_WINDOWS
+ if (!overridden) {
+ icodeset = ibuf;
+ codeset = buf;
+ sprintf(ibuf, "cp%d", GetConsoleCP());
+ sprintf(buf, "cp%d", GetConsoleOutputCP());
+ }
+#endif
+
+ if (codeset) {
+ sys_stream = PySys_GetObject("stdin");
+ sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
+ if (!sys_isatty)
+ PyErr_Clear();
+ if ((overridden ||
+ (sys_isatty && PyObject_IsTrue(sys_isatty))) &&
+ PyFile_Check(sys_stream)) {
+ if (!PyFile_SetEncodingAndErrors(sys_stream, icodeset, errors))
+ Py_FatalError("Cannot set codeset of stdin");
+ }
+ Py_XDECREF(sys_isatty);
+
+ sys_stream = PySys_GetObject("stdout");
+ sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
+ if (!sys_isatty)
+ PyErr_Clear();
+ if ((overridden ||
+ (sys_isatty && PyObject_IsTrue(sys_isatty))) &&
+ PyFile_Check(sys_stream)) {
+ if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors))
+ Py_FatalError("Cannot set codeset of stdout");
+ }
+ Py_XDECREF(sys_isatty);
+
+ sys_stream = PySys_GetObject("stderr");
+ sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
+ if (!sys_isatty)
+ PyErr_Clear();
+ if((overridden ||
+ (sys_isatty && PyObject_IsTrue(sys_isatty))) &&
+ PyFile_Check(sys_stream)) {
+ if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors))
+ Py_FatalError("Cannot set codeset of stderr");
+ }
+ Py_XDECREF(sys_isatty);
+
+ if (free_codeset)
+ free(codeset);
+ }
}
void
@@ -412,49 +382,6 @@ Py_Initialize(void)
extern void dump_counts(FILE*);
#endif
-/* Flush stdout and stderr */
-
-static int
-file_is_closed(PyObject *fobj)
-{
- int r;
- PyObject *tmp = PyObject_GetAttrString(fobj, "closed");
- if (tmp == NULL) {
- PyErr_Clear();
- return 0;
- }
- r = PyObject_IsTrue(tmp);
- Py_DECREF(tmp);
- if (r < 0)
- PyErr_Clear();
- return r > 0;
-}
-
-static void
-flush_std_files(void)
-{
- PyObject *fout = PySys_GetObject("stdout");
- PyObject *ferr = PySys_GetObject("stderr");
- PyObject *tmp;
- _Py_IDENTIFIER(flush);
-
- if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
- tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
- if (tmp == NULL)
- PyErr_WriteUnraisable(fout);
- else
- Py_DECREF(tmp);
- }
-
- if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
- tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");
- if (tmp == NULL)
- PyErr_Clear();
- else
- Py_DECREF(tmp);
- }
-}
-
/* Undo the effect of Py_Initialize().
Beware: if multiple interpreter and/or thread states exist, these
@@ -489,20 +416,13 @@ Py_Finalize(void)
* threads created thru it, so this also protects pending imports in
* the threads created via Threading.
*/
- call_py_exitfuncs();
+ call_sys_exitfunc();
+ initialized = 0;
/* Get current thread state and interpreter pointer */
tstate = PyThreadState_GET();
interp = tstate->interp;
- /* Remaining threads (e.g. daemon threads) will automatically exit
- after taking the GIL (in PyEval_RestoreThread()). */
- _Py_Finalizing = tstate;
- initialized = 0;
-
- /* Flush stdout+stderr */
- flush_std_files();
-
/* Disable signal handling */
PyOS_FiniInterrupts();
@@ -529,18 +449,12 @@ Py_Finalize(void)
while (PyGC_Collect() > 0)
/* nothing */;
#endif
- /* We run this while most interpreter state is still alive, so that
- debug information can be printed out */
- _PyGC_Fini();
/* Destroy all modules */
PyImport_Cleanup();
- /* Flush stdout+stderr (again, in case more was printed) */
- flush_std_files();
-
/* Collect final garbage. This disposes of cycles created by
- * class definitions, for example.
+ * new-style class definitions, for example.
* XXX This is disabled because it caused too many problems. If
* XXX a __del__ or weakref callback triggers here, Python code has
* XXX a hard time running, because even the sys module has been
@@ -561,9 +475,6 @@ Py_Finalize(void)
/* Destroy the database used by _PyImport_{Fixup,Find}Extension */
_PyImport_Fini();
- /* unload faulthandler module */
- _PyFaulthandler_Fini();
-
/* Debugging stuff */
#ifdef COUNT_ALLOCS
dump_counts(stdout);
@@ -608,21 +519,16 @@ Py_Finalize(void)
PyTuple_Fini();
PyList_Fini();
PySet_Fini();
- PyBytes_Fini();
+ PyString_Fini();
PyByteArray_Fini();
- PyLong_Fini();
+ PyInt_Fini();
PyFloat_Fini();
PyDict_Fini();
- PySlice_Fini();
+#ifdef Py_USING_UNICODE
/* Cleanup Unicode implementation */
_PyUnicode_Fini();
-
- /* reset file system default encoding */
- if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
- free((char*)Py_FileSystemDefaultEncoding);
- Py_FileSystemDefaultEncoding = NULL;
- }
+#endif
/* XXX Still allocated:
- various static ad-hoc pointers to interned strings
@@ -642,7 +548,7 @@ Py_Finalize(void)
#endif /* Py_TRACE_REFS */
#ifdef PYMALLOC_DEBUG
if (Py_GETENV("PYTHONMALLOCSTATS"))
- _PyObject_DebugMallocStats(stderr);
+ _PyObject_DebugMallocStats();
#endif
call_ll_exitfuncs();
@@ -686,22 +592,17 @@ Py_NewInterpreter(void)
/* XXX The following is lax in error checking */
interp->modules = PyDict_New();
+ interp->modules_reloading = PyDict_New();
- bimod = _PyImport_FindBuiltin("builtins");
+ bimod = _PyImport_FindExtension("__builtin__", "__builtin__");
if (bimod != NULL) {
interp->builtins = PyModule_GetDict(bimod);
if (interp->builtins == NULL)
goto handle_error;
Py_INCREF(interp->builtins);
}
-
- /* initialize builtin exceptions */
- _PyExc_Init(bimod);
-
- sysmod = _PyImport_FindBuiltin("sys");
+ sysmod = _PyImport_FindExtension("sys", "sys");
if (bimod != NULL && sysmod != NULL) {
- PyObject *pstderr;
-
interp->sysdict = PyModule_GetDict(sysmod);
if (interp->sysdict == NULL)
goto handle_error;
@@ -709,26 +610,8 @@ Py_NewInterpreter(void)
PySys_SetPath(Py_GetPath());
PyDict_SetItemString(interp->sysdict, "modules",
interp->modules);
- /* Set up a preliminary stderr printer until we have enough
- infrastructure for the io module in place. */
- pstderr = PyFile_NewStdPrinter(fileno(stderr));
- if (pstderr == NULL)
- Py_FatalError("Py_Initialize: can't set preliminary stderr");
- PySys_SetObject("stderr", pstderr);
- PySys_SetObject("__stderr__", pstderr);
- Py_DECREF(pstderr);
-
_PyImportHooks_Init();
-
- import_init(interp, sysmod);
-
- if (initfsencoding(interp) < 0)
- goto handle_error;
-
- if (initstdio() < 0)
- Py_FatalError(
- "Py_Initialize: can't initialize sys standard streams");
- initmain(interp);
+ initmain();
if (!Py_NoSiteFlag)
initsite();
}
@@ -739,7 +622,7 @@ Py_NewInterpreter(void)
handle_error:
/* Oops, it didn't work. Undo it all. */
- PyErr_PrintEx(0);
+ PyErr_Print();
PyThreadState_Clear(tstate);
PyThreadState_Swap(save_tstate);
PyThreadState_Delete(tstate);
@@ -778,54 +661,42 @@ Py_EndInterpreter(PyThreadState *tstate)
PyInterpreterState_Delete(interp);
}
-#ifdef MS_WINDOWS
-static wchar_t *progname = L"python";
-#else
-static wchar_t *progname = L"python3";
-#endif
+static char *progname = "python";
void
-Py_SetProgramName(wchar_t *pn)
+Py_SetProgramName(char *pn)
{
if (pn && *pn)
progname = pn;
}
-wchar_t *
+char *
Py_GetProgramName(void)
{
return progname;
}
-static wchar_t *default_home = NULL;
-static wchar_t env_home[PATH_MAX+1];
+static char *default_home = NULL;
void
-Py_SetPythonHome(wchar_t *home)
+Py_SetPythonHome(char *home)
{
default_home = home;
}
-wchar_t *
+char *
Py_GetPythonHome(void)
{
- wchar_t *home = default_home;
- if (home == NULL && !Py_IgnoreEnvironmentFlag) {
- char* chome = Py_GETENV("PYTHONHOME");
- if (chome) {
- size_t r = mbstowcs(env_home, chome, PATH_MAX+1);
- if (r != (size_t)-1 && r <= PATH_MAX)
- home = env_home;
- }
-
- }
+ char *home = default_home;
+ if (home == NULL && !Py_IgnoreEnvironmentFlag)
+ home = Py_GETENV("PYTHONHOME");
return home;
}
/* Create __main__ module */
static void
-initmain(PyInterpreterState *interp)
+initmain(void)
{
PyObject *m, *d;
m = PyImport_AddModule("__main__");
@@ -833,61 +704,12 @@ initmain(PyInterpreterState *interp)
Py_FatalError("can't create __main__ module");
d = PyModule_GetDict(m);
if (PyDict_GetItemString(d, "__builtins__") == NULL) {
- PyObject *bimod = PyImport_ImportModule("builtins");
- if (bimod == NULL) {
- Py_FatalError("Failed to retrieve builtins module");
- }
- if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
- Py_FatalError("Failed to initialize __main__.__builtins__");
- }
- Py_DECREF(bimod);
- }
- /* Main is a little special - imp.is_builtin("__main__") will return
- * False, but BuiltinImporter is still the most appropriate initial
- * setting for its __loader__ attribute. A more suitable value will
- * be set if __main__ gets further initialized later in the startup
- * process.
- */
- if (PyDict_GetItemString(d, "__loader__") == NULL) {
- PyObject *loader = PyObject_GetAttrString(interp->importlib,
- "BuiltinImporter");
- if (loader == NULL) {
- Py_FatalError("Failed to retrieve BuiltinImporter");
- }
- if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
- Py_FatalError("Failed to initialize __main__.__loader__");
- }
- Py_DECREF(loader);
- }
-}
-
-static int
-initfsencoding(PyInterpreterState *interp)
-{
- PyObject *codec;
-
- if (Py_FileSystemDefaultEncoding == NULL)
- {
- Py_FileSystemDefaultEncoding = get_locale_encoding();
- if (Py_FileSystemDefaultEncoding == NULL)
- Py_FatalError("Py_Initialize: Unable to get the locale encoding");
-
- Py_HasFileSystemDefaultEncoding = 0;
- interp->fscodec_initialized = 1;
- return 0;
- }
-
- /* the encoding is mbcs, utf-8 or ascii */
- codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding);
- if (!codec) {
- /* Such error can only occurs in critical situations: no more
- * memory, import a module of the standard library failed,
- * etc. */
- return -1;
+ PyObject *bimod = PyImport_ImportModule("__builtin__");
+ if (bimod == NULL ||
+ PyDict_SetItemString(d, "__builtins__", bimod) != 0)
+ Py_FatalError("can't add __builtins__ to __main__");
+ Py_XDECREF(bimod);
}
- Py_DECREF(codec);
- interp->fscodec_initialized = 1;
- return 0;
}
/* Import the site module (not into __main__ though) */
@@ -907,250 +729,6 @@ initsite(void)
}
}
-static PyObject*
-create_stdio(PyObject* io,
- int fd, int write_mode, char* name,
- char* encoding, char* errors)
-{
- PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
- const char* mode;
- const char* newline;
- PyObject *line_buffering;
- int buffering, isatty;
- _Py_IDENTIFIER(open);
- _Py_IDENTIFIER(isatty);
- _Py_IDENTIFIER(TextIOWrapper);
- _Py_IDENTIFIER(name);
- _Py_IDENTIFIER(mode);
-
- /* stdin is always opened in buffered mode, first because it shouldn't
- make a difference in common use cases, second because TextIOWrapper
- depends on the presence of a read1() method which only exists on
- buffered streams.
- */
- if (Py_UnbufferedStdioFlag && write_mode)
- buffering = 0;
- else
- buffering = -1;
- if (write_mode)
- mode = "wb";
- else
- mode = "rb";
- buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi",
- fd, mode, buffering,
- Py_None, Py_None, Py_None, 0);
- if (buf == NULL)
- goto error;
-
- if (buffering) {
- _Py_IDENTIFIER(raw);
- raw = _PyObject_GetAttrId(buf, &PyId_raw);
- if (raw == NULL)
- goto error;
- }
- else {
- raw = buf;
- Py_INCREF(raw);
- }
-
- text = PyUnicode_FromString(name);
- if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0)
- goto error;
- res = _PyObject_CallMethodId(raw, &PyId_isatty, "");
- if (res == NULL)
- goto error;
- isatty = PyObject_IsTrue(res);
- Py_DECREF(res);
- if (isatty == -1)
- goto error;
- if (isatty || Py_UnbufferedStdioFlag)
- line_buffering = Py_True;
- else
- line_buffering = Py_False;
-
- Py_CLEAR(raw);
- Py_CLEAR(text);
-
-#ifdef MS_WINDOWS
- /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r"
- newlines to "\n".
- sys.stdout and sys.stderr: translate "\n" to "\r\n". */
- newline = NULL;
-#else
- /* sys.stdin: split lines at "\n".
- sys.stdout and sys.stderr: don't translate newlines (use "\n"). */
- newline = "\n";
-#endif
-
- stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO",
- buf, encoding, errors,
- newline, line_buffering);
- Py_CLEAR(buf);
- if (stream == NULL)
- goto error;
-
- if (write_mode)
- mode = "w";
- else
- mode = "r";
- text = PyUnicode_FromString(mode);
- if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0)
- goto error;
- Py_CLEAR(text);
- return stream;
-
-error:
- Py_XDECREF(buf);
- Py_XDECREF(stream);
- Py_XDECREF(text);
- Py_XDECREF(raw);
- return NULL;
-}
-
-static int
-is_valid_fd(int fd)
-{
- int dummy_fd;
- if (fd < 0 || !_PyVerify_fd(fd))
- return 0;
- dummy_fd = dup(fd);
- if (dummy_fd < 0)
- return 0;
- close(dummy_fd);
- return 1;
-}
-
-/* Initialize sys.stdin, stdout, stderr and builtins.open */
-static int
-initstdio(void)
-{
- PyObject *iomod = NULL, *wrapper;
- PyObject *bimod = NULL;
- PyObject *m;
- PyObject *std = NULL;
- int status = 0, fd;
- PyObject * encoding_attr;
- char *encoding = NULL, *errors;
-
- /* Hack to avoid a nasty recursion issue when Python is invoked
- in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
- if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
- goto error;
- }
- Py_DECREF(m);
-
- if (!(m = PyImport_ImportModule("encodings.latin_1"))) {
- goto error;
- }
- Py_DECREF(m);
-
- if (!(bimod = PyImport_ImportModule("builtins"))) {
- goto error;
- }
-
- if (!(iomod = PyImport_ImportModule("io"))) {
- goto error;
- }
- if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) {
- goto error;
- }
-
- /* Set builtins.open */
- if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
- Py_DECREF(wrapper);
- goto error;
- }
- Py_DECREF(wrapper);
-
- encoding = Py_GETENV("PYTHONIOENCODING");
- errors = NULL;
- if (encoding) {
- encoding = strdup(encoding);
- errors = strchr(encoding, ':');
- if (errors) {
- *errors = '\0';
- errors++;
- }
- }
-
- /* Set sys.stdin */
- fd = fileno(stdin);
- /* Under some conditions stdin, stdout and stderr may not be connected
- * and fileno() may point to an invalid file descriptor. For example
- * GUI apps don't have valid standard streams by default.
- */
- if (!is_valid_fd(fd)) {
- std = Py_None;
- Py_INCREF(std);
- }
- else {
- std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors);
- if (std == NULL)
- goto error;
- } /* if (fd < 0) */
- PySys_SetObject("__stdin__", std);
- PySys_SetObject("stdin", std);
- Py_DECREF(std);
-
- /* Set sys.stdout */
- fd = fileno(stdout);
- if (!is_valid_fd(fd)) {
- std = Py_None;
- Py_INCREF(std);
- }
- else {
- std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors);
- if (std == NULL)
- goto error;
- } /* if (fd < 0) */
- PySys_SetObject("__stdout__", std);
- PySys_SetObject("stdout", std);
- Py_DECREF(std);
-
-#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
- /* Set sys.stderr, replaces the preliminary stderr */
- fd = fileno(stderr);
- if (!is_valid_fd(fd)) {
- std = Py_None;
- Py_INCREF(std);
- }
- else {
- std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace");
- if (std == NULL)
- goto error;
- } /* if (fd < 0) */
-
- /* Same as hack above, pre-import stderr's codec to avoid recursion
- when import.c tries to write to stderr in verbose mode. */
- encoding_attr = PyObject_GetAttrString(std, "encoding");
- if (encoding_attr != NULL) {
- const char * encoding;
- encoding = _PyUnicode_AsString(encoding_attr);
- if (encoding != NULL) {
- PyObject *codec_info = _PyCodec_Lookup(encoding);
- Py_XDECREF(codec_info);
- }
- Py_DECREF(encoding_attr);
- }
- PyErr_Clear(); /* Not a fatal error if codec isn't available */
-
- PySys_SetObject("__stderr__", std);
- PySys_SetObject("stderr", std);
- Py_DECREF(std);
-#endif
-
- if (0) {
- error:
- status = -1;
- }
-
- if (encoding)
- free(encoding);
- Py_XDECREF(bimod);
- Py_XDECREF(iomod);
- return status;
-}
-
/* Parse input from a file and execute it */
int
@@ -1182,12 +760,12 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag
}
v = PySys_GetObject("ps1");
if (v == NULL) {
- PySys_SetObject("ps1", v = PyUnicode_FromString(">>> "));
+ PySys_SetObject("ps1", v = PyString_FromString(">>> "));
Py_XDECREF(v);
}
v = PySys_GetObject("ps2");
if (v == NULL) {
- PySys_SetObject("ps2", v = PyUnicode_FromString("... "));
+ PySys_SetObject("ps2", v = PyString_FromString("... "));
Py_XDECREF(v);
}
for (;;) {
@@ -1202,91 +780,60 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flag
}
}
-/* compute parser flags based on compiler flags */
-static int PARSER_FLAGS(PyCompilerFlags *flags)
-{
- int parser_flags = 0;
- if (!flags)
- return 0;
- if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT)
- parser_flags |= PyPARSE_DONT_IMPLY_DEDENT;
- if (flags->cf_flags & PyCF_IGNORE_COOKIE)
- parser_flags |= PyPARSE_IGNORE_COOKIE;
- if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL)
- parser_flags |= PyPARSE_BARRY_AS_BDFL;
- return parser_flags;
-}
-
#if 0
+/* compute parser flags based on compiler flags */
+#define PARSER_FLAGS(flags) \
+ ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
+ PyPARSE_DONT_IMPLY_DEDENT : 0)) : 0)
+#endif
+#if 1
/* Keep an example of flags with future keyword support. */
#define PARSER_FLAGS(flags) \
((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
PyPARSE_DONT_IMPLY_DEDENT : 0) \
- | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \
- PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
+ | (((flags)->cf_flags & CO_FUTURE_PRINT_FUNCTION) ? \
+ PyPARSE_PRINT_IS_FUNCTION : 0) \
+ | (((flags)->cf_flags & CO_FUTURE_UNICODE_LITERALS) ? \
+ PyPARSE_UNICODE_LITERALS : 0) \
+ ) : 0)
#endif
int
PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
{
- PyObject *m, *d, *v, *w, *oenc = NULL;
+ PyObject *m, *d, *v, *w;
mod_ty mod;
PyArena *arena;
- char *ps1 = "", *ps2 = "", *enc = NULL;
+ char *ps1 = "", *ps2 = "";
int errcode = 0;
- _Py_IDENTIFIER(encoding);
- if (fp == stdin) {
- /* Fetch encoding from sys.stdin */
- v = PySys_GetObject("stdin");
- if (v == NULL || v == Py_None)
- return -1;
- oenc = _PyObject_GetAttrId(v, &PyId_encoding);
- if (!oenc)
- return -1;
- enc = _PyUnicode_AsString(oenc);
- if (enc == NULL)
- return -1;
- }
v = PySys_GetObject("ps1");
if (v != NULL) {
v = PyObject_Str(v);
if (v == NULL)
PyErr_Clear();
- else if (PyUnicode_Check(v)) {
- ps1 = _PyUnicode_AsString(v);
- if (ps1 == NULL) {
- PyErr_Clear();
- ps1 = "";
- }
- }
+ else if (PyString_Check(v))
+ ps1 = PyString_AsString(v);
}
w = PySys_GetObject("ps2");
if (w != NULL) {
w = PyObject_Str(w);
if (w == NULL)
PyErr_Clear();
- else if (PyUnicode_Check(w)) {
- ps2 = _PyUnicode_AsString(w);
- if (ps2 == NULL) {
- PyErr_Clear();
- ps2 = "";
- }
- }
+ else if (PyString_Check(w))
+ ps2 = PyString_AsString(w);
}
arena = PyArena_New();
if (arena == NULL) {
Py_XDECREF(v);
Py_XDECREF(w);
- Py_XDECREF(oenc);
return -1;
}
- mod = PyParser_ASTFromFile(fp, filename, enc,
+ mod = PyParser_ASTFromFile(fp, filename,
Py_single_input, ps1, ps2,
flags, &errcode, arena);
Py_XDECREF(v);
Py_XDECREF(w);
- Py_XDECREF(oenc);
if (mod == NULL) {
PyArena_Free(arena);
if (errcode == E_EOF) {
@@ -1304,12 +851,13 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags
d = PyModule_GetDict(m);
v = run_mod(mod, filename, d, d, flags, arena);
PyArena_Free(arena);
- flush_io();
if (v == NULL) {
PyErr_Print();
return -1;
}
Py_DECREF(v);
+ if (Py_FlushLine())
+ PyErr_Clear();
return 0;
}
@@ -1354,44 +902,12 @@ maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)
}
int
-static set_main_loader(PyObject *d, const char *filename, const char *loader_name)
-{
- PyInterpreterState *interp;
- PyThreadState *tstate;
- PyObject *filename_obj, *loader_type, *loader;
- int result = 0;
-
- filename_obj = PyUnicode_DecodeFSDefault(filename);
- if (filename_obj == NULL)
- return -1;
- /* Get current thread state and interpreter pointer */
- tstate = PyThreadState_GET();
- interp = tstate->interp;
- loader_type = PyObject_GetAttrString(interp->importlib, loader_name);
- if (loader_type == NULL) {
- Py_DECREF(filename_obj);
- return -1;
- }
- loader = PyObject_CallFunction(loader_type, "sN", "__main__", filename_obj);
- Py_DECREF(loader_type);
- if (loader == NULL) {
- return -1;
- }
- if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
- result = -1;
- }
- Py_DECREF(loader);
- return result;
-}
-
-int
PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
PyCompilerFlags *flags)
{
PyObject *m, *d, *v;
const char *ext;
- int set_file_name = 0, ret = -1;
- size_t len;
+ int set_file_name = 0, len, ret = -1;
m = PyImport_AddModule("__main__");
if (m == NULL)
@@ -1399,61 +915,41 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
Py_INCREF(m);
d = PyModule_GetDict(m);
if (PyDict_GetItemString(d, "__file__") == NULL) {
- PyObject *f;
- f = PyUnicode_DecodeFSDefault(filename);
+ PyObject *f = PyString_FromString(filename);
if (f == NULL)
goto done;
if (PyDict_SetItemString(d, "__file__", f) < 0) {
Py_DECREF(f);
goto done;
}
- if (PyDict_SetItemString(d, "__cached__", Py_None) < 0) {
- Py_DECREF(f);
- goto done;
- }
set_file_name = 1;
Py_DECREF(f);
}
len = strlen(filename);
ext = filename + len - (len > 4 ? 4 : 0);
if (maybe_pyc_file(fp, filename, ext, closeit)) {
- FILE *pyc_fp;
/* Try to run a pyc file. First, re-open in binary */
if (closeit)
fclose(fp);
- if ((pyc_fp = fopen(filename, "rb")) == NULL) {
+ if ((fp = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "python: Can't reopen .pyc file\n");
goto done;
}
/* Turn on optimization if a .pyo file is given */
if (strcmp(ext, ".pyo") == 0)
Py_OptimizeFlag = 1;
-
- if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) {
- fprintf(stderr, "python: failed to set __main__.__loader__\n");
- ret = -1;
- fclose(pyc_fp);
- goto done;
- }
- v = run_pyc_file(pyc_fp, filename, d, d, flags);
- fclose(pyc_fp);
+ v = run_pyc_file(fp, filename, d, d, flags);
} else {
- /* When running from stdin, leave __main__.__loader__ alone */
- if (strcmp(filename, "<stdin>") != 0 &&
- set_main_loader(d, filename, "SourceFileLoader") < 0) {
- fprintf(stderr, "python: failed to set __main__.__loader__\n");
- ret = -1;
- goto done;
- }
v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,
closeit, flags);
}
- flush_io();
if (v == NULL) {
PyErr_Print();
goto done;
}
Py_DECREF(v);
+ if (Py_FlushLine())
+ PyErr_Clear();
ret = 0;
done:
if (set_file_name && PyDict_DelItemString(d, "__file__"))
@@ -1476,6 +972,8 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
return -1;
}
Py_DECREF(v);
+ if (Py_FlushLine())
+ PyErr_Clear();
return 0;
}
@@ -1485,20 +983,20 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
{
long hold;
PyObject *v;
- _Py_IDENTIFIER(msg);
- _Py_IDENTIFIER(filename);
- _Py_IDENTIFIER(lineno);
- _Py_IDENTIFIER(offset);
- _Py_IDENTIFIER(text);
+
+ /* old style errors */
+ if (PyTuple_Check(err))
+ return PyArg_ParseTuple(err, "O(ziiz)", message, filename,
+ lineno, offset, text);
*message = NULL;
/* new style errors. `err' is an instance */
- *message = _PyObject_GetAttrId(err, &PyId_msg);
+ *message = PyObject_GetAttrString(err, "msg");
if (!*message)
goto finally;
- v = _PyObject_GetAttrId(err, &PyId_filename);
+ v = PyObject_GetAttrString(err, "filename");
if (!v)
goto finally;
if (v == Py_None) {
@@ -1506,36 +1004,36 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
*filename = NULL;
}
else {
- *filename = _PyUnicode_AsString(v);
+ *filename = PyString_AsString(v);
Py_DECREF(v);
if (!*filename)
goto finally;
}
- v = _PyObject_GetAttrId(err, &PyId_lineno);
+ v = PyObject_GetAttrString(err, "lineno");
if (!v)
goto finally;
- hold = PyLong_AsLong(v);
+ hold = PyInt_AsLong(v);
Py_DECREF(v);
if (hold < 0 && PyErr_Occurred())
goto finally;
*lineno = (int)hold;
- v = _PyObject_GetAttrId(err, &PyId_offset);
+ v = PyObject_GetAttrString(err, "offset");
if (!v)
goto finally;
if (v == Py_None) {
*offset = -1;
Py_DECREF(v);
} else {
- hold = PyLong_AsLong(v);
+ hold = PyInt_AsLong(v);
Py_DECREF(v);
if (hold < 0 && PyErr_Occurred())
goto finally;
*offset = (int)hold;
}
- v = _PyObject_GetAttrId(err, &PyId_text);
+ v = PyObject_GetAttrString(err, "text");
if (!v)
goto finally;
if (v == Py_None) {
@@ -1543,7 +1041,7 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
*text = NULL;
}
else {
- *text = _PyUnicode_AsString(v);
+ *text = PyString_AsString(v);
Py_DECREF(v);
if (!*text)
goto finally;
@@ -1587,8 +1085,11 @@ print_error_text(PyObject *f, int offset, const char *text)
if (offset == -1)
return;
PyFile_WriteString(" ", f);
- while (--offset > 0)
+ offset--;
+ while (offset > 0) {
PyFile_WriteString(" ", f);
+ offset--;
+ }
PyFile_WriteString("^\n", f);
}
@@ -1604,13 +1105,14 @@ handle_system_exit(void)
return;
PyErr_Fetch(&exception, &value, &tb);
+ if (Py_FlushLine())
+ PyErr_Clear();
fflush(stdout);
if (value == NULL || value == Py_None)
goto done;
if (PyExceptionInstance_Check(value)) {
/* The error code should be in the `code' attribute. */
- _Py_IDENTIFIER(code);
- PyObject *code = _PyObject_GetAttrId(value, &PyId_code);
+ PyObject *code = PyObject_GetAttrString(value, "code");
if (code) {
Py_DECREF(value);
value = code;
@@ -1620,8 +1122,8 @@ handle_system_exit(void)
/* If we failed to dig out the 'code' attribute,
just let the else clause below print the error. */
}
- if (PyLong_Check(value))
- exitcode = (int)PyLong_AsLong(value);
+ if (PyInt_Check(value))
+ exitcode = (int)PyInt_AsLong(value);
else {
PyObject *sys_stderr = PySys_GetObject("stderr");
if (sys_stderr != NULL && sys_stderr != Py_None) {
@@ -1657,11 +1159,6 @@ PyErr_PrintEx(int set_sys_last_vars)
if (exception == NULL)
return;
PyErr_NormalizeException(&exception, &v, &tb);
- if (tb == NULL) {
- tb = Py_None;
- Py_INCREF(tb);
- }
- PyException_SetTraceback(v, tb);
if (exception == NULL)
return;
/* Now we know v != NULL too */
@@ -1671,8 +1168,9 @@ PyErr_PrintEx(int set_sys_last_vars)
PySys_SetObject("last_traceback", tb);
}
hook = PySys_GetObject("excepthook");
- if (hook) {
- PyObject *args = PyTuple_Pack(3, exception, v, tb);
+ if (hook && hook != Py_None) {
+ PyObject *args = PyTuple_Pack(3,
+ exception, v, tb ? tb : Py_None);
PyObject *result = PyEval_CallObject(hook, args);
if (result == NULL) {
PyObject *exception2, *v2, *tb2;
@@ -1692,6 +1190,8 @@ PyErr_PrintEx(int set_sys_last_vars)
v2 = Py_None;
Py_INCREF(v2);
}
+ if (Py_FlushLine())
+ PyErr_Clear();
fflush(stdout);
PySys_WriteStderr("Error in sys.excepthook:\n");
PyErr_Display(exception2, v2, tb2);
@@ -1712,110 +1212,100 @@ PyErr_PrintEx(int set_sys_last_vars)
Py_XDECREF(tb);
}
-static void
-print_exception(PyObject *f, PyObject *value)
+void
+PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
{
int err = 0;
- PyObject *type, *tb;
- _Py_IDENTIFIER(print_file_and_line);
-
- if (!PyExceptionInstance_Check(value)) {
- PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f);
- PyFile_WriteString(Py_TYPE(value)->tp_name, f);
- PyFile_WriteString(" found\n", f);
- return;
- }
-
+ PyObject *f = PySys_GetObject("stderr");
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;
- const char *filename, *text;
- int lineno, offset;
- if (!parse_syntax_error(value, &message, &filename,
- &lineno, &offset, &text))
+ if (f == NULL || f == Py_None)
+ fprintf(stderr, "lost sys.stderr\n");
+ else {
+ if (Py_FlushLine())
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;
+ 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 {
- PyObject* moduleName;
- char* className;
- _Py_IDENTIFIER(__module__);
- assert(PyExceptionClass_Check(type));
- className = PyExceptionClass_Name(type);
- if (className != NULL) {
- char *dot = strrchr(className, '.');
- if (dot != NULL)
- className = dot+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_GetAttrId(type, &PyId___module__);
- if (moduleName == NULL || !PyUnicode_Check(moduleName))
- {
- Py_XDECREF(moduleName);
- err = PyFile_WriteString("<unknown>", f);
- }
- else {
- char* modstr = _PyUnicode_AsString(moduleName);
- if (modstr && strcmp(modstr, "builtins"))
- {
- err = PyFile_WriteString(modstr, f);
- err += PyFile_WriteString(".", f);
+ 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);
}
- Py_DECREF(moduleName);
- }
- if (err == 0) {
- if (className == NULL)
+ if (err == 0) {
+ if (className == NULL)
err = PyFile_WriteString("<unknown>", f);
- else
+ 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);
+ }
+ /* try to write a newline in any case */
+ err += PyFile_WriteString("\n", 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)
- err = -1;
- 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 */
- 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. */
@@ -1823,83 +1313,6 @@ print_exception(PyObject *f, PyObject *value)
PyErr_Clear();
}
-static const char *cause_message =
- "\nThe above exception was the direct cause "
- "of the following exception:\n\n";
-
-static const char *context_message =
- "\nDuring handling of the above exception, "
- "another exception occurred:\n\n";
-
-static void
-print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)
-{
- int err = 0, res;
- PyObject *cause, *context;
-
- if (seen != NULL) {
- /* Exception chaining */
- if (PySet_Add(seen, value) == -1)
- PyErr_Clear();
- else if (PyExceptionInstance_Check(value)) {
- cause = PyException_GetCause(value);
- context = PyException_GetContext(value);
- if (cause) {
- res = PySet_Contains(seen, cause);
- 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) {
- res = PySet_Contains(seen, context);
- 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);
- }
- }
- print_exception(f, value);
- if (err != 0)
- PyErr_Clear();
-}
-
-void
-PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
-{
- PyObject *seen;
- PyObject *f = PySys_GetObject("stderr");
- if (f == Py_None) {
- /* pass */
- }
- else if (f == NULL) {
- _PyObject_Dump(value);
- fprintf(stderr, "lost sys.stderr\n");
- }
- else {
- /* We choose to ignore seen being possibly NULL, and report
- at least the main exception (it could be a MemoryError).
- */
- seen = PySet_New(NULL);
- if (seen == NULL)
- PyErr_Clear();
- print_exception_recursive(f, value, seen);
- Py_XDECREF(seen);
- }
-}
-
PyObject *
PyRun_StringFlags(const char *str, int start, PyObject *globals,
PyObject *locals, PyCompilerFlags *flags)
@@ -1927,7 +1340,7 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
if (arena == NULL)
return NULL;
- mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0,
+ mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
flags, NULL, arena);
if (closeit)
fclose(fp);
@@ -1940,36 +1353,6 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
return ret;
}
-static void
-flush_io(void)
-{
- PyObject *f, *r;
- PyObject *type, *value, *traceback;
- _Py_IDENTIFIER(flush);
-
- /* Save the current exception */
- PyErr_Fetch(&type, &value, &traceback);
-
- f = PySys_GetObject("stderr");
- if (f != NULL) {
- r = _PyObject_CallMethodId(f, &PyId_flush, "");
- if (r)
- Py_DECREF(r);
- else
- PyErr_Clear();
- }
- f = PySys_GetObject("stdout");
- if (f != NULL) {
- r = _PyObject_CallMethodId(f, &PyId_flush, "");
- if (r)
- Py_DECREF(r);
- else
- PyErr_Clear();
- }
-
- PyErr_Restore(type, value, traceback);
-}
-
static PyObject *
run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
PyCompilerFlags *flags, PyArena *arena)
@@ -1979,7 +1362,7 @@ run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
co = PyAST_Compile(mod, filename, flags, arena);
if (co == NULL)
return NULL;
- v = PyEval_EvalCode((PyObject*)co, globals, locals);
+ v = PyEval_EvalCode(co, globals, locals);
Py_DECREF(co);
return v;
}
@@ -1999,10 +1382,9 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
"Bad magic number in .pyc file");
return NULL;
}
- /* Skip mtime and size */
- (void) PyMarshal_ReadLongFromFile(fp);
(void) PyMarshal_ReadLongFromFile(fp);
v = PyMarshal_ReadLastObjectFromFile(fp);
+ fclose(fp);
if (v == NULL || !PyCode_Check(v)) {
Py_XDECREF(v);
PyErr_SetString(PyExc_RuntimeError,
@@ -2010,7 +1392,7 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
return NULL;
}
co = (PyCodeObject *)v;
- v = PyEval_EvalCode((PyObject*)co, globals, locals);
+ v = PyEval_EvalCode(co, globals, locals);
if (v && flags)
flags->cf_flags |= (co->co_flags & PyCF_MASK);
Py_DECREF(co);
@@ -2018,8 +1400,8 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
}
PyObject *
-Py_CompileStringExFlags(const char *str, const char *filename, int start,
- PyCompilerFlags *flags, int optimize)
+Py_CompileStringFlags(const char *str, const char *filename, int start,
+ PyCompilerFlags *flags)
{
PyCodeObject *co;
mod_ty mod;
@@ -2037,19 +1419,11 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,
PyArena_Free(arena);
return result;
}
- co = PyAST_CompileEx(mod, filename, flags, optimize, arena);
+ co = PyAST_Compile(mod, filename, flags, arena);
PyArena_Free(arena);
return (PyObject *)co;
}
-/* For use in Py_LIMITED_API */
-#undef Py_CompileString
-PyObject *
-PyCompileString(const char *str, const char *filename, int start)
-{
- return Py_CompileStringFlags(str, filename, start, NULL);
-}
-
struct symtable *
Py_SymtableString(const char *str, const char *filename, int start)
{
@@ -2061,6 +1435,7 @@ Py_SymtableString(const char *str, const char *filename, int start)
return NULL;
flags.cf_flags = 0;
+
mod = PyParser_ASTFromString(str, filename, start, &flags, arena);
if (mod == NULL) {
PyArena_Free(arena);
@@ -2092,18 +1467,16 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
flags->cf_flags |= iflags & PyCF_MASK;
mod = PyAST_FromNode(n, flags, filename, arena);
PyNode_Free(n);
+ return mod;
}
else {
err_input(&err);
- mod = NULL;
+ return NULL;
}
- err_free(&err);
- return mod;
}
mod_ty
-PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
- int start, char *ps1,
+PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1,
char *ps2, PyCompilerFlags *flags, int *errcode,
PyArena *arena)
{
@@ -2112,8 +1485,7 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
perrdetail err;
int iflags = PARSER_FLAGS(flags);
- node *n = PyParser_ParseFileFlagsEx(fp, filename, enc,
- &_PyParser_Grammar,
+ node *n = PyParser_ParseFileFlagsEx(fp, filename, &_PyParser_Grammar,
start, ps1, ps2, &err, &iflags);
if (flags == NULL) {
localflags.cf_flags = 0;
@@ -2123,15 +1495,14 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
flags->cf_flags |= iflags & PyCF_MASK;
mod = PyAST_FromNode(n, flags, filename, arena);
PyNode_Free(n);
+ return mod;
}
else {
err_input(&err);
if (errcode)
*errcode = err.error;
- mod = NULL;
+ return NULL;
}
- err_free(&err);
- return mod;
}
/* Simplified interface to parsefile -- return node or set exception */
@@ -2140,12 +1511,10 @@ node *
PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
{
perrdetail err;
- node *n = PyParser_ParseFileFlags(fp, filename, NULL,
- &_PyParser_Grammar,
+ node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
start, NULL, NULL, &err, flags);
if (n == NULL)
err_input(&err);
- err_free(&err);
return n;
}
@@ -2160,7 +1529,6 @@ PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
start, &err, flags);
if (n == NULL)
err_input(&err);
- err_free(&err);
return n;
}
@@ -2173,7 +1541,6 @@ PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
&_PyParser_Grammar, start, &err, flags);
if (n == NULL)
err_input(&err);
- err_free(&err);
return n;
}
@@ -2187,32 +1554,19 @@ PyParser_SimpleParseStringFilename(const char *str, const char *filename, int st
even parser modules. */
void
-PyParser_ClearError(perrdetail *err)
-{
- err_free(err);
-}
-
-void
PyParser_SetError(perrdetail *err)
{
err_input(err);
}
-static void
-err_free(perrdetail *err)
-{
- Py_CLEAR(err->filename);
-}
-
/* Set the error appropriate to the given input error code (see errcode.h) */
static void
err_input(perrdetail *err)
{
- PyObject *v, *w, *errtype, *errtext;
- PyObject *msg_obj = NULL;
+ PyObject *v, *w, *errtype;
+ PyObject* u = NULL;
char *msg = NULL;
-
errtype = PyExc_SyntaxError;
switch (err->error) {
case E_ERROR:
@@ -2267,9 +1621,14 @@ err_input(perrdetail *err)
case E_DECODE: {
PyObject *type, *value, *tb;
PyErr_Fetch(&type, &value, &tb);
- msg = "unknown decode error";
- if (value != NULL)
- msg_obj = PyObject_Str(value);
+ if (value != NULL) {
+ u = PyObject_Str(value);
+ if (u != NULL) {
+ msg = PyString_AsString(u);
+ }
+ }
+ if (msg == NULL)
+ msg = "unknown decode error";
Py_XDECREF(type);
Py_XDECREF(value);
Py_XDECREF(tb);
@@ -2278,41 +1637,21 @@ err_input(perrdetail *err)
case E_LINECONT:
msg = "unexpected character after line continuation character";
break;
-
- case E_IDENTIFIER:
- msg = "invalid character in identifier";
- break;
- case E_BADSINGLE:
- msg = "multiple statements found while compiling a single statement";
- break;
default:
fprintf(stderr, "error=%d\n", err->error);
msg = "unknown parsing error";
break;
}
- /* err->text may not be UTF-8 in case of decoding errors.
- Explicitly convert to an object. */
- if (!err->text) {
- errtext = Py_None;
- Py_INCREF(Py_None);
- } else {
- errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text),
- "replace");
- }
- v = Py_BuildValue("(OiiN)", err->filename,
- err->lineno, err->offset, errtext);
- if (v != NULL) {
- if (msg_obj)
- w = Py_BuildValue("(OO)", msg_obj, v);
- else
- w = Py_BuildValue("(sO)", msg, v);
- } else
- w = NULL;
+ v = Py_BuildValue("(ziiz)", err->filename,
+ err->lineno, err->offset, err->text);
+ w = NULL;
+ if (v != NULL)
+ w = Py_BuildValue("(sO)", msg, v);
+ Py_XDECREF(u);
Py_XDECREF(v);
PyErr_SetObject(errtype, w);
Py_XDECREF(w);
cleanup:
- Py_XDECREF(msg_obj);
if (err->text != NULL) {
PyObject_FREE(err->text);
err->text = NULL;
@@ -2324,23 +1663,8 @@ cleanup:
void
Py_FatalError(const char *msg)
{
- const int fd = fileno(stderr);
- PyThreadState *tstate;
-
fprintf(stderr, "Fatal Python error: %s\n", msg);
fflush(stderr); /* it helps in Windows debug build */
- if (PyErr_Occurred()) {
- PyErr_PrintEx(0);
- }
- else {
- tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current);
- if (tstate != NULL) {
- fputc('\n', stderr);
- fflush(stderr);
- _Py_DumpTracebackThreads(fd, tstate->interp, tstate);
- }
- _PyFaulthandler_Fini();
- }
#ifdef MS_WINDOWS
{
@@ -2371,23 +1695,6 @@ Py_FatalError(const char *msg)
#include "pythread.h"
#endif
-static void (*pyexitfunc)(void) = NULL;
-/* For the atexit module. */
-void _Py_PyAtExit(void (*func)(void))
-{
- pyexitfunc = func;
-}
-
-static void
-call_py_exitfuncs(void)
-{
- if (pyexitfunc == NULL)
- return;
-
- (*pyexitfunc)();
- PyErr_Clear();
-}
-
/* Wait until threading._shutdown completes, provided
the threading module was imported in the first place.
The shutdown routine will wait until all non-daemon
@@ -2396,7 +1703,6 @@ static void
wait_for_thread_shutdown(void)
{
#ifdef WITH_THREAD
- _Py_IDENTIFIER(_shutdown);
PyObject *result;
PyThreadState *tstate = PyThreadState_GET();
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
@@ -2406,13 +1712,11 @@ wait_for_thread_shutdown(void)
PyErr_Clear();
return;
}
- result = _PyObject_CallMethodId(threading, &PyId__shutdown, "");
- if (result == NULL) {
+ result = PyObject_CallMethod(threading, "_shutdown", "");
+ if (result == NULL)
PyErr_WriteUnraisable(threading);
- }
- else {
+ else
Py_DECREF(result);
- }
Py_DECREF(threading);
#endif
}
@@ -2430,6 +1734,29 @@ int Py_AtExit(void (*func)(void))
}
static void
+call_sys_exitfunc(void)
+{
+ PyObject *exitfunc = PySys_GetObject("exitfunc");
+
+ if (exitfunc) {
+ PyObject *res;
+ Py_INCREF(exitfunc);
+ PySys_SetObject("exitfunc", (PyObject *)NULL);
+ res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
+ if (res == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
+ PySys_WriteStderr("Error in sys.exitfunc:\n");
+ }
+ PyErr_Print();
+ }
+ Py_DECREF(exitfunc);
+ }
+
+ if (Py_FlushLine())
+ PyErr_Clear();
+}
+
+static void
call_ll_exitfuncs(void)
{
while (nexitfuncs > 0)
@@ -2463,27 +1790,6 @@ initsigs(void)
}
-/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
- *
- * All of the code in this function must only use async-signal-safe functions,
- * listed at `man 7 signal` or
- * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
- */
-void
-_Py_RestoreSignals(void)
-{
-#ifdef SIGPIPE
- PyOS_setsig(SIGPIPE, SIG_DFL);
-#endif
-#ifdef SIGXFZ
- PyOS_setsig(SIGXFZ, SIG_DFL);
-#endif
-#ifdef SIGXFSZ
- PyOS_setsig(SIGXFSZ, SIG_DFL);
-#endif
-}
-
-
/*
* The file descriptor fd is considered ``interactive'' if either
* a) isatty(fd) is TRUE, or
@@ -2577,11 +1883,6 @@ PyOS_getsig(int sig)
#endif
}
-/*
- * All of the code in this function must only use async-signal-safe functions,
- * listed at `man 7 signal` or
- * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
- */
PyOS_sighandler_t
PyOS_setsig(int sig, PyOS_sighandler_t handler)
{
@@ -2699,15 +2000,7 @@ PyRun_SimpleString(const char *s)
PyAPI_FUNC(PyObject *)
Py_CompileString(const char *str, const char *p, int s)
{
- return Py_CompileStringExFlags(str, p, s, NULL, -1);
-}
-
-#undef Py_CompileStringFlags
-PyAPI_FUNC(PyObject *)
-Py_CompileStringFlags(const char *str, const char *p, int s,
- PyCompilerFlags *flags)
-{
- return Py_CompileStringExFlags(str, p, s, flags, -1);
+ return Py_CompileStringFlags(str, p, s, NULL);
}
#undef PyRun_InteractiveOne
@@ -2727,3 +2020,4 @@ PyRun_InteractiveLoop(FILE *f, const char *p)
#ifdef __cplusplus
}
#endif
+