"Fossies" - the Fresh Open Source Software Archive

Member "roundup-2.0.0/roundup/cgi/ZTUtils/Iterator.py" (26 Aug 2019, 5321 Bytes) of package /linux/www/roundup-2.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "Iterator.py": 1.6.1_vs_2.0.0.

    1 ##############################################################################
    2 #
    3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
    4 # 
    5 # This software is subject to the provisions of the Zope Public License,
    6 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
    7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
    8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
   10 # FOR A PARTICULAR PURPOSE
   11 # 
   12 ##############################################################################
   13 __doc__='''Iterator class
   14 
   15 Unlike the builtin iterators of Python 2.2+, these classes are
   16 designed to maintain information about the state of an iteration.
   17 The Iterator() function accepts either a sequence or a Python
   18 iterator.  The next() method fetches the next item, and returns
   19 true if it succeeds.
   20 
   21 '''
   22 __docformat__ = 'restructuredtext'
   23 
   24 import string
   25 
   26 class Iterator:
   27     '''Simple Iterator class'''
   28 
   29     __allow_access_to_unprotected_subobjects__ = 1
   30 
   31     nextIndex = 0
   32     def __init__(self, seq):
   33         self.seq = iter(seq)     # force seq to be an iterator
   34         self._inner = iterInner
   35         self._prep_next = iterInner.prep_next
   36 
   37     def __getattr__(self, name):
   38         try:
   39             inner = getattr(self._inner, 'it_' + name)
   40         except AttributeError:
   41             raise AttributeError(name)
   42         return inner(self)
   43 
   44     def next(self):
   45         if not (hasattr(self, '_next') or self._prep_next(self)):
   46             return 0
   47         self.index = i = self.nextIndex
   48         self.nextIndex = i+1
   49         self._advance(self)
   50         return 1
   51 
   52     def _advance(self, it):
   53         self.item = self._next
   54         del self._next
   55         del self.end
   56         self._advance = self._inner.advance
   57         self.start = 1
   58             
   59     def number(self): return self.nextIndex
   60 
   61     def even(self): return not self.index % 2
   62 
   63     def odd(self): return self.index % 2
   64 
   65     def letter(self, base=ord('a'), radix=26):
   66         index = self.index
   67         s = ''
   68         while 1:
   69             index, off = divmod(index, radix)
   70             s = chr(base + off) + s
   71             if not index: return s
   72 
   73     def Letter(self):
   74         return self.letter(base=ord('A'))
   75 
   76     def Roman(self, rnvalues=(
   77                     (1000,'M'),(900,'CM'),(500,'D'),(400,'CD'),
   78                     (100,'C'),(90,'XC'),(50,'L'),(40,'XL'),
   79                     (10,'X'),(9,'IX'),(5,'V'),(4,'IV'),(1,'I')) ):
   80         n = self.index + 1
   81         s = ''
   82         for v, r in rnvalues:
   83             rct, n = divmod(n, v)
   84             s = s + r * rct
   85         return s
   86 
   87     def roman(self, lower=lambda x:x.lower):
   88         return lower(self.Roman())
   89 
   90     def first(self, name=None):
   91         if self.start: return 1
   92         return not self.same_part(name, self._last, self.item)
   93 
   94     def last(self, name=None):
   95         if self.end: return 1
   96         return not self.same_part(name, self.item, self._next)
   97 
   98     def same_part(self, name, ob1, ob2):
   99         if name is None:
  100             return ob1 == ob2
  101         no = []
  102         return getattr(ob1, name, no) == getattr(ob2, name, no) is not no
  103 
  104     def __iter__(self):
  105         return IterIter(self)
  106 
  107 class InnerBase:
  108     '''Base Inner class for Iterators'''
  109     # Prep sets up ._next and .end
  110     def prep_next(self, it):
  111         it.next = self.no_next
  112         it.end = 1
  113         return 0
  114 
  115     # Advance knocks them down
  116     def advance(self, it):
  117         it._last = it.item
  118         it.item = it._next
  119         del it._next
  120         del it.end
  121         it.start = 0
  122             
  123     def no_next(self, it):
  124         return 0
  125 
  126     def it_end(self, it):
  127         if hasattr(it, '_next'):
  128             return 0
  129         return not self.prep_next(it)
  130 
  131 class SeqInner(InnerBase):
  132     '''Inner class for sequence Iterators'''
  133 
  134     def _supports(self, ob):
  135         try: ob[0]
  136         except (TypeError, AttributeError): return 0
  137         except: pass
  138         return 1
  139 
  140     def prep_next(self, it):
  141         i = it.nextIndex
  142         try:
  143             it._next = it.seq[i]
  144         except IndexError:
  145             it._prep_next = self.no_next
  146             it.end = 1
  147             return 0
  148         it.end = 0
  149         return 1
  150 
  151     def it_length(self, it):
  152         it.length = l = len(it.seq)
  153         return l
  154 
  155 try:
  156     StopIteration=StopIteration
  157 except NameError:
  158     StopIteration="StopIteration"
  159 
  160 class IterInner(InnerBase):
  161     '''Iterator inner class for Python iterators'''
  162 
  163     def _supports(self, ob):
  164         try:
  165             if hasattr(ob, 'next') and (ob is iter(ob)):
  166                 return 1
  167         except:
  168             return 0
  169 
  170     def prep_next(self, it):
  171         try:
  172             it._next = next(it.seq)
  173         except StopIteration:
  174             it._prep_next = self.no_next
  175             it.end = 1
  176             return 0
  177         it.end = 0
  178         return 1
  179 
  180 class IterIter:
  181     def __init__(self, it):
  182         self.it = it
  183         self.skip = it.nextIndex > 0 and not it.end
  184     def __next__(self):
  185         it = self.it
  186         if self.skip:
  187             self.skip = 0
  188             return it.item
  189         if it.next():
  190             return it.item
  191         raise StopIteration
  192     # Python 2 compatibility:
  193     next = __next__
  194 
  195 seqInner = SeqInner()
  196 iterInner = IterInner()