From commits-noreply at bitbucket.org Fri Jan 1 22:28:49 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 1 Jan 2010 21:28:49 +0000 (UTC) Subject: [execnet-commit] execnet commit ad1480851bf7: skip tests if it's not my account and there are not remote specs given indicating that we have a working ssh setup Message-ID: <20100101212849.EF78E7EF23@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262381245 -3600 # Node ID ad1480851bf77d9ee9a8262cae541c0c8548c978 # Parent 73176c8168f280a27ee9e2b79ab6b3488a943e23 skip tests if it's not my account and there are not remote specs given indicating that we have a working ssh setup --- a/conftest.py +++ b/conftest.py @@ -1,6 +1,6 @@ import execnet import py -import sys +import os, sys import subprocess collect_ignore = ['build', 'doc/_build'] @@ -15,6 +15,12 @@ winpymap = { 'python3.1': r'C:\Python31\python.exe', } +def pytest_runtest_setup(item): + if item.fspath.purebasename in ('test_group', 'test_info'): + if os.environ['USER'] == "hpk": + return + getspecssh(item.config) # will skip if no gx given + pytest_plugins = ['pytester', 'doctest'] # configuration information for tests def pytest_addoption(parser): From commits-noreply at bitbucket.org Fri Jan 1 23:01:01 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 1 Jan 2010 22:01:01 +0000 (UTC) Subject: [execnet-commit] execnet commit 6a3d4508d389: fix typo and bug on windows/python2.4 Message-ID: <20100101220101.D00B37EF25@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262383233 -3600 # Node ID 6a3d4508d3896d12400bccfffb75630bf24b2180 # Parent ad1480851bf77d9ee9a8262cae541c0c8548c978 fix typo and bug on windows/python2.4 --- a/testing/test_termination.py +++ b/testing/test_termination.py @@ -74,7 +74,6 @@ def test_close_initiating_remote_no_erro stdout, stderr = popen.communicate() assert not stderr - at py.test.mark.skipif("not hasattr(os, 'dup')") def test_terminate_implicit_does_trykill(testdir, anypython, capfd): p = testdir.makepyfile(""" import sys @@ -86,6 +85,7 @@ def test_terminate_implicit_does_trykill ch.receive() # remote execution started sys.stdout.write("1\\n") sys.stdout.flush() + sys.stdout.close() # use process at-exit group.terminate call """ % str(execnetdir)) popen = subprocess.Popen([str(anypython), str(p)], stdout=subprocess.PIPE) --- a/execnet/multi.py +++ b/execnet/multi.py @@ -246,6 +246,7 @@ def killpid(pid): try: import ctypes except ImportError: + import subprocess # T: treekill, F: Force cmd = ("taskkill /T /F /PID %d" %(pid)).split() ret = subprocess.call(cmd) --- a/conftest.py +++ b/conftest.py @@ -17,7 +17,7 @@ winpymap = { def pytest_runtest_setup(item): if item.fspath.purebasename in ('test_group', 'test_info'): - if os.environ['USER'] == "hpk": + if os.environ.get('USER', "") == "hpk": return getspecssh(item.config) # will skip if no gx given --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -64,7 +64,7 @@ class TestBasicGateway: status = gw.remote_status() assert status.execqsize == 0 assert status.numexecuting == 0 - assert status.numchannels == 0 + assert status.numchannels == numchannels def test_remote_exec_module(self, tmpdir, gw): p = tmpdir.join("remotetest.py") From commits-noreply at bitbucket.org Sat Jan 2 10:19:00 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 2 Jan 2010 09:19:00 +0000 (UTC) Subject: [execnet-commit] execnet commit 58cb2448414f: add to changelog, bump version Message-ID: <20100102091900.B1CBC7EF3B@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262423085 -3600 # Node ID 58cb2448414f76faacaa1db2883fc7f73b46445a # Parent 6a3d4508d3896d12400bccfffb75630bf24b2180 add to changelog, bump version --- a/execnet/__init__.py +++ b/execnet/__init__.py @@ -3,7 +3,7 @@ execnet: pure python lib for connecting (c) 2009, Holger Krekel and others """ -__version__ = "1.0.2" +__version__ = "1.0.2post1" import execnet.apipkg --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +1.0.2post1 +-------------------------------- + +- Windows/python2.4: fix bug that killing subprocesses would fail + 1.0.2 -------------------------------- From commits-noreply at bitbucket.org Sun Jan 3 13:49:45 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 3 Jan 2010 12:49:45 +0000 (UTC) Subject: [execnet-commit] execnet commit 349c5987d135: fix GC sensitive compare Message-ID: <20100103124945.C5DD47EF3D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262522973 -3600 # Node ID 349c5987d13569b69f1a260b922d7cbe27a51e20 # Parent 58cb2448414f76faacaa1db2883fc7f73b46445a fix GC sensitive compare --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -64,7 +64,7 @@ class TestBasicGateway: status = gw.remote_status() assert status.execqsize == 0 assert status.numexecuting == 0 - assert status.numchannels == numchannels + assert status.numchannels <= numchannels def test_remote_exec_module(self, tmpdir, gw): p = tmpdir.join("remotetest.py") From commits-noreply at bitbucket.org Sun Jan 3 14:28:38 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 3 Jan 2010 13:28:38 +0000 (UTC) Subject: [execnet-commit] execnet commit 239d35261f4b: use newer apipkg Message-ID: <20100103132838.18DFA7EF3D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262525306 -3600 # Node ID 239d35261f4b39b494eade89eecc1edae6a73a77 # Parent 349c5987d13569b69f1a260b922d7cbe27a51e20 use newer apipkg --- a/execnet/apipkg.py +++ b/execnet/apipkg.py @@ -8,7 +8,7 @@ see http://pypi.python.org/pypi/apipkg import sys from types import ModuleType -__version__ = "1.0b2" +__version__ = "1.0b4" def initpkg(pkgname, exportdefs): """ initialize given package from the export definitions. """ @@ -17,6 +17,7 @@ def initpkg(pkgname, exportdefs): mod.__file__ = getattr(oldmod, '__file__', None) mod.__version__ = getattr(oldmod, '__version__', None) mod.__path__ = getattr(oldmod, '__path__', None) + mod.__loader__ = getattr(oldmod, '__loader__', None) sys.modules[pkgname] = mod def importobj(modpath, attrname): @@ -26,7 +27,7 @@ def importobj(modpath, attrname): class ApiModule(ModuleType): def __init__(self, name, importspec, implprefix=None): self.__name__ = name - self.__all__ = list(importspec) + self.__all__ = [x for x in importspec if x != '__onfirstaccess__'] self.__map__ = {} self.__implprefix__ = implprefix or name for name, importspec in importspec.items(): @@ -45,12 +46,26 @@ class ApiModule(ModuleType): self.__map__[name] = (modpath, attrname) def __repr__(self): + l = [] + if hasattr(self, '__version__'): + l.append("version=" + repr(self.__version__)) + if hasattr(self, '__file__'): + l.append('from ' + repr(self.__file__)) + if l: + return '' % (self.__name__, " ".join(l)) return '' % (self.__name__,) def __getattr__(self, name): + target = None + if '__onfirstaccess__' in self.__map__: + target = self.__map__.pop('__onfirstaccess__') + importobj(*target)() try: modpath, attrname = self.__map__[name] except KeyError: + if target is not None and name != '__onfirstaccess__': + # retry, onfirstaccess might have set attrs + return getattr(self, name) raise AttributeError(name) else: result = importobj(modpath, attrname) @@ -63,6 +78,7 @@ class ApiModule(ModuleType): dictdescr = ModuleType.__dict__['__dict__'] dict = dictdescr.__get__(self) if dict is not None: + hasattr(self, 'some') for name in self.__all__: hasattr(self, name) # force attribute load, ignore errors return dict From commits-noreply at bitbucket.org Sun Jan 3 15:03:23 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 3 Jan 2010 14:03:23 +0000 (UTC) Subject: [execnet-commit] execnet commit bb91c389fc3c: actually this check deals with a race-condition Message-ID: <20100103140323.533CB7EE7D@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262527384 -3600 # Node ID bb91c389fc3c5247f0ac5991acf697c23db3c9fd # Parent 239d35261f4b39b494eade89eecc1edae6a73a77 actually this check deals with a race-condition --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -64,7 +64,8 @@ class TestBasicGateway: status = gw.remote_status() assert status.execqsize == 0 assert status.numexecuting == 0 - assert status.numchannels <= numchannels + # race condition + assert status.numchannels <= numchannels + 1 def test_remote_exec_module(self, tmpdir, gw): p = tmpdir.join("remotetest.py") From commits-noreply at bitbucket.org Sun Jan 3 18:40:39 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 3 Jan 2010 17:40:39 +0000 (UTC) Subject: [execnet-commit] execnet commit 8a7228ab86d3: always skip remote tests if not ssh specs given Message-ID: <20100103174039.CA88D7EF2E@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1262540424 -3600 # Node ID 8a7228ab86d3bb547f420096413a1a7fd88208d7 # Parent bb91c389fc3c5247f0ac5991acf697c23db3c9fd always skip remote tests if not ssh specs given --- a/conftest.py +++ b/conftest.py @@ -17,8 +17,6 @@ winpymap = { def pytest_runtest_setup(item): if item.fspath.purebasename in ('test_group', 'test_info'): - if os.environ.get('USER', "") == "hpk": - return getspecssh(item.config) # will skip if no gx given pytest_plugins = ['pytester', 'doctest'] From commits-noreply at bitbucket.org Sun Jan 10 20:13:00 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 10 Jan 2010 19:13:00 +0000 (UTC) Subject: [execnet-commit] execnet commit 6fa3e72d7a74: update apipkg Message-ID: <20100110191300.E61677EF0B@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263150768 -3600 # Node ID 6fa3e72d7a7499940141314e2e1e2561220b7ea2 # Parent 8a7228ab86d3bb547f420096413a1a7fd88208d7 update apipkg --- a/execnet/apipkg.py +++ b/execnet/apipkg.py @@ -55,7 +55,8 @@ class ApiModule(ModuleType): return '' % (self.__name__, " ".join(l)) return '' % (self.__name__,) - def __getattr__(self, name): + def __makeattr(self, name): + """lazily compute value for name or raise AttributeError if unknown.""" target = None if '__onfirstaccess__' in self.__map__: target = self.__map__.pop('__onfirstaccess__') @@ -73,6 +74,8 @@ class ApiModule(ModuleType): del self.__map__[name] return result + __getattr__ = __makeattr + def __dict__(self): # force all the content of the module to be loaded when __dict__ is read dictdescr = ModuleType.__dict__['__dict__'] @@ -80,6 +83,9 @@ class ApiModule(ModuleType): if dict is not None: hasattr(self, 'some') for name in self.__all__: - hasattr(self, name) # force attribute load, ignore errors + try: + self.__makeattr(name) + except AttributeError: + pass return dict __dict__ = property(__dict__) From commits-noreply at bitbucket.org Mon Jan 11 14:48:33 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 11 Jan 2010 13:48:33 +0000 (UTC) Subject: [execnet-commit] execnet commit 80164354090f: fix some doc issues (thanks thm and ronny), add ssh_fileserver example Message-ID: <20100111134833.0DFFF7EE6F@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263217690 -3600 # Node ID 80164354090f54935e5e7d06120334c7e6a8a00e # Parent 6fa3e72d7a7499940141314e2e1e2561220b7ea2 fix some doc issues (thanks thm and ronny), add ssh_fileserver example --- a/doc/example/test_info.txt +++ b/doc/example/test_info.txt @@ -152,3 +152,5 @@ itself into the remote socket endpoint:: That's it, you can now use the gateway object just like a popen- or ssh-based one. + +.. include:: test_ssh_fileserver.txt --- a/doc/example/test_ssh_fileserver.txt +++ b/doc/example/test_ssh_fileserver.txt @@ -2,24 +2,21 @@ Receive file contents from remote SSH account ----------------------------------------------------- -Here is a small program that you can use to retrieve -contents of remote files:: +Here is some small server code that you can use to retrieve +contents of remote files: + +.. include:: servefiles.py + :literal: + +And here is some code to use it to retrieve remote contents:: import execnet - # open a gateway to a fresh child process + import servefiles gw = execnet.makegateway("ssh=codespeak.net") - channel = gw.remote_exec(""" - for fn in channel: - f = open(fn, 'rb') - channel.send(f.read()) - f.close() - """) + gw.remote_exec(servefiles) - for fn in somefilelist: + for fn in ('/etc/passwd', '/etc/group'): channel.send(fn) content = channel.receive() - # process content - - # later you can exit / close down the gateway - gw.exit() - + print(fn) + print(content) --- a/doc/examples.txt +++ b/doc/examples.txt @@ -15,3 +15,8 @@ Note: all examples with `>>>` prompts ar example/test_multi.txt example/hybridpython.txt example/test_debug.txt + +.. toctree:: + :hidden: + + example/test_ssh_fileserver.txt --- a/doc/implnotes.txt +++ b/doc/implnotes.txt @@ -1,5 +1,6 @@ -gateway_base.py:: +gateway_base.py +---------------------- the code of this module is sent to the "other side" as a means of bootstrapping a Gateway object --- a/execnet/multi.py +++ b/execnet/multi.py @@ -51,22 +51,22 @@ class Group: return iter(list(self._gateways)) def makegateway(self, spec=None): - """ create and configure a gateway to a Python interpreter. + """create and configure a gateway to a Python interpreter. + The ``spec`` string encodes the target gateway type + and configuration information. The general format is:: - The ``spec`` string encodes the target gateway type - and configuration information. The general format is:: + key1=value1//key2=value2//... - key1=value1//key2=value2//... + If you leave out the ``=value`` part a True value is assumed. + Valid types: ``popen``, ``ssh=hostname``, ``socket=host:port``. + Valid configuration:: - If you leave out the ``=value`` part a True value is assumed. - Valid types: ``popen``, ``ssh=hostname``, ``socket=host:port``. - Valid configuration:: - id= specifies the gateway id - python= specifies which python interpreter to execute - chdir= specifies to which directory to change - nice= specifies process priority of new process + id= specifies the gateway id + python= specifies which python interpreter to execute + chdir= specifies to which directory to change + nice= specifies process priority of new process - If no spec is given, self.defaultspec is used. + If no spec is given, self.defaultspec is used. """ if not spec: spec = self.defaultspec From commits-noreply at bitbucket.org Tue Jan 12 01:19:48 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 12 Jan 2010 00:19:48 +0000 (UTC) Subject: [execnet-commit] execnet commit 9860c45a5adf: refine termination to a) react on EOFErrors as if GATEWAY_TERMINATE was sent explicitely b) have gateway termination try harder to interrupt execution on slaves. Message-ID: <20100112001948.6339D7EE85@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263255555 -3600 # Node ID 9860c45a5adf33294cb3898ee2cbe89d81182fd6 # Parent 80164354090f54935e5e7d06120334c7e6a8a00e refine termination to a) react on EOFErrors as if GATEWAY_TERMINATE was sent explicitely b) have gateway termination try harder to interrupt execution on slaves. Also CTRL-C should now cleanup local and remote processes better. this should fix http://bitbucket.org/hpk42/py-trunk/issue/71/interrupting-distributed-testing-does-not-clean-up-processes-on-the-remote. --- a/ISSUES.txt +++ b/ISSUES.txt @@ -81,3 +81,12 @@ a virtual environment: sf.sdist_remote_install(newgw) +have callback accept errors / errback +----------------------------------------------- +tags: 1.1 wish + +If using channel.setcallback() it currently is not +impossible notice the exact errors that might happen +on the other side. Either introduce an "errback" +or (probably better) optionally allow an extra 'error' +parameter to execnet callbacks. --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -18,11 +18,16 @@ if ISPY3: "def reraise(cls, val, tb): raise val\n") unicode = str _long_type = int + from _thread import interrupt_main else: exec("def do_exec(co, loc): exec co in loc\n" "def reraise(cls, val, tb): raise cls, val, tb\n") bytes = str _long_type = long + try: + from thread import interrupt_main + except ImportError: + interrupt_main = None sysex = (KeyboardInterrupt, SystemExit) @@ -160,8 +165,7 @@ def _setupmessages(): class GATEWAY_TERMINATE(Message): def received(self, gateway): - gateway._trace("putting None to execqueue") - gateway._execqueue.put(None) + gateway._terminate_execution() raise SystemExit(0) classes = [ @@ -599,10 +603,11 @@ class BaseGateway(object): def _thread_receiver(self): self._trace("starting to receive") - unserializer = Unserializer(self._io, self._channelfactory) + eof = False try: - while 1: - try: + try: + unserializer = Unserializer(self._io, self._channelfactory) + while 1: msg = Message.readfrom(unserializer) self._trace("received", msg) _receivelock = self._receivelock @@ -612,22 +617,25 @@ class BaseGateway(object): del msg finally: _receivelock.release() - except sysex: - self._trace("io.close_read()") - self._io.close_read() - break - except EOFError: - self._error = sys.exc_info()[1] - break - except: - self._trace("RECEIVERTHREAD", - geterrortext(self.exc_info())) - break + except sysex: + self._trace("io.close_read()") + self._io.close_read() + except EOFError: + self._trace("receiverthread: got EOFError") + self._error = self.exc_info()[1] + eof = True + except: + self._trace("RECEIVERTHREAD", geterrortext(self.exc_info())) finally: self._channelfactory._finished_receiving() + if eof: + self._terminate_execution() if threading: # might be None during shutdown/finalization self._trace('leaving', threading.currentThread()) + def _terminate_execution(self): + pass + def _send(self, msg): assert isinstance(msg, Message) msg.writeto(self._serializer) @@ -659,19 +667,36 @@ class SlaveGateway(BaseGateway): def _local_schedulexec(self, channel, sourcetask): self._execqueue.put((channel, sourcetask)) + def _terminate_execution(self): + # called from receiverthread + self._trace("putting None to execqueue") + self._execqueue.put(None) + if interrupt_main: + self._trace("calling interrupt_main()") + interrupt_main() + self._execfinished.wait(10.0) + if not self._execfinished.isSet(): + self._trace("execution did not finish in 10 secs, calling os._exit()") + os._exit(1) + def serve(self, joining=True): - self._execqueue = queue.Queue() - self._initreceive() try: - while 1: - item = self._execqueue.get() - if item is None: - break - try: - self.executetask(item) - except self._StopExecLoop: - break + try: + self._execqueue = queue.Queue() + self._execfinished = threading.Event() + self._initreceive() + while 1: + item = self._execqueue.get() + if item is None: + break + try: + self.executetask(item) + except self._StopExecLoop: + break + except KeyboardInterrupt: + pass finally: + self._execfinished.set() self._trace("io.close_write()") self._io.close_write() self._trace("slavegateway.serve finished") --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ 1.0.2post1 -------------------------------- - Windows/python2.4: fix bug that killing subprocesses would fail +- 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. 1.0.2 -------------------------------- From commits-noreply at bitbucket.org Wed Jan 13 01:51:46 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 13 Jan 2010 00:51:46 +0000 (UTC) Subject: [execnet-commit] execnet commit fe49fd8cb655: popen gateways already re-use an existing installation Message-ID: <20100113005146.B88707EE71@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263343877 -3600 # Node ID fe49fd8cb65531c4e6083cb9944c49fe24659f45 # Parent 9860c45a5adf33294cb3898ee2cbe89d81182fd6 popen gateways already re-use an existing installation --- a/ISSUES.txt +++ b/ISSUES.txt @@ -16,9 +16,6 @@ A building block for keeping permanent n connections would be a started-on-first-access process that keeps state. Considered: -- PopenGateway imports local execnet package - and avoids parse/compile code strings - - a rendevouz process that starts threads for each incoming connection. On each such connection a SocketGateway can be instantiated but it From commits-noreply at bitbucket.org Fri Jan 15 18:54:13 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 15 Jan 2010 17:54:13 +0000 (UTC) Subject: [execnet-commit] execnet commit 8d00cbdaa210: normalize a test with a too small timeout Message-ID: <20100115175413.0E89C7EEDE@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263578034 -3600 # Node ID 8d00cbdaa21029c5b5182317d9a0a125c475400e # Parent fe49fd8cb65531c4e6083cb9944c49fe24659f45 normalize a test with a too small timeout --- a/testing/test_channel.py +++ b/testing/test_channel.py @@ -39,7 +39,7 @@ class TestChannelBasicBehaviour: channel = gw.remote_exec('channel.send(channel.receive())') py.test.raises(channel.TimeoutError, "channel.receive(timeout=0.2)") channel.send(1) - x = channel.receive(timeout=0.1) + x = channel.receive(timeout=TESTTIMEOUT) def test_channel_receive_internal_timeout(self, gw, monkeypatch): channel = gw.remote_exec(""" From commits-noreply at bitbucket.org Sat Jan 16 12:41:41 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 11:41:41 +0000 (UTC) Subject: [execnet-commit] execnet commit 773d50c557aa: going for 1.0.3 Message-ID: <20100116114141.418897EEE3@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263641988 -3600 # Node ID 773d50c557aa4bcfdc4061dbc434ce4b42258e03 # Parent 8d00cbdaa21029c5b5182317d9a0a125c475400e going for 1.0.3 --- a/execnet/__init__.py +++ b/execnet/__init__.py @@ -1,9 +1,9 @@ """ execnet: pure python lib for connecting to local and remote Python Interpreters. -(c) 2009, Holger Krekel and others +(c) 2010, Holger Krekel and others """ -__version__ = "1.0.2post1" +__version__ = "1.0.3" import execnet.apipkg --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,15 @@ -1.0.2post1 +1.0.3 -------------------------------- -- Windows/python2.4: fix bug that killing subprocesses would fail - 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. +- Windows/python2.4: fix bug that killing subprocesses would fail +- fix some doc issues (thanks thm and ronny), add ssh_fileserver example +- update apipkg +- always skip remote tests if not ssh specs given +- fix/refine some tests +- fix typo and bug on windows/python2.4 1.0.2 -------------------------------- From commits-noreply at bitbucket.org Sat Jan 16 15:17:57 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 14:17:57 +0000 (UTC) Subject: [execnet-commit] execnet commit 7614236c59e9: make gateway setup scope configurable for test runs Message-ID: <20100116141757.7E2A37EEE7@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263651398 -3600 # Node ID 7614236c59e96de65e6c5e44fb94da45a20f6c41 # Parent 773d50c557aa4bcfdc4061dbc434ce4b42258e03 make gateway setup scope configurable for test runs --- a/conftest.py +++ b/conftest.py @@ -22,10 +22,15 @@ def pytest_runtest_setup(item): pytest_plugins = ['pytester', 'doctest'] # configuration information for tests def pytest_addoption(parser): - group = parser.getgroup("pylib", "py lib testing options") + group = parser.getgroup("execnet", "execnet testing options") group.addoption('--gx', action="append", dest="gspecs", default=None, help=("add a global test environment, XSpec-syntax. ")) + group.addoption('--gwscope', + action="store", dest="scope", default="session", + type="choice", choices=["session", "function"], + help=("set gateway setup scope, default: session.")) + def pytest_funcarg__specssh(request): return getspecssh(request.config) @@ -98,7 +103,7 @@ def pytest_funcarg__anypython(request): return executable def pytest_funcarg__gw(request): - scope = "session" + scope = request.config.option.scope group = request.cached_setup( setup=execnet.Group, teardown=lambda group: group.terminate(timeout=1), From commits-noreply at bitbucket.org Sat Jan 16 15:28:23 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 14:28:23 +0000 (UTC) Subject: [execnet-commit] execnet commit 8481c6848eb8: report some extra information on execnet test runs Message-ID: <20100116142823.E1D427EE7F@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263651935 -3600 # Node ID 8481c6848eb8323e658b07b1a1967364e4c4235c # Parent 7614236c59e96de65e6c5e44fb94da45a20f6c41 report some extra information on execnet test runs --- a/conftest.py +++ b/conftest.py @@ -30,7 +30,12 @@ def pytest_addoption(parser): action="store", dest="scope", default="session", type="choice", choices=["session", "function"], help=("set gateway setup scope, default: session.")) - + +def pytest_report_header(config): + lines = [] + lines.append("gateway test setup scope: %s" % config.getvalue("scope")) + lines.append("execnet: %s -- %s" %(execnet.__file__, execnet.__version__)) + return lines def pytest_funcarg__specssh(request): return getspecssh(request.config) From commits-noreply at bitbucket.org Sat Jan 16 17:09:08 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 16:09:08 +0000 (UTC) Subject: [execnet-commit] execnet commit 2444a6d0b235: make RemoteError not derive from EOFError to better distinguish error cases. Message-ID: <20100116160908.8BE4C7EEE8@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263658134 -3600 # Node ID 2444a6d0b235c8365e6aabf2a9debf34081529c2 # Parent 8481c6848eb8323e658b07b1a1967364e4c4235c make RemoteError not derive from EOFError to better distinguish error cases. also remove a redundant set of tests. --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -190,11 +190,11 @@ def geterrortext(excinfo): excinfo[1]) return errortext -class RemoteError(EOFError): +class RemoteError(Exception): """ Exception containing a stringified error from the other side. """ def __init__(self, formatted): self.formatted = formatted - EOFError.__init__(self) + Exception.__init__(self) def __str__(self): return self.formatted --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -231,12 +231,11 @@ class TestPopenGateway: py.test.raises(IOError, channel.send, None) py.test.raises(EOFError, channel.receive) - def test_receive_on_remote_io_closed(self): - gw = execnet.makegateway('popen') + def test_receive_on_remote_sysexit(self, gw): channel = gw.remote_exec(""" raise SystemExit() """) - py.test.raises(EOFError, channel.receive) + py.test.raises(channel.RemoteError, channel.receive) def test_socket_gw_host_not_found(gw): py.test.raises(execnet.HostNotFound, --- a/testing/test_channel.py +++ b/testing/test_channel.py @@ -299,7 +299,7 @@ class TestChannelFile: """) first = channel.receive() assert first.strip() == 'hello world' - py.test.raises(EOFError, channel.receive) + py.test.raises(channel.RemoteError, channel.receive) def test_channel_file_read(self, gw): channel = gw.remote_exec(""" @@ -338,77 +338,6 @@ class TestChannelFile: channel = gw.newchannel() py.test.raises(ValueError, 'channel.makefile("rw")') - -class TestPopenGateway: - gwtype = 'popen' - - def test_chdir_separation(self, tmpdir): - old = tmpdir.chdir() - try: - gw = execnet.makegateway('popen') - finally: - waschangedir = old.chdir() - c = gw.remote_exec("import os ; channel.send(os.getcwd())") - x = c.receive() - assert x == str(waschangedir) - - def test_remoteerror_readable_traceback(self, gw): - e = py.test.raises(gateway_base.RemoteError, - 'gw.remote_exec("x y").waitclose()') - assert "gateway_base" in e.value.formatted - - def test_many_popen(self): - num = 4 - l = [] - for i in range(num): - l.append(execnet.makegateway('popen')) - channels = [] - for gw in l: - channel = gw.remote_exec("""channel.send(42)""") - channels.append(channel) -## try: -## while channels: -## channel = channels.pop() -## try: -## ret = channel.receive() -## assert ret == 42 -## finally: -## channel.gateway.exit() -## finally: -## for x in channels: -## x.gateway.exit() - while channels: - channel = channels.pop() - ret = channel.receive() - assert ret == 42 - - def test_rinfo_popen(self, gw): - rinfo = gw._rinfo() - assert rinfo.executable == py.std.sys.executable - assert rinfo.cwd == py.std.os.getcwd() - assert rinfo.version_info == py.std.sys.version_info - - def test_waitclose_on_remote_killed(self): - gw = execnet.makegateway('popen') - channel = gw.remote_exec(""" - import os - import time - channel.send(os.getpid()) - time.sleep(100) - """) - remotepid = channel.receive() - py.process.kill(remotepid) - py.test.raises(EOFError, "channel.waitclose(TESTTIMEOUT)") - py.test.raises(IOError, channel.send, None) - py.test.raises(EOFError, channel.receive) - - def test_receive_on_remote_io_closed(self): - gw = execnet.makegateway('popen') - channel = gw.remote_exec(""" - raise SystemExit() - """) - py.test.raises(EOFError, channel.receive) - def test_socket_gw_host_not_found(gw): py.test.raises(execnet.HostNotFound, 'execnet.makegateway("socket=qwepoipqwe:9000")' From commits-noreply at bitbucket.org Sat Jan 16 17:42:38 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 16:42:38 +0000 (UTC) Subject: [execnet-commit] execnet commit 6673ab104a64: fix an un-nerving issue mostly related to jython - reading from files Message-ID: <20100116164238.B4C817EEE5@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263658137 -3600 # Node ID 6673ab104a647f2d0f4cb21fd8a7867d8d91bb06 # Parent 2444a6d0b235c8365e6aabf2a9debf34081529c2 fix an un-nerving issue mostly related to jython - reading from files in non-blocking mode. --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -74,16 +74,18 @@ class Popen2IO: msvcrt.setmode(outfile.fileno(), os.O_BINARY) except (AttributeError, IOError): pass + self._read = getattr(infile, "buffer", infile).read def read(self, numbytes): """Read exactly 'numbytes' bytes from the pipe. """ - try: - data = self.infile.buffer.read(numbytes) - except AttributeError: - data = self.infile.read(numbytes) - if len(data) < numbytes: - raise EOFError - return data + # a file in non-blocking mode may return less bytes, so we loop + buf = "" + while len(buf) < numbytes: + data = self._read(numbytes) + if not data: + raise EOFError("expected %d bytes, got %d" %(numbytes, len(buf))) + buf += data + return buf def write(self, data): """write out all data bytes. """ @@ -622,6 +624,7 @@ class BaseGateway(object): self._io.close_read() except EOFError: self._trace("receiverthread: got EOFError") + self._trace("traceback was: ", geterrortext(self.exc_info())) self._error = self.exc_info()[1] eof = True except: --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ 1.0.3 - 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 + less bytes than requested - so we now loop. - Windows/python2.4: fix bug that killing subprocesses would fail - fix some doc issues (thanks thm and ronny), add ssh_fileserver example - update apipkg From commits-noreply at bitbucket.org Sat Jan 16 17:57:27 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 16:57:27 +0000 (UTC) Subject: [execnet-commit] execnet commit 1b755541dda9: fix python3 issue Message-ID: <20100116165727.E69B67EEE8@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263661034 -3600 # Node ID 1b755541dda94715fb0374aaceb25e7f0af57555 # Parent 6673ab104a647f2d0f4cb21fd8a7867d8d91bb06 fix python3 issue --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -79,7 +79,7 @@ class Popen2IO: def read(self, numbytes): """Read exactly 'numbytes' bytes from the pipe. """ # a file in non-blocking mode may return less bytes, so we loop - buf = "" + buf = bytes() while len(buf) < numbytes: data = self._read(numbytes) if not data: From commits-noreply at bitbucket.org Sat Jan 16 18:53:56 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 16 Jan 2010 17:53:56 +0000 (UTC) Subject: [execnet-commit] execnet commit 18fd6228a2ea: make RemoteError and TimeoutError available directly, streamline changelog Message-ID: <20100116175356.96F2C7EE7A@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263664423 -3600 # Node ID 18fd6228a2eabf3fc83e36b2b6153a319fbf129f # Parent 1b755541dda94715fb0374aaceb25e7f0af57555 make RemoteError and TimeoutError available directly, streamline changelog --- a/testing/test_basics.py +++ b/testing/test_basics.py @@ -1,9 +1,14 @@ import py import sys, os, subprocess, inspect +import execnet from execnet import gateway_base, gateway from execnet.gateway_base import Message, Channel, ChannelFactory +def test_errors_on_execnet(): + assert hasattr(execnet, 'RemoteError') + assert hasattr(execnet, 'TimeoutError') + def test_subprocess_interaction(anypython): line = gateway.popen_bootstrapline compile(line, 'xyz', 'exec') --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -158,7 +158,7 @@ def _setupmessages(): class CHANNEL_CLOSE_ERROR(Message): def received(self, gateway): - remote_error = gateway._channelfactory.RemoteError(self.data) + remote_error = RemoteError(self.data) gateway._channelfactory._local_close(self.channelid, remote_error) class CHANNEL_LAST_MESSAGE(Message): @@ -433,8 +433,6 @@ class Channel(object): ENDMARKER = object() class ChannelFactory(object): - RemoteError = RemoteError - def __init__(self, gateway, startcount=1): self._channels = weakref.WeakValueDictionary() self._callbacks = {} --- a/execnet/__init__.py +++ b/execnet/__init__.py @@ -13,6 +13,8 @@ execnet.apipkg.initpkg(__name__, { 'SshGateway': '.deprecated:SshGateway', 'makegateway': '.multi:makegateway', 'HostNotFound': '.gateway:HostNotFound', + 'RemoteError': '.gateway_base:RemoteError', + 'TimeoutError': '.gateway_base:TimeoutError', 'XSpec': '.xspec:XSpec', 'Group': '.multi:Group', 'MultiChannel': '.multi:MultiChannel', --- a/CHANGELOG +++ b/CHANGELOG @@ -8,11 +8,11 @@ 1.0.3 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 -- fix some doc issues (thanks thm and ronny), add ssh_fileserver example -- update apipkg -- always skip remote tests if not ssh specs given -- fix/refine some tests -- fix typo and bug on windows/python2.4 +- make RemoteError and TimeoutError available directly on execnet namespace + +- fix some doc and test issues (thanks thm and ronny), add ssh_fileserver example +- update internal copy of apipkg +- always skip remote tests if no ssh specs given 1.0.2 -------------------------------- From commits-noreply at bitbucket.org Mon Jan 18 02:07:09 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 01:07:09 +0000 (UTC) Subject: [execnet-commit] execnet commit f6ca92a5fee1: now that keyboardinterrupts are send from the receiver thread to the execution one, we should better let it pass through and not care anymore at process exit. Message-ID: <20100118010709.CDB7A7EF29@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263776817 -3600 # Node ID f6ca92a5fee114c3ba5b51400dc64716e07c37dc # Parent 18fd6228a2eabf3fc83e36b2b6153a319fbf129f now that keyboardinterrupts are send from the receiver thread to the execution one, we should better let it pass through and not care anymore at process exit. --- a/ISSUES.txt +++ b/ISSUES.txt @@ -87,3 +87,9 @@ impossible notice the exact errors that on the other side. Either introduce an "errback" or (probably better) optionally allow an extra 'error' parameter to execnet callbacks. + +fix rsync between python/jython +----------------------------------------------- +tags: 1.0 bug + +rsync does not complete with jython. --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -694,15 +694,16 @@ class SlaveGateway(BaseGateway): self.executetask(item) except self._StopExecLoop: break - except KeyboardInterrupt: - pass - finally: - self._execfinished.set() - self._trace("io.close_write()") - self._io.close_write() - self._trace("slavegateway.serve finished") - if joining: - self.join() + finally: + self._execfinished.set() + self._trace("io.close_write()") + self._io.close_write() + self._trace("slavegateway.serve finished") + if joining: + self.join() + except KeyboardInterrupt: + # in the slave we can't really do anything sensible + self._trace("swallowing keyboardinterrupt in main-thread, leaving") def executetask(self, item): channel, source = item @@ -719,6 +720,8 @@ class SlaveGateway(BaseGateway): except self._StopExecLoop: channel.close() raise + except KeyboardInterrupt: + raise except: excinfo = self.exc_info() self._trace("got exception: %s" % (excinfo[1],)) From commits-noreply at bitbucket.org Mon Jan 18 02:37:26 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 01:37:26 +0000 (UTC) Subject: [execnet-commit] execnet commit d1e4ec113bfa: send a special interrupt-text - another try to prevent shutdown from some racy messages. Message-ID: <20100118013726.20B837EF1C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263778634 -3600 # Node ID d1e4ec113bfa3967822b33e6407f431fedb26040 # Parent f6ca92a5fee114c3ba5b51400dc64716e07c37dc send a special interrupt-text - another try to prevent shutdown from some racy messages. --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -431,6 +431,7 @@ class Channel(object): __next__ = next ENDMARKER = object() +INTERRUPT_TEXT = "keyboard-interrupted" class ChannelFactory(object): def __init__(self, gateway, startcount=1): @@ -482,7 +483,8 @@ class ChannelFactory(object): if channel is None: # channel already in "deleted" state if remoteerror: - remoteerror.warn() + if remoteerror != INTERRUPT_TEXT: + remoteerror.warn() else: # state transition to "closed" state if remoteerror: @@ -721,6 +723,7 @@ class SlaveGateway(BaseGateway): channel.close() raise except KeyboardInterrupt: + channel.close(INTERRUPT_TEXT) raise except: excinfo = self.exc_info() From commits-noreply at bitbucket.org Mon Jan 18 02:58:07 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 01:58:07 +0000 (UTC) Subject: [execnet-commit] execnet commit bd0553b68265: more info Message-ID: <20100118015807.8F7757EF21@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263777853 -3600 # Node ID bd0553b68265ea531e4d1e2dbc7073a305e0c71d # Parent d1e4ec113bfa3967822b33e6407f431fedb26040 more info --- a/testing/test_termination.py +++ b/testing/test_termination.py @@ -72,6 +72,7 @@ def test_close_initiating_remote_no_erro popen = subprocess.Popen([str(anypython), str(p)], stdout=subprocess.PIPE, stderr=subprocess.PIPE,) stdout, stderr = popen.communicate() + print (stderr) assert not stderr def test_terminate_implicit_does_trykill(testdir, anypython, capfd): From commits-noreply at bitbucket.org Mon Jan 18 12:28:21 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 11:28:21 +0000 (UTC) Subject: [execnet-commit] execnet commit 1222307f5014: try to have finalization code survive interpreter-shutdown and globals being set to None in particular Message-ID: <20100118112821.4325E7EF14@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263814021 -3600 # Node ID 1222307f501440912955d7d7f6d0c839ebcc8c2f # Parent bd0553b68265ea531e4d1e2dbc7073a305e0c71d try to have finalization code survive interpreter-shutdown and globals being set to None in particular --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -441,6 +441,7 @@ class ChannelFactory(object): self.gateway = gateway self.count = startcount self.finished = False + self._list = list # needed during interp-shutdown def new(self, id=None): """ create a new Channel with 'id' (or create new id if None). """ @@ -460,7 +461,7 @@ class ChannelFactory(object): self._writelock.release() def channels(self): - return list(self._channels.values()) + return self._list(self._channels.values()) # # internal methods, called from the receiver thread @@ -526,9 +527,9 @@ class ChannelFactory(object): self.finished = True finally: self._writelock.release() - for id in list(self._channels): + for id in self._list(self._channels): self._local_close(id, sendonly=True) - for id in list(self._callbacks): + for id in self._list(self._callbacks): self._no_longer_opened(id) class ChannelFile(object): From commits-noreply at bitbucket.org Mon Jan 18 12:41:26 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 11:41:26 +0000 (UTC) Subject: [execnet-commit] execnet commit 4112e1d76da6: fixate new doc version Message-ID: <20100118114126.314B67EF14@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263814870 -3600 # Node ID 4112e1d76da68fdac9451a07f4a5143fe3191ec5 # Parent 1222307f501440912955d7d7f6d0c839ebcc8c2f fixate new doc version --- a/doc/conf.py +++ b/doc/conf.py @@ -46,7 +46,7 @@ copyright = '2009, holger krekel and oth # # The short X.Y version. import execnet -version = "1.0.2" +version = "1.0.3" # The full version, including alpha/beta/rc tags. release = version From commits-noreply at bitbucket.org Mon Jan 18 12:49:28 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 11:49:28 +0000 (UTC) Subject: [execnet-commit] execnet commit 5d74dad7f425: generally don't warn about keyboard-interrupted-messages Message-ID: <20100118114928.33B0F7EF1C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263815356 -3600 # Node ID 5d74dad7f425b1e51d15f52825579a83a4b3be99 # Parent 4112e1d76da68fdac9451a07f4a5143fe3191ec5 generally don't warn about keyboard-interrupted-messages --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -205,8 +205,9 @@ class RemoteError(Exception): return "%s: %s" %(self.__class__.__name__, self.formatted) def warn(self): - # XXX do this better - sys.stderr.write("Warning: unhandled %r\n" % (self,)) + if self.formatted != INTERRUPT_TEXT: + # XXX do this better + sys.stderr.write("Warning: unhandled %r\n" % (self,)) class TimeoutError(IOError): """ Exception indicating that a timeout was reached. """ @@ -484,8 +485,7 @@ class ChannelFactory(object): if channel is None: # channel already in "deleted" state if remoteerror: - if remoteerror != INTERRUPT_TEXT: - remoteerror.warn() + remoteerror.warn() else: # state transition to "closed" state if remoteerror: From commits-noreply at bitbucket.org Mon Jan 18 14:25:49 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 18 Jan 2010 13:25:49 +0000 (UTC) Subject: [execnet-commit] execnet commit ca2fc9afbbff: Added tag 1.0.3 for changeset 5d74dad7f425 Message-ID: <20100118132549.88F7C7EF20@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263821134 -3600 # Node ID ca2fc9afbbff46f5def8c05a6d76242d628625d2 # Parent 5d74dad7f425b1e51d15f52825579a83a4b3be99 Added tag 1.0.3 for changeset 5d74dad7f425 --- a/.hgtags +++ b/.hgtags @@ -4,3 +4,4 @@ 7cf86a1811b11aa58112a255e6afba870c8d855e 5d1c438e335dc369834207882ec5f3227d365c11 1.0.0 66760dc71203dbceeb08851cf4cf74e2687156d0 1.0.1 330b0032a09e13e38644c74d4a679d3760cdcdcf 1.0.2 +5d74dad7f425b1e51d15f52825579a83a4b3be99 1.0.3 From commits-noreply at bitbucket.org Tue Jan 19 10:56:31 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 19 Jan 2010 09:56:31 +0000 (UTC) Subject: [execnet-commit] execnet commit df0c1624a2f4: try harder to avoid bogus tracebacks, aim at execnet-1.0.4 Message-ID: <20100119095631.5CED67EF2C@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263894972 -3600 # Node ID df0c1624a2f40c1e9f388137a04f38966f3463c4 # Parent ca2fc9afbbff46f5def8c05a6d76242d628625d2 try harder to avoid bogus tracebacks, aim at execnet-1.0.4 --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -181,9 +181,9 @@ def _setupmessages(): _setupmessages() -def geterrortext(excinfo): +def geterrortext(excinfo, format_exception=traceback.format_exception): try: - l = traceback.format_exception(*excinfo) + l = format_exception(*excinfo) errortext = "".join(l) except sysex: raise @@ -517,7 +517,7 @@ class ChannelFactory(object): except: excinfo = sys.exc_info() self.gateway._trace("exception during callback: %s" % excinfo[1]) - errortext = geterrortext(excinfo) + errortext = self.gateway._geterrortext(excinfo) self.gateway._send(Message.CHANNEL_CLOSE_ERROR(id, errortext)) self._local_close(id, errortext) @@ -593,7 +593,9 @@ class BaseGateway(object): self._channelfactory = ChannelFactory(self, _startcount) self._receivelock = threading.RLock() self._serializer = Serializer(io) - self._globaltrace = trace # globals may be NONE at process-termination + # globals may be NONE at process-termination + self._globaltrace = trace + self._geterrortext = geterrortext def _trace(self, *msg): self._globaltrace(self.id, *msg) @@ -625,11 +627,12 @@ class BaseGateway(object): self._io.close_read() except EOFError: self._trace("receiverthread: got EOFError") - self._trace("traceback was: ", geterrortext(self.exc_info())) + self._trace("traceback was: ", + self._geterrortext(self.exc_info())) self._error = self.exc_info()[1] eof = True except: - self._trace("RECEIVERTHREAD", geterrortext(self.exc_info())) + self._trace("RECEIVERTHREAD", self._geterrortext(self.exc_info())) finally: self._channelfactory._finished_receiving() if eof: @@ -729,7 +732,7 @@ class SlaveGateway(BaseGateway): except: excinfo = self.exc_info() self._trace("got exception: %s" % (excinfo[1],)) - errortext = geterrortext(excinfo) + errortext = self._geterrortext(excinfo) channel.close(errortext) else: channel.close() --- a/execnet/__init__.py +++ b/execnet/__init__.py @@ -3,7 +3,7 @@ execnet: pure python lib for connecting (c) 2010, Holger Krekel and others """ -__version__ = "1.0.3" +__version__ = "1.0.4" import execnet.apipkg --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +1.0.4 +-------------------------------- + +- try harder to not have globals involved during finalization handling, + this should (hopefully) fix bogus tracebacks at process exit. + 1.0.3 -------------------------------- From commits-noreply at bitbucket.org Tue Jan 19 12:21:18 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 19 Jan 2010 11:21:18 +0000 (UTC) Subject: [execnet-commit] execnet commit e479c0849fce: making trace "global-None" safe as well and striking some duplicate tests Message-ID: <20100119112118.2D04A8385E@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263899846 -3600 # Node ID e479c0849fced39bde354691ac6a24cf23e482f1 # Parent df0c1624a2f40c1e9f388137a04f38966f3463c4 making trace "global-None" safe as well and striking some duplicate tests --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -31,35 +31,41 @@ else: sysex = (KeyboardInterrupt, SystemExit) -DEBUG = os.environ.get('EXECNET_DEBUG') -pid = os.getpid() -if DEBUG == '2': - def trace(*msg): - line = " ".join(map(str, msg)) - sys.stderr.write("[%s] %s\n" % (pid, line)) - sys.stderr.flush() -elif DEBUG: - import tempfile, os.path - fn = os.path.join(tempfile.gettempdir(), 'execnet-debug-%d' % os.getpid()) - debugfile = open(fn, 'w') - def trace(*msg): - line = " ".join(map(str, msg)) - try: - debugfile.write(line + "\n") - debugfile.flush() - except sysex: - raise - except: - v = sys.exc_info()[1] +class Trace: + pid = os.getpid() + stderr = sys.stderr + exc_info = sys.exc_info + _sysex = sysex + DEBUG = os.environ.get('EXECNET_DEBUG') + + def __init__(self): + if self.DEBUG == '2': + self.stream = sys.stderr + elif self.DEBUG: + import tempfile, os.path + fn = os.path.join(tempfile.gettempdir(),'execnet-debug-%s' % self.pid) + self.stream = open(fn, 'w') + else: + self.stream = None + def trace(self, *msg): + if self.stream: + line = " ".join(map(str, msg)) try: - sys.stderr.write( - "[%d] exception during tracing: %r\n" % (pid, v)) - except (IOError,ValueError): - pass # nothing we can do anymore -else: - def trace(*msg): - pass + self.stream.write("[%s] %s\n" % (self.pid, line)) + self.stream.flush() + except self._sysex: + raise + except: + if self.stream != self.stderr: + try: + v = self.exc_info()[1] + self.stderr.write( + "[%s] exception during tracing: %r\n" % (self.pid, v)) + except: + pass # nothing we can do anymore +_trace = Trace() +trace = _trace.trace class Popen2IO: error = (IOError, OSError, EOFError) @@ -181,7 +187,8 @@ def _setupmessages(): _setupmessages() -def geterrortext(excinfo, format_exception=traceback.format_exception): +def geterrortext(excinfo, + format_exception=traceback.format_exception, sysex=sysex): try: l = format_exception(*excinfo) errortext = "".join(l) @@ -582,6 +589,7 @@ class ChannelFileRead(ChannelFile): class BaseGateway(object): exc_info = sys.exc_info + _sysex = sysex id = "" class _StopExecLoop(Exception): @@ -622,7 +630,7 @@ class BaseGateway(object): del msg finally: _receivelock.release() - except sysex: + except self._sysex: self._trace("io.close_read()") self._io.close_read() except EOFError: --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -303,11 +303,12 @@ class TestThreads: class TestTracing: def test_debug(self, monkeypatch): - monkeypatch.setenv('EXECNET_DEBUG', "1") + monkeypatch.setenv('EXECNET_DEBUG', "2") source = py.std.inspect.getsource(gateway_base) d = {} gateway_base.do_exec(source, d) - assert 'debugfile' in d + t = d['_trace'] + assert t.stream == py.std.sys.stderr def test_popen_filetracing(self, monkeypatch): monkeypatch.setenv('EXECNET_DEBUG', "1") @@ -335,6 +336,6 @@ class TestTracing: def test_nodebug(): from execnet import gateway_base - assert not hasattr(gateway_base, 'debugfile') + assert not gateway_base.Trace.DEBUG --- a/testing/test_channel.py +++ b/testing/test_channel.py @@ -402,40 +402,3 @@ class TestThreads: py.test.raises(IOError, gw.remote_init_threads, 3) -class TestTracing: - def test_debug(self, monkeypatch): - monkeypatch.setenv('EXECNET_DEBUG', "1") - source = py.std.inspect.getsource(gateway_base) - d = {} - gateway_base.do_exec(source, d) - assert 'debugfile' in d - - def test_popen_filetracing(self, monkeypatch): - monkeypatch.setenv('EXECNET_DEBUG', "1") - gw = execnet.makegateway("popen") - pid = gw.remote_exec("import os ; channel.send(os.getpid())").receive() - tmpdir = py.path.local(py.std.tempfile.gettempdir()) - slavefile = tmpdir.join("execnet-debug-%s" % pid) - slave_line = "creating slavegateway" - for line in slavefile.readlines(): - if slave_line in line: - break - else: - py.test.fail("did not find %r in tracefile" %(slave_line,)) - gw.exit() - - @needs_osdup - def test_popen_stderr_tracing(self, capfd, monkeypatch): - monkeypatch.setenv('EXECNET_DEBUG', "2") - gw = execnet.makegateway("popen") - pid = gw.remote_exec("import os ; channel.send(os.getpid())").receive() - out, err = capfd.readouterr() - slave_line = "[%s] creating slavegateway" % pid - assert slave_line in err - gw.exit() - -def test_nodebug(): - from execnet import gateway_base - assert not hasattr(gateway_base, 'debugfile') - - From commits-noreply at bitbucket.org Tue Jan 19 15:03:22 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 19 Jan 2010 14:03:22 +0000 (UTC) Subject: [execnet-commit] execnet commit 534f61972976: revert back to old tracing, rather simplify by trying less hard to keep tracing when globals are None during shutdown, cleanup tests Message-ID: <20100119140322.419717EED0@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263908748 -3600 # Node ID 534f61972976f51c9163bbae3cf3cf6b97cabb8a # Parent e479c0849fced39bde354691ac6a24cf23e482f1 revert back to old tracing, rather simplify by trying less hard to keep tracing when globals are None during shutdown, cleanup tests --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -31,41 +31,35 @@ else: sysex = (KeyboardInterrupt, SystemExit) -class Trace: - pid = os.getpid() - stderr = sys.stderr - exc_info = sys.exc_info - _sysex = sysex - DEBUG = os.environ.get('EXECNET_DEBUG') - def __init__(self): - if self.DEBUG == '2': - self.stream = sys.stderr - elif self.DEBUG: - import tempfile, os.path - fn = os.path.join(tempfile.gettempdir(),'execnet-debug-%s' % self.pid) - self.stream = open(fn, 'w') - else: - self.stream = None - def trace(self, *msg): - if self.stream: +DEBUG = os.environ.get('EXECNET_DEBUG') +pid = os.getpid() +if DEBUG == '2': + def trace(*msg): + try: line = " ".join(map(str, msg)) + sys.stderr.write("[%s] %s\n" % (pid, line)) + sys.stderr.flush() + except Exception: + pass # nothing we can do, likely interpreter-shutdown +elif DEBUG: + import tempfile, os.path + fn = os.path.join(tempfile.gettempdir(), 'execnet-debug-%d' % pid) + debugfile = open(fn, 'w') + def trace(*msg): + try: + line = " ".join(map(str, msg)) + debugfile.write(line + "\n") + debugfile.flush() + except Exception: try: - self.stream.write("[%s] %s\n" % (self.pid, line)) - self.stream.flush() - except self._sysex: - raise - except: - if self.stream != self.stderr: - try: - v = self.exc_info()[1] - self.stderr.write( - "[%s] exception during tracing: %r\n" % (self.pid, v)) - except: - pass # nothing we can do anymore - -_trace = Trace() -trace = _trace.trace + v = exc_info()[1] + sys.stderr.write( + "[%s] exception during tracing: %r\n" % (pid, v)) + except Exception: + pass # nothing we can do, likely interpreter-shutdown +else: + notrace = trace = lambda *msg: None class Popen2IO: error = (IOError, OSError, EOFError) @@ -602,11 +596,11 @@ class BaseGateway(object): self._receivelock = threading.RLock() self._serializer = Serializer(io) # globals may be NONE at process-termination - self._globaltrace = trace + self._trace = trace self._geterrortext = geterrortext def _trace(self, *msg): - self._globaltrace(self.id, *msg) + self._trace(self.id, *msg) def _initreceive(self): self._receiverthread = threading.Thread(name="receiver", --- a/testing/test_gateway.py +++ b/testing/test_gateway.py @@ -302,20 +302,15 @@ class TestThreads: class TestTracing: - def test_debug(self, monkeypatch): - monkeypatch.setenv('EXECNET_DEBUG', "2") - source = py.std.inspect.getsource(gateway_base) - d = {} - gateway_base.do_exec(source, d) - t = d['_trace'] - assert t.stream == py.std.sys.stderr - - def test_popen_filetracing(self, monkeypatch): + def test_popen_filetracing(self, testdir, monkeypatch): + tmpdir = testdir.tmpdir + monkeypatch.setenv("TMP", tmpdir) + monkeypatch.setenv("TEMP", tmpdir) # windows monkeypatch.setenv('EXECNET_DEBUG', "1") gw = execnet.makegateway("popen") pid = gw.remote_exec("import os ; channel.send(os.getpid())").receive() - tmpdir = py.path.local(py.std.tempfile.gettempdir()) slavefile = tmpdir.join("execnet-debug-%s" % pid) + assert slavefile.check() slave_line = "creating slavegateway" for line in slavefile.readlines(): if slave_line in line: @@ -324,7 +319,6 @@ class TestTracing: py.test.fail("did not find %r in tracefile" %(slave_line,)) gw.exit() - @needs_osdup def test_popen_stderr_tracing(self, capfd, monkeypatch): monkeypatch.setenv('EXECNET_DEBUG', "2") gw = execnet.makegateway("popen") @@ -334,8 +328,6 @@ class TestTracing: assert slave_line in err gw.exit() -def test_nodebug(): - from execnet import gateway_base - assert not gateway_base.Trace.DEBUG - - + def test_no_tracing_by_default(self): + assert gateway_base.trace == gateway_base.notrace, \ + "trace does not to default to empty tracing" --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,8 @@ 1.0.4 -------------------------------- -- try harder to not have globals involved during finalization handling, - this should (hopefully) fix bogus tracebacks at process exit. +- try to deal more cleanly with interpreter shutdown setting globals to + None. this avoids (hopefully) some bogus tracebacks at process exit. 1.0.3 -------------------------------- From commits-noreply at bitbucket.org Tue Jan 19 16:35:16 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 19 Jan 2010 15:35:16 +0000 (UTC) Subject: [execnet-commit] execnet commit 88d4464d2afb: fix doc-tagging, Added tag 1.0.4 for changeset 534f61972976 Message-ID: <20100119153516.3B9637EF14@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1263915164 -3600 # Node ID 88d4464d2afbbc716159c175ee5548d044b89b99 # Parent 534f61972976f51c9163bbae3cf3cf6b97cabb8a fix doc-tagging, Added tag 1.0.4 for changeset 534f61972976 --- a/doc/conf.py +++ b/doc/conf.py @@ -46,7 +46,7 @@ copyright = '2009, holger krekel and oth # # The short X.Y version. import execnet -version = "1.0.3" +version = "1.0.4" # The full version, including alpha/beta/rc tags. release = version --- a/.hgtags +++ b/.hgtags @@ -5,3 +5,4 @@ 5d1c438e335dc369834207882ec5f3227d365c11 66760dc71203dbceeb08851cf4cf74e2687156d0 1.0.1 330b0032a09e13e38644c74d4a679d3760cdcdcf 1.0.2 5d74dad7f425b1e51d15f52825579a83a4b3be99 1.0.3 +534f61972976f51c9163bbae3cf3cf6b97cabb8a 1.0.4 From commits-noreply at bitbucket.org Thu Jan 21 12:52:05 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 21 Jan 2010 11:52:05 +0000 (UTC) Subject: [execnet-commit] execnet commit a1442c86ae53: fix glitch in example (thanks xa) Message-ID: <20100121115205.AECD97EEFC@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1264074709 -3600 # Node ID a1442c86ae53ae42313af6ea15de56faeca5b222 # Parent 88d4464d2afbbc716159c175ee5548d044b89b99 fix glitch in example (thanks xa) --- a/doc/example/test_ssh_fileserver.txt +++ b/doc/example/test_ssh_fileserver.txt @@ -13,7 +13,7 @@ And here is some code to use it to retri import execnet import servefiles gw = execnet.makegateway("ssh=codespeak.net") - gw.remote_exec(servefiles) + channel = gw.remote_exec(servefiles) for fn in ('/etc/passwd', '/etc/group'): channel.send(fn) From commits-noreply at bitbucket.org Thu Jan 21 20:19:48 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 21 Jan 2010 19:19:48 +0000 (UTC) Subject: [execnet-commit] execnet commit a5590cbab71b: just silence shutdown related exceptions at receiver-thread end (sigh) Message-ID: <20100121191948.1B6007EF78@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1264101569 -3600 # Node ID a5590cbab71b89f61e550a5b4e15641ecd32dc91 # Parent a1442c86ae53ae42313af6ea15de56faeca5b222 just silence shutdown related exceptions at receiver-thread end (sigh) --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -636,11 +636,15 @@ class BaseGateway(object): except: self._trace("RECEIVERTHREAD", self._geterrortext(self.exc_info())) finally: - self._channelfactory._finished_receiving() - if eof: - self._terminate_execution() - if threading: # might be None during shutdown/finalization - self._trace('leaving', threading.currentThread()) + try: + self._trace('entering finalization', threading.currentThread()) + if eof: + self._terminate_execution() + self._channelfactory._finished_receiving() + if threading: # might be None during shutdown/finalization + self._trace('leaving', threading.currentThread()) + except Exception: + pass # XXX be silent at interp-shutdown def _terminate_execution(self): pass --- a/execnet/__init__.py +++ b/execnet/__init__.py @@ -3,7 +3,7 @@ execnet: pure python lib for connecting (c) 2010, Holger Krekel and others """ -__version__ = "1.0.4" +__version__ = "1.0.4post1" import execnet.apipkg --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +1.0.4post1 +-------------------------------- + +- silence receiver-thread finalization exceptions during interp-shutdown +- fix glitch in ssh-fileserver example + 1.0.4 -------------------------------- From commits-noreply at bitbucket.org Fri Feb 5 21:31:36 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 5 Feb 2010 20:31:36 +0000 (UTC) Subject: [execnet-commit] execnet commit 3fc00577c03e: add a "setup.py test" target which runs py.test Message-ID: <20100205203136.00F667EE79@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1265401882 -3600 # Node ID 3fc00577c03e9d1a108fc268910c80f226e64778 # Parent a5590cbab71b89f61e550a5b4e15641ecd32dc91 add a "setup.py test" target which runs py.test --- a/setup.py +++ b/setup.py @@ -31,9 +31,9 @@ Features """ try: - from setuptools import setup + from setuptools import setup, Command except ImportError: - from distutils.core import setup + from distutils.core import setup, Command from execnet import __version__ @@ -48,6 +48,7 @@ def main(): platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel and others', author_email='holger at merlinux.eu', + cmdclass = {'test': PyTest}, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', @@ -63,5 +64,15 @@ def main(): packages=['execnet', 'execnet.script'], ) +class PyTest(Command): + user_options = [] + def initialize_options(self): + pass + def finalize_options(self): + pass + def run(self): + import py + py.cmdline.pytest(py.std.sys.argv[2:]) + if __name__ == '__main__': main() --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ 1.0.4post1 - silence receiver-thread finalization exceptions during interp-shutdown - fix glitch in ssh-fileserver example +- experimentally add "setup.py test" support - will run py.test 1.0.4 -------------------------------- From commits-noreply at bitbucket.org Sun Feb 7 12:43:14 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 11:43:14 +0000 (UTC) Subject: [execnet-commit] execnet commit 7094cc4bfb7e: fix docstring, more carefullness during receiverthread finalization Message-ID: <20100207114314.E4B2F7EEEF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1265542894 -3600 # Node ID 7094cc4bfb7e1a82987eac65c3f6e73ef11bc952 # Parent 3fc00577c03e9d1a108fc268910c80f226e64778 fix docstring, more carefullness during receiverthread finalization --- a/execnet/multi.py +++ b/execnet/multi.py @@ -135,8 +135,8 @@ class Group: def terminate(self, timeout=None): """ trigger exit of member gateways and wait for termination of member gateways and associated subprocesses. After waiting - timeout seconds an attempt to kill local sub processes of popen- - and ssh-gateways is started. Timeout defaults to None meaning + timeout seconds try to to kill local sub processes of popen- + and ssh-gateways. Timeout defaults to None meaning open-ended waiting and no kill attempts. """ for gw in self: --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -637,7 +637,8 @@ class BaseGateway(object): self._trace("RECEIVERTHREAD", self._geterrortext(self.exc_info())) finally: try: - self._trace('entering finalization', threading.currentThread()) + if threading: # might be None during shutdown/finalization + self._trace('entering finalization', threading.currentThread()) if eof: self._terminate_execution() self._channelfactory._finished_receiving() From commits-noreply at bitbucket.org Sun Feb 7 13:30:29 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 12:30:29 +0000 (UTC) Subject: [execnet-commit] execnet commit 9e7b55db59f9: prepare a 1.0.5 release, try to finalize interp-shutdown issues Message-ID: <20100207123029.4EA1A7EEE2@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1265545819 -3600 # Node ID 9e7b55db59f94009e739273916efbb356d385b96 # Parent 7094cc4bfb7e1a82987eac65c3f6e73ef11bc952 prepare a 1.0.5 release, try to finalize interp-shutdown issues --- a/testing/test_termination.py +++ b/testing/test_termination.py @@ -72,6 +72,7 @@ def test_close_initiating_remote_no_erro popen = subprocess.Popen([str(anypython), str(p)], stdout=subprocess.PIPE, stderr=subprocess.PIPE,) stdout, stderr = popen.communicate() + print (stdout) print (stderr) assert not stderr --- a/doc/conf.py +++ b/doc/conf.py @@ -46,7 +46,7 @@ copyright = '2009, holger krekel and oth # # The short X.Y version. import execnet -version = "1.0.4" +version = "1.0.5" # The full version, including alpha/beta/rc tags. release = version --- a/execnet/gateway_base.py +++ b/execnet/gateway_base.py @@ -609,7 +609,7 @@ class BaseGateway(object): self._receiverthread.start() def _thread_receiver(self): - self._trace("starting to receive") + self._trace("RECEIVERTHREAD: starting to run") eof = False try: try: @@ -625,11 +625,11 @@ class BaseGateway(object): finally: _receivelock.release() except self._sysex: - self._trace("io.close_read()") + self._trace("RECEIVERTHREAD: doing io.close_read()") self._io.close_read() except EOFError: - self._trace("receiverthread: got EOFError") - self._trace("traceback was: ", + self._trace("RECEIVERTHREAD: got EOFError") + self._trace("RECEIVERTHREAD: traceback was: ", self._geterrortext(self.exc_info())) self._error = self.exc_info()[1] eof = True @@ -637,13 +637,11 @@ class BaseGateway(object): self._trace("RECEIVERTHREAD", self._geterrortext(self.exc_info())) finally: try: - if threading: # might be None during shutdown/finalization - self._trace('entering finalization', threading.currentThread()) + self._trace('RECEIVERTHREAD', 'entering finalization') if eof: self._terminate_execution() self._channelfactory._finished_receiving() - if threading: # might be None during shutdown/finalization - self._trace('leaving', threading.currentThread()) + self._trace('RECEIVERTHREAD', 'leaving finalization') except Exception: pass # XXX be silent at interp-shutdown @@ -712,11 +710,11 @@ class SlaveGateway(BaseGateway): self._trace("io.close_write()") self._io.close_write() self._trace("slavegateway.serve finished") - if joining: - self.join() except KeyboardInterrupt: # in the slave we can't really do anything sensible - self._trace("swallowing keyboardinterrupt in main-thread, leaving") + self._trace("swallowing keyboardinterrupt in main-thread") + if joining: + self.join() def executetask(self, item): channel, source = item --- a/execnet/__init__.py +++ b/execnet/__init__.py @@ -3,7 +3,7 @@ execnet: pure python lib for connecting (c) 2010, Holger Krekel and others """ -__version__ = "1.0.4post1" +__version__ = "1.0.5" import execnet.apipkg --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,8 @@ -1.0.4post1 +1.0.5 -------------------------------- -- silence receiver-thread finalization exceptions during interp-shutdown +- 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 From commits-noreply at bitbucket.org Sun Feb 7 17:44:56 2010 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 7 Feb 2010 16:44:56 +0000 (UTC) Subject: [execnet-commit] execnet commit 6cc53b6a86e1: Added tag 1.0.5 for changeset 9e7b55db59f9 Message-ID: <20100207164456.EFDDA7EEEF@bitbucket.org> # HG changeset patch -- Bitbucket.org # Project execnet # URL http://bitbucket.org/hpk42/execnet/overview/ # User holger krekel # Date 1265561038 -3600 # Node ID 6cc53b6a86e1a781ba1c64922757e8f1dd9a2058 # Parent 9e7b55db59f94009e739273916efbb356d385b96 Added tag 1.0.5 for changeset 9e7b55db59f9 --- a/.hgtags +++ b/.hgtags @@ -6,3 +6,4 @@ 66760dc71203dbceeb08851cf4cf74e2687156d0 330b0032a09e13e38644c74d4a679d3760cdcdcf 1.0.2 5d74dad7f425b1e51d15f52825579a83a4b3be99 1.0.3 534f61972976f51c9163bbae3cf3cf6b97cabb8a 1.0.4 +9e7b55db59f94009e739273916efbb356d385b96 1.0.5