From f241eac5ce2302f9e0d698adf43e99caaf750bd5 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Sun, 18 Mar 2018 20:35:52 +0545 Subject: [PATCH] parent: allow Python to determine its install prefix from argv[0] Fixes support for virtualenv. Closes #152. --- docs/api.rst | 5 +++++ docs/index.rst | 2 +- mitogen/parent.py | 12 ++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 56850232..29f88c32 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -525,6 +525,11 @@ Router Class If unspecified, defaults to ``@:``. + This variable cannot contain slash characters, as the resulting + ``argv[0]`` must be presented in such a way as to allow Python to + determine its installation prefix. This is required to support + virtualenv. + :param str python_path: Path to the Python interpreter to use for bootstrap. Defaults to ``python2.7``. In future this may default to ``sys.executable``. diff --git a/docs/index.rst b/docs/index.rst index 6a8d461e..215dc4d0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -68,7 +68,7 @@ using the UNIX **ps** command: 20051 ? Ss 0:00 \_ sshd: dmw [priv] 20053 ? S 0:00 | \_ sshd: dmw@notty - 20054 ? Ssl 0:00 | \_ mitogen:dmw@Eldil.home:22476 + 20054 ? Ssl 0:00 | \_ /usr/bin/python(mitogen:dmw@Eldil.home:22476) 20103 ? S 0:00 | \_ tar zxvf myapp.tar.gz The example context was started by UID ``dmw`` on host ``Eldil.home``, process diff --git a/mitogen/parent.py b/mitogen/parent.py index 1b81124e..8537fd1b 100644 --- a/mitogen/parent.py +++ b/mitogen/parent.py @@ -313,6 +313,8 @@ class Stream(mitogen.core.Stream): if remote_name is None: remote_name = '%s@%s:%d' remote_name %= (getpass.getuser(), socket.gethostname(), os.getpid()) + if '/' in remote_name or '\\' in remote_name: + raise ValueError('remote_name= cannot contain slashes') self.remote_name = remote_name self.debug = debug self.profiling = profiling @@ -332,9 +334,11 @@ class Stream(mitogen.core.Stream): # Minimised, gzipped, base64'd and passed to 'python -c'. It forks, dups # file descriptor 0 as 100, creates a pipe, then execs a new interpreter # with a custom argv. - # 'CONTEXT_NAME', 'PREAMBLE_COMPRESSED_LEN', and 'PREAMBLE_LEN' are - # substituted with their respective values. - # Optimized for minimum byte count after minification & compression. + # * Optimized for minimum byte count after minification & compression. + # * 'CONTEXT_NAME', 'PREAMBLE_COMPRESSED_LEN', and 'PREAMBLE_LEN' are + # substituted with their respective values. + # * CONTEXT_NAME must be prefixed with the name of the Python binary in + # order to allow virtualenvs to detect their install prefix. @staticmethod def _first_stage(): R,W=os.pipe() @@ -348,7 +352,7 @@ class Stream(mitogen.core.Stream): os.close(W) os.close(w) os.environ['ARGV0']=sys.executable - os.execl(sys.executable,'mitogen:CONTEXT_NAME') + os.execl(sys.executable,sys.executable+'(mitogen:CONTEXT_NAME)') os.write(1,'EC0\n') C=_(os.fdopen(0,'rb').read(PREAMBLE_COMPRESSED_LEN),'zip') os.fdopen(W,'w',0).write(C)