execnet: rapid multi-Python deployment

home |  install |  examples |  basic API |  support 

Table Of Contents

Previous topic

advanced (multi) channel communication

Next topic

Debugging execnet / Wire messages

Connecting different Python interpreters

Connect to Python2/Numpy from Python3

Here we run a Python3 interpreter to connect to a Python2.6 interpreter that has numpy installed. We send items to be added to an array and receive back the remote “repr” of the array:

import execnet
gw = execnet.makegateway("popen//python=python2.6")
channel = gw.remote_exec("""
    import numpy
    array = numpy.array([1,2,3])
    while 1:
        x = channel.receive()
        if x is None:
            break
        array = numpy.append(array, x)
    channel.send(repr(array))
""")
for x in range(10):
    channel.send(x)
channel.send(None)
print (channel.receive())

will print on the CPython3.1 side:

array([1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

A more refined real-life example of python3/python2 interaction is the anyvc project which uses version-control bindings in a Python2 subprocess in order to offer Python3-based library functionality.

Reconfiguring the string coercion between python2 and python3

Sometimes the default configuration of string coercion (2str to 3str, 3str to 2unicode) is inconvient, thus it can be reconfigured via gw.reconfigure.

>>> import execnet
>>> execnet.makegateway("popen//python=python3.1")
<PopenGateway id='gw0' receive-live, 0 active channels>
>>> gw=execnet.makegateway("popen//python=python3.1")
>>> gw.remote_exec("channel.send('hello')").receive()
u'hello'
>>> gw.reconfigure(py3str_as_py2str=True)
>>> gw.remote_exec("channel.send('hello')").receive()
'hello'
>>> ch = gw.remote_exec("channel.send(isinstance(channel.receive(), bytes)")
>>> ch.send('a')
>>> ch.receive()
False
>>> gw.reconfigure(py2str_as_py3str=False)
>>> ch = gw.remote_exec("channel.send(isinstance(channel.receive(), bytes)")
>>> ch.send('a')
>>> ch.receive()
True

Work with Java objects from CPython

Use your CPython interpreter to connect to a Jython 2.5.1 interpreter and work with Java types:

import execnet
gw = execnet.makegateway("popen//python=jython")
channel = gw.remote_exec("""
    from java.util import Vector
    v = Vector()
    v.add('aaa')
    v.add('bbb')
    for val in v:
        channel.send(val)
""")

for item in channel:
    print (item)

will print on the CPython side:

aaa
bbb

Work with C# objects from CPython

(Experimental) use your CPython interpreter to connect to a IronPython interpreter which can work with C# classes. Here is an example for instantiating a CLR Array instance and sending back its representation:

import execnet
gw = execnet.makegateway("popen//python=ipy")

channel = gw.remote_exec("""
    import clr
    clr.AddReference("System")
    from System import Array
    array = Array[float]([1,2])
    channel.send(str(array))
""")
print (channel.receive())

using Mono 2.0 and IronPython-1.1 this will print on the CPython side:

System.Double[](1.0, 2.0)

Note

Using IronPython needs more testing, likely newer versions will work better. please feedback if you have information.