This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author foutrelis
Recipients foutrelis
Date 2012-09-19.19:57:39
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1348084661.36.0.682682476046.issue15976@psf.upfronthosting.co.za>
In-reply-to
Content
On Arch Linux /lib is a symbolic link to /usr/lib. When the Python interpreter is provided with an argv[0] of e.g. '/python2.7' and the current working directory is /, it'll fail to start with the following error:

IOError: invalid Python installation: unable to open //include/python2.7/pyconfig.h (No such file or directory)


From what I understand, what is happening inside Modules/getpath.c is:

1) search_for_exec_prefix() is given an empty `argv0_path`
2) PYTHONHOME is not set, and we're not in a build directory, so step three is executed:

 * Step 3. Try to find prefix and exec_prefix relative to argv0_path,
 * backtracking up the path until it is exhausted.  This is the most common
 * step to succeed.  Note that if prefix and exec_prefix are different,
 * exec_prefix is more likely to be found; however if exec_prefix is a
 * subdirectory of prefix, both will be found.

3) copy_absolute() sets `exec_prefix` to '/'
4) 'lib/python2.7' gets appended to `exec_prefix` using joinpath()
5) 'lib-dynload' gets appended to `exec_prefix` using joinpath()
6) '/lib/python2.7/lib-dynload' exists and the function returns 1 (success)
7) control is returned to calculate_path() which later reduces `exec_prefix` to '/'

During further initialization, sysconfig.py tries to open pyconfig.h, whose path is calculated as {exec_prefix}/include/python2.7/pyconfig.h; thus ending up with the nonexistent path //include/python2.7/pyconfig.h. The correct exec_prefix would be /usr.


Moreover, if argv[0] and/or the current working directory are one level deeper (or more), `exec_prefix` will not be reduced to '/' and search_for_exec_prefix() will proceed to step four:

 * Step 4. Search the directories pointed to by the preprocessor variables
 * PREFIX and EXEC_PREFIX.  These are supplied by the Makefile but can be
 * passed in as options to the configure script.

i.e.: If search_for_exec_prefix() is passed an `argv0_path` with the value '/mnt', step three will only check '/mnt' but not '/', because '/mnt' will be reduced to '' and the `while (exec_prefix[0])` condition will be false.


I see two problems with the behavior I describe above:

1) Step three will skip checking the root directory (/) if argv[0] or the current working directory are one or more levels below / (in other words, not directly under /). Its behavior in this regard is inconsistent.
2) When argv[0] is e.g. '/python2.7' and the current working directory is /, it'll use '/' as the exec_prefix and fail to start. The /lib -> /usr/lib symbolic link should get dereferenced and not used as is.


I'm not sure how this should be fixed, so I only tried to present the issue with as many details as I could. If something is unclear, let me know.


Lastly, search_for_prefix() has very similar code, so any fix will have to be applied there too.


(There is also a downstream bug report @ https://bugs.archlinux.org/task/30812.)
History
Date User Action Args
2012-09-19 19:57:41foutrelissetrecipients: + foutrelis
2012-09-19 19:57:41foutrelissetmessageid: <1348084661.36.0.682682476046.issue15976@psf.upfronthosting.co.za>
2012-09-19 19:57:40foutrelislinkissue15976 messages
2012-09-19 19:57:39foutreliscreate