Mercurial > p > roundup > code
annotate roundup/cgi/ZTUtils/Iterator.py @ 8543:1ffa1f42e1da
refactor: rework mime type comparison and clean code
rest.py:
accept application/* as match for application/json in non
/binary_context rest path.
allow defining default mime type to return when file/message is
missing mime type. Make it a class variable to it can be changed from
text/plain to text/markdown or whatever.
extract code from determine_output_format() to create
create_valid_content_types() method which returns a list of matching
mime types for a given type/subtype.
Eliminate mostly duplicate return statements by introducing a variable
to specify valid mime types in error message.
rest_common.py:
Fix error messages that now return application/* as valid mime type.
CHANGES.txt upgrading.txt rest.txt:
top level notes and corrections.
Also correct rst syntax on earlier change.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 24 Mar 2026 21:30:47 -0400 |
| parents | fed0f839c260 |
| children |
| rev | line source |
|---|---|
| 1049 | 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 | |
|
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 | 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): | |
|
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 | 36 |
| 37 def __getattr__(self, name): | |
| 38 try: | |
| 39 inner = getattr(self._inner, 'it_' + name) | |
| 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 | 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 | |
|
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): |
|
7866
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
88 return self.Roman().lower() |
| 1049 | 89 |
| 90 def first(self, name=None): | |
| 91 if self.start: return 1 | |
|
7866
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
92 return self.same_part(name, self._last, self.item) |
| 1049 | 93 |
| 94 def last(self, name=None): | |
| 95 if self.end: return 1 | |
|
7866
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
96 return self.same_part(name, self.item, self._next) |
| 1049 | 97 |
| 98 def same_part(self, name, ob1, ob2): | |
|
7866
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
99 """I have no idea what this does. |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
100 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
101 It returns True for first()/last() when there are more items |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
102 in the sequence. Called by first() to compare the previous |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
103 item in sequence and the current item. Caled by last() to |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
104 compare the current item and next item in sequence. |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
105 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
106 Accepts a string version of the name of an attribute as 'name'. |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
107 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
108 If no attribute name is provided, return True if the two items: |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
109 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
110 are equal (==) - duplicate strings/integer/same object |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
111 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
112 else False. |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
113 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
114 If a non-existent attribute name is provided return False. |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
115 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
116 If the attribute is present and the named attributes compare |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
117 equal (==) return True else False. |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
118 |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
119 No idea what use case this handles. Maybe this has |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
120 something to do with batching and first/last returning True |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
121 triggers a new group? |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
122 """ |
|
9bbc1d951677
issue2551331 - Fix repeat first/last methods.
John Rouillard <rouilj@ieee.org>
parents:
5419
diff
changeset
|
123 |
| 1049 | 124 if name is None: |
| 125 return ob1 == ob2 | |
| 126 no = [] | |
| 127 return getattr(ob1, name, no) == getattr(ob2, name, no) is not no | |
| 128 | |
| 129 def __iter__(self): | |
| 130 return IterIter(self) | |
| 131 | |
| 132 class InnerBase: | |
| 133 '''Base Inner class for Iterators''' | |
| 134 # Prep sets up ._next and .end | |
| 135 def prep_next(self, it): | |
| 136 it.next = self.no_next | |
| 137 it.end = 1 | |
| 138 return 0 | |
| 139 | |
| 140 # Advance knocks them down | |
| 141 def advance(self, it): | |
| 142 it._last = it.item | |
| 143 it.item = it._next | |
| 144 del it._next | |
| 145 del it.end | |
| 146 it.start = 0 | |
| 147 | |
| 148 def no_next(self, it): | |
| 149 return 0 | |
| 150 | |
| 151 def it_end(self, it): | |
| 152 if hasattr(it, '_next'): | |
| 153 return 0 | |
| 154 return not self.prep_next(it) | |
| 155 | |
| 156 class SeqInner(InnerBase): | |
| 157 '''Inner class for sequence Iterators''' | |
| 158 | |
| 159 def _supports(self, ob): | |
| 160 try: ob[0] | |
|
1233
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1049
diff
changeset
|
161 except (TypeError, AttributeError): return 0 |
| 1049 | 162 except: pass |
| 163 return 1 | |
| 164 | |
| 165 def prep_next(self, it): | |
| 166 i = it.nextIndex | |
| 167 try: | |
| 168 it._next = it.seq[i] | |
| 169 except IndexError: | |
| 170 it._prep_next = self.no_next | |
| 171 it.end = 1 | |
| 172 return 0 | |
| 173 it.end = 0 | |
| 174 return 1 | |
| 175 | |
| 176 def it_length(self, it): | |
| 177 it.length = l = len(it.seq) | |
| 178 return l | |
| 179 | |
| 180 try: | |
| 181 StopIteration=StopIteration | |
| 182 except NameError: | |
| 183 StopIteration="StopIteration" | |
| 184 | |
| 185 class IterInner(InnerBase): | |
| 186 '''Iterator inner class for Python iterators''' | |
| 187 | |
| 188 def _supports(self, ob): | |
| 189 try: | |
| 190 if hasattr(ob, 'next') and (ob is iter(ob)): | |
| 191 return 1 | |
|
8528
fed0f839c260
fix: replace except: with except Exception: (by haosenwang1018@github)
John Rouillard <rouilj@ieee.org>
parents:
7866
diff
changeset
|
192 except Exception: |
| 1049 | 193 return 0 |
| 194 | |
| 195 def prep_next(self, it): | |
| 196 try: | |
|
5396
831787cf6694
Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5378
diff
changeset
|
197 it._next = next(it.seq) |
| 1049 | 198 except StopIteration: |
| 199 it._prep_next = self.no_next | |
| 200 it.end = 1 | |
| 201 return 0 | |
| 202 it.end = 0 | |
| 203 return 1 | |
| 204 | |
| 205 class IterIter: | |
| 206 def __init__(self, it): | |
| 207 self.it = it | |
| 208 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
|
209 def __next__(self): |
| 1049 | 210 it = self.it |
| 211 if self.skip: | |
| 212 self.skip = 0 | |
| 213 return it.item | |
| 214 if it.next(): | |
| 215 return it.item | |
| 216 raise StopIteration | |
|
5396
831787cf6694
Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5378
diff
changeset
|
217 # Python 2 compatibility: |
|
831787cf6694
Python 3 preparation: update next() usage for iterators.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5378
diff
changeset
|
218 next = __next__ |
| 1049 | 219 |
| 220 seqInner = SeqInner() | |
| 221 iterInner = IterInner() |
