[svn r63147] get rid of old method for specifying remote execution places.
--HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									9cd41c91bd
								
							
						
					
					
						commit
						a4c14e83f0
					
				|  | @ -27,8 +27,8 @@ version = "1.0.0a1" | ||||||
| 
 | 
 | ||||||
| initpkg(__name__, | initpkg(__name__, | ||||||
|     description = "pylib and py.test: agile development and test support library", |     description = "pylib and py.test: agile development and test support library", | ||||||
|     revision = int('$LastChangedRevision: 63144 $'.split(':')[1][:-1]), |     revision = int('$LastChangedRevision: 63147 $'.split(':')[1][:-1]), | ||||||
|     lastchangedate = '$LastChangedDate: 2009-03-20 16:36:45 +0100 (Fri, 20 Mar 2009) $', |     lastchangedate = '$LastChangedDate: 2009-03-20 17:28:14 +0100 (Fri, 20 Mar 2009) $', | ||||||
|     version = version,  |     version = version,  | ||||||
|     url = "http://pylib.org",  |     url = "http://pylib.org",  | ||||||
|     download_url = "http://codespeak.net/py/0.9.2/download.html", |     download_url = "http://codespeak.net/py/0.9.2/download.html", | ||||||
|  | @ -151,7 +151,6 @@ initpkg(__name__, | ||||||
|     'execnet.SocketGateway'  : ('./execnet/register.py', 'SocketGateway'), |     'execnet.SocketGateway'  : ('./execnet/register.py', 'SocketGateway'), | ||||||
|     'execnet.PopenGateway'   : ('./execnet/register.py', 'PopenGateway'), |     'execnet.PopenGateway'   : ('./execnet/register.py', 'PopenGateway'), | ||||||
|     'execnet.SshGateway'     : ('./execnet/register.py', 'SshGateway'), |     'execnet.SshGateway'     : ('./execnet/register.py', 'SshGateway'), | ||||||
|     'execnet.GatewaySpec'    : ('./execnet/gwmanage.py', 'GatewaySpec'), |  | ||||||
|     'execnet.XSpec'          : ('./execnet/xspec.py', 'XSpec'), |     'execnet.XSpec'          : ('./execnet/xspec.py', 'XSpec'), | ||||||
|     'execnet.makegateway'    : ('./execnet/xspec.py', 'makegateway'), |     'execnet.makegateway'    : ('./execnet/xspec.py', 'makegateway'), | ||||||
|     'execnet.MultiGateway'   : ('./execnet/multi.py', 'MultiGateway'), |     'execnet.MultiGateway'   : ('./execnet/multi.py', 'MultiGateway'), | ||||||
|  |  | ||||||
|  | @ -37,9 +37,11 @@ def getspecssh(config=None): | ||||||
|             if not py.path.local.sysfind("ssh"): |             if not py.path.local.sysfind("ssh"): | ||||||
|                 py.test.skip("command not found: ssh") |                 py.test.skip("command not found: ssh") | ||||||
|             return spec |             return spec | ||||||
|  |     py.test.skip("need '--gx ssh=...'") | ||||||
| 
 | 
 | ||||||
| def getsocketspec(config=None): | def getsocketspec(config=None): | ||||||
|     xspecs = getgspecs(config) |     xspecs = getgspecs(config) | ||||||
|     for spec in xspecs: |     for spec in xspecs: | ||||||
|         if spec.socket: |         if spec.socket: | ||||||
|             return spec |             return spec | ||||||
|  |     py.test.skip("need '--gx socket=...'") | ||||||
|  |  | ||||||
|  | @ -1,105 +1,19 @@ | ||||||
| """ | """ | ||||||
|     instantiating, managing and rsyncing to hosts |     instantiating, managing and rsyncing to hosts | ||||||
| 
 | 
 | ||||||
| Host specification strings and implied gateways: |  | ||||||
| 
 |  | ||||||
|     socket:hostname:port:path SocketGateway |  | ||||||
|     popen[-executable][:path]          PopenGateway |  | ||||||
|     [ssh:]spec:path           SshGateway |  | ||||||
|     * [SshGateway] |  | ||||||
| 
 |  | ||||||
| on hostspec.makeconnection() a Host object |  | ||||||
| will be created which has an instantiated gateway.  |  | ||||||
| the remote side will be chdir()ed to the specified path.  |  | ||||||
| if no path was specified, do no chdir() at all.  |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| """ | """ | ||||||
|  | 
 | ||||||
| import py | import py | ||||||
| import sys, os | import sys, os | ||||||
| from py.__.test.dsession.masterslave import MasterNode |  | ||||||
| from py.__.test import event |  | ||||||
| from py.__.execnet.channel import RemoteError | from py.__.execnet.channel import RemoteError | ||||||
| 
 | 
 | ||||||
| NO_ENDMARKER_WANTED = object() | NO_ENDMARKER_WANTED = object() | ||||||
| 
 | 
 | ||||||
| class GatewaySpec(object): |  | ||||||
|     python = None |  | ||||||
|     def __init__(self, spec, defaultjoinpath="pyexecnetcache"): |  | ||||||
|         self._spec = spec |  | ||||||
|         if spec == "popen" or spec.startswith("popen:"): |  | ||||||
|             parts = spec.split(":", 2) |  | ||||||
|             self.type = self.address = parts.pop(0) |  | ||||||
|             if parts: |  | ||||||
|                 python = parts.pop(0) |  | ||||||
|                 # XXX XXX XXX do better GWSPEC that can deal |  | ||||||
|                 # with "C:"  |  | ||||||
|                 if py.std.sys.platform == "win32" and len(python) == 1: |  | ||||||
|                     python = "%s:%s" %(python, parts.pop(0)) |  | ||||||
|                 self.python = python |  | ||||||
|             if parts: |  | ||||||
|                 self.joinpath = parts.pop(0) |  | ||||||
|             else: |  | ||||||
|                 self.joinpath = "" |  | ||||||
|             if not self.python: |  | ||||||
|                 self.python = py.std.sys.executable |  | ||||||
| 
 |  | ||||||
|         elif spec.startswith("socket:"): |  | ||||||
|             parts = spec[7:].split(":", 2) |  | ||||||
|             self.address = parts.pop(0) |  | ||||||
|             if parts: |  | ||||||
|                 port = int(parts.pop(0)) |  | ||||||
|                 self.address = self.address, port |  | ||||||
|             self.joinpath = parts and parts.pop(0) or "" |  | ||||||
|             self.type = "socket" |  | ||||||
|         else: |  | ||||||
|             if spec.startswith("ssh:"): |  | ||||||
|                 spec = spec[4:] |  | ||||||
|             parts = spec.split(":", 2) |  | ||||||
|             self.address = parts.pop(0) |  | ||||||
|             self.python = parts and parts.pop(0) or "python" |  | ||||||
|             self.joinpath = parts and parts.pop(0) or "" |  | ||||||
|             self.type = "ssh" |  | ||||||
|         if not self.joinpath and not self.inplacelocal(): |  | ||||||
|             self.joinpath = defaultjoinpath |  | ||||||
| 
 |  | ||||||
|     def inplacelocal(self): |  | ||||||
|         return bool(self.type == "popen" and not self.joinpath) |  | ||||||
| 
 |  | ||||||
|     def __str__(self): |  | ||||||
|         return "<GatewaySpec %s>" % self._spec |  | ||||||
|     __repr__ = __str__ |  | ||||||
| 
 |  | ||||||
|     def makegateway(self, waitclose=True): |  | ||||||
|         if self.type == "popen": |  | ||||||
|             gw = py.execnet.PopenGateway(python=self.python) |  | ||||||
|         elif self.type == "socket": |  | ||||||
|             gw = py.execnet.SocketGateway(*self.address) |  | ||||||
|         elif self.type == "ssh": |  | ||||||
|             gw = py.execnet.SshGateway(self.address, remotepython=self.python) |  | ||||||
|         if self.joinpath: |  | ||||||
|             channel = gw.remote_exec(""" |  | ||||||
|                 import os  |  | ||||||
|                 path = %r |  | ||||||
|                 try: |  | ||||||
|                     os.chdir(path) |  | ||||||
|                 except OSError: |  | ||||||
|                     os.mkdir(path) |  | ||||||
|                     os.chdir(path) |  | ||||||
|             """ % self.joinpath) |  | ||||||
|             if waitclose: |  | ||||||
|                 channel.waitclose() |  | ||||||
|         else: |  | ||||||
|             if waitclose: |  | ||||||
|                 gw.remote_exec("").waitclose() |  | ||||||
|         gw.spec = self |  | ||||||
|         return gw  |  | ||||||
| 
 |  | ||||||
| class GatewayManager: | class GatewayManager: | ||||||
|     RemoteError = RemoteError |     RemoteError = RemoteError | ||||||
| 
 | 
 | ||||||
|     def __init__(self, specs): |     def __init__(self, specs): | ||||||
|         self.specs = [GatewaySpec(spec) for spec in specs] |         self.specs = [py.execnet.XSpec(spec) for spec in specs] | ||||||
|         self.gateways = [] |         self.gateways = [] | ||||||
| 
 | 
 | ||||||
|     def trace(self, msg): |     def trace(self, msg): | ||||||
|  | @ -111,7 +25,7 @@ class GatewayManager: | ||||||
|     def makegateways(self): |     def makegateways(self): | ||||||
|         assert not self.gateways |         assert not self.gateways | ||||||
|         for spec in self.specs: |         for spec in self.specs: | ||||||
|             gw = spec.makegateway() |             gw = py.execnet.makegateway(spec) | ||||||
|             self.gateways.append(gw) |             self.gateways.append(gw) | ||||||
|             gw.id = "[%s]" % len(self.gateways) |             gw.id = "[%s]" % len(self.gateways) | ||||||
|             self.notify("gwmanage_newgateway", gw) |             self.notify("gwmanage_newgateway", gw) | ||||||
|  | @ -121,7 +35,7 @@ class GatewayManager: | ||||||
|             self.makegateways() |             self.makegateways() | ||||||
|         l = [] |         l = [] | ||||||
|         for gw in self.gateways: |         for gw in self.gateways: | ||||||
|             if gw.spec.inplacelocal(): |             if gw.spec._samefilesystem(): | ||||||
|                 if inplacelocal: |                 if inplacelocal: | ||||||
|                     l.append(gw) |                     l.append(gw) | ||||||
|             else: |             else: | ||||||
|  | @ -150,15 +64,14 @@ class GatewayManager: | ||||||
|         seen = {} |         seen = {} | ||||||
|         for gateway in self.gateways: |         for gateway in self.gateways: | ||||||
|             spec = gateway.spec |             spec = gateway.spec | ||||||
|             if not spec.inplacelocal(): |             if not spec._samefilesystem(): | ||||||
|                 key = spec.type, spec.address, spec.joinpath |                 if spec in seen: | ||||||
|                 if key in seen: |  | ||||||
|                     continue  |                     continue  | ||||||
|                 def finished(): |                 def finished(): | ||||||
|                     if notify: |                     if notify: | ||||||
|                         notify("rsyncrootready", spec, source) |                         notify("rsyncrootready", spec, source) | ||||||
|                 rsync.add_target_host(gateway, finished=finished) |                 rsync.add_target_host(gateway, finished=finished) | ||||||
|                 seen[key] = gateway |                 seen[spec] = gateway | ||||||
|         if seen: |         if seen: | ||||||
|             self.notify("gwmanage_rsyncstart", source=source, gateways=seen.values()) |             self.notify("gwmanage_rsyncstart", source=source, gateways=seen.values()) | ||||||
|             rsync.send() |             rsync.send() | ||||||
|  | @ -203,5 +116,5 @@ class HostRSync(py.execnet.RSync): | ||||||
|     def _report_send_file(self, gateway, modified_rel_path): |     def _report_send_file(self, gateway, modified_rel_path): | ||||||
|         if self._verbose: |         if self._verbose: | ||||||
|             path = os.path.basename(self._sourcedir) + "/" + modified_rel_path |             path = os.path.basename(self._sourcedir) + "/" + modified_rel_path | ||||||
|             remotepath = gateway.spec.joinpath |             remotepath = gateway.spec.chdir | ||||||
|             print '%s:%s <= %s' % (gateway.remoteaddress, remotepath, path) |             print '%s:%s <= %s' % (gateway.remoteaddress, remotepath, path) | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ class TestGatewayManagerPopen: | ||||||
|         assert not len(hm.gateways)  |         assert not len(hm.gateways)  | ||||||
| 
 | 
 | ||||||
|     def test_hostmanager_rsync_popen_with_path(self, source, dest): |     def test_hostmanager_rsync_popen_with_path(self, source, dest): | ||||||
|         hm = GatewayManager(["popen::%s" %dest] * 1) |         hm = GatewayManager(["popen//chdir=%s" %dest] * 1) | ||||||
|         hm.makegateways() |         hm.makegateways() | ||||||
|         source.ensure("dir1", "dir2", "hello") |         source.ensure("dir1", "dir2", "hello") | ||||||
|         l = [] |         l = [] | ||||||
|  | @ -51,7 +51,7 @@ class TestGatewayManagerPopen: | ||||||
|         assert dest.join("dir1", "dir2", 'hello').check() |         assert dest.join("dir1", "dir2", 'hello').check() | ||||||
| 
 | 
 | ||||||
|     def test_hostmanage_rsync_same_popen_twice(self, source, dest, eventrecorder): |     def test_hostmanage_rsync_same_popen_twice(self, source, dest, eventrecorder): | ||||||
|         hm = GatewayManager(["popen::%s" %dest] * 2) |         hm = GatewayManager(["popen//chdir=%s" %dest] * 2) | ||||||
|         hm.makegateways() |         hm.makegateways() | ||||||
|         source.ensure("dir1", "dir2", "hello") |         source.ensure("dir1", "dir2", "hello") | ||||||
|         hm.rsync(source) |         hm.rsync(source) | ||||||
|  | @ -65,7 +65,7 @@ class TestGatewayManagerPopen: | ||||||
| 
 | 
 | ||||||
|     def test_multi_chdir_popen_with_path(self, testdir): |     def test_multi_chdir_popen_with_path(self, testdir): | ||||||
|         import os |         import os | ||||||
|         hm = GatewayManager(["popen::hello"] * 2) |         hm = GatewayManager(["popen//chdir=hello"] * 2) | ||||||
|         testdir.tmpdir.chdir() |         testdir.tmpdir.chdir() | ||||||
|         hellopath = testdir.tmpdir.mkdir("hello") |         hellopath = testdir.tmpdir.mkdir("hello") | ||||||
|         hm.makegateways() |         hm.makegateways() | ||||||
|  | @ -122,8 +122,7 @@ class TestHRSync: | ||||||
|         assert 'somedir' in basenames |         assert 'somedir' in basenames | ||||||
| 
 | 
 | ||||||
|     def test_hrsync_one_host(self, source, dest): |     def test_hrsync_one_host(self, source, dest): | ||||||
|         spec = py.execnet.GatewaySpec("popen::%s" % dest) |         gw = py.execnet.makegateway("popen//chdir=%s" % dest) | ||||||
|         gw = spec.makegateway() |  | ||||||
|         finished = [] |         finished = [] | ||||||
|         rsync = HostRSync(source) |         rsync = HostRSync(source) | ||||||
|         rsync.add_target_host(gw, finished=lambda: finished.append(1)) |         rsync.add_target_host(gw, finished=lambda: finished.append(1)) | ||||||
|  |  | ||||||
|  | @ -1,101 +0,0 @@ | ||||||
| """  |  | ||||||
|     tests for py.execnet.GatewaySpec |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import py |  | ||||||
| 
 |  | ||||||
| class TestGatewaySpec: |  | ||||||
|     """ |  | ||||||
|     socket:hostname:port:path SocketGateway |  | ||||||
|     popen[-executable][:path] PopenGateway |  | ||||||
|     [ssh:]spec:path           SshGateway |  | ||||||
|     * [SshGateway] |  | ||||||
|     """ |  | ||||||
|     def test_popen(self): |  | ||||||
|         for python in ('', 'python2.4'): |  | ||||||
|             for joinpath in ('', 'abc', 'ab:cd', '/x/y'): |  | ||||||
|                 s = ":".join(["popen", python, joinpath]) |  | ||||||
|                 print s |  | ||||||
|                 spec = py.execnet.GatewaySpec(s) |  | ||||||
|                 assert spec.address == "popen" |  | ||||||
|                 assert spec.python == (python or py.std.sys.executable) |  | ||||||
|                 assert spec.joinpath == joinpath |  | ||||||
|                 assert spec.type == "popen" |  | ||||||
|                 spec2 = py.execnet.GatewaySpec("popen" + joinpath) |  | ||||||
|                 self._equality(spec, spec2) |  | ||||||
| 
 |  | ||||||
|     def test_ssh(self): |  | ||||||
|         for prefix in ('ssh', ''): # ssh is default |  | ||||||
|             for hostpart in ('x.y', 'xyz@x.y'): |  | ||||||
|                 for python in ('python', 'python2.5'): |  | ||||||
|                     for joinpath in ('', 'abc', 'ab:cd', '/tmp'): |  | ||||||
|                         specstring = ":".join([prefix, hostpart, python, joinpath]) |  | ||||||
|                         if specstring[0] == ":": |  | ||||||
|                             specstring = specstring[1:] |  | ||||||
|                         print specstring |  | ||||||
|                         spec = py.execnet.GatewaySpec(specstring) |  | ||||||
|                         assert spec.address == hostpart  |  | ||||||
|                         assert spec.python == python |  | ||||||
|                         if joinpath: |  | ||||||
|                             assert spec.joinpath == joinpath |  | ||||||
|                         else: |  | ||||||
|                             assert spec.joinpath == "pyexecnetcache" |  | ||||||
|                         assert spec.type == "ssh" |  | ||||||
|                         spec2 = py.execnet.GatewaySpec(specstring) |  | ||||||
|                         self._equality(spec, spec2)  |  | ||||||
|      |  | ||||||
|     def test_socket(self): |  | ||||||
|         for hostpart in ('x.y', 'x', 'popen'): |  | ||||||
|             for port in ":80", ":1000": |  | ||||||
|                 for joinpath in ('', ':abc', ':abc:de'): |  | ||||||
|                     spec = py.execnet.GatewaySpec("socket:" + hostpart + port + joinpath) |  | ||||||
|                     assert spec.address == (hostpart, int(port[1:])) |  | ||||||
|                     if joinpath[1:]: |  | ||||||
|                         assert spec.joinpath == joinpath[1:] |  | ||||||
|                     else: |  | ||||||
|                         assert spec.joinpath == "pyexecnetcache" |  | ||||||
|                     assert spec.type == "socket" |  | ||||||
|                     spec2 = py.execnet.GatewaySpec("socket:" + hostpart + port + joinpath) |  | ||||||
|                     self._equality(spec, spec2)  |  | ||||||
| 
 |  | ||||||
|     def _equality(self, spec1, spec2): |  | ||||||
|         assert spec1 != spec2 |  | ||||||
|         assert hash(spec1) != hash(spec2) |  | ||||||
|         assert not (spec1 == spec2) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class TestGatewaySpecAPI: |  | ||||||
|     def test_popen_nopath_makegateway(self, testdir): |  | ||||||
|         spec = py.execnet.GatewaySpec("popen") |  | ||||||
|         gw = spec.makegateway() |  | ||||||
|         p = gw.remote_exec("import os; channel.send(os.getcwd())").receive() |  | ||||||
|         curdir = py.std.os.getcwd() |  | ||||||
|         assert curdir == p |  | ||||||
|         gw.exit() |  | ||||||
| 
 |  | ||||||
|     def test_popen_makegateway(self, testdir): |  | ||||||
|         spec = py.execnet.GatewaySpec("popen::" + str(testdir.tmpdir)) |  | ||||||
|         gw = spec.makegateway() |  | ||||||
|         p = gw.remote_exec("import os; channel.send(os.getcwd())").receive() |  | ||||||
|         assert spec.joinpath == p |  | ||||||
|         gw.exit() |  | ||||||
| 
 |  | ||||||
|     def test_popen_makegateway_python(self, testdir): |  | ||||||
|         spec = py.execnet.GatewaySpec("popen:%s" % py.std.sys.executable) |  | ||||||
|         gw = spec.makegateway() |  | ||||||
|         res = gw.remote_exec("import sys ; channel.send(sys.executable)").receive() |  | ||||||
|         assert py.std.sys.executable == py.std.sys.executable |  | ||||||
|         gw.exit() |  | ||||||
| 
 |  | ||||||
|     def test_ssh(self, specssh): |  | ||||||
|         sshhost = specssh.ssh |  | ||||||
|         spec = py.execnet.GatewaySpec("ssh:" + sshhost) |  | ||||||
|         gw = spec.makegateway() |  | ||||||
|         p = gw.remote_exec("import os ; channel.send(os.getcwd())").receive() |  | ||||||
|         gw.exit() |  | ||||||
| 
 |  | ||||||
|     @py.test.mark.xfail("implement socketserver test scenario") |  | ||||||
|     def test_socketgateway(self): |  | ||||||
|         gw = py.execnet.PopenGateway() |  | ||||||
|         spec = py.execnet.GatewaySpec("ssh:" + sshhost) |  | ||||||
| 
 |  | ||||||
|  | @ -4,23 +4,23 @@ XSpec = py.execnet.XSpec | ||||||
| 
 | 
 | ||||||
| class TestXSpec: | class TestXSpec: | ||||||
|     def test_attributes(self): |     def test_attributes(self): | ||||||
|         spec = XSpec("socket=192.168.102.2:8888//python=c:/this/python2.5//path=d:\hello") |         spec = XSpec("socket=192.168.102.2:8888//python=c:/this/python2.5//chdir=d:\hello") | ||||||
|         assert spec.socket == "192.168.102.2:8888" |         assert spec.socket == "192.168.102.2:8888" | ||||||
|         assert spec.python == "c:/this/python2.5"  |         assert spec.python == "c:/this/python2.5"  | ||||||
|         assert spec.path == "d:\hello" |         assert spec.chdir == "d:\hello" | ||||||
|         assert spec.xyz is None |         assert not hasattr(spec, 'xyz') | ||||||
| 
 | 
 | ||||||
|         py.test.raises(AttributeError, "spec._hello") |         py.test.raises(AttributeError, "spec._hello") | ||||||
| 
 | 
 | ||||||
|         spec = XSpec("socket=192.168.102.2:8888//python=python2.5") |         spec = XSpec("socket=192.168.102.2:8888//python=python2.5") | ||||||
|         assert spec.socket == "192.168.102.2:8888" |         assert spec.socket == "192.168.102.2:8888" | ||||||
|         assert spec.python == "python2.5" |         assert spec.python == "python2.5" | ||||||
|         assert spec.path is None |         assert spec.chdir is None | ||||||
| 
 | 
 | ||||||
|         spec = XSpec("ssh=user@host//path=/hello/this//python=/usr/bin/python2.5") |         spec = XSpec("ssh=user@host//chdir=/hello/this//python=/usr/bin/python2.5") | ||||||
|         assert spec.ssh == "user@host" |         assert spec.ssh == "user@host" | ||||||
|         assert spec.python == "/usr/bin/python2.5" |         assert spec.python == "/usr/bin/python2.5" | ||||||
|         assert spec.path == "/hello/this" |         assert spec.chdir == "/hello/this" | ||||||
| 
 | 
 | ||||||
|         spec = XSpec("popen") |         spec = XSpec("popen") | ||||||
|         assert spec.popen == True |         assert spec.popen == True | ||||||
|  | @ -28,7 +28,17 @@ class TestXSpec: | ||||||
|     def test__samefilesystem(self): |     def test__samefilesystem(self): | ||||||
|         assert XSpec("popen")._samefilesystem() |         assert XSpec("popen")._samefilesystem() | ||||||
|         assert XSpec("popen//python=123")._samefilesystem() |         assert XSpec("popen//python=123")._samefilesystem() | ||||||
|         assert not XSpec("popen//path=hello")._samefilesystem() |         assert not XSpec("popen//chdir=hello")._samefilesystem() | ||||||
|  | 
 | ||||||
|  |     def test__spec_spec(self): | ||||||
|  |         for x in ("popen", "popen//python=this"): | ||||||
|  |             assert XSpec(x)._spec == x | ||||||
|  | 
 | ||||||
|  |     def test_hash_equality(self): | ||||||
|  |         assert XSpec("popen") == XSpec("popen") | ||||||
|  |         assert hash(XSpec("popen")) == hash(XSpec("popen")) | ||||||
|  |         assert XSpec("popen//python=123") != XSpec("popen") | ||||||
|  |         assert hash(XSpec("socket=hello:8080")) != hash(XSpec("popen")) | ||||||
| 
 | 
 | ||||||
| class TestMakegateway: | class TestMakegateway: | ||||||
|     def test_popen(self): |     def test_popen(self): | ||||||
|  |  | ||||||
|  | @ -9,22 +9,36 @@ class XSpec: | ||||||
|         * keys are not allowed to start with underscore  |         * keys are not allowed to start with underscore  | ||||||
|         * if no "=value" is given, assume a boolean True value  |         * if no "=value" is given, assume a boolean True value  | ||||||
|     """ |     """ | ||||||
|     def __init__(self, *strings): |     # XXX for now we are very restrictive about actually allowed key-values  | ||||||
|         for string in strings: |     popen = ssh = socket = python = chdir = None | ||||||
|  | 
 | ||||||
|  |     def __init__(self, string): | ||||||
|  |         self._spec = string | ||||||
|         for keyvalue in string.split("//"): |         for keyvalue in string.split("//"): | ||||||
|             i = keyvalue.find("=") |             i = keyvalue.find("=") | ||||||
|             if i == -1: |             if i == -1: | ||||||
|                     setattr(self, keyvalue, True) |                 key, value = keyvalue, True | ||||||
|             else: |             else: | ||||||
|                     setattr(self, keyvalue[:i], keyvalue[i+1:]) |                 key, value = keyvalue[:i], keyvalue[i+1:] | ||||||
|  |             # XXX be restrictive for now | ||||||
|  |             if key not in XSpec.__dict__: | ||||||
|  |                 raise AttributeError("%r not a valid attribute" % key) | ||||||
|  |             setattr(self, key, value) | ||||||
| 
 | 
 | ||||||
|     def __getattr__(self, name): |     def __hash__(self): | ||||||
|         if name[0] == "_": |         return hash(self._spec) | ||||||
|             raise AttributeError(name)  |     def __eq__(self, other): | ||||||
|         return None |         return self._spec == getattr(other, '_spec', None) | ||||||
|  |     def __ne__(self, other): | ||||||
|  |         return self._spec != getattr(other, '_spec', None) | ||||||
|  | 
 | ||||||
|  |     #def __getattr__(self, name): | ||||||
|  |     #    if name[0] == "_": | ||||||
|  |     #        raise AttributeError(name)  | ||||||
|  |     #    return None | ||||||
| 
 | 
 | ||||||
|     def _samefilesystem(self): |     def _samefilesystem(self): | ||||||
|         return bool(self.popen and not self.path) |         return bool(self.popen and not self.chdir) | ||||||
| 
 | 
 | ||||||
| def makegateway(spec): | def makegateway(spec): | ||||||
|     if not isinstance(spec, XSpec): |     if not isinstance(spec, XSpec): | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue