Skip to content

Commit ab9f6a7

Browse files
committed
remove py.execnet, substitute py.execnet usages with "execnet" ones.
--HG-- branch : trunk
1 parent 496e3b1 commit ab9f6a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+66
-3851
lines changed

bin-for-dist/gensetup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
sys.path.insert(0, sys.argv[1])
44
import py
55

6-
toolpath = py.magic.autopath()
6+
toolpath = py.path.local(__file__)
77
binpath = py.path.local(py.__file__).dirpath('bin')
88

99
def error(msg):

bin-for-dist/test_install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def create(self, sitepackages=False):
7878

7979
def makegateway(self):
8080
python = self._cmd('python')
81-
return py.execnet.makegateway("popen//python=%s" %(python,))
81+
return execnet.makegateway("popen//python=%s" %(python,))
8282

8383
def pcall(self, cmd, *args, **kw):
8484
self.ensure()

conftest.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ def pytest_addoption(parser):
1717

1818
def pytest_funcarg__specssh(request):
1919
return getspecssh(request.config)
20-
def pytest_funcarg__specsocket(request):
21-
return getsocketspec(request.config)
20+
def getgspecs(config=None):
21+
if config is None:
22+
config = py.test.config
23+
return [execnet.XSpec(spec)
24+
for spec in config.getvalueorskip("gspecs")]
2225

2326

2427
# configuration information for tests
2528
def getgspecs(config=None):
2629
if config is None:
2730
config = py.test.config
28-
return [py.execnet.XSpec(spec)
31+
return [execnet.XSpec(spec)
2932
for spec in config.getvalueorskip("gspecs")]
3033

3134
def getspecssh(config=None):

contrib/svn-sync-repo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
55
small utility for hot-syncing a svn repository through ssh.
6-
uses py.execnet.
6+
uses execnet.
77
88
"""
99

@@ -105,7 +105,7 @@ def get_svn_youngest(repo):
105105
return int(rev)
106106

107107
def getgateway(host, keyfile=None):
108-
return py.execnet.SshGateway(host, identity=keyfile)
108+
return execnet.SshGateway(host, identity=keyfile)
109109

110110
if __name__ == '__main__':
111111
if len(sys.argv) < 3:

contrib/sysinfo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def error(*args):
9595
def getinfo(sshname, ssh_config=None, loginfo=sys.stdout):
9696
debug("connecting to", sshname)
9797
try:
98-
gw = py.execnet.SshGateway(sshname, ssh_config=ssh_config)
98+
gw = execnet.SshGateway(sshname, ssh_config=ssh_config)
9999
except IOError:
100100
error("could not get sshagteway", sshname)
101101
else:

doc/changelog.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Changes between 1.0.x and 'trunk'
22
=====================================
33

4+
* remove py.execnet code and substitute all usages with 'execnet' proper
5+
46
* fix issue50 - cached_setup now caches more to expectations
57
for test functions with multiple arguments.
68

doc/execnet.txt

Lines changed: 6 additions & 258 deletions
Original file line numberDiff line numberDiff line change
@@ -2,263 +2,11 @@
22
py.execnet: *elastic* distributed programming
33
==============================================================================
44

5-
``execnet`` helps you to:
5+
Since pylib 1.1 "py.execnet" is separated out of hte lib and now
6+
available through the standalone `execnet standalone package`_.
67

7-
* ad-hoc instantiate local or remote Python Processes
8-
* send code for execution in one or many processes
9-
* send and receive data between processes through channels
10-
11-
One of it's unique features is that it uses a **zero-install**
12-
technique: no manual installation steps are required on
13-
remote places, only a basic working Python interpreter
14-
and some input/output connection to it.
15-
16-
There is a `EuroPython2009 talk`_ from July 2009 with
17-
examples and some pictures.
18-
19-
.. contents::
20-
:local:
21-
:depth: 2
22-
23-
.. _`EuroPython2009 talk`: http://codespeak.net/download/py/ep2009-execnet.pdf
24-
25-
Gateways: immediately spawn local or remote process
26-
===================================================
27-
28-
In order to send code to a remote place or a subprocess
29-
you need to instantiate a so-called Gateway object.
30-
There are currently three Gateway classes:
31-
32-
* :api:`py.execnet.PopenGateway` to open a subprocess
33-
on the local machine. Useful for making use
34-
of multiple processors to to contain code execution
35-
in a separated environment.
36-
37-
* :api:`py.execnet.SshGateway` to connect to
38-
a remote ssh server and distribute execution to it.
39-
40-
* :api:`py.execnet.SocketGateway` a way to connect to
41-
a remote Socket based server. *Note* that this method
42-
requires a manually started
43-
:source:py/execnet/script/socketserver.py
44-
script. You can run this "server script" without
45-
having the py lib installed on the remote system
46-
and you can setup it up as permanent service.
47-
48-
49-
remote_exec: execute source code remotely
50-
===================================================
51-
52-
All gateways offer remote code execution via this high level function::
53-
54-
def remote_exec(source):
55-
"""return channel object for communicating with the asynchronously
56-
executing 'source' code which will have a corresponding 'channel'
57-
object in its executing namespace."""
58-
59-
With `remote_exec` you send source code to the other
60-
side and get both a local and a remote Channel_ object,
61-
which you can use to have the local and remote site
62-
communicate data in a structured way. Here is
63-
an example for reading the PID::
64-
65-
>>> import py
66-
>>> gw = py.execnet.PopenGateway()
67-
>>> channel = gw.remote_exec("""
68-
... import os
69-
... channel.send(os.getpid())
70-
... """)
71-
>>> remote_pid = channel.receive()
72-
>>> remote_pid != py.std.os.getpid()
73-
True
74-
75-
.. _`Channel`:
76-
.. _`channel-api`:
77-
.. _`exchange data`:
78-
79-
Channels: bidirectionally exchange data between hosts
80-
=======================================================
81-
82-
A channel object allows to send and receive data between
83-
two asynchronously running programs. When calling
84-
`remote_exec` you will get a channel object back and
85-
the code fragment running on the other side will
86-
see a channel object in its global namespace.
87-
88-
Here is the interface of channel objects::
89-
90-
#
91-
# API for sending and receiving anonymous values
92-
#
93-
channel.send(item):
94-
sends the given item to the other side of the channel,
95-
possibly blocking if the sender queue is full.
96-
Note that items need to be marshallable (all basic
97-
python types are).
98-
99-
channel.receive():
100-
receives an item that was sent from the other side,
101-
possibly blocking if there is none.
102-
Note that exceptions from the other side will be
103-
reraised as gateway.RemoteError exceptions containing
104-
a textual representation of the remote traceback.
105-
106-
channel.waitclose(timeout=None):
107-
wait until this channel is closed. Note that a closed
108-
channel may still hold items that will be received or
109-
send. Note that exceptions from the other side will be
110-
reraised as gateway.RemoteError exceptions containing
111-
a textual representation of the remote traceback.
112-
113-
channel.close():
114-
close this channel on both the local and the remote side.
115-
A remote side blocking on receive() on this channel
116-
will get woken up and see an EOFError exception.
117-
118-
119-
.. _xspec:
120-
121-
122-
XSpec: string specification for gateway type and configuration
123-
===============================================================
124-
125-
``py.execnet`` supports a simple extensible format for
126-
specifying and configuring Gateways for remote execution.
127-
You can use a string specification to instantiate a new gateway,
128-
for example a new SshGateway::
129-
130-
gateway = py.execnet.makegateway("ssh=myhost")
131-
132-
Let's look at some examples for valid specifications.
133-
Specification for an ssh connection to `wyvern`, running on python2.4 in the (newly created) 'mycache' subdirectory::
134-
135-
ssh=wyvern//python=python2.4//chdir=mycache
136-
137-
Specification of a python2.5 subprocess; with a low CPU priority ("nice" level). Current dir will be the current dir of the instantiator (that's true for all 'popen' specifications unless they specify 'chdir')::
138-
139-
popen//python=2.5//nice=20
140-
141-
Specification of a Python Socket server process that listens on 192.168.1.4:8888; current dir will be the 'pyexecnet-cache' sub directory which is used a default for all remote processes::
142-
143-
socket=192.168.1.4:8888
144-
145-
More generally, a specification string has this general format::
146-
147-
key1=value1//key2=value2//key3=value3
148-
149-
If you omit a value, a boolean true value is assumed. Currently
150-
the following key/values are supported:
151-
152-
* ``popen`` for a PopenGateway
153-
* ``ssh=host`` for a SshGateway
154-
* ``socket=address:port`` for a SocketGateway
155-
* ``python=executable`` for specifying Python executables
156-
* ``chdir=path`` change remote working dir to given relative or absolute path
157-
* ``nice=value`` decrease remote nice level if platforms supports it
158-
159-
160-
Examples of py.execnet usage
161-
===============================================================
162-
163-
Compare cwd() of Popen Gateways
164-
----------------------------------------
165-
166-
A PopenGateway has the same working directory as the instantiatior::
167-
168-
>>> import py, os
169-
>>> gw = py.execnet.PopenGateway()
170-
>>> ch = gw.remote_exec("import os; channel.send(os.getcwd())")
171-
>>> res = ch.receive()
172-
>>> assert res == os.getcwd()
173-
>>> gw.exit()
174-
175-
Synchronously receive results from two sub processes
176-
-----------------------------------------------------
177-
178-
Use MultiChannels for receiving multiple results from remote code::
179-
180-
>>> import py
181-
>>> ch1 = py.execnet.PopenGateway().remote_exec("channel.send(1)")
182-
>>> ch2 = py.execnet.PopenGateway().remote_exec("channel.send(2)")
183-
>>> mch = py.execnet.MultiChannel([ch1, ch2])
184-
>>> l = mch.receive_each()
185-
>>> assert len(l) == 2
186-
>>> assert 1 in l
187-
>>> assert 2 in l
188-
189-
Asynchronously receive results from two sub processes
190-
-----------------------------------------------------
191-
192-
Use ``MultiChannel.make_receive_queue()`` for asynchronously receiving
193-
multiple results from remote code. This standard Queue provides
194-
``(channel, result)`` tuples which allows to determine where
195-
a result comes from::
196-
197-
>>> import py
198-
>>> ch1 = py.execnet.PopenGateway().remote_exec("channel.send(1)")
199-
>>> ch2 = py.execnet.PopenGateway().remote_exec("channel.send(2)")
200-
>>> mch = py.execnet.MultiChannel([ch1, ch2])
201-
>>> queue = mch.make_receive_queue()
202-
>>> chan1, res1 = queue.get() # you may also specify a timeout
203-
>>> chan2, res2 = queue.get()
204-
>>> res1 + res2
205-
3
206-
>>> assert chan1 in (ch1, ch2)
207-
>>> assert chan2 in (ch1, ch2)
208-
>>> assert chan1 != chan2
209-
210-
Receive file contents from remote SSH account
211-
-----------------------------------------------------
212-
213-
Here is a small program that you can use to retrieve
214-
contents of remote files::
215-
216-
import py
217-
# open a gateway to a fresh child process
218-
gw = py.execnet.SshGateway('codespeak.net')
219-
channel = gw.remote_exec("""
220-
for fn in channel:
221-
f = open(fn, 'rb')
222-
channel.send(f.read())
223-
f.close()
224-
""")
225-
226-
for fn in somefilelist:
227-
channel.send(fn)
228-
content = channel.receive()
229-
# process content
230-
231-
# later you can exit / close down the gateway
232-
gw.exit()
233-
234-
235-
Instantiate a socket server in a new subprocess
236-
-----------------------------------------------------
237-
238-
The following example opens a PopenGateway, i.e. a python
239-
child process, and starts a socket server within that process
240-
and then opens a second gateway to the freshly started
241-
socketserver::
242-
243-
import py
244-
245-
popengw = py.execnet.PopenGateway()
246-
socketgw = py.execnet.SocketGateway.new_remote(popengw, ("127.0.0.1", 0))
247-
248-
print socketgw._rinfo() # print some info about the remote environment
249-
250-
251-
Sending a module / checking if run through remote_exec
252-
--------------------------------------------------------------
253-
254-
You can pass a module object to ``remote_exec`` in which case
255-
its source code will be sent. No dependencies will be transferred
256-
so the module must be self-contained or only use modules that are
257-
installed on the "other" side. Module code can detect if it is
258-
running in a remote_exec situation by checking for the special
259-
``__name__`` attribute like this::
260-
261-
if __name__ == '__channelexec__':
262-
# ... call module functions ...
263-
8+
If you have usages of the "py.execnet.*" 1.0 API you can likely
9+
rename all occurences of the string ``py.execnet.`` with the
10+
string ``execnet.``.
26411

12+
.. _`execnet standalone package`: http://codespeak.net/execnet

doc/test/customize.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ remote environment. For this you can implement the newgateway hook:
364364
def pytest_gwmanage_newgateway(gateway, platinfo):
365365
""" called after a gateway is instantiated. """
366366

367-
The ``gateway`` object here has a ``spec`` attribute which is an ``py.execnet.XSpec``
367+
The ``gateway`` object here has a ``spec`` attribute which is an ``execnet.XSpec``
368368
object, which has attributes that map key/values as specified from a ``--txspec``
369369
option. The platinfo object is a dictionary with information about the remote process:
370370

doc/test/funcargs.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ and to offer a new mysetup method:
165165
host = self.config.option.ssh
166166
if host is None:
167167
py.test.skip("specify ssh host with --ssh")
168-
return py.execnet.SshGateway(host)
168+
return execnet.SshGateway(host)
169169

170170

171171
Now any test function can use the ``mysetup.getsshconnection()`` method like this:

example/execnet/popen_read_multiple.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
channels = []
1111
for i in range(NUM_PROCESSES):
12-
gw = py.execnet.PopenGateway() # or use SSH or socket gateways
12+
gw = execnet.PopenGateway() # or use SSH or socket gateways
1313
channel = gw.remote_exec("""
1414
import time
1515
secs = channel.receive()
@@ -19,7 +19,7 @@
1919
channels.append(channel)
2020
print "*** instantiated subprocess", gw
2121

22-
mc = py.execnet.MultiChannel(channels)
22+
mc = execnet.MultiChannel(channels)
2323
queue = mc.make_receive_queue()
2424

2525
print "***", "verifying that timeout on receiving results from blocked subprocesses works"

0 commit comments

Comments
 (0)