Skip to content

Commit afdfc07

Browse files
committed
Incorporates virtualenv-pythonw-osx pypa#54
* makes Framework bundle virtualenvs play nicer with OSX widgets * based on work at https://github.com/gldnspud/virtualenv-pythonw-osx * Needs code review (fragile, path based, uses tmpfiles) TODO: * What is the general fix for this for non-Framework installs?
1 parent 2d06518 commit afdfc07

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

virtualenv.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,62 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
13461346
os.unlink(pth)
13471347
os.symlink(os.path.basename(py_executable), pth)
13481348

1349+
## incorporate the best bits of virtualenv-pythonw-osx
1350+
# to prevent errors like:
1351+
# http://stackoverflow.com/questions/3692928/why-doesnt-the-save-button-work-on-a-matplotlib-plot
1352+
1353+
# TODO: review. Is this the right way to store this stub?
1354+
pythonw_c_contents = """
1355+
/*
1356+
* This wrapper program executes a python executable hidden inside an
1357+
* application bundle inside the Python framework. This is needed to run
1358+
* GUI code: some GUI API's don't work unless the program is inside an
1359+
* application bundle.
1360+
*/
1361+
#include <unistd.h>
1362+
#include <stdlib.h>
1363+
#include <string.h>
1364+
#include <err.h>
1365+
1366+
static char Python[] = PYTHONWEXECUTABLE;
1367+
1368+
int main(int argc, char **argv) {
1369+
char **a;
1370+
a = malloc((argc + 2) * sizeof(char *));
1371+
memcpy(a + 2, argv, argc * sizeof(char *));
1372+
a[0] = "/usr/bin/arch";
1373+
a[1] = sizeof(char *) == 4 ? "-i386" : "-x86_64";
1374+
a[2] = Python;
1375+
execv("/usr/bin/arch", a);
1376+
err(1, "execv: %s", "arch");
1377+
/* NOTREACHED */
1378+
}
1379+
"""
1380+
import tempfile
1381+
pythonw_c = tempfile.NamedTemporaryFile('w',suffix='.c')
1382+
pythonw_c.write(pythonw_c_contents)
1383+
pythonw_c.flush()
1384+
python_app_src = os.path.join(prefix, 'Resources', 'Python.app')
1385+
python_app_dest = os.path.join(home_dir, 'Python.app')
1386+
shutil.copytree(python_app_src, python_app_dest)
1387+
pythonw_executable = os.path.join(python_app_dest, 'Contents', 'MacOS', 'Python')
1388+
call_subprocess(["install_name_tool", "-change",
1389+
os.path.join(prefix, 'Python'),
1390+
'@executable_path/../../../.Python', # point indirectly to earlier .Python
1391+
pythonw_executable])
1392+
1393+
# Compile bin/python{,w}
1394+
for name in ['python','pythonw']:
1395+
pythonw_dest = os.path.join(home_dir, 'bin', name)
1396+
call_subprocess([
1397+
'cc',
1398+
'-arch', 'i386', '-arch', 'x86_64',
1399+
'-DPYTHONWEXECUTABLE="%s"' % (pythonw_executable,),
1400+
'-o',
1401+
pythonw_dest,
1402+
pythonw_c.name,
1403+
])
1404+
13491405
if sys.platform == 'win32' and ' ' in py_executable:
13501406
# There's a bug with subprocess on Windows when using a first
13511407
# argument that has a space in it. Instead we have to quote

0 commit comments

Comments
 (0)