Author steve.dower
Recipients ncoghlan, paul.moore, steve.dower, tim.golden, zach.ware
Date 2017-01-19.17:14:57
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1484846097.99.0.435362846525.issue29319@psf.upfronthosting.co.za>
In-reply-to
Content
Found it in Modules/main.c in RunMainFromImporter():

    /* argv0 is usable as an import source, so put it in sys.path[0]
       and import __main__ */
    sys_path = PySys_GetObject("path");
    if (sys_path == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
        goto error;
    }
    if (PyList_SetItem(sys_path, 0, argv0)) {
        argv0 = NULL;
        goto error;
    }
    Py_INCREF(argv0);

When running with a ._pth file, we force the -I option, which removes the empty entry at sys.path[0]. Instead, it becomes the path to the .zip file with the standard library, so when RunMainFromImporter overwrites it blindly, it's cutting out the only hope it has of finding runpy.

You can see this in a normal install by doing:

    py -I -c "import sys; print(sys.path)"
    [correct output]

    py -Ii test.pyz
    [output from test.pyz]
    >>> import sys; sys.path
    [incorrect output]

So we need to stop blindly overwriting sys.path[0] here. I'm not sure what the best approach would be, but maybe Nick has a preference? Perhaps we should pass the zip file path into runpy._run_module_as_main so it can initialize __path__ with it rather than making a global change? Or maybe an insert rather than a set is the right way and I'm over-thinking this.
History
Date User Action Args
2017-01-19 17:14:58steve.dowersetrecipients: + steve.dower, paul.moore, ncoghlan, tim.golden, zach.ware
2017-01-19 17:14:57steve.dowersetmessageid: <1484846097.99.0.435362846525.issue29319@psf.upfronthosting.co.za>
2017-01-19 17:14:57steve.dowerlinkissue29319 messages
2017-01-19 17:14:57steve.dowercreate