Commits

Alex Gaynor committed ecabfc1

Added dont_write_bytecode flag for Popen gateways.

  • Participants
  • Parent commits 3949932

Comments (0)

Files changed (5)

+1.0.10
+--------------------------------
+
+- added a ``dont_write_bytecode`` option to Popen gateways, this sets the
+  ``sys.dont_write_bytecode`` flag on the spawned process, this only works on
+  CPython 2.6 and higher.
+
 1.0.9
 --------------------------------
 
 - channel.makefile() objects now have a isatty() returning False
 
 - group.allocate_id(spec) allows to early-determine an (automatic) id
-  
+
 - internal refactorings and cleanups (thanks Ronny Pfannschmidt):
   - refactor message types into received handler functions
   - refactor b(chr(opcode)) to bchr(opcode)
   for writing a "pure-function" checker so that on Python2.6
   onwards non-pure functions will be rejected.
 
-- enhance rsyncing to also sync permissions (stat().st_mode) 
-  of directories and files. 
+- enhance rsyncing to also sync permissions (stat().st_mode)
+  of directories and files.
   (should also resolve http://bitbucket.org/hpk42/py-trunk/issue/68/)
 
-- fix rsyncing of symlinks, thanks to Charles Solar 
+- fix rsyncing of symlinks, thanks to Charles Solar
   (should also resolve http://bitbucket.org/hpk42/py-trunk/issue/70/)
 
 - update internal usage of apipkg to 1.0b6
 
 - remote_exec(module) now makes sure that the linecache is updated
-  before reading and sending the source.  thanks Ronny, Matt. 
+  before reading and sending the source.  thanks Ronny, Matt.
 
 - removed all trailing whitespace from source files
 
 --------------------------------
 
 - try to avoid a random KeyboardInterrupt Error when threads
-  are ending. 
+  are ending.
 
-- extend xspec syntax to allow for one or multiple "env:NAME=value" 
-  environment variable settings which will be set on the remote side. 
+- extend xspec syntax to allow for one or multiple "env:NAME=value"
+  environment variable settings which will be set on the remote side.
   (thanks Jakub Gustak)
 
 1.0.6
 --------------------------------
 
-- fix jython/windows interactions 
+- fix jython/windows interactions
 - fix waitclose/callback-with-endmarker race condition
 - fix race condition where multiple threads sending data over channels
-  would crash the serializer and process 
+  would crash the serializer and process
 
 1.0.5
 --------------------------------
 
 - more care during receiver-thread finalization during interp-shutdown,
   should get rid of annoying and meaningless exceptions
-- fix glitch in ssh-fileserver example 
-- experimentally add "setup.py test" support - will run py.test 
+- fix glitch in ssh-fileserver example
+- experimentally add "setup.py test" support - will run py.test
 
 1.0.4
 --------------------------------
 
 - try to deal more cleanly with interpreter shutdown setting globals to
-  None. this avoids (hopefully) some bogus tracebacks at process exit. 
+  None. this avoids (hopefully) some bogus tracebacks at process exit.
 
 1.0.3
 --------------------------------
 
-- refine termination some more: CTRL-C and gateway.exit will 
-  now try harder to interrupt remote execution.  this 
+- refine termination some more: CTRL-C and gateway.exit will
+  now try harder to interrupt remote execution.  this
   helps to avoid left-over ssh-processes.
-- fix read-on-non-blocking-files issue probably related to jython only:  
-  the low-level read on subprocess pipes may be non-blocking, returning 
+- fix read-on-non-blocking-files issue probably related to jython only:
+  the low-level read on subprocess pipes may be non-blocking, returning
   less bytes than requested - so we now loop.
 - Windows/python2.4: fix bug that killing subprocesses would fail
 - make RemoteError and TimeoutError available directly on execnet namespace
 - update internal copy of apipkg
 - always skip remote tests if no ssh specs given
 
-1.0.2 
+1.0.2
 --------------------------------
 
-- generalize channel-over-channel sending: you can now have channels 
+- generalize channel-over-channel sending: you can now have channels
   anywhere in a data structure (i.e. as an item of a container type).
   Add according examples.
 
-- automatically close a channel when a remote callback raises 
-  an exception, makes communication more robust because until 
-  now failing callbacks rendered the receiverthread unuseable 
+- automatically close a channel when a remote callback raises
+  an exception, makes communication more robust because until
+  now failing callbacks rendered the receiverthread unuseable
   leaving the remote side in-accessible.
 
 - internally split socket gateways, speeds up popen-gateways
-  by 10% (now at <50 milliseconds per-gateway on a 1.5 GHZ machine) 
+  by 10% (now at <50 milliseconds per-gateway on a 1.5 GHZ machine)
 
-- fix bug in channel.receive() that would wrongly raise a TimeoutError 
-  after 1000 seconds (thanks Ronny Pfannschmidt) 
+- fix bug in channel.receive() that would wrongly raise a TimeoutError
+  after 1000 seconds (thanks Ronny Pfannschmidt)
 
 1.0.1
 --------------------------------
 
 - revamp and better structure documentation
 
-- new method: gateway.hasreceiver() returns True 
+- new method: gateway.hasreceiver() returns True
   if the gateway is still receive-active. remote_status
   now only carries information about remote execution status.
 
 - new: execnet.Group can be indexed by integer
 
 - new: group.makegateway() uses group.default_spec if no spec is given
-  and the execnet.default_group uses ``popen`` as a default spec. 
+  and the execnet.default_group uses ``popen`` as a default spec.
 
 - have popen-gateways use imports instead of source-strings,
   also improves debugging/tracebacks, as a side effect
   within time.
 
 - EOFError on channel.receive/waitclose if the other
-  side unexpectedly went away.  When a gateway exits 
+  side unexpectedly went away.  When a gateway exits
   it now internally sends an explicit termination message
-  instead of abruptly closing.  
+  instead of abruptly closing.
 
-- introduce a timeout parameter to channel.receive() 
+- introduce a timeout parameter to channel.receive()
   and default to periodically internally wake up
   to let KeyboardInterrupts pass through.
 
 - EXECNET_DEBUG=2 will cause tracing to go to stderr,
-  which with popen slave gateways will relay back 
+  which with popen slave gateways will relay back
   tracing to the instantiator process.
-  
+
 
 1.0.0
 --------------------------------
 
-* introduce execnet.Group for managing gateway creation 
-  and termination.  Introduce execnet.default_group through which 
+* introduce execnet.Group for managing gateway creation
+  and termination.  Introduce execnet.default_group through which
   all "global" calls are routed.  cleanup gateway termination.
-  All Gateways get an id through which they can be 
+  All Gateways get an id through which they can be
   retrieved from a group object.
 
 * deprecate execnet.XYZGateway in favour of direct makegateway() calls.
   way to indirectly setup a socket server ("installvia")
   through a gateway url.
 
-* refine and automatically test documentation examples 
+* refine and automatically test documentation examples
 
 1.0.0b3
 --------------------------------
 
-* fix EXECNET_DEBUG to work with win32 
+* fix EXECNET_DEBUG to work with win32
 * add support for serializing longs, sets and frozensets  (thanks
-  Benjamin Peterson) 
+  Benjamin Peterson)
 * introduce remote_status() method which on the low level gives
   information about the remote side of a gateway
 * disallow explicit close in remote_exec situation
 * integrated new serializer code from Benjamin Peterson
 * improved support for Jython-2.5.1
 
-1.0.0alpha2 
+1.0.0alpha2
 ----------------------------
 
 * improve documentation, new website
 
-* use sphinx for documentation, added boilerplate files and setup.py 
+* use sphinx for documentation, added boilerplate files and setup.py
 
 * fixes for standalone usage, adding boilerplate files
 

File execnet/gateway.py

     """ This Gateway provides interaction with a newly started
         python subprocess.
     """
-    def __init__(self, id, python=None):
+    def __init__(self, id, python=None, spec=None):
         """ instantiate a gateway to a subprocess
             started with the given 'python' executable.
         """
         if not python:
             python = sys.executable
-        args = [str(python), '-u', '-c', popen_bootstrapline]
+        args = [str(python), '-u']
+        if spec is not None and spec.dont_write_bytecode:
+            args.append("-B")
+        # Slight gymnastics in ordering these arguments because CPython (as of
+        # 2.7.1) ignores -B if you provide `python -c "something" -B`
+        args.extend(['-c', popen_bootstrapline])
         super(PopenGateway, self).__init__(args, id=id)
 
     def _remote_bootstrap_gateway(self, io):

File execnet/multi.py

             spec = XSpec(spec)
         self.allocate_id(spec)
         if spec.popen:
-            gw = gateway.PopenGateway(python=spec.python, id=spec.id)
+            gw = gateway.PopenGateway(python=spec.python, id=spec.id, spec=spec)
         elif spec.ssh:
             gw = gateway.SshGateway(spec.ssh, remotepython=spec.python,
                                     ssh_config=spec.ssh_config, id=spec.id)

File execnet/xspec.py

         * if no "=value" is given, assume a boolean True value
     """
     # XXX allow customization, for only allow specific key names
-    popen = ssh = socket = python = chdir = nice = None
+    popen = ssh = socket = python = chdir = nice = dont_write_bytecode = None
 
     def __init__(self, string):
         self._spec = string

File testing/test_gateway.py

         """)
         py.test.raises(channel.RemoteError, channel.receive)
 
+    @py.test.mark.skipif('sys.version_info < (2, 6)')
+    def test_dont_write_bytecode(self):
+        check_sys_dont_write_bytecode = """
+            import sys
+            channel.send(sys.dont_write_bytecode)
+        """
+
+        gw = execnet.makegateway('popen')
+        channel = gw.remote_exec(check_sys_dont_write_bytecode)
+        ret = channel.receive()
+        assert not ret
+        gw = execnet.makegateway('popen//dont_write_bytecode')
+        channel = gw.remote_exec(check_sys_dont_write_bytecode)
+        ret = channel.receive()
+        assert ret
+
 @py.test.mark.skipif("config.option.broken_isp")
 def test_socket_gw_host_not_found(gw):
     py.test.raises(execnet.HostNotFound,