Commits

Lynn Rees committed ba26d01

- tweak

Comments (0)

Files changed (14)

 *twoq* chains iterators together using a double-headed input and output queue,
 that can be shifted and synced as needed.
 
-*twoq* also includes Python 2 <-> 3 compatibility aids and exposes some useful
+*twoq* includes Python 2 <-> 3 compatibility aids. It also exposes some useful
 features buried in the standard library.
 
 Mirrored on https://github.com/kwarterthieves/twoq/
 except ImportError:
     from distutils.core import setup
 
-install_requires = ['stuf>=0.8.4']
+install_requires = ['stuf>=0.8.6']
 if sys.version_info[0] == 2 and sys.version_info[1] < 7:
     install_requires.extend(['ordereddict', 'unittest2'])
 
 setup(
     name='twoq',
-    version='0.1.8',
+    version='0.1.9',
     description='iterator chaining, underscored by two-headed queues',
     long_description=open(os.path.join(os.getcwd(), 'README.rst'), 'r').read(),
     author='L. C. Rees',
 # -*- coding: utf-8 -*-
 '''twoq iterator utilities'''
 
-from twoq.support import port, iterexcept
+from twoq.support import port
 from twoq.active.queuing import twoq, manq, autoq, syncq
 
-__all__ = ('twoq', 'manq', 'autoq', 'port', 'syncq', 'iterexcept')
+__all__ = ('twoq', 'manq', 'autoq', 'port', 'syncq')
 
-__version__ = (0, 1, 1)
+__version__ = (0, 1, 8)

twoq/active/mixins.py

 from collections import deque
 from bisect import bisect_right
 
-from twoq.support import iterexcept
+from stuf.utils import iterexcept
+
 from twoq.mixins.queuing import QueueingMixin
 
 from twoq.active.contexts import AutoContext, ManContext, SyncContext

twoq/active/queuing.py

 
 from twoq.active.mixins import AutoQMixin, ManQMixin, SyncQMixin
 
-__all__ = ['twoq', 'manq', 'autoq', 'syncq']
+__all__ = ('autoq', 'manq', 'syncq', 'twoq')
 
 
-class autoq(
-    AutoQMixin, FilterMixin, MapMixin, ReduceMixin, OrderMixin
-):
+class autoq(AutoQMixin, FilterMixin, MapMixin, ReduceMixin, OrderMixin):
 
     '''auto-balancing manipulation queue'''
 
 
-class manq(
-    ManQMixin, FilterMixin, MapMixin, ReduceMixin, OrderMixin
-):
+class manq(ManQMixin, FilterMixin, MapMixin, ReduceMixin, OrderMixin):
 
     '''manually balanced manipulation queue'''
 
 
-class syncq(
-    SyncQMixin, FilterMixin, MapMixin, ReduceMixin, OrderMixin
-):
+class syncq(SyncQMixin, FilterMixin, MapMixin, ReduceMixin, OrderMixin):
 
     '''autosyncing manipulation queue'''
 
+
 twoq = autoq

twoq/mixins/filtering.py

         with self._sync as sync:
             sync(ct.filterfalse(lambda x: x in things, sync.iterable))
         return self
-    
+
     _owithout = without
 
 
 class CollectMixin(local):
 
     '''gathering mixin'''
-    
+
     def deepmembers(self, mz=mfilter, ci=chain_iter, gc=getcls):
         '''collect members of incoming things and their bases'''
         _mz = ft.partial(mz, self._call)

twoq/mixins/mapping.py

         with self._sync as sync:
             sync(_map(lambda x, y: self._call(*x, **y), sync.iterable))
         return self
-    
+
     _oeach = each
 
     def invoke(self, name, _mc=mc, _invoke=invoke, _map=ct.map):
         with self._sync as sync:
             sync(_map(_call, sync.iterable))
         return self
-    
+
     _oinvoke = invoke
-    
+
     def items(self, _s=it.starmap, _c=chain_iter, _m=ct.map, _i=port.items):
         '''invoke call on each mapping to get key, value pairs'''
         with self._sync as sync:
             sync(_s(self._call, _c(_m(_i, sync.iterable))))
         return self
-    
+
     _ostarmap = items
 
     def map(self, _map=ct.map):
         with self._sync as sync:
             sync(_map(self._call, sync.iterable))
         return self
-    
+
     _omap = map
-    
+
     def starmap(self, _map=it.starmap):
         '''invoke call on each incoming pair of things'''
         with self._sync as sync:
             sync(_map(self._call, sync.iterable))
         return self
-    
+
     _ostarmap = starmap
 
 
         with self._sync as sync:
             sync.iter(_chain(sync.iterable, _repeat(None)))
         return self
-    
+
     _opadnone = padnone
 
     def range(self, start, stop=0, step=1, _range=ct.xrange):
             else:
                 sync(_range(start))
         return self
-    
+
     _orange = range
 
     def repeat(self, n, _repeat=it.repeat, _tuple=tuple):
         with self._sync as sync:
             sync(_repeat(_tuple(sync.iterable), n))
         return self
-    
+
     _orepeat = repeat
 
     def times(self, n=None, _starmap=it.starmap, _repeat=it.repeat):
             else:
                 sync(_starmap(self._call, _repeat(sync.iterable, n)))
         return self
-    
+
     _otimes = times
 
 

twoq/mixins/ordering.py

                     _groupby(sync.iterable, self._call),
                 ))
         return self
-    
+
     _ogroup = group
 
     def grouper(self, n, fill=None, _zipl=ct.zip_longest, _iter=iter):
         with self._sync as sync:
             sync(_zipl(fillvalue=fill, *[_iter(sync.iterable)] * n))
         return self
-    
+
     _ogrouper = grouper
 
     def reverse(self, _reversed=reversed):
         with self._sync as sync:
             sync(_reversed(sync.iterable))
         return self
-    
+
     _oreverse = reverse
 
     def sort(self, _sorted=sorted):
             else:
                 sync(_sorted(sync.iterable, key=self._call))
         return self
-    
+
     _osort = sort
 
 
         with self._sync as sync:
             sync.append(_choice(sync.iterable))
         return self
-    
+
     _ochoice = choice
 
     def sample(self, n, _sample=rm.sample, _list=list):
         with self._sync as sync:
             sync(_sample(_list(sync.iterable), n))
         return self
-    
+
     _osample = sample
 
     def shuffle(self, _shuffle=rm.shuffle):
             _shuffle(iterable)
             sync(iterable)
         return self
-    
+
     _oshuffle = shuffle
 
 

twoq/mixins/reducing.py

 
     '''reduce mixin'''
 
-    def flatten(self, _chain=it.chain.from_iterable):
-        '''flatten nested incoming things'''
-        with self._sync as sync:
-            sync(_chain(sync.iterable))
-        return self
-
-    _oflatten = flatten
-
     def merge(self, _merge=hq.merge):
         '''flatten nested and ordered incoming things'''
         with self._sync as sync:
             sync(_smash(sync.iterable))
         return self
 
-    _osmash = smash
+    _osmash = flatten = smash
 
     def pairwise(self, _tee=it.tee, _next=next, _zip=ct.zip):
         '''
             else:
                 sync(_reduce(lambda x, y: self._call(y, x), sync.iterable))
         return self
-    
+
     _oreduce_right = reduce_right
 
     def roundrobin(self, _roundrobin=roundrobin):
         with self._sync as sync:
             sync(_roundrobin(sync.iterable))
         return self
-    
+
     _oroundrobin = roundrobin
 
     def zip(self, _zip=ct.zip):
         with self._sync as sync:
             sync.append(_all(_map(self._call, sync.iterable)))
         return self
-    
+
     _oall = all
 
     def any(self, _any=any, _map=ct.map):
         with self._sync as sync:
             sync.append(_contains(sync.iterable, thing))
         return self
-    
+
     _ocontains = contains
 
     def quantify(self, _sum=isum, _map=ct.map):
         with self._sync as sync:
             sync.append(_sum(_map(self._call, sync.iterable)))
         return self
-    
+
     _oquantify = quantify
 
 
     map, filterfalse, filter, zip, zip_longest, xrange)  # @UnresolvedImport @UnusedImport @IgnorePep8
 # pylint: enable-msg=f0401
 
-__all__ = ['port', 'iterexcerpt']
+__all__ = ['port']
 items = six.items
 
 
-def iterexcept(func, exception):
-    '''
-    call a function repeatedly until an exception is raised
-
-    Converts a call-until-exception interface to an iterator interface. Like
-    `__builtin__.iter(func, sentinel)` but uses an exception instead of a
-    sentinel to end the loop.
-    '''
-    try:
-        while 1:
-            yield func()
-    except exception:
-        pass
-
-
 class port(object):
 
     '''python 2/3 helper'''
 
         '''dict subclass for counting hashable items'''
 
-        def __init__(self, iterable=None, **kwds):
+        def __init__(self, iterable=None, **kw):
             '''
             If given, count elements from an input iterable. Or, initialize
             count from another mapping of elements to their counts.
             '''
             super(Counter, self).__init__()
-            self.update(iterable, **kwds)
+            self.update(iterable, **kw)
 
         def __missing__(self, key):
             '''count of elements not in the Counter is zero'''
                 'Use Counter(iterable) instead.'
             )
 
-        def update(self, iterable=None, **kwds):
+        def update(self, iterable=None, **kw):
             '''like dict.update() but add counts instead of replacing them'''
             if iterable is not None:
                 if isinstance(iterable, Mapping):
                     self_get = self.get
                     for elem in iterable:
                         self[elem] = self_get(elem, 0) + 1
-            if kwds:
-                self.update(kwds)
+            if kw:
+                self.update(kw)
 
-        def subtract(self, iterable=None, **kwds):
+        def subtract(self, iterable=None, **kw):
             '''
             like dict.update() but subtracts counts instead of replacing them.
 
                 else:
                     for elem in iterable:
                         self[elem] = self_get(elem, 0) - 1
-            if kwds:
-                self.subtract(kwds)
+            if kw:
+                self.subtract(kw)
 
         def copy(self):
             '''return a shallow copy'''

twoq/tests/active/auto/mixins/ordering.py

             [5, 4, 6, 3, 1, 2],
         )
         self.assertEqual(
-            self.qclass(4, 6, 65, 3, 63, 2,  4).sort().value(),
+            self.qclass(4, 6, 65, 3, 63, 2, 4).sort().value(),
             [2, 3, 4, 4, 6, 63, 65],
         )
 
 
 
 class AOrderQMixin(AOrderingQMixin, ARandomQMixin):
-    
+
     '''combination mixin'''
 
 __all__ = sorted(name for name, obj in port.items(locals()) if not any([

twoq/tests/active/auto/mixins/reducing.py

 
 class AReducingQMixin(object):
 
-    def test_flatten(self):
-        self.assertEquals(
-            self.qclass([[1], [2], [3, [[4]]]]).flatten().value(),
-            [[1], [2], [3, [[4]]]],
-        )
-
     def test_smash(self):
         self.assertEquals(
             self.qclass([[1, [2], [3, [[4]]]]]).smash().value(), [1, 2, 3, 4],
             self.qclass(10, 5, 100, 2, 1000).tap(lambda x: x).min().value(),
             2,
         )
-        
+
     def test_minmax(self):
         self.assertEquals(self.qclass(1, 2, 4).minmax().value(), [1, 4])
         self.assertEquals(
             self.qclass(10, 5, 100, 2, 1000).minmax().value(), [2, 1000],
         )
-        
+
     def test_median(self):
         self.assertEquals(self.qclass(4, 5, 7, 2, 1).median().value(), 4)
         self.assertEquals(self.qclass(4, 5, 7, 2, 1, 8).median().value(), 4.5)
         self.assertEquals(
             self.qclass(11, 3, 5, 11, 7, 3, 11).mode().value(), 11,
         )
-        
+
     def test_uncommon(self):
         self.assertEquals(
             self.qclass(11, 3, 5, 11, 7, 3, 11).uncommon().value(), 7,
         )
-        
+
     def test_frequency(self):
         self.assertEquals(
             self.qclass(11, 3, 5, 11, 7, 3, 11).frequency().value(),
             self.qclass(None, 0, 'yes', False).tap(bool).quantify().value(),
             1
         )
-        
-        
+
+
 class AReduceQMixin(AMathQMixin, AReducingQMixin, ATruthQMixin):
-    
+
     '''combination mixin'''
 
 __all__ = sorted(name for name, obj in port.items(locals()) if not any([

twoq/tests/active/man/mixins/ordering.py

         self.assertFalse(manq.balanced)
         self.assertEqual(manq.outcount(), 0)
 
+
 class MRandomQMixin(object):
 
     def test_choice(self):
 
 
 class MOrderQMixin(MOrderingQMixin, MRandomQMixin):
-    
+
     '''combination mixin'''
 
 __all__ = sorted(name for name, obj in port.items(locals()) if not any([

twoq/tests/active/man/mixins/reducing.py

 
 class MReducingQMixin(object):
 
-    def test_flatten(self):
-        manq = self.qclass([[1], [2], [3, [[4]]]]).flatten()
-        self.assertFalse(manq.balanced)
-        manq.sync()
-        self.assertTrue(manq.balanced)
-        self.assertEquals(manq.value(), [[1], [2], [3, [[4]]]])
-        self.assertFalse(manq.balanced)
-
     def test_smash(self):
         manq = self.qclass([[1, [2], [3, [[4]]]]]).smash()
         self.assertFalse(manq.balanced)
         self.assertTrue(manq.balanced)
         self.assertEquals(manq.value(), 2)
         self.assertFalse(manq.balanced)
-        
+
     def test_minmax(self):
         manq = self.qclass(1, 2, 4).minmax()
         self.assertFalse(manq.balanced)
         self.assertTrue(manq.balanced)
         self.assertEquals(manq.value(), 7)
         self.assertFalse(manq.balanced)
-        
+
     def test_mode(self):
         manq = self.qclass(11, 3, 5, 11, 7, 3, 11).mode()
         self.assertFalse(manq.balanced)
         self.assertTrue(manq.balanced)
         self.assertEquals(manq.value(), 31.666666666666668)
         self.assertFalse(manq.balanced)
-        
+
     def test_uncommon(self):
         manq = self.qclass(11, 3, 5, 11, 7, 3, 11).uncommon()
         self.assertFalse(manq.balanced)
         self.assertTrue(manq.balanced)
         self.assertEquals(manq.value(), 7)
         self.assertFalse(manq.balanced)
-        
+
     def test_frequency(self):
         manq = self.qclass(11, 3, 5, 11, 7, 3, 11).frequency()
         self.assertFalse(manq.balanced)
 
 
 class MReduceQMixin(MMathQMixin, MReducingQMixin, MTruthQMixin):
-    
+
     '''combination mixin'''
 
 __all__ = sorted(name for name, obj in port.items(locals()) if not any([