comparison Python/pythonrun.c @ 78107:3987667bf98f

Take the first step in resolving the messy pkgutil vs importlib edge cases by basing pkgutil explicitly on importlib, deprecating its internal import emulation and setting __main__.__loader__ correctly so that runpy still works (Affects #15343, #15314, #15357)
author Nick Coghlan <ncoghlan@gmail.com>
date Sun, 15 Jul 2012 18:09:52 +1000
parents 61e6ac40c816
children ba264b26d8d9
comparison
equal deleted inserted replaced
78106:51b5ee7cfa3b 78107:3987667bf98f
50 extern wchar_t *Py_GetPath(void); 50 extern wchar_t *Py_GetPath(void);
51 51
52 extern grammar _PyParser_Grammar; /* From graminit.c */ 52 extern grammar _PyParser_Grammar; /* From graminit.c */
53 53
54 /* Forward */ 54 /* Forward */
55 static void initmain(void); 55 static void initmain(PyInterpreterState *interp);
56 static int initfsencoding(PyInterpreterState *interp); 56 static int initfsencoding(PyInterpreterState *interp);
57 static void initsite(void); 57 static void initsite(void);
58 static int initstdio(void); 58 static int initstdio(void);
59 static void flush_io(void); 59 static void flush_io(void);
60 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, 60 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
374 Py_FatalError("Py_Initialize: unable to load the file system codec"); 374 Py_FatalError("Py_Initialize: unable to load the file system codec");
375 375
376 if (install_sigs) 376 if (install_sigs)
377 initsigs(); /* Signal handling stuff, including initintr() */ 377 initsigs(); /* Signal handling stuff, including initintr() */
378 378
379 initmain(); /* Module __main__ */ 379 initmain(interp); /* Module __main__ */
380 if (initstdio() < 0) 380 if (initstdio() < 0)
381 Py_FatalError( 381 Py_FatalError(
382 "Py_Initialize: can't initialize sys standard streams"); 382 "Py_Initialize: can't initialize sys standard streams");
383 383
384 /* Initialize warnings. */ 384 /* Initialize warnings. */
726 goto handle_error; 726 goto handle_error;
727 727
728 if (initstdio() < 0) 728 if (initstdio() < 0)
729 Py_FatalError( 729 Py_FatalError(
730 "Py_Initialize: can't initialize sys standard streams"); 730 "Py_Initialize: can't initialize sys standard streams");
731 initmain(); 731 initmain(interp);
732 if (!Py_NoSiteFlag) 732 if (!Py_NoSiteFlag)
733 initsite(); 733 initsite();
734 } 734 }
735 735
736 if (!PyErr_Occurred()) 736 if (!PyErr_Occurred())
823 } 823 }
824 824
825 /* Create __main__ module */ 825 /* Create __main__ module */
826 826
827 static void 827 static void
828 initmain(void) 828 initmain(PyInterpreterState *interp)
829 { 829 {
830 PyObject *m, *d; 830 PyObject *m, *d;
831 m = PyImport_AddModule("__main__"); 831 m = PyImport_AddModule("__main__");
832 if (m == NULL) 832 if (m == NULL)
833 Py_FatalError("can't create __main__ module"); 833 Py_FatalError("can't create __main__ module");
834 d = PyModule_GetDict(m); 834 d = PyModule_GetDict(m);
835 if (PyDict_GetItemString(d, "__builtins__") == NULL) { 835 if (PyDict_GetItemString(d, "__builtins__") == NULL) {
836 PyObject *bimod = PyImport_ImportModule("builtins"); 836 PyObject *bimod = PyImport_ImportModule("builtins");
837 if (bimod == NULL || 837 if (bimod == NULL) {
838 PyDict_SetItemString(d, "__builtins__", bimod) != 0) 838 Py_FatalError("Failed to retrieve builtins module");
839 Py_FatalError("can't add __builtins__ to __main__"); 839 }
840 if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
841 Py_FatalError("Failed to initialize __main__.__builtins__");
842 }
840 Py_DECREF(bimod); 843 Py_DECREF(bimod);
844 }
845 /* Main is a little special - imp.is_builtin("__main__") will return
846 * False, but BuiltinImporter is still the most appropriate initial
847 * setting for its __loader__ attribute. A more suitable value will
848 * be set if __main__ gets further initialized later in the startup
849 * process.
850 */
851 if (PyDict_GetItemString(d, "__loader__") == NULL) {
852 PyObject *loader = PyObject_GetAttrString(interp->importlib,
853 "BuiltinImporter");
854 if (loader == NULL) {
855 Py_FatalError("Failed to retrieve BuiltinImporter");
856 }
857 if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
858 Py_FatalError("Failed to initialize __main__.__loader__");
859 }
860 Py_DECREF(loader);
841 } 861 }
842 } 862 }
843 863
844 static int 864 static int
845 initfsencoding(PyInterpreterState *interp) 865 initfsencoding(PyInterpreterState *interp)
1329 } 1349 }
1330 return 0; 1350 return 0;
1331 } 1351 }
1332 1352
1333 int 1353 int
1354 set_main_loader(PyObject *d, const char *filename, const char *loader_name)
1355 {
1356 PyInterpreterState *interp;
1357 PyThreadState *tstate;
1358 PyObject *loader;
1359 /* Get current thread state and interpreter pointer */
1360 tstate = PyThreadState_GET();
1361 interp = tstate->interp;
1362 loader = PyObject_GetAttrString(interp->importlib, loader_name);
1363 if (loader == NULL ||
1364 (PyDict_SetItemString(d, "__loader__", loader) < 0)) {
1365 return -1;
1366 }
1367 Py_DECREF(loader);
1368 return 0;
1369 }
1370
1371 int
1334 PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, 1372 PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
1335 PyCompilerFlags *flags) 1373 PyCompilerFlags *flags)
1336 { 1374 {
1337 PyObject *m, *d, *v; 1375 PyObject *m, *d, *v;
1338 const char *ext; 1376 const char *ext;
1371 goto done; 1409 goto done;
1372 } 1410 }
1373 /* Turn on optimization if a .pyo file is given */ 1411 /* Turn on optimization if a .pyo file is given */
1374 if (strcmp(ext, ".pyo") == 0) 1412 if (strcmp(ext, ".pyo") == 0)
1375 Py_OptimizeFlag = 1; 1413 Py_OptimizeFlag = 1;
1414
1415 if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) {
1416 fprintf(stderr, "python: failed to set __main__.__loader__\n");
1417 ret = -1;
1418 goto done;
1419 }
1376 v = run_pyc_file(fp, filename, d, d, flags); 1420 v = run_pyc_file(fp, filename, d, d, flags);
1377 } else { 1421 } else {
1422 /* When running from stdin, leave __main__.__loader__ alone */
1423 if (strcmp(filename, "<stdin>") != 0 &&
1424 set_main_loader(d, filename, "SourceFileLoader") < 0) {
1425 fprintf(stderr, "python: failed to set __main__.__loader__\n");
1426 ret = -1;
1427 goto done;
1428 }
1378 v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d, 1429 v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,
1379 closeit, flags); 1430 closeit, flags);
1380 } 1431 }
1381 flush_io(); 1432 flush_io();
1382 if (v == NULL) { 1433 if (v == NULL) {