* allowing arbitrary keys for xspecs but adding some sanity checks to xspec-parsing and makegateway.

* fixing a python3 IO issue - we need to retain sys.stdout/stdin
  references to keep the underlying byte stream open.

--HG--
branch : trunk
This commit is contained in:
holger krekel 2009-09-22 18:40:20 +02:00
parent 1b97d06a09
commit e3b34c9da3
4 changed files with 40 additions and 24 deletions

View File

@ -226,7 +226,7 @@ class PopenGateway(PopenCmdGateway):
s = "\n".join([extra,
"import sys ; sys.path[:0] = %r" % (plist,),
"import os ; os.environ['PYTHONPATH'] = %r" % ppath,
str(py.code.Source(stdouterrin_setnull)),
inspect.getsource(stdouterrin_setnull),
"stdouterrin_setnull()",
""
])

View File

@ -119,10 +119,6 @@ sys.stdin = tempfile.TemporaryFile('r')
def __init__(self, outfile, infile):
# we need raw byte streams
if hasattr(infile, 'buffer'):
infile = infile.buffer
if hasattr(outfile, 'buffer'):
outfile = outfile.buffer
self.outfile, self.infile = outfile, infile
if sys.platform == "win32":
import msvcrt
@ -132,7 +128,10 @@ sys.stdin = tempfile.TemporaryFile('r')
def read(self, numbytes):
"""Read exactly 'numbytes' bytes from the pipe. """
data = self.infile.read(numbytes)
try:
data = self.infile.buffer.read(numbytes)
except AttributeError:
data = self.infile.read(numbytes)
if len(data) < numbytes:
raise EOFError
return data
@ -140,7 +139,10 @@ sys.stdin = tempfile.TemporaryFile('r')
def write(self, data):
"""write out all data bytes. """
assert isinstance(data, bytes)
self.outfile.write(data)
try:
self.outfile.buffer.write(data)
except AttributeError:
self.outfile.write(data)
self.outfile.flush()
def close_read(self):

View File

@ -22,11 +22,17 @@ class XSpec:
key, value = keyvalue, True
else:
key, value = keyvalue[:i], keyvalue[i+1:]
# XXX be restrictive for now
if key not in XSpec.__dict__:
if key[0] == "_":
raise AttributeError("%r not a valid XSpec key" % key)
if key in self.__dict__:
raise ValueError("duplicate key: %r in %r" %(key, string))
setattr(self, key, value)
def __getattr__(self, name):
if name[0] == "_":
raise AttributeError(name)
return None
def __repr__(self):
return "<XSpec %r>" %(self._spec,)
def __str__(self):
@ -39,11 +45,6 @@ class XSpec:
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):
return bool(self.popen and not self.chdir)
@ -58,6 +59,8 @@ def makegateway(spec):
assert not spec.python, "socket: specifying python executables not supported"
hostport = spec.socket.split(":")
gw = py.execnet.SocketGateway(*hostport)
else:
raise ValueError("no gateway type found for %r" % (spec._spec,))
gw.spec = spec
if spec.chdir or spec.nice:
channel = gw.remote_exec("""

View File

@ -9,7 +9,7 @@ class TestXSpec:
assert spec.python == "c:/this/python2.5"
assert spec.chdir == "d:\hello"
assert spec.nice is None
assert not hasattr(spec, 'xyz')
assert not hasattr(spec, '_xyz')
py.test.raises(AttributeError, "spec._hello")
@ -36,6 +36,14 @@ class TestXSpec:
for x in ("popen", "popen//python=this"):
assert XSpec(x)._spec == x
def test_samekeyword_twice_raises(self):
py.test.raises(ValueError, "XSpec('popen//popen')")
py.test.raises(ValueError, "XSpec('popen//popen=123')")
def test_unknown_keys_allowed(self):
xspec = XSpec("hello=3")
assert xspec.hello == '3'
def test_repr_and_string(self):
for x in ("popen", "popen//python=this"):
assert repr(XSpec(x)).find("popen") != -1
@ -48,6 +56,9 @@ class TestXSpec:
assert hash(XSpec("socket=hello:8080")) != hash(XSpec("popen"))
class TestMakegateway:
def test_no_type(self):
py.test.raises(ValueError, "py.execnet.makegateway('hello')")
def test_popen(self):
gw = py.execnet.makegateway("popen")
assert gw.spec.python == None
@ -76,20 +87,20 @@ class TestMakegateway:
assert rinfo.cwd == py.std.os.getcwd()
assert rinfo.version_info == py.std.sys.version_info
def test_popen_cpython24(self):
for trypath in ('python2.4', r'C:\Python24\python.exe'):
cpython24 = py.path.local.sysfind(trypath)
if cpython24 is not None:
cpython24 = cpython24.realpath()
def test_popen_cpython25(self):
for trypath in ('python2.5', r'C:\Python25\python.exe'):
cpython25 = py.path.local.sysfind(trypath)
if cpython25 is not None:
cpython25 = cpython25.realpath()
break
else:
py.test.skip("cpython2.4 not found")
gw = py.execnet.makegateway("popen//python=%s" % cpython24)
py.test.skip("cpython2.5 not found")
gw = py.execnet.makegateway("popen//python=%s" % cpython25)
rinfo = gw._rinfo()
if py.std.sys.platform != "darwin": # it's confusing there
assert rinfo.executable == cpython24
assert rinfo.executable == cpython25
assert rinfo.cwd == py.std.os.getcwd()
assert rinfo.version_info[:2] == (2,4)
assert rinfo.version_info[:2] == (2,5)
def test_popen_cpython26(self):
for trypath in ('python2.6', r'C:\Python26\python.exe'):