#76: routing records the destination context IDs ever received on each stream, and when disconnection occurs, propagates mitogen.core.DEL_ROUTE messages towards every stream that ever communicated with the disappearing peer, rather than simply towards parents. Conversations between nodes anywhere in the tree receive mitogen.core.DEL_ROUTE when either participant disconnects, allowing receivers to wake with mitogen.core.ChannelError , even when one participant is not a parent of the other.

#109, 57504ba6: newer Python 3 releases explicitly populate sys.meta_path with importer internals, causing Mitogen to install itself at the end of the importer chain rather than the front.

#310: support has returned for trying to figure out the real source of non-module objects installed in sys.modules , so they can be imported. This is needed to handle syntax sugar used by packages like plumbum .

#349: an incorrect format string could cause large stack traces when attempting to import built-in modules on Python 3.

#387, #413: dead messages include an optional reason in their body. This is used to cause mitogen.core.ChannelError to report far more useful diagnostics at the point the error occurs that previously would have been buried in debug log output from an unrelated context.

#408: a variety of fixes were made to restore Python 2.4 compatibility.

#399, #437: ignore a DeprecationWarning to avoid failure of the su method on Python 3.7.

#405: if an oversized message is rejected, and it has a reply_to set, a dead message is returned to the sender. This ensures function calls exceeding the configured maximum size crash rather than hang.

#406: mitogen.core.Broker did not call mitogen.core.Poller.close() during shutdown, leaking the underlying poller FD in masters and parents.

#406: connections could leak FDs when a child process failed to start.

#288, #406, #417: connections could leave FD wrapper objects that had not been closed lying around to be closed during garbage collection, causing reused FD numbers to be closed at random moments.

#411: the SSH method typed “ y ” rather than the requisite “ yes ” when check_host_keys=”accept” was configured. This would lead to connection timeouts due to the hung response.

#414, #425: avoid deadlock of forked children by reinitializing the mitogen.service pool lock.

#416: around 1.4KiB of memory was leaked on every RPC, due to a list of strong references keeping alive any handler ever registered for disconnect notification.

#418: the mitogen.parent.iter_read() helper would leak poller FDs, because execution of its finally block was delayed on Python 3. Now callers explicitly close the generator when finished.

#422: the fork method could fail to start if sys.stdout was opened in block buffered mode, and buffered data was pending in the parent prior to fork.

#438: a descriptive error is logged when stream corruption is detected.

#439: descriptive errors are raised when attempting to invoke unsupported function types.

#444: messages regarding unforwardable extension module are no longer logged as errors.

#445: service pools unregister the mitogen.core.CALL_SERVICE handle at shutdown, ensuring any outstanding messages are either processed by the pool as it shuts down, or have dead messages sent in reply to them, preventing peer contexts from hanging due to a forgotten buffered message.

#446: given thread A calling mitogen.core.Receiver.close() , and thread B, C, and D sleeping in mitogen.core.Receiver.get() , previously only one sleeping thread would be woken with mitogen.core.ChannelError when the receiver was closed. Now all threads are woken per the docstring.

#447: duplicate attempts to invoke mitogen.core.Router.add_handler() cause an error to be raised, ensuring accidental re-registration of service pools are reported correctly.

#448: the import hook implementation now raises ModuleNotFoundError instead of ImportError in Python 3.6 and above, to cope with an upcoming version of the subprocess module requiring this new subclass to be raised.

#453: the loggers used in children for standard IO redirection have propagation disabled, preventing accidental reconfiguration of the logging package in a child from setting up a feedback loop.

#456: a descriptive error is logged when mitogen.core.Broker.defer() is called after the broker has shut down, preventing new messages being enqueued that will never be sent, and subsequently producing a program hang.

#459: the beginnings of a mitogen.master.Router.get_stats() call has been added. The initial statistics cover the module loader only.

#462: Mitogen could fail to open a PTY on broken Linux systems due to a bad interaction between the glibc grantpt() function and an incorrectly mounted /dev/pts filesystem. Since correct group ownership is not required in most scenarios, when this problem is detected, the PTY is allocated and opened directly by the library.

#479: Mitogen could fail to import __main__ on Python 3.4 and newer due to a breaking change in the pkgutil API. The program’s main script is now handled specially.

#481: the version of sudo that shipped with CentOS 5 replaced itself with the program to be executed, and therefore did not hold any child PTY open on our behalf. The child context is updated to preserve any PTY FD in order to avoid the kernel sending SIGHUP early during startup.

#523: the test suite didn’t generate a code coverage report if any test failed.

#524: Python 3.6+ emitted a DeprecationWarning for mitogen.utils.run_with_router() .

#529: Code coverage of the test suite was not measured across all Python versions.

16ca111e: handle OpenSSH 7.5 permission denied prompts when ~/.ssh/config rewrites are present.

9ec360c2: a new mitogen.core.Broker.defer_sync() utility function is provided.

f20e0bba: mitogen.service.FileService.register_prefix() permits granting unprivileged access to whole filesystem subtrees, rather than single files at a time.

8f85ee03: mitogen.core.Router.myself() returns a mitogen.core.Context referring to the current process.

824c7931: exceptions raised by the import hook were updated to include probable reasons for a failure.