Thomas Farvour
Thomas Farvour

Reputation: 1103

Installing Python 3 on Dreamhost

Perhaps I am missing something here, but I'm following the directions on Dreamhost's documentation for installing a custom Python interpreter. I suspect there is an issue with execl() in Python 2.x -> Python 3.x but I cannot be sure.

http://wiki.dreamhost.com/Python#Building_a_custom_version_of_Python

Here is the issue I am having. It seems like the same interpreter gets run, twice, even though I tell it something else.

import os, sys

log = file('/home/user/mysite.com/passengerwsgi.log', 'a')
log.write("Running %s\n" % (sys.executable))
log.write("Python %s\n" % (sys.version))
log.write("Path %s\n" % (sys.path))

INTERP = "/home/user/Python-3.3.5/bin/python3.3"
PACKAGES = "/home/user/mysite.com/packages"

if sys.executable != INTERP:
    log.write("Detected wrong interpreter location, swapping to %s\n" % (INTERP))
    # Swapping interpreters will not flush any files.
    log.flush()
    log.close()
    os.execl(INTERP, INERP, *sys.argv)
    # Should resume execution from the top of the file.

log.write("Loading pypiserver...")
log.flush()
sys.path.append(os.getcwd())
import site
import pypiserver
application = pypiserver.app(PACKAGES, redirect_to_fallback=False)

When it runs, I get the dreaded 500 server error, but it doesn't seem like the interpeter I specify is actually running as indicated by this output. If I specify a bad path to the interpreter, it fails completely as I would expect.

> Running /usr/bin/python Python 2.6.6 (r266:84292, Dec 26 2010,
> 22:31:48) [GCC 4.4.5] Path
> ['/usr/local/dh/passenger/lib/phusion_passenger/wsgi',
> '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2',
> '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old',
> '/usr/lib/python2.6/lib-dynload',
> '/usr/local/lib/python2.6/dist-packages',
> '/usr/lib/python2.6/dist-packages',
> '/usr/lib/python2.6/dist-packages/PIL',
> '/usr/lib/pymodules/python2.6'] Detected wrong interpreter location,
> swapping to /home/user/Python-3.3.5/bin/python3.3 Running
> /usr/bin/python Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) [GCC
> 4.4.5] Path ['/usr/local/dh/passenger/lib/phusion_passenger/wsgi', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2',
> '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old',
> '/usr/lib/python2.6/lib-dynload',
> '/usr/local/lib/python2.6/dist-packages',
> '/usr/lib/python2.6/dist-packages',
> '/usr/lib/python2.6/dist-packages/PIL',
> '/usr/lib/pymodules/python2.6'] Detected wrong interpreter location,
> swapping to /home/user/Python-3.3.5/bin/python3.3

Why is it executing the /usr/bin/python interpreter twice?

Upvotes: 2

Views: 1023

Answers (1)

fluffy
fluffy

Reputation: 5314

Here is my passenger_wsgi.py that I use to launch a Flask app that is managed via pipenv. This may or may not be helpful for you, although I can't see anything that's majorly different aside from how I determine which interpreter to run. Make sure that the path you're pointing to isn't actually a symlink or a script that launches the wrong python version.

import sys, os
import subprocess

INTERP = subprocess.check_output(['pipenv', 'run', 'which', 'python3']).strip().decode('utf-8')
if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)

sys.path.append(os.getcwd())
from my_site import app

# hackish way to make Passenger urldecode the same way WSGI does
import urllib.parse
def application(environ, start_response):
    environ["PATH_INFO"] = urllib.parse.unquote(environ["PATH_INFO"])
    return app(environ, start_response)

As far as my environment goes, I followed Dreamhost's suggested convention and installed Python 3.6.4 with a prefix of $HOME/opt/python-3.6.4 and added $HOME/opt/python-3.6.4/bin to my $PATH, and used Python's make install with no additional wrappers to put it in that place. pipenv was installed using pip install --user pipenv and I added $HOME/.local/bin to my $PATH as well.

Upvotes: 1

Related Questions