Commits

Lynn Rees committed e35a47a

- reorg

Comments (0)

Files changed (34)

 deps=
   nose
   coverage
+  bpython
+  ipython
 commands=
   nosetests {posargs:--with-coverage --cover-package=twoq}
   
   unittest2
   nose
   coverage
+  bpython
+  ipython
 commands=
   nosetests {posargs:--with-coverage  --cover-package=twoq}

twoq/active/__init__.py

 # -*- coding: utf-8 -*-
 '''active twoqs'''
-
-from twoq.active.mixins import (
-    AutoResultMixin, AutoQMixin, ManQMixin, ManResultMixin)

twoq/active/filtering.py

 # -*- coding: utf-8 -*-
 '''twoq active filtering queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.filtering import (
     FilteringMixin, CollectMixin, SetMixin, SliceMixin)
 

twoq/active/mapping.py

 # -*- coding: utf-8 -*-
 '''twoq active mapping queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.mapping import DelayMixin, RepeatMixin, MappingMixin
 
 from twoq.active.mixins import AutoResultMixin, ManResultMixin

twoq/active/mixins.py

 '''active twoq mixins'''
 
 from copy import copy
+from itertools import repeat
 from collections import deque
 from contextlib import contextmanager
 
 from stuf.utils import clsname
 
-from twoq.queuing import ThingsMixin, ResultMixin
+from twoq.core import ThingsMixin, ResultsMixin
 
 
-__all__ = ('AutoQMixin', 'ManQMixin', 'AutoResultMixin', 'ManResultMixin')
-
-
-class BaseQMixin(ThingsMixin):
+class BaseMixin(ThingsMixin):
 
     '''base active things'''
 
     def __init__(self, *things):
-        deque_ = deque
-        incoming = deque_(things[0]) if len(things) == 1 else deque_(things)
-        super(BaseQMixin, self).__init__(incoming, deque_())
+        try:
+            incoming = deque(things[0]) if len(things) == 1 else deque(things)
+        except TypeError:
+            incoming = deque([things])
+        super(BaseMixin, self).__init__(incoming, deque())
         # set iterator
         self._iterator = self._iterexcept
         # work things
-        self._work = deque_()
+        self._work = deque()
         # utility things
-        self._util = deque_()
-
-    def __repr__(self):
-        getr_, list_ = lambda x: getattr(self, x), list
-        return self._repr(
-            self.__module__,
-            clsname(self),
-            self.current_mode.upper(),
-            self._INQ,
-            list_(getr_(self._INQ)),
-            self._WORKQ,
-            list_(getr_(self._WORKQ)),
-            self._UTILQ,
-            list_(getr_(self._UTILQ)),
-            self._OUTQ,
-            list_(getr_(self._OUTQ)),
-            id(self),
-        )
+        self._util = deque()
 
     ###########################################################################
-    ## snapshots ##############################################################
+    ## mode things ############################################################
     ###########################################################################
 
-    def snapshot(self):
-        '''take snapshot of incoming'''
-        self._snapshots.append(copy(getattr(self, self._INQ)))
-        return self
+    def ro(self):
+        '''switch to read-only mode'''
+        with self.ctx3(outq=self._UTILVAR, savepoint=False):
+            self._xtend(self._iterable)
+        with self.ctx1(hard=True, workq=self._UTILVAR, savepoint=False):
+            self.current_mode = self._RO
+            return self
 
     ###########################################################################
-    ## thing length ###########################################################
-    ###########################################################################
-
-    def __len__(self):
-        '''number of incoming things'''
-        return len(self.incoming)
-
-    def outcount(self):
-        '''number of outgoing things'''
-        return len(self.outgoing)
-
-    ###########################################################################
-    ## iterators ##############################################################
-    ###########################################################################
-
-    def __iter__(self):
-        '''yield outgoing things, clearing outgoing things as it iterates'''
-        return self.iterexcept(self.outgoing.popleft, IndexError)
-
-    @property
-    def _iterable(self):
-        '''iterable'''
-        return self._iterator(self._WORKQ)
-
-    def _iterexcept(self, attr='_UTILQ'):
-        '''
-        iterator broken on exception
-
-        @param attr: things to iterate over
-        '''
-        return self.iterexcept(getattr(self, attr).popleft, IndexError)
-
-    def _breakcount(self, attr='_UTILQ'):
-        '''
-        breakcount iterator
-
-        @param attr: things to iterate over
-        '''
-        dq = getattr(self, attr)
-        return self.breakcount(dq.popleft, len(dq), IndexError,)
-
-    ###########################################################################
-    ## clear things ###########################################################
-    ###########################################################################
-
-    def _uclear(self):
-        '''clear utility things'''
-        self._util.clear()
-        return self
-
-    def _wclear(self):
-        '''clear work things'''
-        self._work.clear()
-        return self
-
-    def inclear(self):
-        '''clear incoming things'''
-        self.incoming.clear()
-        return self
-
-    def outclear(self):
-        '''clear outgoing things'''
-        self.outgoing.clear()
-        return self
-
-    def ssclear(self):
-        self._snapshots.clear()
-        return self
-
-    ###########################################################################
-    ## extend #################################################################
-    ###########################################################################
-
-    def _xtend(self, things):
-        '''extend utility things with `things` wrapped'''
-        getattr(self, self._UTILQ).extend(things)
-        return self
-
-    def _xtendleft(self, things):
-        '''extend left side of utility things with `things`'''
-        getattr(self, self._UTILQ).extendleft(things)
-        return self
-
-    def _iter(self, things):
-        '''extend work things with `things` wrapped in iterator'''
-        getattr(self, self._UTILQ).extend(iter(things))
-        return self
-
-    ###########################################################################
-    ## append #################################################################
-    ###########################################################################
-
-    def _append(self, things):
-        '''append `things` to utility things'''
-        getattr(self, self._UTILQ).append(things)
-        return self
-
-    def _appendleft(self, things):
-        '''append `things` to left side of utility things'''
-        getattr(self, self._UTILQ).appendleft(things)
-        return self
-
-    ###########################################################################
-    ## context rotation #######################################################
+    ## context things #######################################################
     ###########################################################################
 
     @contextmanager
     def ctx2(self, **kw):
         '''swap for two-armed context'''
-        self.snapshot()
         self.swap(
             outq=kw.get(self._OUTCFG, self._INVAR), context=self.ctx2(), **kw
         )
     @contextmanager
     def ctx3(self, **kw):
         '''swap for three-armed context'''
-        self.snapshot()
         self.swap(
             utilq=kw.get(self._WORKCFG, self._WORKVAR), context=self.ctx3, **kw
         )
     @contextmanager
     def ctx4(self, **kw):
         '''swap for four-armed context'''
-        self.snapshot()
         self.swap(context=self.ctx4, **kw)
         getr_ = lambda x: getattr(self, x)
         outq = getr_(self._OUTQ)
     @contextmanager
     def autoctx(self, **kw):
         '''swap for auto-synchronizing context'''
-        self.snapshot()
         self.swap(context=self.autoctx, **kw)
         getr_ = lambda x: getattr(self, x)
         outq = getr_(self._OUTQ)
         # return to global context
         self.reswap()
 
-    def ro(self):
-        '''switch to read-only mode'''
-        with self.ctx3(outq=self._UTILVAR):
-            self._xtend(self._iterable)
-        with self.ctx1(hard=True, workq=self._UTILVAR):
-            self.current_mode = self._RO
-            return self
+    ###########################################################################
+    ## savepoint for things ###################################################
+    ###########################################################################
 
+    def savepoint(self):
+        '''take savepoint of incoming things'''
+        self._savepoints.append(copy(getattr(self, self._INQ)))
+        return self
 
-class AutoQMixin(BaseQMixin):
+    ###########################################################################
+    ## iterate things #########################################################
+    ###########################################################################
+
+    def __iter__(self):
+        '''yield outgoing things, clearing outgoing things as it iterates'''
+        return self._iterexcept(getattr(self, self._OUTQ), IndexError)
+
+    @property
+    def _iterable(self):
+        '''iterable'''
+        return self._iterator(self._WORKQ)
+
+    def _breakcount(self, attr='_UTILQ'):
+        '''
+        breakcount iterator
+
+        @param attr: things to iterate over
+        '''
+        dq = getattr(self, attr)
+        length = len(dq)
+        call = dq.popleft
+        for i in repeat(None, length):  # @UnusedVariable
+            try:
+                yield call()
+            except IndexError:
+                pass
+
+    def _iterexcept(self, attr='_UTILQ'):
+        '''
+        call a function repeatedly until an exception is raised
+
+        Converts a call-until-exception interface to an iterator interface.
+        Like `iter(call, sentinel)` but uses an exception instead of a sentinel
+        to end the loop.
+
+        Raymond Hettinger, Python Cookbook recipe # 577155
+        '''
+        call = getattr(self, attr).popleft
+        try:
+            while 1:
+                yield call()
+        except IndexError:
+            pass
+
+    ###########################################################################
+    ## extend things ##########################################################
+    ###########################################################################
+
+    def _xtend(self, things):
+        '''extend utility things with `things` wrapped'''
+        getattr(self, self._UTILQ).extend(things)
+        return self
+
+    def _xtendleft(self, things):
+        '''extend left side of utility things with `things`'''
+        getattr(self, self._UTILQ).extendleft(things)
+        return self
+
+    def _iter(self, things):
+        '''extend work things with `things` wrapped in iterator'''
+        getattr(self, self._UTILQ).extend(iter(things))
+        return self
+
+    ###########################################################################
+    ## append things ##########################################################
+    ###########################################################################
+
+    def _append(self, things):
+        '''append `things` to utility things'''
+        getattr(self, self._UTILQ).append(things)
+        return self
+
+    def _appendleft(self, things):
+        '''append `things` to left side of utility things'''
+        getattr(self, self._UTILQ).appendleft(things)
+        return self
+
+    ###########################################################################
+    ## know things ############################################################
+    ###########################################################################
+
+    def __len__(self):
+        '''number of incoming things'''
+        return len(self.incoming)
+
+    def __repr__(self):
+        getr_, list_ = lambda x: getattr(self, x), list
+        return self._repr(
+            self.__module__,
+            clsname(self),
+            self.current_mode.upper(),
+            self._INQ,
+            list_(getr_(self._INQ)),
+            self._WORKQ,
+            list_(getr_(self._WORKQ)),
+            self._UTILQ,
+            list_(getr_(self._UTILQ)),
+            self._OUTQ,
+            list_(getr_(self._OUTQ)),
+            id(self),
+        )
+
+    def outcount(self):
+        '''number of outgoing things'''
+        return len(self.outgoing)
+
+    ###########################################################################
+    ## clear things ###########################################################
+    ###########################################################################
+
+    def _uclear(self):
+        '''clear utility things'''
+        self._util.clear()
+        return self
+
+    def _wclear(self):
+        '''clear work things'''
+        self._work.clear()
+        return self
+
+    def inclear(self):
+        '''clear incoming things'''
+        self.incoming.clear()
+        return self
+
+    def outclear(self):
+        '''clear outgoing things'''
+        self.outgoing.clear()
+        return self
+
+
+class AutoMixin(BaseMixin):
 
     '''auto-balancing queue mixin'''
 
     _default_context = 'autoctx'
 
 
-class ManQMixin(BaseQMixin):
+class ManMixin(BaseMixin):
 
     '''manually balanced queue mixin'''
 
     _default_context = 'ctx4'
 
 
-class EndMixin(ResultMixin):
+class EndMixin(ResultsMixin):
 
     '''result things mixin'''
 
         wrap, outgoing = self._wrapper, self.outgoing
         out = self.outgoing.pop() if len(outgoing) == 1 else wrap(outgoing)
         # clear every last thing
-        self.clear()
+        self.clear()._ssclear()
         return out
 
+    def snapshot(self):
+        '''snapshot of current outgoing things'''
+        out = copy(getattr(self, self._OUTQ))
+        return out.pop() if len(out) == 1 else self._wrapper(out)
+
     def value(self):
         '''return outgoing things and clear outgoing things'''
         # return to default context
         return out
 
 
-class AutoResultMixin(AutoQMixin, EndMixin):
+class AutoResultMixin(AutoMixin, EndMixin):
 
     '''auto-balancing manipulation things (with results extractor) mixin'''
 
 
-class ManResultMixin(ManQMixin, EndMixin):
+class ManResultMixin(ManMixin, EndMixin):
 
     '''manually balanced things (with results extractor) mixin'''

twoq/active/ordering.py

 # -*- coding: utf-8 -*-
 '''twoq active ordering queues'''
 
-from twoq.queuing import SLOTS
-from twoq.ordering import RandomMixin, OrderingMixin, CombineMixin
+from twoq.core import SLOTS
+from twoq.ordering import RandomMixin, OrderingMixin
 
 from twoq.active.mixins import AutoResultMixin, ManResultMixin
 
     '''manually balanced order queue'''
 
     __slots__ = SLOTS
-
-
-class combineq(AutoResultMixin, CombineMixin):
-
-    '''auto-balanced combination queue'''
-
-    __slots__ = SLOTS
-
-
-class mcombineq(ManResultMixin, CombineMixin):
-
-    '''manually balanced combination queue'''
-
-    __slots__ = SLOTS

twoq/active/queuing.py

 # -*- coding: utf-8 -*-
 '''twoq active queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.mapping import MappingMixin as MapMixin
 from twoq.ordering import OrderingMixin as OrderMixin
 from twoq.reducing import ReducingMixin as ReduceMixin

twoq/active/reducing.py

 # -*- coding: utf-8 -*-
 '''twoq active reducing queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.reducing import MathMixin, TruthMixin, ReducingMixin
 
 from twoq.active.mixins import AutoResultMixin, ManResultMixin
+# -*- coding: utf-8 -*-
+'''twoq queuing mixins'''
+
+from threading import local
+from collections import deque
+from contextlib import contextmanager
+
+from stuf.utils import OrderedDict
+from stuf.core import stuf, frozenstuf, orderedstuf
+
+from twoq.support import n2u, n2b
+
+SLOTS = [
+    '_work', 'outgoing', '_util', 'incoming', '_call', '_alt', '_wrapper',
+    '_args', '_kw', '_clearout', '_context', '_CONFIG', '_INQ', '_WORKQ',
+    '_UTILQ', '_OUTQ', '_iterator', 'current_mode', '_savepoints', '_start',
+]
+
+
+class ThingsMixin(local):
+
+    '''things management mixin'''
+
+    def __init__(self, incoming, outgoing, **kw):
+        '''
+        init
+
+        @param incoming: incoming things
+        @param outgoing: outgoing things
+        '''
+        super(ThingsMixin, self).__init__()
+        # incoming things
+        self.incoming = incoming
+        # outgoing things
+        self.outgoing = outgoing
+        # preferred mode
+        self.current_mode = self._RW
+        #######################################################################
+        ## context defaults ###################################################
+        #######################################################################
+        # preferred context
+        self._context = self._default_context
+        # default context settings
+        self._CONFIG = {}
+        # 1. default incoming things
+        self._INQ = self._INVAR
+        # 2. default work things
+        self._WORKQ = self._WORKVAR
+        # 3. default utility things
+        self._UTILQ = self._UTILVAR
+        # 4. default outgoing things
+        self._OUTQ = self._OUTVAR
+        # clear outgoing things before extending/appending to them?
+        self._clearout = True
+        #######################################################################
+        ## snapshotting defaults ##############################################
+        #######################################################################
+        # number of savepoints to keep (default: 5)
+        maxlen = kw.pop('savepoints', 5)
+        # create stack for savepoint things
+        self._savepoints = deque(maxlen=maxlen) if maxlen is not None else None
+        # savepoint of original incoming things
+        if self._savepoints is not None:
+            self._original()
+        #######################################################################
+        ## callable defaults ##################################################
+        #######################################################################
+        # current callable (default: identity)
+        self._call = lambda x: x
+        # current alternate callable (default: identity)
+        self._alt = lambda x: x
+        # iterable export wrapper (default: `list`)
+        self._wrapper = list
+        # postition arguments (default: `tuple`)
+        self._args = ()
+        # keyword arguments (default: `dict`)
+        self._kw = {}
+
+    ###########################################################################
+    ## mode things ############################################################
+    ###########################################################################
+
+    # read/write mode
+    _RW = 'read/write'
+    # read-only mode
+    _RO = 'read-only'
+
+    def rw(self):
+        '''switch to read/write mode'''
+        self.current_mode = self._RW
+        return self._uclear().unswap()
+
+    ###########################################################################
+    ## context things #EE######################################################
+    ###########################################################################
+
+    # 1. incoming things
+    _INCFG = 'inq'
+    _INVAR = 'incoming'
+    # 2. utility things
+    _UTILCFG = 'utilq'
+    _UTILVAR = '_util'
+    # 3. work things
+    _WORKCFG = 'workq'
+    _WORKVAR = '_work'
+    # 4. outgoing things
+    _OUTCFG = 'outq'
+    _OUTVAR = 'outgoing'
+
+    def swap(self, **kw):
+        '''swap context'''
+        # savepoint
+        savepoint = kw.pop('savepoint', True)
+        if savepoint:
+            self.savepoint()
+        # keep context-specific settings between context swaps
+        self._CONFIG = kw if kw.get('hard', False) else {}
+        # set context
+        self._context = kw.get('context', getattr(self, self._default_context))
+        # clear out outgoing things before extending them?
+        self._clearout = kw.get('clearout', True)
+        # 1. incoming things
+        self._INQ = kw.get(self._INCFG, self._INVAR)
+        # 2. work things
+        self._WORKQ = kw.get(self._WORKCFG, self._WORKVAR)
+        # 3. utility things
+        self._UTILQ = kw.get(self._UTILCFG, self._UTILVAR)
+        # 4. outgoing things
+        self._OUTQ = kw.get(self._OUTCFG, self._OUTVAR)
+        return self
+
+    def reswap(self):
+        '''swap for preferred context'''
+        return self.swap(**self._CONFIG)
+
+    def unswap(self):
+        '''swap for current default context'''
+        return self.swap()
+
+    @contextmanager
+    def ctx1(self, **kw):
+        '''swap for one-armed context'''
+        q = kw.pop(self._WORKCFG, self._INVAR)
+        self.swap(workq=q, utilq=q, context=self.ctx1, **kw)
+        yield
+        self.reswap()
+
+    ###########################################################################
+    ## savepoint for things ###################################################
+    ###########################################################################
+
+    def _original(self):
+        '''preserve original incoming things'''
+        self.savepoint()
+        # preserve from savepoint stack
+        self._start = self._savepoints.pop()
+        return self
+
+    def undo(self, index=0):
+        '''
+        revert to previous savepoint
+
+        @param savepoint: index of savepoint (default: 0)
+        '''
+        self.clear()
+        if not index:
+            self.incoming = self._savepoints.pop()
+        else:
+            self._savepoints.reverse()
+            self.incoming = self._savepoints[index]
+            self._savepoints.reverse()
+        return self.savepoint()
+
+    def rollback(self):
+        '''revert to original things'''
+        self.clear()._ssclear()
+        self.incoming = self._start
+        self._original()
+        return self
+
+    ###########################################################################
+    ## rotate things ##########################################################
+    ###########################################################################
+
+    def reup(self):
+        '''put incoming things in incoming things as one incoming thing'''
+        with self.ctx2():
+            return self._append(list(self._iterable))
+
+    def sync(self):
+        '''shift outgoing things to incoming things'''
+        with self.autoctx(inq=self._OUTVAR, outq=self._INVAR):
+            return self._xtend(self._iterable)
+
+    def outsync(self):
+        '''shift incoming things to outgoing things'''
+        with self.autoctx():
+            return self._xtend(self._iterable)
+
+    ###########################################################################
+    ## extend incoming things #################################################
+    ###########################################################################
+
+    def extend(self, things):
+        '''
+        extend after incoming things
+
+        @param thing: some things
+        '''
+        with self.ctx1():
+            return self._xtend(things)
+
+    def extendleft(self, things):
+        '''
+        extend before incoming things
+
+        @param thing: some things
+        '''
+        with self.ctx1():
+            return self._xtendleft(things)
+
+    def outextend(self, things):
+        '''
+        extend right side of outgoing things
+
+        @param thing: some things
+        '''
+        with self.ctx1(workq=self._OUTVAR):
+            return self._xtend(things)
+
+    ###########################################################################
+    ## append incoming things #################################################
+    ###########################################################################
+
+    def append(self, thing):
+        '''
+        append after incoming things
+
+        @param thing: some thing
+        '''
+        with self.ctx1():
+            return self._append(thing)
+
+    def prepend(self, thing):
+        '''
+        append before incoming things
+
+        @param thing: some thing
+        '''
+        with self.ctx1():
+            return self._appendleft(thing)
+
+    ###########################################################################
+    ## call things ############################################################
+    ###########################################################################
+
+    def args(self, *args, **kw):
+        '''set arguments for current or alternative callable'''
+        # set position arguments
+        self._args = args
+        # set keyword arguemnts
+        self._kw = kw
+        return self
+
+    def tap(self, call, alt=None, factory=False):
+        '''
+        set current callable
+
+        @param call: a callable
+        @param alt: an alternative callable (default: None)
+        @param factor: call is a factory? (default: False)
+        '''
+        # reset postition arguments
+        self._args = ()
+        # reset keyword arguments
+        self._kw = {}
+        # set factory for building current callable
+        if factory:
+            def factory(*args, **kw):
+                return call(*args, **kw)
+            self._call = factory
+        else:
+            # set current callable
+            self._call = call
+        # set alternative callable
+        self._alt = alt if alt is not None else lambda x: x
+        return self
+
+    def untap(self):
+        '''clear current callable'''
+        # reset postition arguments
+        self._args = ()
+        # reset keyword arguments
+        self._kw = {}
+        # reset current callable (default is identity)
+        self._call = lambda x: x
+        # reset alternative callable
+        self._alt = lambda x: x
+        return self
+
+    ###########################################################################
+    ## know things ############################################################
+    ###########################################################################
+
+    @staticmethod
+    def _repr(*args):
+        '''queue representation'''
+        return (
+            '<{0}.{1}<<{2}>>([IN: {3}({4}) => WORK: {5}({6}) => UTIL: {7}({8})'
+            ' => OUT: {9}: ({10})]) at {11}>'
+        ).format(*args)
+
+    @property
+    def balanced(self):
+        '''queues are balanced?'''
+        return self.outcount() == self.__len__()
+
+    ###########################################################################
+    ## clear things ###########################################################
+    ###########################################################################
+
+    def _ssclear(self):
+        '''clear savepoints'''
+        self._savepoints.clear()
+        return self
+
+    def clear(self):
+        '''clear anything'''
+        return self.untap().unwrap().outclear().inclear()._wclear()._uclear()
+
+
+class ResultsMixin(local):
+
+    '''result of things mixin'''
+
+    ###########################################################################
+    ## outgoing things export #################################################
+    ###########################################################################
+
+    def peek(self):
+        '''results from read-only context'''
+        self.ro()
+        out = self._wrapper(self._util)
+        results = out[0] if len(out) == 1 else out
+        self.rw()
+        return results
+
+    def results(self):
+        '''yield outgoing things, clearing outgoing things as it iterates'''
+        return self.__iter__()
+
+    ###########################################################################
+    ## wrap outgoing things ###################################################
+    ###########################################################################
+
+    def wrap(self, wrapper):
+        '''
+        wrapper for outgoing things
+
+        @param wrapper: an iterator class
+        '''
+        self._wrapper = wrapper
+        return self
+
+    def tuple_wrap(self):
+        '''set wrapper to `tuple`'''
+        return self.wrap(tuple)
+
+    def set_wrap(self):
+        '''set wrapper to `set`'''
+        return self.wrap(set)
+
+    def byte_wrap(self, encoding='ISO-8859-1'):
+        '''set wrapper to `bytes` with given `encoding`'''
+        return self.wrap(lambda x: n2b(x, encoding))
+
+    def deque_wrap(self):
+        '''set wrapper to `deque`'''
+        return self.wrap(deque)
+
+    def dict_wrap(self):
+        '''set wrapper to `dict`'''
+        return self.wrap(dict)
+
+    def frozenset_wrap(self):
+        '''set wrapper to `frozenset`'''
+        return self.wrap(frozenset)
+
+    def frozenstuf_wrap(self):
+        '''set wrapper to `frozenstuf`'''
+        return self.wrap(frozenstuf)
+
+    def ordereddict_wrap(self):
+        '''set wrapper to `OrderedDict`'''
+        return self.wrap(OrderedDict)
+
+    def orderedstuf_wrap(self):
+        '''set wrapper to `orderedstuf`'''
+        return self.wrap(orderedstuf)
+
+    def stuf_wrap(self):
+        '''set wrapper to `stuf`'''
+        return self.wrap(stuf)
+
+    def unicode_wrap(self, encoding='utf-8'):
+        '''set wrapper to `unicode` with given `encoding`'''
+        return self.wrap(lambda x: n2u(x, encoding))
+
+    def list_wrap(self):
+        '''clear current wrapper'''
+        return self.wrap(list)
+
+    unwrap = list_wrap

twoq/filtering.py

 from inspect import getmro
 from threading import local
 from functools import reduce
+from collections import deque
 from itertools import tee, islice
 from operator import attrgetter, itemgetter, truth
 
-from stuf.utils import getcls
-
 from twoq.support import ifilter, ichain, imap, filterfalse
 
 
         ):
             yield member
 
-    @classmethod
-    def _mfilter(cls, call, iterable):
-        '''
-        filter members of things
-
-        @param call: "Truth" filter
-        @param iterable: an iterable
-        '''
-        def members(): #@IgnorePep8
-            itrbl, get_, AttributeError_ = iterable, getattr, AttributeError
-            test = lambda x: x.startswith('__') or x.startswith('mro')
-            for key in filterfalse(test, dir(iterable)):
-                try:
-                    thing = get_(itrbl, key)
-                except AttributeError_:
-                    pass
-                else:
-                    yield key, thing
-        for i in ifilter(call, members()):
-            yield i
-
     @staticmethod
     def _pick(names, iterable):
         '''
             except (IndexError_, KeyError_, TypeError_):
                 pass
 
-    def deepmembers(self):
-        '''collect object members from incoming things and their bases'''
-        _mf, mro = self._mfilter, getmro
-        _mz = lambda x: _mf(self._call, x)
-        def memfilters(thing, mz=_mz, gc=getcls, ci=ichain, mro=mro): #@IgnorePep8
-            return ci(imap(mz, ci([mro((gc(thing))), [thing]])))
-        with self._context():
-            return self._xtend(
-                ichain(imap(memfilters, self._iterable))
-            )
-
-    def extract(self):
-        '''extract object members from incoming things'''
-        with self._context():
-            walk_ = self._extract
-            call_, alt_, wrap_ = self._call, self._alt, self._wrapper
-            return self._xtend(ichain(imap(
-                lambda x: walk_(call_, alt_, wrap_, x), self._iterable,
-            )))
-
     def members(self):
         '''collect object members from incoming things'''
         with self._context():
     def mro(self):
         '''extract ancestors of things by method resolution order'''
         with self._context():
-            return self._extend(getmro(i) for i in self._iterable)
+            return self._xtend(getmro(i) for i in self._iterable)
 
     def pick(self, *names):
         '''collect object attributes from incoming things by their `*names`'''
 
     '''slicing mixin'''
 
+    def first(self):
+        '''first incoming thing'''
+        with self._context():
+            return self._append(next(self._iterable))
+
+    def last(self):
+        '''last incoming thing'''
+        with self._context():
+            i1, _ = tee(self._iterable)
+            return self._append(deque(i1, maxlen=1).pop())
+
     def nth(self, n, default=None):
         '''
         `nth` incoming thing or default thing
             i1, i2 = tee(self._iterable)
             return self._xtend(islice(i1, len(list(i2)) - 1))
 
+    def partition(self):
+        '''
+        split incoming things into `True` and `False` things based on results
+        of call
+        '''
+        list_, call_ = list, self._call
+        with self._context():
+            falsy, truey = tee(self._iterable)
+            return self._xtend(iter([
+                list_(filterfalse(call_, falsy)), list_(ifilter(call_, truey)),
+            ]))
+
     def rest(self):
         '''all incoming things except the first thing'''
         with self._context():
                 next(ifilter(self._call, self._iterable))
             )
 
-    def partition(self):
-        '''
-        split incoming things into `True` and `False` things based on results
-        of call
-        '''
-        list_, call_ = list, self._call
-        with self._context():
-            falsy, truey = tee(self._iterable)
-            return self._xtend(iter([
-                list_(filterfalse(call_, falsy)), list_(ifilter(call_, truey)),
-            ]))
-
     def reject(self):
         '''incoming things for which call is `False`'''
         with self._context():

twoq/lazy/__init__.py

 # -*- coding: utf-8 -*-
 '''lazy twoqs'''
-
-from twoq.lazy.mixins import (
-    AutoResultMixin, AutoQMixin, ManQMixin, ManResultMixin)

twoq/lazy/filtering.py

 # -*- coding: utf-8 -*-
 '''twoq lazy filtering queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.filtering import (
     FilteringMixin, CollectMixin, SetMixin, SliceMixin)
 

twoq/lazy/mapping.py

 # -*- coding: utf-8 -*-
 '''twoq lazy mapping queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.mapping import DelayMixin, RepeatMixin, MappingMixin
 
 from twoq.lazy.mixins import AutoResultMixin, ManResultMixin

twoq/lazy/mixins.py

 
 from stuf.utils import clsname
 
-from twoq.queuing import ResultMixin, ThingsMixin
+from twoq.core import ResultsMixin, ThingsMixin
 
-__all__ = ('AutoQMixin', 'ManQMixin', 'AutoResultMixin', 'ManResultMixin')
+__all__ = ('AutoMixin', 'ManMixin', 'AutoResultMixin', 'ManResultMixin')
 
 
-class BaseQMixin(ThingsMixin):
+class BaseMixin(ThingsMixin):
 
     '''base lazy things'''
 
     def __init__(self, *things):
-        iter_ = iter
-        incoming = iter_([things[0]]) if len(things) == 1 else iter_(things)
-        super(BaseQMixin, self).__init__(incoming, iter_([]))
+        try:
+            incoming = iter([things[0]]) if len(things) == 1 else iter(things)
+        except TypeError:
+            incoming = iter([things])
+        super(BaseMixin, self).__init__(incoming, iter([]))
         # work things
-        self._work = iter_([])
+        self._work = iter([])
         # utility things
-        self._util = iter_([])
+        self._util = iter([])
 
     def __repr__(self):
         list_, tee_ = list, tee
     ## snapshots ##############################################################
     ###########################################################################
 
-    def snapshot(self):
-        '''take snapshot of incoming'''
-        snapshot, self.incoming = tee(getattr(self, self._INQ))
-        self._snapshots.append(snapshot)
+    def savepoint(self):
+        '''take savepoint of incoming'''
+        savepoint, self.incoming = tee(getattr(self, self._INQ))
+        self._savepoints.append(savepoint)
         return self
 
     ###########################################################################
     @contextmanager
     def ctx2(self, **kw):
         '''swap for two-armed context'''
-        self.snapshot()
         self.swap(
             context=self.ctx2, outq=kw.get(self._OUTCFG, self._INVAR), **kw
         )._clearwork()
     @contextmanager
     def ctx3(self, **kw):
         '''swap for three-armed context'''
-        self.snapshot()
         self.swap(
             utilq=kw.get(self._WORKCFG, self._WORKVAR), context=self.ctx3, **kw
         )._clearwork()
 
     def ro(self):
         '''switch to read-only mode'''
-        with self.ctx3(outq=self._UTILVAR):
+        with self.ctx3(outq=self._UTILVAR, savepoint=False):
             self._xreplace(self._iterable)
-        with self.ctx1(hard=True, workq=self._UTILVAR):
+        with self.ctx1(hard=True, workq=self._UTILVAR, savepoint=False):
             self.current_mode = self._RO
             return self
 
 
-class AutoQMixin(BaseQMixin):
+class AutoMixin(BaseMixin):
 
     '''auto-balancing things mixin'''
 
     _default_context = 'autoctx'
 
 
-class ManQMixin(BaseQMixin):
+class ManMixin(BaseMixin):
 
     '''manually balanced things mixin'''
 
     _default_context = 'ctx4'
 
 
-class EndMixin(ResultMixin):
+class EndMixin(ResultsMixin):
 
     '''result things mixin'''
 
     def end(self):
         '''return outgoing things then clear out everything'''
-        # return to default context
+        # swap for default context
         self.unswap()
         out, tell = tee(self.outgoing)
         wrap = self._wrapper
         self.clear()
         return out
 
+    def snapshot(self):
+        '''snapshot of current outgoing things'''
+        out, tell, self.outgoing = tee(getattr(self, self._OUTQ), 3)
+        wrap = self._wrapper
+        return out.pop() if len(wrap(tell)) == 1 else wrap(out)
+
     def value(self):
         '''return outgoing things and clear outgoing things'''
-        # return to default context
+        # swap for default context
         self.unswap()
         out, tell = tee(self.outgoing)
         wrap = self._wrapper
         return out
 
 
-class AutoResultMixin(EndMixin, AutoQMixin):
+class AutoResultMixin(EndMixin, AutoMixin):
 
     '''auto-balancing things (with results extraction) mixin'''
 
 
-class ManResultMixin(EndMixin, ManQMixin):
+class ManResultMixin(EndMixin, ManMixin):
 
     '''manually balanced things (with results extraction) mixin'''

twoq/lazy/ordering.py

 # -*- coding: utf-8 -*-
 '''twoq lazy ordering queues'''
 
-from twoq.queuing import SLOTS
-from twoq.ordering import RandomMixin, OrderingMixin, CombineMixin
+from twoq.core import SLOTS
+from twoq.ordering import RandomMixin, OrderingMixin
 
 from twoq.lazy.mixins import AutoResultMixin, ManResultMixin
 
     '''manually balanced order queue'''
 
     __slots__ = SLOTS
-
-
-class combineq(AutoResultMixin, CombineMixin):
-
-    '''auto-balanced combination queue'''
-
-    __slots__ = SLOTS
-
-
-class mcombineq(ManResultMixin, CombineMixin):
-
-    '''manually balanced combination queue'''
-
-    __slots__ = SLOTS

twoq/lazy/queuing.py

 # -*- coding: utf-8 -*-
 '''twoq lazy queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.mapping import MappingMixin as MapMixin
 from twoq.ordering import OrderingMixin as OrderMixin
 from twoq.reducing import ReducingMixin as ReduceMixin

twoq/lazy/reducing.py

 # -*- coding: utf-8 -*-
 '''twoq lazy reducing queues'''
 
-from twoq.queuing import SLOTS
+from twoq.core import SLOTS
 from twoq.reducing import MathMixin, TruthMixin, ReducingMixin
 
 from twoq.lazy.mixins import AutoResultMixin, ManResultMixin
         with self._context():
             return self._xtend(sorted(self._iterable, key=call_))
 
-
-class CombineMixin(local):
-
-    '''combination mixin'''
-
     def product(self, n=1):
         '''
         nested for each loops repeated `n` times
             return self._xtend(product(*self._iterable, repeat=n))
 
 
-class OrderingMixin(OrderMixin, RandomMixin, CombineMixin):
+class OrderingMixin(OrderMixin, RandomMixin):
 
     '''ordering mixin'''

twoq/queuing.py

-# -*- coding: utf-8 -*-
-'''twoq queuing mixins'''
-
-from threading import local
-from collections import deque
-from itertools import tee, repeat
-from contextlib import contextmanager
-
-from stuf.utils import OrderedDict
-from stuf.core import stuf, frozenstuf, orderedstuf
-
-from twoq.support import n2u, n2b
-
-SLOTS = [
-    '_work', 'outgoing', '_util', 'incoming', '_call', '_alt', '_wrapper',
-    '_args', '_kw', '_clearout', '_context', '_CONFIG', '_INQ', '_WORKQ',
-    '_UTILQ', '_OUTQ', '_iterator', 'current_mode', '_snapshots',
-]
-
-
-class ThingsMixin(local):
-
-    '''things management mixin'''
-
-    # 1. incoming things
-    _INCFG = 'inq'
-    _INVAR = 'incoming'
-    # 2. utility things
-    _UTILCFG = 'utilq'
-    _UTILVAR = '_util'
-    # 3. work things
-    _WORKCFG = 'workq'
-    _WORKVAR = '_work'
-    # 4. outgoing things
-    _OUTCFG = 'outq'
-    _OUTVAR = 'outgoing'
-    # read/write mode marker
-    _RW = 'read/write'
-    # read-only mode marker
-    _RO = 'read-only'
-
-    def __init__(self, incoming, outgoing, **kw):
-        '''
-        init
-
-        @param incoming: incoming things
-        @param outgoing: outgoing things
-        '''
-        super(ThingsMixin, self).__init__()
-        # snapshots
-        self._snapshots = deque(maxlen=kw.pop('snapshots', 5))
-        # incoming things
-        self.incoming = incoming
-        # outgoing things
-        self.outgoing = outgoing
-        # current callable
-        self._call = lambda x: x
-        # current alt callable
-        self._alt = lambda x: x
-        # clear wrapper
-        self._wrapper = list
-        # reset postitional arguments
-        self._args = ()
-        # reset keyword arguments
-        self._kw = {}
-        # mode
-        self.current_mode = self._RW
-        # set defaults
-        self.unswap()
-
-    @property
-    def balanced(self):
-        '''if queues are balanced'''
-        return self.outcount() == self.__len__()
-
-    @staticmethod
-    def _repr(*args):
-        return (
-            '<{0}.{1}<<{2}>>([IN: {3}({4}) => WORK: {5}({6}) => UTIL: {7}({8})'
-            ' => OUT: {9}: ({10})]) at {11}>'
-        ).format(*args)
-
-    def clear(self):
-        '''clear every thing'''
-        self.detap().unwrap().dealt()
-        return self.outclear().inclear()._wclear()._uclear()
-
-    ###########################################################################
-    ## context rotation #######################################################
-    ###########################################################################
-
-    @contextmanager
-    def ctx1(self, **kw):
-        '''swap to one-armed context'''
-        self.snapshot()
-        q = kw.pop(self._WORKCFG, self._INVAR)
-        self.swap(workq=q, utilq=q, context=self.ctx1, **kw)
-        yield
-        # return to global context
-        self.reswap()
-
-    def swap(self, hard=False, **kw):
-        '''swap contexts'''
-        self._context = kw.get('context', getattr(self, self._default_context))
-        # clear out outgoing things before extending them?
-        self._clearout = kw.get('clearout', True)
-        # keep context-specific settings between context swaps
-        self._CONFIG = kw if kw.get('hard', False) else {}
-        # 1. incoming things
-        self._INQ = kw.get(self._INCFG, self._INVAR)
-        # 2. work things
-        self._WORKQ = kw.get(self._WORKCFG, self._WORKVAR)
-        # 3. utility things
-        self._UTILQ = kw.get(self._UTILCFG, self._UTILVAR)
-        # 4. outgoing things
-        self._OUTQ = kw.get(self._OUTCFG, self._OUTVAR)
-        return self
-
-    def unswap(self):
-        '''swap context to default context'''
-        return self.swap()
-
-    def reswap(self):
-        '''swap contexts to current preferred context'''
-        return self.swap(**self._CONFIG)
-
-    ###########################################################################
-    ## mode ###################################################################
-    ###########################################################################
-
-    def rw(self):
-        '''switch to read/write mode'''
-        self.current_mode = self._RW
-        return self._uclear().unswap()
-
-    ###########################################################################
-    ## snapshots ##############################################################
-    ###########################################################################
-
-    def undo(self):
-        '''revert to last snapshot'''
-        self.clear()
-        self.incoming = self._snapshots.pop()
-        self.snapshot()
-        return self
-
-    def revert(self, snapshot=0):
-        '''revert to specific snapshot'''
-        self.clear()
-        self.incoming = self._snapshots[snapshot]
-        self.snapshot()
-        return self
-
-    ###########################################################################
-    ## current callable management ############################################
-    ###########################################################################
-
-    def args(self, *args, **kw):
-        '''arguments for current callable'''
-        # set positional arguments
-        self._args = args
-        # set keyword arguemnts
-        self._kw = kw
-        return self
-
-    def tap(self, call):
-        '''
-        set current callable
-
-        @param call: a callabler
-        '''
-        # reset postitional arguments
-        self._args = ()
-        # reset keyword arguments
-        self._kw = {}
-        # set current callable
-        self._call = call
-        return self
-
-    def alt(self, call):
-        '''
-        set alternative current callable
-
-        @param call: an alternative callable
-        '''
-        self._alt = call
-        return self
-
-    def detap(self):
-        '''clear current callable'''
-        # reset postitional arguments
-        self._args = ()
-        # reset keyword arguments
-        self._kw = {}
-        # reset current callable (default is identity)
-        self._call = lambda x: x
-        return self
-
-    def dealt(self):
-        '''clear current alternative callable'''
-        self._alt = lambda x: x
-        return self
-
-    def factory(self, call):
-        '''
-        build current callable from factory
-
-        @param call: a callable
-        '''
-        def wrap(*args, **kw):
-            return call(*args, **kw)
-        return self.tap(wrap)
-
-    defactory = detap
-
-    ###########################################################################
-    ## things rotation ########################################################
-    ###########################################################################
-
-    def outshift(self):
-        '''shift incoming things to outgoing things'''
-        with self.autoctx():
-            return self._xtend(self._iterable)
-
-    outsync = outshift
-
-    def reup(self):
-        '''put incoming things in incoming things as one incoming thing'''
-        with self.ctx2():
-            return self._append(list(self._iterable))
-
-    def shift(self):
-        '''shift outgoing things to incoming things'''
-        with self.autoctx(inq=self._OUTVAR, outq=self._INVAR):
-            return self._xtend(self._iterable)
-
-    sync = shift
-
-    ###########################################################################
-    ## things appending #######################################################
-    ###########################################################################
-
-    def append(self, thing):
-        '''
-        append thing to right side of incoming things
-
-        @param thing: some thing
-        '''
-        with self.ctx1():
-            return self._append(thing)
-
-    def prepend(self, thing):
-        '''
-        append `thing` to left side of incoming things
-
-        @param thing: some thing
-        '''
-        with self.ctx1():
-            return self._appendleft(thing)
-
-    appendleft = prepend
-
-    ###########################################################################
-    ## things extension #######################################################
-    ###########################################################################
-
-    def extend(self, things):
-        '''
-        extend right side of incoming things with `things`
-
-        @param thing: some things
-        '''
-        with self.ctx1():
-            return self._xtend(things)
-
-    def prextend(self, things):
-        '''
-        extend left side of incoming things with `things`
-
-        @param thing: some things
-        '''
-        with self.ctx1():
-            return self._xtendleft(things)
-
-    extendleft = prextend
-
-    def outextend(self, things):
-        '''
-        extend right side of outgoing things with `things`
-
-        @param thing: some things
-        '''
-        with self.ctx1(workq=self._OUTVAR):
-            return self._xtend(things)
-
-    ###########################################################################
-    ## iteration runners ######################################################
-    ###########################################################################
-
-    @classmethod
-    def breakcount(cls, call, length, exception=StopIteration):
-        '''
-        rotate through iterator until it reaches its original length
-
-        @param iterable: an iterable to exhaust
-        '''
-        for i in repeat(None, length):  # @UnusedVariable
-            try:
-                yield call()
-            except exception:
-                pass
-
-    @staticmethod
-    def iterexcept(call, exception):
-        '''
-        call a function repeatedly until an exception is raised
-
-        Converts a call-until-exception interface to an iterator interface.
-        Like `iter(call, sentinel)` but uses an exception instead of a sentinel
-        to end the loop.
-
-        Raymond Hettinger, Python Cookbook recipe # 577155
-        '''
-        try:
-            while 1:
-                yield call()
-        except exception:
-            pass
-
-
-class ResultMixin(local):
-
-    '''result things mixin'''
-
-    def wrap(self, wrapper):
-        '''
-        wrapper for outgoing things
-
-        @param wrapper: an iterator
-        '''
-        self._wrapper = wrapper
-        return self
-
-    def unwrap(self):
-        '''clear current wrapper'''
-        return self.list()
-
-    def dict(self):
-        '''set wrapper to `d    ict`'''
-        self._wrap = dict
-        return self
-
-    def ordered_dict(self):
-        '''set wrapper to `OrderedDict`'''
-        self._wrap = OrderedDict
-
-    def list(self):
-        '''set wrapper to `list`'''
-        self._wrap = list
-        return self
-
-    def unicode(self, encoding='utf-8'):
-        '''set wrapper to `unicode` with given `encoding`'''
-        self._wrap = lambda x: n2u(x, encoding)
-        return self
-
-    def bytes(self, encoding='ISO-8859-1'):
-        '''set wrapper to `bytes` with given `encoding`'''
-        self._wrap = lambda x: n2b(x, encoding)
-        return self
-
-    def tuple(self):
-        '''set wrapper to `tuple`'''
-        self._wrap = tuple
-        return self
-
-    def set(self):
-        '''set wrapper to `set`'''
-        self._wrap = set
-        return self
-
-    def frozenset(self):
-        '''set wrapper to `frozenset`'''
-        self._wrap = frozenset
-        return self
-
-    def deque(self):
-        '''set wrapper to `deque`'''
-        self._wrap = deque
-        return self
-
-    def stuf(self):
-        '''set wrapper to `stuf`'''
-        self._wrap = stuf
-        return self
-
-    def frozenstuf(self):
-        '''set wrapper to `frozenstuf`'''
-        self._wrap = frozenstuf
-        return self
-
-    def orderedstuf(self):
-        '''set wrapper to `orderedstuf`'''
-        self._wrap = orderedstuf
-        return self
-
-    def first(self):
-        '''first incoming thing'''
-        with self._context():
-            return self._append(next(self._iterable))
-
-    def last(self):
-        '''last incoming thing'''
-        with self._context():
-            i1, _ = tee(self._iterable)
-            return self._append(deque(i1, maxlen=1).pop())
-
-    def peek(self):
-        '''results from read-only context'''
-        self.ro()
-        out = self._wrapper(self._util)
-        results = out[0] if len(out) == 1 else out
-        self.rw()
-        return results
-
-    def results(self):
-        '''yield outgoing things, clearing outgoing things as it iterates'''
-        return self.__iter__()
         '''interleave incoming things into one thing'''
         with self._context():
             return self._xtend(self._roundrobin(self._iterable))
-        
-    def smash(self):
+
+    def flatten(self):
         '''flatten deeply nested incoming things'''
         with self._context():
             return self._xtend(self._smash(self._iterable))
 
-    flatten = smash
-
     def zip(self):
         '''
         smash incoming things into one single thing, pairing things by iterable
 try:
     import unittest2 as unittest
 except ImportError:
-    import unittest
+    import unittest  # @UnusedImport
 
 from stuf import six
 # pylint: disable-msg=f0401,w0611

twoq/tests/active/auto/test_ordering.py

         from twoq.active.ordering import randomq
         self.qclass = randomq
 
-
-class TestAutoPermutationQ(unittest.TestCase, AQMixin, ACombineQMixin):
-
-    def setUp(self):
-        from twoq.active.ordering import combineq
-        self.qclass = combineq
-
-
 if __name__ == '__main__':
     unittest.main()

twoq/tests/active/man/test_ordering.py

         from twoq.active.ordering import mrandomq
         self.qclass = mrandomq
 
-
-class TestManPermutationQ(Manning, MQMixin, MCombineQMixin):
-
-    def setUp(self):
-        from twoq.active.ordering import mcombineq
-        self.qclass = mcombineq
-
-
 if __name__ == '__main__':
     unittest.main()

twoq/tests/auto/filtering.py

     def test_takeback(self):
         self.assertEqual(self.qclass(5, 4, 3, 2, 1).snatch(2).end(), [2, 1])
 
+    def test_partition(self):
+        self.assertEqual(
+            self.qclass(1, 2, 3, 4, 5, 6).tap(
+                lambda x: x % 2 == 0
+            ).partition().end(), [[1, 3, 5], [2, 4, 6]]
+        )
+
 
 class ACollectQMixin(object):
 
     def test_members(self):
-        class stooges:
-            name = 'moe'
-            age = 40
-        class stoog2: #@IgnorePep8
-            name = 'larry'
-            age = 50
-        class stoog3: #@IgnorePep8
-            name = 'curly'
-            age = 60
-        test = lambda x: not x[0].startswith('__')
-        self.assertEqual(
-            self.qclass(
-                stooges, stoog2, stoog3
-            ).tap(test).members().detap().end(),
-            [('age', 40), ('name', 'moe'), ('age', 50), ('name', 'larry'),
-            ('age', 60), ('name', 'curly')],
-        )
-
-    def test_extract(self):
         from inspect import isclass
         class stooges: #@IgnorePep8
             name = 'moe'
         test = lambda x: not x[0].startswith('__')
         value = self.qclass(
             stooges, stoog2, stoog3
-        ).tap(test).alt(isclass).wrap(tuple).extract().detap().end(),
+        ).tap(test).alt(isclass).wrap(tuple).extract().untap().end(),
         self.assertEqual(
             value,
             ((('age', 40), ('name', 'moe'), ('age', 50), ('name', 'larry'),
             value,
         )
 
-    def test_deepmembers(self):
-        class stooges:
-            name = 'moe'
-            age = 40
-            def boo(self):#@IgnorePep8
-                return 'boo'
-            def foo(self):#@IgnorePep8
-                return 'foo'
-        class stoog2: #@IgnorePep8
-            name = 'larry'
-            age = 50
-            def boo(self):#@IgnorePep8
-                return 'boo'
-            def foo(self):#@IgnorePep8
-                return 'foo'
-        class stoog3: #@IgnorePep8
-            name = 'curly'
-            age = 60
-            def boo(self):#@IgnorePep8
-                return 'boo'
-            def foo(self):#@IgnorePep8
-                return 'foo'
-        test = lambda x: not x[0].startswith('__')
-        self.assertSequenceEqual(
-            self.qclass(
-                stooges, stoog2, stoog3
-            ).tap(test).deepmembers().sync().end(),
-            [('age', 40), ('boo', stooges.boo), ('foo', stooges.foo),
-            ('name', 'moe'), ('age', 50), ('boo', stoog2.boo),
-            ('foo', stoog2.foo), ('name', 'larry'), ('age', 60),
-            ('boo', stoog3.boo), ('foo', stoog3.foo), ('name', 'curly')],
-        )
-        from stuf.six import callable
-        test = lambda x: not x[0].startswith('_') and callable(x[1])
-        self.assertSequenceEqual(
-            self.qclass(
-                stooges, stoog2, stoog3
-            ).tap(test).deepmembers().sync().end(),
-            [('boo', stooges.boo), ('foo', stooges.foo), ('boo', stoog2.boo),
-            ('foo', stoog2.foo), ('boo', stoog3.boo), ('foo', stoog3.foo)],
-        )
-
     def test_pick(self):
         from stuf import stuf
         stooges = [
             ).reject().end(), [1, 3, 5]
         )
 
-    def test_partition(self):
-        self.assertEqual(
-            self.qclass(1, 2, 3, 4, 5, 6).tap(
-                lambda x: x % 2 == 0
-            ).partition().end(), [[1, 3, 5], [2, 4, 6]]
-        )
-
     def test_compact(self):
         self.assertEqual(
             self.qclass(0, 1, False, 2, '', 3).compact().end(), [1, 2, 3],

twoq/tests/auto/mapping.py

         self.assertDictEqual(
             self.qclass(
                 ('a', 1), ('b', 2), ('c', 3)
-            ).reup().factory(stuf).map().end(),
+            ).reup().tap(stuf, factory=True).map().end(),
             stuf(a=1, b=2, c=3),
         )
 

twoq/tests/auto/ordering.py

         )
 
 
-class ACombineQMixin(object):
-
-#    def test_combinations(self):
-#        foo = self.qclass('ABCD').combinations(2).value(),
-#        self.assertEqual(
-#            foo[0],
-#            [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'),
-#            ('C', 'D')],
-#            foo,
-#        )
-#
-#    def test_permutations(self):
-#        foo = self.qclass('ABCD').permutations(2).value()
-#        self.assertEqual(
-#            foo[0],
-#            [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'),
-#            ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'),
-#            ('D', 'B'), ('D', 'C')],
-#            foo,
-#        )
-
-    def test_product(self):
-        foo = self.qclass('ABCD', 'xy').product().value()
-        self.assertEqual(
-            foo,
-            [('A', 'x'), ('A', 'y'), ('B', 'x'), ('B', 'y'), ('C', 'x'),
-            ('C', 'y'), ('D', 'x'), ('D', 'y')],
-            foo,
-        )
-
-
-class AOrderQMixin(ARandomQMixin, ACombineQMixin):
+class AOrderQMixin(ARandomQMixin):
 
     '''combination mixin'''
 
             [2, 3, 4, 4, 6, 63, 65],
         )
 
+    def test_product(self):
+        foo = self.qclass('ABCD', 'xy').product().value()
+        self.assertEqual(
+            foo,
+            [('A', 'x'), ('A', 'y'), ('B', 'x'), ('B', 'y'), ('C', 'x'),
+            ('C', 'y'), ('D', 'x'), ('D', 'y')],
+            foo,
+        )
+
 
 __all__ = sorted(name for name, obj in port.items(locals()) if not any([
     name.startswith('_'), ismodule(obj), name in ['ismodule', 'port']

twoq/tests/auto/queuing.py

         autoq = self.qclass().append('foo').outsync()
         self.assertEqual(autoq.end(), 'foo')
 
-    def test_appendleft(self):
-        autoq = self.qclass().appendleft('foo').outsync()
+    def test_prepend(self):
+        autoq = self.qclass().prepend('foo').outsync()
         self.assertEqual(autoq.end(), 'foo')
 
     def test_inclear(self):
         q = self.qclass([1, 2, 3, 4, 5, 6]).outshift().inclear().shift()
         self.assertListEqual(list(q.incoming), list(q.outgoing))
 
-    def test_inshift(self):
-        q = self.qclass([1, 2, 3, 4, 5, 6]).outshift().sync()
-        self.assertListEqual(list(q.incoming), list(q.outgoing))
-
     def test_outsync(self):
         q = self.qclass([1, 2, 3, 4, 5, 6]).outshift()
         self.assertListEqual(list(q.incoming), list(q.outgoing))
 
-    def test_outshift(self):
-        q = self.qclass([1, 2, 3, 4, 5, 6]).outsync()
-        self.assertListEqual(list(q.incoming), list(q.outgoing))
-
     ##########################################################################
     # queue information ######################################################
     ##########################################################################

twoq/tests/auto/reducing.py

 
 class AReduceQMixin(AMathQMixin, ATruthQMixin):
 
-    def test_smash(self):
+    def test_flatten(self):
         self.assertEqual(
-            self.qclass([[1, [2], [3, [[4]]]]]).smash().end(), [1, 2, 3, 4],
+            self.qclass([[1, [2], [3, [[4]]]]]).flatten().end(), [1, 2, 3, 4],
         )
 
     def test_merge(self):

twoq/tests/lazy/auto/test_ordering.py

         from twoq.lazy.ordering import randomq
         self.qclass = randomq
 
-
-class TestAutoPermutationQ(unittest.TestCase, AQMixin, ACombineQMixin):
-
-    def setUp(self):
-        from twoq.lazy.ordering import combineq
-        self.qclass = combineq
-
 if __name__ == '__main__':
     unittest.main()

twoq/tests/lazy/man/test_ordering.py

         self.qclass = mrandomq
 
 
-class TestManPermutationQ(Manning, MQMixin, MCombineQMixin):
-
-    def setUp(self):
-        from twoq.lazy.ordering import mcombineq
-        self.qclass = mcombineq
-
-
 if __name__ == '__main__':
     unittest.main()

twoq/tests/man/filtering.py

 
 class MSliceQMixin(object):
 
+    def test_partition(self):
+        self._false_true_false(
+            self.qclass(
+                1, 2, 3, 4, 5, 6
+            ).tap(lambda x: x % 2 == 0).partition(),
+            self.assertEqual,
+            [[1, 3, 5], [2, 4, 6]],
+        )
+
     def test_first(self):
         manq = self.qclass(5, 4, 3, 2, 1).first()
         self.assertFalse(manq.balanced)
 class MCollectQMixin(object):
 
     def test_members(self):
-        class stooges:
-            name = 'moe'
-            age = 40
-        class stoog2: #@IgnorePep8
-            name = 'larry'
-            age = 50
-        class stoog3: #@IgnorePep8
-            name = 'curly'
-            age = 60
-        self._true_true_false(
-            self.qclass(
-                stooges, stoog2, stoog3
-            ).tap(
-                lambda x: not x[0].startswith('__')
-            ).members().detap().sync(),
-            self.assertEqual,
-            [('age', 40), ('name', 'moe'), ('age', 50), ('name', 'larry'),
-