[py-svn] py-trunk commit 852bdd2c8a78: * allowing arbitrary keys for xspecs but adding some sanity checks to xspec-parsing and makegateway.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Tue Sep 22 19:14:01 CEST 2009


# HG changeset patch -- Bitbucket.org
# Project py-trunk
# URL http://bitbucket.org/hpk42/py-trunk/overview/
# User holger krekel <holger at merlinux.eu>
# Date 1253637620 -7200
# Node ID 852bdd2c8a7825903dc7bdfa6e7befe900e25f5f
# Parent c4b739c83e0ccf8ebc85b686735c5789e27c23ed
* 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.

--- a/py/execnet/gateway_base.py
+++ b/py/execnet/gateway_base.py
@@ -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):

--- a/py/execnet/gateway.py
+++ b/py/execnet/gateway.py
@@ -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()", 
             ""
             ])

--- a/py/execnet/xspec.py
+++ b/py/execnet/xspec.py
@@ -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("""

--- a/testing/execnet/test_xspec.py
+++ b/testing/execnet/test_xspec.py
@@ -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'):



More information about the pytest-commit mailing list