From 0e193c223c7418ed8a2e65dcd79c1e9f01bf92db Mon Sep 17 00:00:00 2001 From: David Wilson Date: Fri, 1 Feb 2019 00:58:42 +0000 Subject: [PATCH] issue #508: master: minify all Mitogen/ansible_mitogen sources. Minify-safe files are marked with a magical "# !mitogen: minify_safe" comment anywhere in the file, which activates the minifier. The result is naturally cached by ModuleResponder, therefore lru_cache is gone too. Given: import os, mitogen @mitogen.main() def main(router): c = router.ssh(hostname='k3') c.call(os.getpid) router.sudo(via=c) SSH footprint drops from 56.2 KiB to 42.75 KiB (-23.9%) Ansible "shell: hostname" drops 149.26 KiB to 117.42 KiB (-21.3%) --- ansible_mitogen/runner.py | 2 + ansible_mitogen/services.py | 2 + ansible_mitogen/target.py | 2 + mitogen/__init__.py | 2 + mitogen/compat/functools.py | 288 ------------------------------------ mitogen/compat/pkgutil.py | 2 + mitogen/compat/tokenize.py | 2 + mitogen/core.py | 2 + mitogen/debug.py | 2 + mitogen/doas.py | 2 + mitogen/docker.py | 2 + mitogen/fakessh.py | 2 + mitogen/fork.py | 2 + mitogen/jail.py | 2 + mitogen/kubectl.py | 2 + mitogen/lxc.py | 2 + mitogen/lxd.py | 2 + mitogen/master.py | 19 ++- mitogen/minify.py | 8 +- mitogen/parent.py | 2 + mitogen/profiler.py | 2 + mitogen/select.py | 2 + mitogen/service.py | 2 + mitogen/setns.py | 2 + mitogen/ssh.py | 2 + mitogen/su.py | 2 + mitogen/sudo.py | 2 + mitogen/unix.py | 2 + mitogen/utils.py | 2 + tests/module_finder_test.py | 3 - 30 files changed, 72 insertions(+), 298 deletions(-) delete mode 100644 mitogen/compat/functools.py diff --git a/ansible_mitogen/runner.py b/ansible_mitogen/runner.py index 608a707f..768cc57c 100644 --- a/ansible_mitogen/runner.py +++ b/ansible_mitogen/runner.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ These classes implement execution for each style of Ansible module. They are instantiated in the target context by way of target.py::run_module(). diff --git a/ansible_mitogen/services.py b/ansible_mitogen/services.py index 76d9f590..61286382 100644 --- a/ansible_mitogen/services.py +++ b/ansible_mitogen/services.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ Classes in this file define Mitogen 'services' that run (initially) within the connection multiplexer process that is forked off the top-level controller diff --git a/ansible_mitogen/target.py b/ansible_mitogen/target.py index 84fd3359..01877e34 100644 --- a/ansible_mitogen/target.py +++ b/ansible_mitogen/target.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ Helper functions intended to be executed on the target. These are entrypoints for file transfer, module execution and sundry bits like changing file modes. diff --git a/mitogen/__init__.py b/mitogen/__init__.py index cb0cfa74..b55876c0 100644 --- a/mitogen/__init__.py +++ b/mitogen/__init__.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ On the Mitogen master, this is imported from ``mitogen/__init__.py`` as would be expected. On the slave, it is built dynamically during startup. diff --git a/mitogen/compat/functools.py b/mitogen/compat/functools.py deleted file mode 100644 index 6ca75292..00000000 --- a/mitogen/compat/functools.py +++ /dev/null @@ -1,288 +0,0 @@ -# encoding: utf-8 -"""Selected backports from Python stdlib functools module -""" -# Written by Nick Coghlan , -# Raymond Hettinger , -# and Ɓukasz Langa . -# Copyright (C) 2006-2013 Python Software Foundation. - -__all__ = [ - 'update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', - 'lru_cache', -] - -from threading import RLock - - -################################################################################ -### update_wrapper() and wraps() decorator -################################################################################ - -# update_wrapper() and wraps() are tools to help write -# wrapper functions that can handle naive introspection - -WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', - '__annotations__') -WRAPPER_UPDATES = ('__dict__',) -def update_wrapper(wrapper, - wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Update a wrapper function to look like the wrapped function - wrapper is the function to be updated - wrapped is the original function - assigned is a tuple naming the attributes assigned directly - from the wrapped function to the wrapper function (defaults to - functools.WRAPPER_ASSIGNMENTS) - updated is a tuple naming the attributes of the wrapper that - are updated with the corresponding attribute from the wrapped - function (defaults to functools.WRAPPER_UPDATES) - """ - for attr in assigned: - try: - value = getattr(wrapped, attr) - except AttributeError: - pass - else: - setattr(wrapper, attr, value) - for attr in updated: - getattr(wrapper, attr).update(getattr(wrapped, attr, {})) - # Issue #17482: set __wrapped__ last so we don't inadvertently copy it - # from the wrapped function when updating __dict__ - wrapper.__wrapped__ = wrapped - # Return the wrapper so this can be used as a decorator via partial() - return wrapper - -def wraps(wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Decorator factory to apply update_wrapper() to a wrapper function - Returns a decorator that invokes update_wrapper() with the decorated - function as the wrapper argument and the arguments to wraps() as the - remaining arguments. Default arguments are as for update_wrapper(). - This is a convenience function to simplify applying partial() to - update_wrapper(). - """ - return partial(update_wrapper, wrapped=wrapped, - assigned=assigned, updated=updated) - - -################################################################################ -### partial() argument application -################################################################################ - -# Purely functional, no descriptor behaviour -def partial(func, *args, **keywords): - """New function with partial application of the given arguments - and keywords. - """ - if hasattr(func, 'func'): - args = func.args + args - tmpkw = func.keywords.copy() - tmpkw.update(keywords) - keywords = tmpkw - del tmpkw - func = func.func - - def newfunc(*fargs, **fkeywords): - newkeywords = keywords.copy() - newkeywords.update(fkeywords) - return func(*(args + fargs), **newkeywords) - newfunc.func = func - newfunc.args = args - newfunc.keywords = keywords - return newfunc - - -################################################################################ -### LRU Cache function decorator -################################################################################ - -class _HashedSeq(list): - """ This class guarantees that hash() will be called no more than once - per element. This is important because the lru_cache() will hash - the key multiple times on a cache miss. - """ - - __slots__ = 'hashvalue' - - def __init__(self, tup, hash=hash): - self[:] = tup - self.hashvalue = hash(tup) - - def __hash__(self): - return self.hashvalue - -def _make_key(args, kwds, typed, - kwd_mark = (object(),), - fasttypes = set([int, str, frozenset, type(None)]), - sorted=sorted, tuple=tuple, type=type, len=len): - """Make a cache key from optionally typed positional and keyword arguments - The key is constructed in a way that is flat as possible rather than - as a nested structure that would take more memory. - If there is only a single argument and its data type is known to cache - its hash value, then that argument is returned without a wrapper. This - saves space and improves lookup speed. - """ - key = args - if kwds: - sorted_items = sorted(kwds.items()) - key += kwd_mark - for item in sorted_items: - key += item - if typed: - key += tuple(type(v) for v in args) - if kwds: - key += tuple(type(v) for k, v in sorted_items) - elif len(key) == 1 and type(key[0]) in fasttypes: - return key[0] - return _HashedSeq(key) - -def lru_cache(maxsize=128, typed=False): - """Least-recently-used cache decorator. - If *maxsize* is set to None, the LRU features are disabled and the cache - can grow without bound. - If *typed* is True, arguments of different types will be cached separately. - For example, f(3.0) and f(3) will be treated as distinct calls with - distinct results. - Arguments to the cached function must be hashable. - View the cache statistics named tuple (hits, misses, maxsize, currsize) - with f.cache_info(). Clear the cache and statistics with f.cache_clear(). - Access the underlying function with f.__wrapped__. - See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used - """ - - # Users should only access the lru_cache through its public API: - # cache_info, cache_clear, and f.__wrapped__ - # The internals of the lru_cache are encapsulated for thread safety and - # to allow the implementation to change (including a possible C version). - - # Early detection of an erroneous call to @lru_cache without any arguments - # resulting in the inner function being passed to maxsize instead of an - # integer or None. - if maxsize is not None and not isinstance(maxsize, int): - raise TypeError('Expected maxsize to be an integer or None') - - def decorating_function(user_function): - wrapper = _lru_cache_wrapper(user_function, maxsize, typed) - return update_wrapper(wrapper, user_function) - - return decorating_function - -def _lru_cache_wrapper(user_function, maxsize, typed): - # Constants shared by all lru cache instances: - sentinel = object() # unique object used to signal cache misses - make_key = _make_key # build a key from the function arguments - PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields - - cache = {} - cache_get = cache.get # bound method to lookup a key or return None - lock = RLock() # because linkedlist updates aren't threadsafe - root = [] # root of the circular doubly linked list - root[:] = [root, root, None, None] # initialize by pointing to self - hits_misses_full_root = [0, 0, False, root] - HITS,MISSES,FULL,ROOT = 0, 1, 2, 3 - - if maxsize == 0: - - def wrapper(*args, **kwds): - # No caching -- just a statistics update after a successful call - result = user_function(*args, **kwds) - hits_misses_full_root[MISSES] += 1 - return result - - elif maxsize is None: - - def wrapper(*args, **kwds): - # Simple caching without ordering or size limit - key = make_key(args, kwds, typed) - result = cache_get(key, sentinel) - if result is not sentinel: - hits_misses_full_root[HITS] += 1 - return result - result = user_function(*args, **kwds) - cache[key] = result - hits_misses_full_root[MISSES] += 1 - return result - - else: - - def wrapper(*args, **kwds): - # Size limited caching that tracks accesses by recency - key = make_key(args, kwds, typed) - lock.acquire() - try: - link = cache_get(key) - if link is not None: - # Move the link to the front of the circular queue - root = hits_misses_full_root[ROOT] - link_prev, link_next, _key, result = link - link_prev[NEXT] = link_next - link_next[PREV] = link_prev - last = root[PREV] - last[NEXT] = root[PREV] = link - link[PREV] = last - link[NEXT] = root - hits_misses_full_root[HITS] += 1 - return result - finally: - lock.release() - result = user_function(*args, **kwds) - lock.acquire() - try: - if key in cache: - # Getting here means that this same key was added to the - # cache while the lock was released. Since the link - # update is already done, we need only return the - # computed result and update the count of misses. - pass - elif hits_misses_full_root[FULL]: - # Use the old root to store the new key and result. - oldroot = root = hits_misses_full_root[ROOT] - oldroot[KEY] = key - oldroot[RESULT] = result - # Empty the oldest link and make it the new root. - # Keep a reference to the old key and old result to - # prevent their ref counts from going to zero during the - # update. That will prevent potentially arbitrary object - # clean-up code (i.e. __del__) from running while we're - # still adjusting the links. - root = hits_misses_full_root[ROOT] = oldroot[NEXT] - oldkey = root[KEY] - oldresult = root[RESULT] - root[KEY] = root[RESULT] = None - # Now update the cache dictionary. - del cache[oldkey] - # Save the potentially reentrant cache[key] assignment - # for last, after the root and links have been put in - # a consistent state. - cache[key] = oldroot - else: - # Put result in a new link at the front of the queue. - root = hits_misses_full_root[ROOT] - last = root[PREV] - link = [last, root, key, result] - last[NEXT] = root[PREV] = cache[key] = link - # Use the __len__() method instead of the len() function - # which could potentially be wrapped in an lru_cache itself. - hits_misses_full_root[FULL] = (cache.__len__() >= maxsize) - hits_misses_full_root[MISSES] - finally: - lock.release() - return result - - def cache_clear(): - """Clear the cache and cache statistics""" - lock.acquire() - try: - cache.clear() - root = hits_misses_full_root[ROOT] - root[:] = [root, root, None, None] - hits_misses_full[HITS] = 0 - hits_misses_full[MISSES] = 0 - hits_misses_full[FULL] = False - finally: - lock.release() - - wrapper.cache_clear = cache_clear - return wrapper diff --git a/mitogen/compat/pkgutil.py b/mitogen/compat/pkgutil.py index ce072ec9..28e2aead 100644 --- a/mitogen/compat/pkgutil.py +++ b/mitogen/compat/pkgutil.py @@ -1,5 +1,7 @@ """Utilities to support packages.""" +# !mitogen: minify_safe + # NOTE: This module must remain compatible with Python 2.3, as it is shared # by setuptools for distribution with Python 2.3 and up. diff --git a/mitogen/compat/tokenize.py b/mitogen/compat/tokenize.py index 45260497..0473c6a5 100644 --- a/mitogen/compat/tokenize.py +++ b/mitogen/compat/tokenize.py @@ -22,6 +22,8 @@ are the same, except instead of generating tokens, tokeneater is a callback function to which the 5 fields described above are passed as 5 arguments, each time a new token is found.""" +# !mitogen: minify_safe + __author__ = 'Ka-Ping Yee ' __credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' 'Skip Montanaro, Raymond Hettinger') diff --git a/mitogen/core.py b/mitogen/core.py index 5c7eeab4..602b84d8 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ This module implements most package functionality, but remains separate from non-essential code in order to reduce its size, since it is also serves as the diff --git a/mitogen/debug.py b/mitogen/debug.py index b1372e3e..8f290c4d 100644 --- a/mitogen/debug.py +++ b/mitogen/debug.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ Basic signal handler for dumping thread stacks. """ diff --git a/mitogen/doas.py b/mitogen/doas.py index fe814d7b..250b6faf 100644 --- a/mitogen/doas.py +++ b/mitogen/doas.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/docker.py b/mitogen/docker.py index 3962f13c..074f0e90 100644 --- a/mitogen/docker.py +++ b/mitogen/docker.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/fakessh.py b/mitogen/fakessh.py index 582017bc..2f2726eb 100644 --- a/mitogen/fakessh.py +++ b/mitogen/fakessh.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ :mod:`mitogen.fakessh` is a stream implementation that starts a subprocess with its environment modified such that ``PATH`` searches for `ssh` return a Mitogen diff --git a/mitogen/fork.py b/mitogen/fork.py index 6859a140..081f7e3d 100644 --- a/mitogen/fork.py +++ b/mitogen/fork.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import os import random diff --git a/mitogen/jail.py b/mitogen/jail.py index 85a4a6ca..fade8cbb 100644 --- a/mitogen/jail.py +++ b/mitogen/jail.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/kubectl.py b/mitogen/kubectl.py index 7079bcab..ef626e1b 100644 --- a/mitogen/kubectl.py +++ b/mitogen/kubectl.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/lxc.py b/mitogen/lxc.py index 78c32528..6d4acba6 100644 --- a/mitogen/lxc.py +++ b/mitogen/lxc.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/lxd.py b/mitogen/lxd.py index eef53c73..7de4903a 100644 --- a/mitogen/lxd.py +++ b/mitogen/lxd.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/master.py b/mitogen/master.py index 4dcb70f1..8e314774 100644 --- a/mitogen/master.py +++ b/mitogen/master.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ This module implements functionality required by master processes, such as starting new contexts via SSH. Its size is also restricted, since it must @@ -714,6 +716,8 @@ class ModuleResponder(object): self.get_module_count = 0 #: Total time spent in uncached GET_MODULE. self.get_module_secs = 0.0 + #: Total time spent minifying modules. + self.minify_secs = 0.0 #: Number of successful LOAD_MODULE messages sent. self.good_load_module_count = 0 #: Total bytes in successful LOAD_MODULE payloads. @@ -770,6 +774,8 @@ class ModuleResponder(object): def _make_negative_response(self, fullname): return (fullname, None, None, None, ()) + minify_safe_re = re.compile(r'\s+#\s*!mitogen:\s*minify_safe') + def _build_tuple(self, fullname): if fullname in self._cache: return self._cache[fullname] @@ -795,6 +801,12 @@ class ModuleResponder(object): self._cache[fullname] = tup return tup + if self.minify_safe_re.search(source): + # If the module contains a magic marker, it's safe to minify. + t0 = time.time() + source = mitogen.minify.minimize_source(source) + self.minify_secs += time.time() - t0 + if is_pkg: pkg_present = get_child_modules(path) LOG.debug('_build_tuple(%r, %r) -> %r', @@ -1024,6 +1036,7 @@ class Router(mitogen.parent.Router): super(Router, self)._on_broker_exit() dct = self.get_stats() dct['self'] = self + dct['minify_ms'] = 1000 * dct['minify_secs'] dct['get_module_ms'] = 1000 * dct['get_module_secs'] dct['good_load_module_size_kb'] = dct['good_load_module_size'] / 1024.0 dct['good_load_module_size_avg'] = ( @@ -1037,7 +1050,8 @@ class Router(mitogen.parent.Router): '%(self)r: stats: ' '%(get_module_count)d module requests in ' '%(get_module_ms)d ms, ' - '%(good_load_module_count)d sent, ' + '%(good_load_module_count)d sent ' + '(%(minify_ms)d ms minify time), ' '%(bad_load_module_count)d negative responses. ' 'Sent %(good_load_module_size_kb).01f kb total, ' '%(good_load_module_size_avg).01f kb avg.' @@ -1062,6 +1076,8 @@ class Router(mitogen.parent.Router): :data:`mitogen.core.LOAD_MODULE` message payloads. * `bad_load_module_count`: Integer count of negative :data:`mitogen.core.LOAD_MODULE` messages sent. + * `minify_secs`: CPU seconds spent minifying modules marked + minify-safe. """ return { 'get_module_count': self.responder.get_module_count, @@ -1069,6 +1085,7 @@ class Router(mitogen.parent.Router): 'good_load_module_count': self.responder.good_load_module_count, 'good_load_module_size': self.responder.good_load_module_size, 'bad_load_module_count': self.responder.bad_load_module_count, + 'minify_secs': self.responder.minify_secs, } def enable_debug(self): diff --git a/mitogen/minify.py b/mitogen/minify.py index a261bf6a..dc9f517c 100644 --- a/mitogen/minify.py +++ b/mitogen/minify.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import sys try: @@ -40,13 +42,7 @@ if sys.version_info < (2, 7, 11): else: import tokenize -try: - from functools import lru_cache -except ImportError: - from mitogen.compat.functools import lru_cache - -@lru_cache() def minimize_source(source): """Remove comments and docstrings from Python `source`, preserving line numbers and syntax of empty blocks. diff --git a/mitogen/parent.py b/mitogen/parent.py index b748a9f6..91a4e5eb 100644 --- a/mitogen/parent.py +++ b/mitogen/parent.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ This module defines functionality common to master and parent processes. It is sent to any child context that is due to become a parent, due to recursive diff --git a/mitogen/profiler.py b/mitogen/profiler.py index 841f96a9..10ec6086 100644 --- a/mitogen/profiler.py +++ b/mitogen/profiler.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """mitogen.profiler Record and report cProfile statistics from a run. Creates one aggregated output file, one aggregate containing only workers, and one for the diff --git a/mitogen/select.py b/mitogen/select.py index 92945a9d..6b87e671 100644 --- a/mitogen/select.py +++ b/mitogen/select.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import mitogen.core diff --git a/mitogen/service.py b/mitogen/service.py index 9d9cf2da..e72ac61d 100644 --- a/mitogen/service.py +++ b/mitogen/service.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import grp import os import os.path diff --git a/mitogen/setns.py b/mitogen/setns.py index ced44add..d38aa092 100644 --- a/mitogen/setns.py +++ b/mitogen/setns.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import ctypes import grp import logging diff --git a/mitogen/ssh.py b/mitogen/ssh.py index 607d7f44..47c90fff 100644 --- a/mitogen/ssh.py +++ b/mitogen/ssh.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ Functionality to allow establishing new slave contexts over an SSH connection. """ diff --git a/mitogen/su.py b/mitogen/su.py index 9401aee9..0d2fef2f 100644 --- a/mitogen/su.py +++ b/mitogen/su.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import logging import mitogen.core diff --git a/mitogen/sudo.py b/mitogen/sudo.py index 708953cd..05a04989 100644 --- a/mitogen/sudo.py +++ b/mitogen/sudo.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import base64 import logging import optparse diff --git a/mitogen/unix.py b/mitogen/unix.py index 5d20b6b1..3e315d6f 100644 --- a/mitogen/unix.py +++ b/mitogen/unix.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + """ Permit connection of additional contexts that may act with the authority of this context. For now, the UNIX socket is always mode 0600, i.e. can only be diff --git a/mitogen/utils.py b/mitogen/utils.py index 5fdb2a2c..6c56d6d5 100644 --- a/mitogen/utils.py +++ b/mitogen/utils.py @@ -26,6 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +# !mitogen: minify_safe + import datetime import logging import os diff --git a/tests/module_finder_test.py b/tests/module_finder_test.py index bce3b70d..618ed9ec 100644 --- a/tests/module_finder_test.py +++ b/tests/module_finder_test.py @@ -220,9 +220,6 @@ class FindRelatedTest(testlib.TestCase): u'mitogen.parent', ]) - if sys.version_info < (3, 2): - SIMPLE_EXPECT.add('mitogen.compat') - SIMPLE_EXPECT.add('mitogen.compat.functools') if sys.version_info < (2, 7): SIMPLE_EXPECT.add('mitogen.compat.tokenize') if sys.version_info < (2, 6):