Commits

Lynn Rees committed e74f0ee Merge

automerge

Comments (0)

Files changed (9)

 syntax: regexp
 ^graphalchemy/tests/foo3$
 syntax: regexp
-^profile$
+^profile$
+syntax: regexp
+^support\.py$
 d667503e900ab0a8e038f9e32a84cb85c283d1bd 0.8.3
 8e2864f2f8311c88abd210b71f459e60fd2c1da8 0.8.4
 08ebd60ddf162d0bef6e2b6aaed40087c306e8b7 0.8.5
+3de8e164d24f2ee82c967700a27eae9f3f90d5ae 0.8.6
-A collection of Python dictionary that support attribute-style access. Includes  
+A collection of Python dictionaries supporting attribute-style access. Includes  
 *defaultdict*,  *OrderedDict*, restricted, and frozen implementations.
 except ImportError:
     from distutils.core import setup
 
-install_requires = []
+install_requires = ['distribute>=0.6.25']
 if sys.version_info[0] == 2 and sys.version_info[1] < 7:
     install_requires.extend(['ordereddict', 'unittest2'])
 
 setup(
     name='stuf',
-    version='0.8.5    ',
+    version='0.8.7',
     description='''stuf has attributes''',
     long_description=open(os.path.join(os.getcwd(), 'README.rst'), 'r').read(),
     author='L. C. Rees',
 from stuf.core import defaultstuf, fixedstuf, frozenstuf, orderedstuf, stuf
 
 __all__ = ('defaultstuf', 'fixedstuf', 'frozenstuf', 'orderedstuf', 'stuf')
+__version__ = (0, 8, 7)
+
 
 idefaultstuf = defaultstuf
 ifixedstuf = fixedstuf
 from collections import Mapping, Sequence, MutableMapping
 
 from stuf.six import items, strings, keys, values
-from stuf.utils import clsname, lazy, recursive_repr
+from stuf.utils import clsname, lazy, recursive_repr, exhaust, imap
 
 __all__ = ['corestuf', 'directstuf', 'wrapstuf', 'writestuf', 'writewrapstuf']
 
     _map = dict
     _reserved = ['allowed', '_wrapped', '_map']
 
-    def __getattr__(self, key):
+    def __getattr__(self, key, _getter=object.__getattribute__):
         try:
             return self[key]
         except KeyError:
                 return keys(self)
             elif key == 'itervalues':
                 return values(self)
-            return object.__getattribute__(self, key)
+            return _getter(self, key)
 
     @recursive_repr
     def __repr__(self, _clsname=clsname, _mcaller=methodcaller):
         ))
 
     @classmethod
-    def _build(cls, iterable, _map=map, _is=isinstance, _list=list):
+    def _build(cls, iterable, _map=imap, _is=isinstance, _list=exhaust):
         kind = cls._map
         # add class to handle potential nested objects of the same class
         kw = kind()
                     update(arg)
                 except (ValueError, TypeError):
                     pass
-            _list(map(_coro, iterable))
+            _list(_map(_coro, iterable))
         return kw
 
     @classmethod
                     future[key] = value
             else:
                 future[key] = value
-        list(m(_coro, _i(past)))
+        exhaust(m(_coro, _i(past)))
         return cls._postpopulate(future)
 
     @classmethod
 from collections import Mapping, Sequence, defaultdict, namedtuple
 
 from stuf.six import items, keys, values
-from stuf.utils import OrderedDict, getter, imap
+from stuf.utils import OrderedDict, getter, imap, exhaust
 from stuf.base import directstuf, wrapstuf, writewrapstuf
 
 __all__ = ('defaultstuf', 'fixedstuf', 'frozenstuf', 'orderedstuf', 'stuf')
 
     _map = defaultdict
 
-    def __getattr__(self, key):
+    def __getattr__(self, key, _getter=object.__getattribute__):
         try:
             if key == 'iteritems':
                 return items(self)
                 return keys(self)
             elif key == 'itervalues':
                 return values(self)
-            return object.__getattribute__(self, key)
+            return _getter(self, key)
         except AttributeError:
             return self[key]
 
         directstuf.__init__(self, *args, **kw)
 
     @classmethod
-    def _build(cls, default, iterable, _map=imap, _list=list):
+    def _build(cls, default, iterable, _map=imap, _list=exhaust):
         kind = cls._map
         # add class to handle potential nested objects of the same class
         kw = kind(default)
                     future[key] = value
             else:
                 future[key] = value
-        list(_map(_coro, _items(past)))
+        exhaust(_map(_coro, _items(past)))
 
     def _prepopulate(self, *args, **kw):
         kw.update(self._build(self.default_factory, args))
     strings = str,
     integers = int,
     classes = type,
-    texts = str
+    native = texts = str
     binaries = bytes
 
     MAXSIZE = sys.maxsize
     integers = (int, long)
     classes = (type, types.ClassType)
     texts = unicode
-    binaries = str
+    native = binaries = str
 
     # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
     class X(object):
     MovedAttribute('StringIO', 'StringIO', 'io'),
     MovedAttribute('xrange', '__builtin__', 'builtins', 'xrange', 'range'),
     MovedAttribute('zip', 'itertools', 'builtins', 'izip', 'zip'),
-
+    MovedAttribute('parsedate_tz', 'rfc822', 'email.utils', 'parsedate_tz'),
+    MovedAttribute('formatdate', 'rfc822', 'email.utils', 'formatdate'),
+    MovedAttribute('xrange', '__builtin__', 'builtins', 'xrange', 'range'),
+    MovedAttribute(
+        'read_plist',
+        'plistlib',
+        'plistlib',
+        'readPlistFromString',
+        'readPlistFromBytes',
+    ),
+    MovedAttribute(
+        'write_plist',
+        'plistlib',
+        'plistlib',
+        'writePlistFromString',
+        'writePlistFromBytes',
+    ),
+    MovedAttribute('parse_qs', 'cgi', 'urllib.parse', 'parse_qs'),
+    MovedAttribute('urlencode', 'urlparse', 'urllib.parse', 'urlencode'),
     MovedModule('builtins', '__builtin__'),
     MovedModule('configparser', 'ConfigParser'),
     MovedModule('copyreg', 'copy_reg'),
     MovedModule('socketserver', 'SocketServer'),
     MovedModule('urllib_robotparser', 'robotparser', 'urllib.robotparser'),
     MovedModule('winreg', '_winreg'),
+    MovedModule('xmlrpc', 'xmlrpclib', 'xmlrpc.client'),
 ]
 for attr in _moved_attributes:
     setattr(_MovedItems, attr.name, attr)
     _itervalues = 'values'
     _iteritems = 'items'
 
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
 if PY3:
     def get_unbound_function(unbound):
         return unbound
 
-    advance_iterator = next
+    Iterator = object
 
     def callable(obj):
         return any('__call__' in klass.__dict__ for klass in type(obj).__mro__)
     def get_unbound_function(unbound):
         return unbound.im_func
 
-    def advance_iterator(it):
-        return it.next()
+    class Iterator(object):
+        def next(self):
+            return type(self).__next__(self)
 
     callable = callable
 
 '''stuf utilities'''
 
 from inspect import ismodule
+from itertools import starmap
 try:
     from collections import OrderedDict
 except  ImportError:
         return default
 
 
+def exhaust(iterable, exception=StopIteration, _n=next):
+    '''
+    call next on an iterator until it's exhausted
+
+    @param iterable: an iterable to exhaust
+    @param exception: exception that marks end of iteration
+    '''
+    try:
+        while True:
+            _n(iterable)
+    except exception:
+        pass
+
+
+def exhaustmap(mapping, call, filter=False, exception=StopIteration, _n=next):
+    '''
+    call `next` on an iterator until it's exhausted
+
+    @param mapping: a mapping to exhaust
+    @param call: call to handle what survives the filter
+    @param filter: a filter to apply to mapping (default: `None`)
+    @param exception: exception sentinel (default: `StopIteration`)
+    '''
+    subiter = ifilter(filter, items(mapping)) if filter else items(mapping)
+    try:
+        while True:
+            _n(starmap(call, subiter))
+    except exception:
+        pass
+
+
 def deleter(this, key):
     '''
     delete an attribute
         return default
 
 
+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 True:
+            yield func()
+    except exception:
+        pass
+
+
 def lru(this, maxsize=100):
     '''
     least-recently-used cache decorator from Raymond Hettinger
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.