summaryrefslogtreecommitdiffstats
path: root/Python/pythonrun.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pythonrun.c')
-rw-r--r--Python/pythonrun.c224
1 files changed, 163 insertions, 61 deletions
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 9ef653b..c2ca563 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -35,12 +35,30 @@
#define PATH_MAX MAXPATHLEN
#endif
+#ifdef Py_REF_DEBUG
+static
+void _print_total_refs(void) {
+ PyObject *xoptions, *key, *value;
+ xoptions = PySys_GetXOptions();
+ if (xoptions == NULL)
+ return;
+ key = PyUnicode_FromString("showrefcount");
+ if (key == NULL)
+ return;
+ value = PyDict_GetItem(xoptions, key);
+ Py_DECREF(key);
+ if (value == Py_True)
+ fprintf(stderr,
+ "[%" PY_FORMAT_SIZE_T "d refs, "
+ "%" PY_FORMAT_SIZE_T "d blocks]\n",
+ _Py_GetRefTotal(), _Py_GetAllocatedBlocks());
+}
+#endif
+
#ifndef Py_REF_DEBUG
#define PRINT_TOTAL_REFS()
#else /* Py_REF_DEBUG */
-#define PRINT_TOTAL_REFS() fprintf(stderr, \
- "[%" PY_FORMAT_SIZE_T "d refs]\n", \
- _Py_GetRefTotal())
+#define PRINT_TOTAL_REFS() _print_total_refs()
#endif
#ifdef __cplusplus
@@ -68,6 +86,7 @@ static void call_py_exitfuncs(void);
static void wait_for_thread_shutdown(void);
static void call_ll_exitfuncs(void);
extern int _PyUnicode_Init(void);
+extern int _PyStructSequence_Init(void);
extern void _PyUnicode_Fini(void);
extern int _PyLong_Init(void);
extern void PyLong_Fini(void);
@@ -93,6 +112,7 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
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 */
+int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
PyThreadState *_Py_Finalizing = NULL;
@@ -156,7 +176,7 @@ get_codec_name(const char *encoding)
name_utf8 = _PyUnicode_AsString(name);
if (name_utf8 == NULL)
goto error;
- name_str = strdup(name_utf8);
+ name_str = _PyMem_RawStrdup(name_utf8);
Py_DECREF(name);
if (name_str == NULL) {
PyErr_NoMemory();
@@ -309,7 +329,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
if (!PyByteArray_Init())
Py_FatalError("Py_Initialize: can't init bytearray");
- _PyFloat_Init();
+ if (!_PyFloat_Init())
+ Py_FatalError("Py_Initialize: can't init float");
interp->modules = PyDict_New();
if (interp->modules == NULL)
@@ -318,6 +339,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
/* Init Unicode implementation; relies on the codec registry */
if (_PyUnicode_Init() < 0)
Py_FatalError("Py_Initialize: can't initialize unicode");
+ if (_PyStructSequence_Init() < 0)
+ Py_FatalError("Py_Initialize: can't initialize structseq");
bimod = _PyBuiltin_Init();
if (bimod == NULL)
@@ -526,10 +549,6 @@ 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();
@@ -592,11 +611,6 @@ Py_Finalize(void)
_PyExc_Fini();
- /* Cleanup auto-thread-state */
-#ifdef WITH_THREAD
- _PyGILState_Fini();
-#endif /* WITH_THREAD */
-
/* Sundry finalizers */
PyMethod_Fini();
PyFrame_Fini();
@@ -610,17 +624,15 @@ Py_Finalize(void)
PyFloat_Fini();
PyDict_Fini();
PySlice_Fini();
+ _PyGC_Fini();
+ _PyRandom_Fini();
/* Cleanup Unicode implementation */
_PyUnicode_Fini();
- /* Delete current thread. After this, many C API calls become crashy. */
- PyThreadState_Swap(NULL);
- PyInterpreterState_Delete(interp);
-
/* reset file system default encoding */
if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
- free((char*)Py_FileSystemDefaultEncoding);
+ PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
Py_FileSystemDefaultEncoding = NULL;
}
@@ -632,6 +644,15 @@ Py_Finalize(void)
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
+ /* Cleanup auto-thread-state */
+#ifdef WITH_THREAD
+ _PyGILState_Fini();
+#endif /* WITH_THREAD */
+
+ /* Delete current thread. After this, many C API calls become crashy. */
+ PyThreadState_Swap(NULL);
+ PyInterpreterState_Delete(interp);
+
#ifdef Py_TRACE_REFS
/* Display addresses (& refcnts) of all objects still alive.
* An address can be used to find the repr of the object, printed
@@ -769,6 +790,9 @@ Py_EndInterpreter(PyThreadState *tstate)
Py_FatalError("Py_EndInterpreter: thread is not current");
if (tstate->frame != NULL)
Py_FatalError("Py_EndInterpreter: thread still has a frame");
+
+ wait_for_thread_shutdown();
+
if (tstate != interp->tstate_head || tstate->next != NULL)
Py_FatalError("Py_EndInterpreter: not the last thread");
@@ -798,7 +822,7 @@ Py_GetProgramName(void)
}
static wchar_t *default_home = NULL;
-static wchar_t env_home[PATH_MAX+1];
+static wchar_t env_home[MAXPATHLEN+1];
void
Py_SetPythonHome(wchar_t *home)
@@ -827,7 +851,7 @@ Py_GetPythonHome(void)
static void
initmain(PyInterpreterState *interp)
{
- PyObject *m, *d;
+ PyObject *m, *d, *loader;
m = PyImport_AddModule("__main__");
if (m == NULL)
Py_FatalError("can't create __main__ module");
@@ -848,7 +872,8 @@ initmain(PyInterpreterState *interp)
* be set if __main__ gets further initialized later in the startup
* process.
*/
- if (PyDict_GetItemString(d, "__loader__") == NULL) {
+ loader = PyDict_GetItemString(d, "__loader__");
+ if (loader == NULL || loader == Py_None) {
PyObject *loader = PyObject_GetAttrString(interp->importlib,
"BuiltinImporter");
if (loader == NULL) {
@@ -898,6 +923,7 @@ initsite(void)
PyObject *m;
m = PyImport_ImportModule("site");
if (m == NULL) {
+ fprintf(stderr, "Failed to import the site module\n");
PyErr_Print();
Py_Finalize();
exit(1);
@@ -1030,7 +1056,7 @@ initstdio(void)
PyObject *std = NULL;
int status = 0, fd;
PyObject * encoding_attr;
- char *encoding = NULL, *errors;
+ char *pythonioencoding = NULL, *encoding, *errors;
/* Hack to avoid a nasty recursion issue when Python is invoked
in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
@@ -1062,15 +1088,23 @@ initstdio(void)
}
Py_DECREF(wrapper);
- encoding = Py_GETENV("PYTHONIOENCODING");
- errors = NULL;
- if (encoding) {
- encoding = strdup(encoding);
- errors = strchr(encoding, ':');
+ pythonioencoding = Py_GETENV("PYTHONIOENCODING");
+ encoding = errors = NULL;
+ if (pythonioencoding) {
+ pythonioencoding = _PyMem_Strdup(pythonioencoding);
+ if (pythonioencoding == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ errors = strchr(pythonioencoding, ':');
if (errors) {
*errors = '\0';
errors++;
+ if (!*errors)
+ errors = NULL;
}
+ if (*pythonioencoding)
+ encoding = pythonioencoding;
}
/* Set sys.stdin */
@@ -1124,18 +1158,24 @@ initstdio(void)
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);
+ const char * std_encoding;
+ std_encoding = _PyUnicode_AsString(encoding_attr);
+ if (std_encoding != NULL) {
+ PyObject *codec_info = _PyCodec_Lookup(std_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);
+ if (PySys_SetObject("__stderr__", std) < 0) {
+ Py_DECREF(std);
+ goto error;
+ }
+ if (PySys_SetObject("stderr", std) < 0) {
+ Py_DECREF(std);
+ goto error;
+ }
Py_DECREF(std);
#endif
@@ -1144,8 +1184,7 @@ initstdio(void)
status = -1;
}
- if (encoding)
- free(encoding);
+ PyMem_Free(pythonioencoding);
Py_XDECREF(bimod);
Py_XDECREF(iomod);
return status;
@@ -1352,8 +1391,8 @@ maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)
return 0;
}
-int
-static set_main_loader(PyObject *d, const char *filename, const char *loader_name)
+static int
+set_main_loader(PyObject *d, const char *filename, const char *loader_name)
{
PyInterpreterState *interp;
PyThreadState *tstate;
@@ -1420,7 +1459,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
/* Try to run a pyc file. First, re-open in binary */
if (closeit)
fclose(fp);
- if ((pyc_fp = fopen(filename, "rb")) == NULL) {
+ if ((pyc_fp = _Py_fopen(filename, "rb")) == NULL) {
fprintf(stderr, "python: Can't reopen .pyc file\n");
goto done;
}
@@ -2017,8 +2056,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_CompileStringObject(const char *str, PyObject *filename, int start,
+ PyCompilerFlags *flags, int optimize)
{
PyCodeObject *co;
mod_ty mod;
@@ -2026,7 +2065,7 @@ Py_CompileStringExFlags(const char *str, const char *filename, int start,
if (arena == NULL)
return NULL;
- mod = PyParser_ASTFromString(str, filename, start, flags, arena);
+ mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena);
if (mod == NULL) {
PyArena_Free(arena);
return NULL;
@@ -2036,11 +2075,24 @@ 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_CompileObject(mod, filename, flags, optimize, arena);
PyArena_Free(arena);
return (PyObject *)co;
}
+PyObject *
+Py_CompileStringExFlags(const char *str, const char *filename_str, int start,
+ PyCompilerFlags *flags, int optimize)
+{
+ PyObject *filename, *co;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ co = Py_CompileStringObject(str, filename, start, flags, optimize);
+ Py_DECREF(filename);
+ return co;
+}
+
/* For use in Py_LIMITED_API */
#undef Py_CompileString
PyObject *
@@ -2050,46 +2102,62 @@ PyCompileString(const char *str, const char *filename, int start)
}
struct symtable *
-Py_SymtableString(const char *str, const char *filename, int start)
+Py_SymtableStringObject(const char *str, PyObject *filename, int start)
{
struct symtable *st;
mod_ty mod;
PyCompilerFlags flags;
- PyArena *arena = PyArena_New();
+ PyArena *arena;
+
+ arena = PyArena_New();
if (arena == NULL)
return NULL;
flags.cf_flags = 0;
- mod = PyParser_ASTFromString(str, filename, start, &flags, arena);
+ mod = PyParser_ASTFromStringObject(str, filename, start, &flags, arena);
if (mod == NULL) {
PyArena_Free(arena);
return NULL;
}
- st = PySymtable_Build(mod, filename, 0);
+ st = PySymtable_BuildObject(mod, filename, 0);
PyArena_Free(arena);
return st;
}
+struct symtable *
+Py_SymtableString(const char *str, const char *filename_str, int start)
+{
+ PyObject *filename;
+ struct symtable *st;
+
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ st = Py_SymtableStringObject(str, filename, start);
+ Py_DECREF(filename);
+ return st;
+}
+
/* Preferred access to parser is through AST. */
mod_ty
-PyParser_ASTFromString(const char *s, const char *filename, int start,
- PyCompilerFlags *flags, PyArena *arena)
+PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start,
+ PyCompilerFlags *flags, PyArena *arena)
{
mod_ty mod;
PyCompilerFlags localflags;
perrdetail err;
int iflags = PARSER_FLAGS(flags);
- node *n = PyParser_ParseStringFlagsFilenameEx(s, filename,
- &_PyParser_Grammar, start, &err,
- &iflags);
+ node *n = PyParser_ParseStringObject(s, filename,
+ &_PyParser_Grammar, start, &err,
+ &iflags);
if (flags == NULL) {
localflags.cf_flags = 0;
flags = &localflags;
}
if (n) {
flags->cf_flags |= iflags & PyCF_MASK;
- mod = PyAST_FromNode(n, flags, filename, arena);
+ mod = PyAST_FromNodeObject(n, flags, filename, arena);
PyNode_Free(n);
}
else {
@@ -2101,26 +2169,40 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,
}
mod_ty
-PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
- int start, char *ps1,
- char *ps2, PyCompilerFlags *flags, int *errcode,
- PyArena *arena)
+PyParser_ASTFromString(const char *s, const char *filename_str, int start,
+ PyCompilerFlags *flags, PyArena *arena)
+{
+ PyObject *filename;
+ mod_ty mod;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ mod = PyParser_ASTFromStringObject(s, filename, start, flags, arena);
+ Py_DECREF(filename);
+ return mod;
+}
+
+mod_ty
+PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc,
+ int start, char *ps1,
+ char *ps2, PyCompilerFlags *flags, int *errcode,
+ PyArena *arena)
{
mod_ty mod;
PyCompilerFlags localflags;
perrdetail err;
int iflags = PARSER_FLAGS(flags);
- node *n = PyParser_ParseFileFlagsEx(fp, filename, enc,
- &_PyParser_Grammar,
- start, ps1, ps2, &err, &iflags);
+ node *n = PyParser_ParseFileObject(fp, filename, enc,
+ &_PyParser_Grammar,
+ start, ps1, ps2, &err, &iflags);
if (flags == NULL) {
localflags.cf_flags = 0;
flags = &localflags;
}
if (n) {
flags->cf_flags |= iflags & PyCF_MASK;
- mod = PyAST_FromNode(n, flags, filename, arena);
+ mod = PyAST_FromNodeObject(n, flags, filename, arena);
PyNode_Free(n);
}
else {
@@ -2133,6 +2215,23 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,
return mod;
}
+mod_ty
+PyParser_ASTFromFile(FILE *fp, const char *filename_str, const char* enc,
+ int start, char *ps1,
+ char *ps2, PyCompilerFlags *flags, int *errcode,
+ PyArena *arena)
+{
+ mod_ty mod;
+ PyObject *filename;
+ filename = PyUnicode_DecodeFSDefault(filename_str);
+ if (filename == NULL)
+ return NULL;
+ mod = PyParser_ASTFromFileObject(fp, filename, enc, start, ps1, ps2,
+ flags, errcode, arena);
+ Py_DECREF(filename);
+ return mod;
+}
+
/* Simplified interface to parsefile -- return node or set exception */
node *
@@ -2459,6 +2558,9 @@ initsigs(void)
PyOS_setsig(SIGXFSZ, SIG_IGN);
#endif
PyOS_InitInterrupts(); /* May imply initsignal() */
+ if (PyErr_Occurred()) {
+ Py_FatalError("Py_Initialize: can't import signal");
+ }
}