-
Notifications
You must be signed in to change notification settings - Fork 0
/
ppiper.py
55 lines (45 loc) · 1.92 KB
/
ppiper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import execnet
"""
Pied Piper module allows to charm any python version
you need with its subprocess magic.
Set CPU priority via the nice argument to adjust performance
"""
def call_python(version, module, function, arglist=None, kwargdict=None, nice=None):
pystr = f"//python=python{version}"
nicestr = "" if nice is None else f"//nice={nice}"
# creates and configures a gateway to a Python interpreter.
# gateways execute code and exchange data
# via a bidirectional connection
# between the running process and a pool of configurable
# local/remote interpreters via different thread mechanisms
# The spec string encodes the target gateway type and configuration.
# the format is: host-type/key1=value1//key2=value2//...
# valid types are popen, ssh=hostname, socket=host:port
gateway = execnet.makegateway(f"popen{pystr}{nicestr}")
# to make the subprocess wait for arguments
# it is probably possible to do this in one sweep...
argstr = "" if arglist is None else "*channel.receive(),"
kwargstr = "" if kwargdict is None else "**channel.receive()"
# executes source code in the instantiated subprocess-interpreter
# by sending it trough a symmetrical channel, retured as object
# here a simple callback that executes the imported
# function with the arguments that receive from the host is passed.
channel = gateway.remote_exec(
f"""
from {module} import {function} as f
channel.send(f({argstr}{kwargstr}))
""")
# now hat th channel is open, is possible to send and
# recieve the data as configured
if arglist is not None:
channel.send(arglist)
if kwargdict is not None:
channel.send(kwargdict)
# wraps receiver exception status
try:
result = channel.receive()
except channel.RemoteError as e:
raise Exception(e)
finally:
channel.close
return result