issue #291: permit supplying a full Python argv.
This commit is contained in:
parent
bb74217604
commit
f977be2868
10
docs/api.rst
10
docs/api.rst
|
@ -483,9 +483,13 @@ Router Class
|
|||
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
|
||||
:data:`sys.executable`. For SSH, defaults to ``python``.
|
||||
:param str|list python_path:
|
||||
String or list path to the Python interpreter to use for bootstrap.
|
||||
Defaults to :data:`sys.executable` for local connections, and
|
||||
``python`` for remote connections.
|
||||
|
||||
It is possible to pass a list to invoke Python wrapped using
|
||||
another tool, such as ``["/usr/bin/env", "python"]``.
|
||||
|
||||
:param bool debug:
|
||||
If :data:`True`, arrange for debug logging (:py:meth:`enable_debug`) to
|
||||
|
|
|
@ -871,6 +871,19 @@ class Stream(mitogen.core.Stream):
|
|||
fp.close()
|
||||
os.write(1,'MITO001\n'.encode())
|
||||
|
||||
def get_python_argv(self):
|
||||
"""
|
||||
Return the initial argument vector elements necessary to invoke Python,
|
||||
by returning a 1-element list containing :attr:`python_path` if it is a
|
||||
string, or simply returning it if it is already a list.
|
||||
|
||||
This allows emulation of existing tools where the Python invocation may
|
||||
be set to e.g. `['/usr/bin/env', 'python']`.
|
||||
"""
|
||||
if isinstance(self.python_path, list):
|
||||
return self.python_path
|
||||
return [self.python_path]
|
||||
|
||||
def get_boot_command(self):
|
||||
source = inspect.getsource(self._first_stage)
|
||||
source = textwrap.dedent('\n'.join(source.strip().split('\n')[2:]))
|
||||
|
@ -886,8 +899,8 @@ class Stream(mitogen.core.Stream):
|
|||
# codecs.decode() requires a bytes object. Since we must be compatible
|
||||
# with 2.4 (no bytes literal), an extra .encode() either returns the
|
||||
# same str (2.x) or an equivalent bytes (3.x).
|
||||
return [
|
||||
self.python_path, '-c',
|
||||
return self.get_python_argv() + [
|
||||
'-c',
|
||||
'import codecs,os,sys;_=codecs.decode;'
|
||||
'exec(_(_("%s".encode(),"base64"),"zip"))' % (encoded.decode(),)
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import unittest2
|
||||
|
||||
|
@ -11,6 +12,14 @@ import testlib
|
|||
import plain_old_module
|
||||
|
||||
|
||||
def get_sys_executable():
|
||||
return sys.executable
|
||||
|
||||
|
||||
def get_os_environ():
|
||||
return dict(os.environ)
|
||||
|
||||
|
||||
class LocalTest(testlib.RouterMixin, unittest2.TestCase):
|
||||
stream_class = mitogen.ssh.Stream
|
||||
|
||||
|
@ -20,5 +29,35 @@ class LocalTest(testlib.RouterMixin, unittest2.TestCase):
|
|||
self.assertEquals('local.%d' % (pid,), context.name)
|
||||
|
||||
|
||||
class PythonPathTest(testlib.RouterMixin, unittest2.TestCase):
|
||||
stream_class = mitogen.ssh.Stream
|
||||
|
||||
def test_inherited(self):
|
||||
context = self.router.local()
|
||||
self.assertEquals(sys.executable, context.call(get_sys_executable))
|
||||
|
||||
def test_string(self):
|
||||
os.environ['PYTHON'] = sys.executable
|
||||
context = self.router.local(
|
||||
python_path=testlib.data_path('env_wrapper.sh'),
|
||||
)
|
||||
self.assertEquals(sys.executable, context.call(get_sys_executable))
|
||||
env = context.call(get_os_environ)
|
||||
self.assertEquals('1', env['EXECUTED_VIA_ENV_WRAPPER'])
|
||||
|
||||
def test_list(self):
|
||||
context = self.router.local(
|
||||
python_path=[
|
||||
testlib.data_path('env_wrapper.sh'),
|
||||
"magic_first_arg",
|
||||
sys.executable
|
||||
]
|
||||
)
|
||||
self.assertEquals(sys.executable, context.call(get_sys_executable))
|
||||
env = context.call(get_os_environ)
|
||||
self.assertEquals('magic_first_arg', env['ENV_WRAPPER_FIRST_ARG'])
|
||||
self.assertEquals('1', env['EXECUTED_VIA_ENV_WRAPPER'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
|
|
Loading…
Reference in New Issue