annotate roundup/cgi/ZTUtils/Iterator.py @ 5973:fe334430ca07

issue2550919 - Anti-bot signup using 4 second delay Took the code by erik forsberg and massaged it into the core. So this is no longer needed in the tracker. Updated devel and responsive trackers to remove timestamp.py and update input field name. Docs, changes and tests complete. Hopefully these tracker changes won't cause an issue for other tests.
author John Rouillard <rouilj@ieee.org>
date Sat, 09 Nov 2019 00:30:37 -0500
parents ef6631409171
children 9bbc1d951677
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
11 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
12 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 __doc__='''Iterator class
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
15 Unlike the builtin iterators of Python 2.2+, these classes are
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 designed to maintain information about the state of an iteration.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17 The Iterator() function accepts either a sequence or a Python
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 iterator. The next() method fetches the next item, and returns
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 true if it succeeds.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
4570
6e3e4f24c753 Remove keyword expansions from CVS. All regression tests passed afterwards.
Eric S. Raymond <esr@thyrsus.com>
parents: 3200
diff changeset
21 '''
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 1233
diff changeset
22 __docformat__ = 'restructuredtext'
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24 import string
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26 class Iterator:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 '''Simple Iterator class'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31 nextIndex = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 def __init__(self, seq):
3200
d2b1a946fdf4 change ZTUtils Iterator to always iter() its sequence argument
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
33 self.seq = iter(seq) # force seq to be an iterator
d2b1a946fdf4 change ZTUtils Iterator to always iter() its sequence argument
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
34 self._inner = iterInner
d2b1a946fdf4 change ZTUtils Iterator to always iter() its sequence argument
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
35 self._prep_next = iterInner.prep_next
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 def __getattr__(self, name):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 inner = getattr(self._inner, 'it_' + name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 except AttributeError:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 4570
diff changeset
41 raise AttributeError(name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 return inner(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 def next(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 if not (hasattr(self, '_next') or self._prep_next(self)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 self.index = i = self.nextIndex
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 self.nextIndex = i+1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 self._advance(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 def _advance(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 self.item = self._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 del self._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 del self.end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 self._advance = self._inner.advance
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 self.start = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 def number(self): return self.nextIndex
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 def even(self): return not self.index % 2
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 def odd(self): return self.index % 2
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65 def letter(self, base=ord('a'), radix=26):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 index = self.index
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 s = ''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 while 1:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 index, off = divmod(index, radix)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 s = chr(base + off) + s
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 if not index: return s
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 def Letter(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 return self.letter(base=ord('A'))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 def Roman(self, rnvalues=(
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 (1000,'M'),(900,'CM'),(500,'D'),(400,'CD'),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 (100,'C'),(90,'XC'),(50,'L'),(40,'XL'),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 (10,'X'),(9,'IX'),(5,'V'),(4,'IV'),(1,'I')) ):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 n = self.index + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 s = ''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 for v, r in rnvalues:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 rct, n = divmod(n, v)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 s = s + r * rct
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 return s
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86
5419
ef6631409171 Python 3 preparation: avoid string.lower.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5396
diff changeset
87 def roman(self, lower=lambda x:x.lower):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 return lower(self.Roman())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 def first(self, name=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 if self.start: return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 return not self.same_part(name, self._last, self.item)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 def last(self, name=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 if self.end: return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 return not self.same_part(name, self.item, self._next)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 def same_part(self, name, ob1, ob2):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 if name is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 return ob1 == ob2
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 no = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 return getattr(ob1, name, no) == getattr(ob2, name, no) is not no
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 def __iter__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 return IterIter(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 class InnerBase:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 '''Base Inner class for Iterators'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 # Prep sets up ._next and .end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 def prep_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 it.next = self.no_next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 it.end = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 # Advance knocks them down
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 def advance(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 it._last = it.item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 it.item = it._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 del it._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 del it.end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 it.start = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 def no_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 def it_end(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 if hasattr(it, '_next'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 return not self.prep_next(it)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 class SeqInner(InnerBase):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 '''Inner class for sequence Iterators'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 def _supports(self, ob):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 try: ob[0]
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
136 except (TypeError, AttributeError): return 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 except: pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 def prep_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 i = it.nextIndex
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 it._next = it.seq[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 except IndexError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 it._prep_next = self.no_next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146 it.end = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 it.end = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 def it_length(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 it.length = l = len(it.seq)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 return l
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 StopIteration=StopIteration
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 except NameError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 StopIteration="StopIteration"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 class IterInner(InnerBase):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 '''Iterator inner class for Python iterators'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 def _supports(self, ob):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 if hasattr(ob, 'next') and (ob is iter(ob)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 except:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 def prep_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 try:
5396
831787cf6694 Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
172 it._next = next(it.seq)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 except StopIteration:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 it._prep_next = self.no_next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 it.end = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 it.end = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 class IterIter:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 def __init__(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 self.it = it
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 self.skip = it.nextIndex > 0 and not it.end
5396
831787cf6694 Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
184 def __next__(self):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185 it = self.it
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 if self.skip:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 self.skip = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 return it.item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 if it.next():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 return it.item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 raise StopIteration
5396
831787cf6694 Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
192 # Python 2 compatibility:
831787cf6694 Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
193 next = __next__
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 seqInner = SeqInner()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 iterInner = IterInner()

Roundup Issue Tracker: http://roundup-tracker.org/