summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_osx_env.py34
-rw-r--r--Modules/getpath.c10
-rw-r--r--Modules/main.c19
3 files changed, 58 insertions, 5 deletions
diff --git a/Lib/test/test_osx_env.py b/Lib/test/test_osx_env.py
new file mode 100644
index 0000000..5b3f3e1
--- /dev/null
+++ b/Lib/test/test_osx_env.py
@@ -0,0 +1,34 @@
+"""
+Test suite for OS X interpreter environment variables.
+"""
+
+from test.support import EnvironmentVarGuard, run_unittest
+import subprocess
+import sys
+import unittest
+
+class OSXEnvironmentVariableTestCase(unittest.TestCase):
+ def _check_sys(self, ev, cond, sv, val = '/some/path/to/python'):
+ with EnvironmentVarGuard() as evg:
+ subpc = [str(sys.executable), '-c',
+ 'import sys; sys.exit(2 if "%s" %s %s else 3)' % (val, cond, sv)]
+ # ensure environment variable does not exist
+ evg.unset(ev)
+ # test that test on sys.xxx normally fails
+ rc = subprocess.call(subpc)
+ self.assertEqual(rc, 3, "expected %s not %s %s" % (ev, cond, sv))
+ # set environ variable
+ evg.set(ev, val)
+ # test that sys.xxx has been influenced by the environ value
+ rc = subprocess.call(subpc)
+ self.assertEqual(rc, 2, "expected %s %s %s" % (ev, cond, sv))
+
+ def test_pythonexecutable_sets_sys_executable(self):
+ self._check_sys('PYTHONEXECUTABLE', '==', 'sys.executable')
+
+def test_main():
+ if sys.platform == 'darwin':
+ run_unittest(OSXEnvironmentVariableTestCase)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Modules/getpath.c b/Modules/getpath.c
index 064877c..b7f178e 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -457,6 +457,7 @@ calculate_path(void)
#else
unsigned long nsexeclength = MAXPATHLEN;
#endif
+ char execpath[MAXPATHLEN+1];
#endif
if (_path) {
@@ -486,8 +487,13 @@ calculate_path(void)
* will fail if a relative path was used. but in that case,
* absolutize() should help us out below
*/
- else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
- ;
+ else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) {
+ size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1);
+ if (r == (size_t)-1 || r > MAXPATHLEN) {
+ /* Could not convert execpath, or it's too long. */
+ progpath[0] = '\0';
+ }
+ }
#endif /* __APPLE__ */
else if (path) {
while (1) {
diff --git a/Modules/main.c b/Modules/main.c
index 6de1523..8352e66 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -487,10 +487,23 @@ Py_Main(int argc, wchar_t **argv)
so the actual executable path is passed in an environment variable.
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
script. */
- if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')
- Py_SetProgramName(p);
- else
+ if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
+ wchar_t* buffer;
+ size_t len = strlen(p);
+ size_t r;
+
+ buffer = malloc(len * sizeof(wchar_t));
+ if (buffer == NULL) {
+ Py_FatalError(
+ "not enough memory to copy PYTHONEXECUTABLE");
+ }
+
+ r = mbstowcs(buffer, p, len);
+ Py_SetProgramName(buffer);
+ /* buffer is now handed off - do not free */
+ } else {
Py_SetProgramName(argv[0]);
+ }
#else
Py_SetProgramName(argv[0]);
#endif