Mercurial > cpython-lru_cache-weakref
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) { |
