annotate roundup/cgi/ZTUtils/Iterator.py @ 3909:e89bcb28f683

indexargs_url force ids to int ids appear as hyperdb.String instances, which confused indexargs_url when they appear in the filterspec. They need to be treated as treated as integers when generating URLs. It feels sort of hacky to check for 'id' like this but I'm at a loss for what else to do in this case. Suggestions are welcome :) Maybe we should look into using some other hyperdb class to represent ids? this fixes [SF#783492] Some trailing whitespace also got trimmed.
author Justus Pendleton <jpend@users.sourceforge.net>
date Tue, 18 Sep 2007 16:59:42 +0000
parents d2b1a946fdf4
children 6e3e4f24c753
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
3200
d2b1a946fdf4 change ZTUtils Iterator to always iter() its sequence argument
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
21 $Id: Iterator.py,v 1.4 2005-02-16 22:07:33 richard Exp $'''
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 1233
diff changeset
22 __docformat__ = 'restructuredtext'
3200
d2b1a946fdf4 change ZTUtils Iterator to always iter() its sequence argument
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
23 __version__='$Revision: 1.4 $'[11:-2]
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25 import string
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 class Iterator:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 '''Simple Iterator class'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 nextIndex = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 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
34 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
35 self._inner = iterInner
d2b1a946fdf4 change ZTUtils Iterator to always iter() its sequence argument
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
36 self._prep_next = iterInner.prep_next
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 def __getattr__(self, name):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 inner = getattr(self._inner, 'it_' + name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 except AttributeError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 raise AttributeError, name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 return inner(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 def next(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 if not (hasattr(self, '_next') or self._prep_next(self)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 self.index = i = self.nextIndex
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 self.nextIndex = i+1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 self._advance(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 def _advance(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 self.item = self._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 del self._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 del self.end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 self._advance = self._inner.advance
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 self.start = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60 def number(self): return self.nextIndex
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62 def even(self): return not self.index % 2
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 def odd(self): return self.index % 2
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 def letter(self, base=ord('a'), radix=26):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 index = self.index
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 s = ''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 while 1:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 index, off = divmod(index, radix)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 s = chr(base + off) + s
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 if not index: return s
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 def Letter(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 return self.letter(base=ord('A'))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 def Roman(self, rnvalues=(
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 (1000,'M'),(900,'CM'),(500,'D'),(400,'CD'),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 (100,'C'),(90,'XC'),(50,'L'),(40,'XL'),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 (10,'X'),(9,'IX'),(5,'V'),(4,'IV'),(1,'I')) ):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 n = self.index + 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 s = ''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 for v, r in rnvalues:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 rct, n = divmod(n, v)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 s = s + r * rct
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 return s
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 def roman(self, lower=string.lower):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 return lower(self.Roman())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 def first(self, name=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 if self.start: return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 return not self.same_part(name, self._last, self.item)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 def last(self, name=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 if self.end: return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 return not self.same_part(name, self.item, self._next)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 def same_part(self, name, ob1, ob2):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 if name is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 return ob1 == ob2
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 no = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 return getattr(ob1, name, no) == getattr(ob2, name, no) is not no
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 def __iter__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 return IterIter(self)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 class InnerBase:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 '''Base Inner class for Iterators'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 # Prep sets up ._next and .end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 def prep_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 it.next = self.no_next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 it.end = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 # Advance knocks them down
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 def advance(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 it._last = it.item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 it.item = it._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 del it._next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 del it.end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 it.start = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 def no_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 def it_end(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 if hasattr(it, '_next'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 return not self.prep_next(it)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 class SeqInner(InnerBase):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 '''Inner class for sequence Iterators'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 def _supports(self, ob):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 try: ob[0]
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
137 except (TypeError, AttributeError): return 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 except: pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 def prep_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 i = it.nextIndex
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 it._next = it.seq[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 except IndexError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146 it._prep_next = self.no_next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 it.end = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 it.end = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 def it_length(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 it.length = l = len(it.seq)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 return l
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 StopIteration=StopIteration
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 except NameError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159 StopIteration="StopIteration"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 class IterInner(InnerBase):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 '''Iterator inner class for Python iterators'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 def _supports(self, ob):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 if hasattr(ob, 'next') and (ob is iter(ob)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 except:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 def prep_next(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 it._next = it.seq.next()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 except StopIteration:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 it._prep_next = self.no_next
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 it.end = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 it.end = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 class IterIter:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 def __init__(self, it):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 self.it = it
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
184 self.skip = it.nextIndex > 0 and not it.end
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185 def next(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 it = self.it
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 if self.skip:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 self.skip = 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 return it.item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 if it.next():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 return it.item
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 raise StopIteration
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 seqInner = SeqInner()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 iterInner = IterInner()

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