Mercurial > p > roundup > code
annotate roundup/cgi/TAL/TALInterpreter.py @ 5253:2d61e39b89c8
Issue2550716 Email address displayed after password reset request (fix)
Change the message displayed upon password reset using an account name
to no longer expose the email address. Password reset triggered using
an email address will still display the user supplied email address.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 26 Aug 2017 20:27:08 -0400 |
| parents | 8c2402a78bb0 |
| children | 12fe83f90f0d |
| rev | line source |
|---|---|
| 1049 | 1 ############################################################################## |
| 2 # | |
| 3 # Copyright (c) 2001, 2002 Zope Corporation and Contributors. | |
| 4 # All Rights Reserved. | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
5 # |
| 1049 | 6 # This software is subject to the provisions of the Zope Public License, |
| 7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. | |
| 8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | |
| 9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
11 # FOR A PARTICULAR PURPOSE. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
12 # |
| 1049 | 13 ############################################################################## |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
14 # Modifications for Roundup: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
15 # 1. implemented ustr as str |
| 1049 | 16 """ |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
17 Interpreter for a pre-compiled TAL program. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
18 """ |
| 1049 | 19 |
| 20 import sys | |
| 21 import getopt | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
22 import re |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
23 from types import ListType |
| 1049 | 24 from cgi import escape |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
25 # Do not use cStringIO here! It's not unicode aware. :( |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
26 from StringIO import StringIO |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
27 #from DocumentTemplate.DT_Util import ustr |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
28 ustr = str |
| 1049 | 29 |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
30 from TALDefs import TAL_VERSION, TALError, METALError, attrEscape |
| 1049 | 31 from TALDefs import isCurrentVersion, getProgramVersion, getProgramMode |
| 32 from TALGenerator import TALGenerator | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
33 from TranslationContext import TranslationContext |
| 1049 | 34 |
| 35 BOOLEAN_HTML_ATTRS = [ | |
| 36 # List of Boolean attributes in HTML that should be rendered in | |
| 37 # minimized form (e.g. <img ismap> rather than <img ismap="">) | |
| 38 # From http://www.w3.org/TR/xhtml1/#guidelines (C.10) | |
| 39 # XXX The problem with this is that this is not valid XML and | |
| 40 # can't be parsed back! | |
| 41 "compact", "nowrap", "ismap", "declare", "noshade", "checked", | |
| 42 "disabled", "readonly", "multiple", "selected", "noresize", | |
| 43 "defer" | |
| 44 ] | |
| 45 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
46 def normalize(text): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
47 # Now we need to normalize the whitespace in implicit message ids and |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
48 # implicit $name substitution values by stripping leading and trailing |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
49 # whitespace, and folding all internal whitespace to a single space. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
50 return ' '.join(text.split()) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
51 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
52 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
53 NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*" |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
54 _interp_regex = re.compile(r'(?<!\$)(\$(?:%(n)s|{%(n)s}))' %({'n': NAME_RE})) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
55 _get_var_regex = re.compile(r'%(n)s' %({'n': NAME_RE})) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
56 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
57 def interpolate(text, mapping): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
58 """Interpolate ${keyword} substitutions. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
59 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
60 This is called when no translation is provided by the translation |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
61 service. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
62 """ |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
63 if not mapping: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
64 return text |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
65 # Find all the spots we want to substitute. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
66 to_replace = _interp_regex.findall(text) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
67 # Now substitute with the variables in mapping. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
68 for string in to_replace: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
69 var = _get_var_regex.findall(string)[0] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
70 if mapping.has_key(var): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
71 # Call ustr because we may have an integer for instance. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
72 subst = ustr(mapping[var]) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
73 try: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
74 text = text.replace(string, subst) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
75 except UnicodeError: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
76 # subst contains high-bit chars... |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
77 # As we have no way of knowing the correct encoding, |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
78 # substitue something instead of raising an exception. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
79 subst = `subst`[1:-1] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
80 text = text.replace(string, subst) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
81 return text |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
82 |
| 1049 | 83 |
| 84 class AltTALGenerator(TALGenerator): | |
| 85 | |
| 86 def __init__(self, repldict, expressionCompiler=None, xml=0): | |
| 87 self.repldict = repldict | |
| 88 self.enabled = 1 | |
| 89 TALGenerator.__init__(self, expressionCompiler, xml) | |
| 90 | |
| 91 def enable(self, enabled): | |
| 92 self.enabled = enabled | |
| 93 | |
| 94 def emit(self, *args): | |
| 95 if self.enabled: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
96 TALGenerator.emit(self, *args) |
| 1049 | 97 |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
98 def emitStartElement(self, name, attrlist, taldict, metaldict, i18ndict, |
| 1049 | 99 position=(None, None), isend=0): |
| 100 metaldict = {} | |
| 101 taldict = {} | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
102 i18ndict = {} |
| 1049 | 103 if self.enabled and self.repldict: |
| 104 taldict["attributes"] = "x x" | |
| 105 TALGenerator.emitStartElement(self, name, attrlist, | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
106 taldict, metaldict, i18ndict, |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
107 position, isend) |
| 1049 | 108 |
| 109 def replaceAttrs(self, attrlist, repldict): | |
| 110 if self.enabled and self.repldict: | |
| 111 repldict = self.repldict | |
| 112 self.repldict = None | |
| 113 return TALGenerator.replaceAttrs(self, attrlist, repldict) | |
| 114 | |
| 115 | |
| 116 class TALInterpreter: | |
| 117 | |
| 118 def __init__(self, program, macros, engine, stream=None, | |
| 119 debug=0, wrap=60, metal=1, tal=1, showtal=-1, | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
120 strictinsert=1, stackLimit=100, i18nInterpolate=1): |
| 1049 | 121 self.program = program |
| 122 self.macros = macros | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
123 self.engine = engine # Execution engine (aka context) |
| 1049 | 124 self.Default = engine.getDefault() |
| 125 self.stream = stream or sys.stdout | |
| 126 self._stream_write = self.stream.write | |
| 127 self.debug = debug | |
| 128 self.wrap = wrap | |
| 129 self.metal = metal | |
| 130 self.tal = tal | |
| 131 if tal: | |
| 132 self.dispatch = self.bytecode_handlers_tal | |
| 133 else: | |
| 134 self.dispatch = self.bytecode_handlers | |
| 135 assert showtal in (-1, 0, 1) | |
| 136 if showtal == -1: | |
| 137 showtal = (not tal) | |
| 138 self.showtal = showtal | |
| 139 self.strictinsert = strictinsert | |
| 140 self.stackLimit = stackLimit | |
| 141 self.html = 0 | |
| 142 self.endsep = "/>" | |
| 143 self.endlen = len(self.endsep) | |
| 144 self.macroStack = [] | |
| 145 self.position = None, None # (lineno, offset) | |
| 146 self.col = 0 | |
| 147 self.level = 0 | |
| 148 self.scopeLevel = 0 | |
| 149 self.sourceFile = None | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
150 self.i18nStack = [] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
151 self.i18nInterpolate = i18nInterpolate |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
152 self.i18nContext = TranslationContext() |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
153 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
154 def StringIO(self): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
155 # Third-party products wishing to provide a full Unicode-aware |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
156 # StringIO can do so by monkey-patching this method. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
157 return FasterStringIO() |
| 1049 | 158 |
| 159 def saveState(self): | |
| 160 return (self.position, self.col, self.stream, | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
161 self.scopeLevel, self.level, self.i18nContext) |
| 1049 | 162 |
| 163 def restoreState(self, state): | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
164 (self.position, self.col, self.stream, scopeLevel, level, i18n) = state |
| 1049 | 165 self._stream_write = self.stream.write |
| 166 assert self.level == level | |
| 167 while self.scopeLevel > scopeLevel: | |
| 168 self.engine.endScope() | |
| 169 self.scopeLevel = self.scopeLevel - 1 | |
| 170 self.engine.setPosition(self.position) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
171 self.i18nContext = i18n |
| 1049 | 172 |
| 173 def restoreOutputState(self, state): | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
174 (dummy, self.col, self.stream, scopeLevel, level, i18n) = state |
| 1049 | 175 self._stream_write = self.stream.write |
| 176 assert self.level == level | |
| 177 assert self.scopeLevel == scopeLevel | |
| 178 | |
| 179 def pushMacro(self, macroName, slots, entering=1): | |
| 180 if len(self.macroStack) >= self.stackLimit: | |
| 181 raise METALError("macro nesting limit (%d) exceeded " | |
| 182 "by %s" % (self.stackLimit, `macroName`)) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
183 self.macroStack.append([macroName, slots, entering, self.i18nContext]) |
| 1049 | 184 |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
185 def popMacro(self): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
186 return self.macroStack.pop() |
| 1049 | 187 |
| 188 def __call__(self): | |
| 189 assert self.level == 0 | |
| 190 assert self.scopeLevel == 0 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
191 assert self.i18nContext.parent is None |
| 1049 | 192 self.interpret(self.program) |
| 193 assert self.level == 0 | |
| 194 assert self.scopeLevel == 0 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
195 assert self.i18nContext.parent is None |
| 1049 | 196 if self.col > 0: |
| 197 self._stream_write("\n") | |
| 198 self.col = 0 | |
| 199 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
200 def stream_write(self, s, |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
201 len=len): |
| 1049 | 202 self._stream_write(s) |
|
1309
309f125f86cc
removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents:
1049
diff
changeset
|
203 i = s.rfind('\n') |
| 1049 | 204 if i < 0: |
| 205 self.col = self.col + len(s) | |
| 206 else: | |
| 207 self.col = len(s) - (i + 1) | |
| 208 | |
| 209 bytecode_handlers = {} | |
| 210 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
211 def interpretWithStream(self, program, stream): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
212 oldstream = self.stream |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
213 self.stream = stream |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
214 self._stream_write = stream.write |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
215 try: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
216 self.interpret(program) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
217 finally: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
218 self.stream = oldstream |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
219 self._stream_write = oldstream.write |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
220 |
|
1409
8dc60d87ab42
Fixed a backlog of bug reports, and worked on python 2.3 compatibility:
Richard Jones <richard@users.sourceforge.net>
parents:
1309
diff
changeset
|
221 def interpret(self, program): |
| 1049 | 222 oldlevel = self.level |
| 223 self.level = oldlevel + 1 | |
| 224 handlers = self.dispatch | |
| 225 try: | |
| 226 if self.debug: | |
| 227 for (opcode, args) in program: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
228 s = "%sdo_%s(%s)\n" % (" "*self.level, opcode, |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
229 repr(args)) |
| 1049 | 230 if len(s) > 80: |
| 231 s = s[:76] + "...\n" | |
| 232 sys.stderr.write(s) | |
| 233 handlers[opcode](self, args) | |
| 234 else: | |
| 235 for (opcode, args) in program: | |
| 236 handlers[opcode](self, args) | |
| 237 finally: | |
| 238 self.level = oldlevel | |
| 239 | |
| 240 def do_version(self, version): | |
| 241 assert version == TAL_VERSION | |
| 242 bytecode_handlers["version"] = do_version | |
| 243 | |
| 244 def do_mode(self, mode): | |
| 245 assert mode in ("html", "xml") | |
| 246 self.html = (mode == "html") | |
| 247 if self.html: | |
| 248 self.endsep = " />" | |
| 249 else: | |
| 250 self.endsep = "/>" | |
| 251 self.endlen = len(self.endsep) | |
| 252 bytecode_handlers["mode"] = do_mode | |
| 253 | |
| 254 def do_setSourceFile(self, source_file): | |
| 255 self.sourceFile = source_file | |
| 256 self.engine.setSourceFile(source_file) | |
| 257 bytecode_handlers["setSourceFile"] = do_setSourceFile | |
| 258 | |
| 259 def do_setPosition(self, position): | |
| 260 self.position = position | |
| 261 self.engine.setPosition(position) | |
| 262 bytecode_handlers["setPosition"] = do_setPosition | |
| 263 | |
| 264 def do_startEndTag(self, stuff): | |
| 265 self.do_startTag(stuff, self.endsep, self.endlen) | |
| 266 bytecode_handlers["startEndTag"] = do_startEndTag | |
| 267 | |
| 268 def do_startTag(self, (name, attrList), | |
| 269 end=">", endlen=1, _len=len): | |
| 270 # The bytecode generator does not cause calls to this method | |
| 271 # for start tags with no attributes; those are optimized down | |
| 272 # to rawtext events. Hence, there is no special "fast path" | |
| 273 # for that case. | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
274 L = ["<", name] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
275 append = L.append |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
276 col = self.col + _len(name) + 1 |
| 1049 | 277 wrap = self.wrap |
| 278 align = col + 1 | |
| 279 if align >= wrap/2: | |
| 280 align = 4 # Avoid a narrow column far to the right | |
| 281 attrAction = self.dispatch["<attrAction>"] | |
| 282 try: | |
| 283 for item in attrList: | |
| 284 if _len(item) == 2: | |
| 285 name, s = item | |
| 286 else: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
287 # item[2] is the 'action' field: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
288 if item[2] in ('metal', 'tal', 'xmlns', 'i18n'): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
289 if not self.showtal: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
290 continue |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
291 ok, name, s = self.attrAction(item) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
292 else: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
293 ok, name, s = attrAction(self, item) |
| 1049 | 294 if not ok: |
| 295 continue | |
| 296 slen = _len(s) | |
| 297 if (wrap and | |
| 298 col >= align and | |
| 299 col + 1 + slen > wrap): | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
300 append("\n") |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
301 append(" "*align) |
| 1049 | 302 col = align + slen |
| 303 else: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
304 append(" ") |
| 1049 | 305 col = col + 1 + slen |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
306 append(s) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
307 append(end) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
308 self._stream_write("".join(L)) |
| 1049 | 309 col = col + endlen |
| 310 finally: | |
| 311 self.col = col | |
| 312 bytecode_handlers["startTag"] = do_startTag | |
| 313 | |
| 314 def attrAction(self, item): | |
| 315 name, value, action = item[:3] | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
316 if action == 'insert': |
| 1049 | 317 return 0, name, value |
| 318 macs = self.macroStack | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
319 if action == 'metal' and self.metal and macs: |
| 1049 | 320 if len(macs) > 1 or not macs[-1][2]: |
| 321 # Drop all METAL attributes at a use-depth above one. | |
| 322 return 0, name, value | |
| 323 # Clear 'entering' flag | |
| 324 macs[-1][2] = 0 | |
| 325 # Convert or drop depth-one METAL attributes. | |
|
1309
309f125f86cc
removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents:
1049
diff
changeset
|
326 i = name.rfind(":") + 1 |
| 1049 | 327 prefix, suffix = name[:i], name[i:] |
| 328 if suffix == "define-macro": | |
| 329 # Convert define-macro as we enter depth one. | |
| 330 name = prefix + "use-macro" | |
| 331 value = macs[-1][0] # Macro name | |
| 332 elif suffix == "define-slot": | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
333 name = prefix + "fill-slot" |
| 1049 | 334 elif suffix == "fill-slot": |
| 335 pass | |
| 336 else: | |
| 337 return 0, name, value | |
| 338 | |
| 339 if value is None: | |
| 340 value = name | |
| 341 else: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
342 value = '%s="%s"' % (name, attrEscape(value)) |
| 1049 | 343 return 1, name, value |
| 344 | |
| 345 def attrAction_tal(self, item): | |
| 346 name, value, action = item[:3] | |
| 347 ok = 1 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
348 expr, xlat, msgid = item[3:] |
|
1309
309f125f86cc
removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents:
1049
diff
changeset
|
349 if self.html and name.lower() in BOOLEAN_HTML_ATTRS: |
| 1049 | 350 evalue = self.engine.evaluateBoolean(item[3]) |
| 351 if evalue is self.Default: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
352 if action == 'insert': # Cancelled insert |
| 1049 | 353 ok = 0 |
| 354 elif evalue: | |
| 355 value = None | |
| 356 else: | |
| 357 ok = 0 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
358 elif expr is not None: |
| 1049 | 359 evalue = self.engine.evaluateText(item[3]) |
| 360 if evalue is self.Default: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
361 if action == 'insert': # Cancelled insert |
| 1049 | 362 ok = 0 |
| 363 else: | |
| 364 if evalue is None: | |
| 365 ok = 0 | |
| 366 value = evalue | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
367 else: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
368 evalue = None |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
369 |
| 1049 | 370 if ok: |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
371 if xlat: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
372 translated = self.translate(msgid or value, value, {}) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
373 if translated is not None: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
374 value = translated |
| 1049 | 375 if value is None: |
| 376 value = name | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
377 elif evalue is self.Default: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
378 value = attrEscape(value) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
379 else: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
380 value = escape(value, quote=1) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
381 value = '%s="%s"' % (name, value) |
| 1049 | 382 return ok, name, value |
| 383 bytecode_handlers["<attrAction>"] = attrAction | |
| 384 | |
| 385 def no_tag(self, start, program): | |
| 386 state = self.saveState() | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
387 self.stream = stream = self.StringIO() |
| 1049 | 388 self._stream_write = stream.write |
| 389 self.interpret(start) | |
| 390 self.restoreOutputState(state) | |
| 391 self.interpret(program) | |
| 392 | |
| 393 def do_optTag(self, (name, cexpr, tag_ns, isend, start, program), | |
| 394 omit=0): | |
| 395 if tag_ns and not self.showtal: | |
| 396 return self.no_tag(start, program) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
397 |
| 1049 | 398 self.interpret(start) |
| 399 if not isend: | |
| 400 self.interpret(program) | |
| 401 s = '</%s>' % name | |
| 402 self._stream_write(s) | |
| 403 self.col = self.col + len(s) | |
| 404 | |
| 405 def do_optTag_tal(self, stuff): | |
| 406 cexpr = stuff[1] | |
| 407 if cexpr is not None and (cexpr == '' or | |
| 408 self.engine.evaluateBoolean(cexpr)): | |
| 409 self.no_tag(stuff[-2], stuff[-1]) | |
| 410 else: | |
| 411 self.do_optTag(stuff) | |
| 412 bytecode_handlers["optTag"] = do_optTag | |
| 413 | |
| 414 def do_rawtextBeginScope(self, (s, col, position, closeprev, dict)): | |
| 415 self._stream_write(s) | |
| 416 self.col = col | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
417 self.position = position |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
418 self.engine.setPosition(position) |
| 1049 | 419 if closeprev: |
| 420 engine = self.engine | |
| 421 engine.endScope() | |
| 422 engine.beginScope() | |
| 423 else: | |
| 424 self.engine.beginScope() | |
| 425 self.scopeLevel = self.scopeLevel + 1 | |
| 426 | |
| 427 def do_rawtextBeginScope_tal(self, (s, col, position, closeprev, dict)): | |
| 428 self._stream_write(s) | |
| 429 self.col = col | |
| 430 engine = self.engine | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
431 self.position = position |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
432 engine.setPosition(position) |
| 1049 | 433 if closeprev: |
| 434 engine.endScope() | |
| 435 engine.beginScope() | |
| 436 else: | |
| 437 engine.beginScope() | |
| 438 self.scopeLevel = self.scopeLevel + 1 | |
| 439 engine.setLocal("attrs", dict) | |
| 440 bytecode_handlers["rawtextBeginScope"] = do_rawtextBeginScope | |
| 441 | |
| 442 def do_beginScope(self, dict): | |
| 443 self.engine.beginScope() | |
| 444 self.scopeLevel = self.scopeLevel + 1 | |
| 445 | |
| 446 def do_beginScope_tal(self, dict): | |
| 447 engine = self.engine | |
| 448 engine.beginScope() | |
| 449 engine.setLocal("attrs", dict) | |
| 450 self.scopeLevel = self.scopeLevel + 1 | |
| 451 bytecode_handlers["beginScope"] = do_beginScope | |
| 452 | |
| 453 def do_endScope(self, notused=None): | |
| 454 self.engine.endScope() | |
| 455 self.scopeLevel = self.scopeLevel - 1 | |
| 456 bytecode_handlers["endScope"] = do_endScope | |
| 457 | |
| 458 def do_setLocal(self, notused): | |
| 459 pass | |
| 460 | |
| 461 def do_setLocal_tal(self, (name, expr)): | |
| 462 self.engine.setLocal(name, self.engine.evaluateValue(expr)) | |
| 463 bytecode_handlers["setLocal"] = do_setLocal | |
| 464 | |
| 465 def do_setGlobal_tal(self, (name, expr)): | |
| 466 self.engine.setGlobal(name, self.engine.evaluateValue(expr)) | |
| 467 bytecode_handlers["setGlobal"] = do_setLocal | |
| 468 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
469 def do_beginI18nContext(self, settings): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
470 get = settings.get |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
471 self.i18nContext = TranslationContext(self.i18nContext, |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
472 domain=get("domain"), |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
473 source=get("source"), |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
474 target=get("target")) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
475 bytecode_handlers["beginI18nContext"] = do_beginI18nContext |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
476 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
477 def do_endI18nContext(self, notused=None): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
478 self.i18nContext = self.i18nContext.parent |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
479 assert self.i18nContext is not None |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
480 bytecode_handlers["endI18nContext"] = do_endI18nContext |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
481 |
| 1049 | 482 def do_insertText(self, stuff): |
| 483 self.interpret(stuff[1]) | |
| 484 | |
| 485 def do_insertText_tal(self, stuff): | |
| 486 text = self.engine.evaluateText(stuff[0]) | |
| 487 if text is None: | |
| 488 return | |
| 489 if text is self.Default: | |
| 490 self.interpret(stuff[1]) | |
| 491 return | |
| 492 s = escape(text) | |
| 493 self._stream_write(s) | |
|
1309
309f125f86cc
removed use of string/strop from TAL/TALInterpreter
Richard Jones <richard@users.sourceforge.net>
parents:
1049
diff
changeset
|
494 i = s.rfind('\n') |
| 1049 | 495 if i < 0: |
| 496 self.col = self.col + len(s) | |
| 497 else: | |
| 498 self.col = len(s) - (i + 1) | |
| 499 bytecode_handlers["insertText"] = do_insertText | |
| 500 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
501 def do_i18nVariable(self, stuff): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
502 varname, program, expression = stuff |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
503 if expression is None: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
504 # The value is implicitly the contents of this tag, so we have to |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
505 # evaluate the mini-program to get the value of the variable. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
506 state = self.saveState() |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
507 try: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
508 tmpstream = self.StringIO() |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
509 self.interpretWithStream(program, tmpstream) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
510 value = normalize(tmpstream.getvalue()) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
511 finally: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
512 self.restoreState(state) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
513 else: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
514 # Evaluate the value to be associated with the variable in the |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
515 # i18n interpolation dictionary. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
516 value = self.engine.evaluate(expression) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
517 # Either the i18n:name tag is nested inside an i18n:translate in which |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
518 # case the last item on the stack has the i18n dictionary and string |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
519 # representation, or the i18n:name and i18n:translate attributes are |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
520 # in the same tag, in which case the i18nStack will be empty. In that |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
521 # case we can just output the ${name} to the stream |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
522 i18ndict, srepr = self.i18nStack[-1] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
523 i18ndict[varname] = value |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
524 placeholder = '${%s}' % varname |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
525 srepr.append(placeholder) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
526 self._stream_write(placeholder) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
527 bytecode_handlers['i18nVariable'] = do_i18nVariable |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
528 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
529 def do_insertTranslation(self, stuff): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
530 i18ndict = {} |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
531 srepr = [] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
532 obj = None |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
533 self.i18nStack.append((i18ndict, srepr)) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
534 msgid = stuff[0] |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
535 # We need to evaluate the content of the tag because that will give us |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
536 # several useful pieces of information. First, the contents will |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
537 # include an implicit message id, if no explicit one was given. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
538 # Second, it will evaluate any i18nVariable definitions in the body of |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
539 # the translation (necessary for $varname substitutions). |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
540 # |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
541 # Use a temporary stream to capture the interpretation of the |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
542 # subnodes, which should /not/ go to the output stream. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
543 tmpstream = self.StringIO() |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
544 self.interpretWithStream(stuff[1], tmpstream) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
545 default = tmpstream.getvalue() |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
546 # We only care about the evaluated contents if we need an implicit |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
547 # message id. All other useful information will be in the i18ndict on |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
548 # the top of the i18nStack. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
549 if msgid == '': |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
550 msgid = normalize(default) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
551 self.i18nStack.pop() |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
552 # See if there is was an i18n:data for msgid |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
553 if len(stuff) > 2: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
554 obj = self.engine.evaluate(stuff[2]) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
555 xlated_msgid = self.translate(msgid, default, i18ndict, obj) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
556 assert xlated_msgid is not None, self.position |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
557 self._stream_write(xlated_msgid) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
558 bytecode_handlers['insertTranslation'] = do_insertTranslation |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
559 |
| 1049 | 560 def do_insertStructure(self, stuff): |
| 561 self.interpret(stuff[2]) | |
| 562 | |
| 563 def do_insertStructure_tal(self, (expr, repldict, block)): | |
| 564 structure = self.engine.evaluateStructure(expr) | |
| 565 if structure is None: | |
| 566 return | |
| 567 if structure is self.Default: | |
| 568 self.interpret(block) | |
| 569 return | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
570 text = ustr(structure) |
| 1049 | 571 if not (repldict or self.strictinsert): |
| 572 # Take a shortcut, no error checking | |
| 573 self.stream_write(text) | |
| 574 return | |
| 575 if self.html: | |
| 576 self.insertHTMLStructure(text, repldict) | |
| 577 else: | |
| 578 self.insertXMLStructure(text, repldict) | |
| 579 bytecode_handlers["insertStructure"] = do_insertStructure | |
| 580 | |
| 581 def insertHTMLStructure(self, text, repldict): | |
| 582 from HTMLTALParser import HTMLTALParser | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
583 gen = AltTALGenerator(repldict, self.engine.getCompiler(), 0) |
| 1049 | 584 p = HTMLTALParser(gen) # Raises an exception if text is invalid |
| 585 p.parseString(text) | |
| 586 program, macros = p.getCode() | |
| 587 self.interpret(program) | |
| 588 | |
| 589 def insertXMLStructure(self, text, repldict): | |
| 590 from TALParser import TALParser | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
591 gen = AltTALGenerator(repldict, self.engine.getCompiler(), 0) |
| 1049 | 592 p = TALParser(gen) |
| 593 gen.enable(0) | |
| 594 p.parseFragment('<!DOCTYPE foo PUBLIC "foo" "bar"><foo>') | |
| 595 gen.enable(1) | |
| 596 p.parseFragment(text) # Raises an exception if text is invalid | |
| 597 gen.enable(0) | |
| 598 p.parseFragment('</foo>', 1) | |
| 599 program, macros = gen.getCode() | |
| 600 self.interpret(program) | |
| 601 | |
| 602 def do_loop(self, (name, expr, block)): | |
| 603 self.interpret(block) | |
| 604 | |
| 605 def do_loop_tal(self, (name, expr, block)): | |
| 606 iterator = self.engine.setRepeat(name, expr) | |
| 607 while iterator.next(): | |
| 608 self.interpret(block) | |
| 609 bytecode_handlers["loop"] = do_loop | |
| 610 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
611 def translate(self, msgid, default, i18ndict, obj=None): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
612 if obj: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
613 i18ndict.update(obj) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
614 if not self.i18nInterpolate: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
615 return msgid |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
616 # XXX We need to pass in one of context or target_language |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
617 return self.engine.translate(self.i18nContext.domain, |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
618 msgid, i18ndict, default=default) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
619 |
| 1049 | 620 def do_rawtextColumn(self, (s, col)): |
| 621 self._stream_write(s) | |
| 622 self.col = col | |
| 623 bytecode_handlers["rawtextColumn"] = do_rawtextColumn | |
| 624 | |
| 625 def do_rawtextOffset(self, (s, offset)): | |
| 626 self._stream_write(s) | |
| 627 self.col = self.col + offset | |
| 628 bytecode_handlers["rawtextOffset"] = do_rawtextOffset | |
| 629 | |
| 630 def do_condition(self, (condition, block)): | |
| 631 if not self.tal or self.engine.evaluateBoolean(condition): | |
| 632 self.interpret(block) | |
| 633 bytecode_handlers["condition"] = do_condition | |
| 634 | |
| 635 def do_defineMacro(self, (macroName, macro)): | |
| 636 macs = self.macroStack | |
| 637 if len(macs) == 1: | |
| 638 entering = macs[-1][2] | |
| 639 if not entering: | |
| 640 macs.append(None) | |
| 641 self.interpret(macro) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
642 assert macs[-1] is None |
| 1049 | 643 macs.pop() |
| 644 return | |
| 645 self.interpret(macro) | |
| 646 bytecode_handlers["defineMacro"] = do_defineMacro | |
| 647 | |
| 648 def do_useMacro(self, (macroName, macroExpr, compiledSlots, block)): | |
| 649 if not self.metal: | |
| 650 self.interpret(block) | |
| 651 return | |
| 652 macro = self.engine.evaluateMacro(macroExpr) | |
| 653 if macro is self.Default: | |
| 654 macro = block | |
| 655 else: | |
| 656 if not isCurrentVersion(macro): | |
| 657 raise METALError("macro %s has incompatible version %s" % | |
| 658 (`macroName`, `getProgramVersion(macro)`), | |
| 659 self.position) | |
| 660 mode = getProgramMode(macro) | |
| 661 if mode != (self.html and "html" or "xml"): | |
| 662 raise METALError("macro %s has incompatible mode %s" % | |
| 663 (`macroName`, `mode`), self.position) | |
| 664 self.pushMacro(macroName, compiledSlots) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
665 prev_source = self.sourceFile |
| 1049 | 666 self.interpret(macro) |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
667 if self.sourceFile != prev_source: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
668 self.engine.setSourceFile(prev_source) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
669 self.sourceFile = prev_source |
| 1049 | 670 self.popMacro() |
| 671 bytecode_handlers["useMacro"] = do_useMacro | |
| 672 | |
| 673 def do_fillSlot(self, (slotName, block)): | |
| 674 # This is only executed if the enclosing 'use-macro' evaluates | |
| 675 # to 'default'. | |
| 676 self.interpret(block) | |
| 677 bytecode_handlers["fillSlot"] = do_fillSlot | |
| 678 | |
| 679 def do_defineSlot(self, (slotName, block)): | |
| 680 if not self.metal: | |
| 681 self.interpret(block) | |
| 682 return | |
| 683 macs = self.macroStack | |
| 684 if macs and macs[-1] is not None: | |
| 685 macroName, slots = self.popMacro()[:2] | |
| 686 slot = slots.get(slotName) | |
| 687 if slot is not None: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
688 prev_source = self.sourceFile |
| 1049 | 689 self.interpret(slot) |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
690 if self.sourceFile != prev_source: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
691 self.engine.setSourceFile(prev_source) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
692 self.sourceFile = prev_source |
| 1049 | 693 self.pushMacro(macroName, slots, entering=0) |
| 694 return | |
| 695 self.pushMacro(macroName, slots) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
696 # Falling out of the 'if' allows the macro to be interpreted. |
| 1049 | 697 self.interpret(block) |
| 698 bytecode_handlers["defineSlot"] = do_defineSlot | |
| 699 | |
| 700 def do_onError(self, (block, handler)): | |
| 701 self.interpret(block) | |
| 702 | |
| 703 def do_onError_tal(self, (block, handler)): | |
| 704 state = self.saveState() | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
705 self.stream = stream = self.StringIO() |
| 1049 | 706 self._stream_write = stream.write |
| 707 try: | |
| 708 self.interpret(block) | |
| 709 except: | |
| 710 exc = sys.exc_info()[1] | |
| 711 self.restoreState(state) | |
| 712 engine = self.engine | |
| 713 engine.beginScope() | |
| 714 error = engine.createErrorInfo(exc, self.position) | |
| 715 engine.setLocal('error', error) | |
| 716 try: | |
| 717 self.interpret(handler) | |
| 718 finally: | |
| 719 engine.endScope() | |
| 720 else: | |
| 721 self.restoreOutputState(state) | |
| 722 self.stream_write(stream.getvalue()) | |
| 723 bytecode_handlers["onError"] = do_onError | |
| 724 | |
| 725 bytecode_handlers_tal = bytecode_handlers.copy() | |
| 726 bytecode_handlers_tal["rawtextBeginScope"] = do_rawtextBeginScope_tal | |
| 727 bytecode_handlers_tal["beginScope"] = do_beginScope_tal | |
| 728 bytecode_handlers_tal["setLocal"] = do_setLocal_tal | |
| 729 bytecode_handlers_tal["setGlobal"] = do_setGlobal_tal | |
| 730 bytecode_handlers_tal["insertStructure"] = do_insertStructure_tal | |
| 731 bytecode_handlers_tal["insertText"] = do_insertText_tal | |
| 732 bytecode_handlers_tal["loop"] = do_loop_tal | |
| 733 bytecode_handlers_tal["onError"] = do_onError_tal | |
| 734 bytecode_handlers_tal["<attrAction>"] = attrAction_tal | |
| 735 bytecode_handlers_tal["optTag"] = do_optTag_tal | |
| 736 | |
| 737 | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
738 class FasterStringIO(StringIO): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
739 """Append-only version of StringIO. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
740 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
741 This let's us have a much faster write() method. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
742 """ |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
743 def close(self): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
744 if not self.closed: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
745 self.write = _write_ValueError |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
746 StringIO.close(self) |
| 1049 | 747 |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
748 def seek(self, pos, mode=0): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
749 raise RuntimeError("FasterStringIO.seek() not allowed") |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
750 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
751 def write(self, s): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
752 #assert self.pos == self.len |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
753 self.buflist.append(s) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
754 self.len = self.pos = self.pos + len(s) |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
755 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
756 |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
757 def _write_ValueError(s): |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
758 raise ValueError, "I/O operation on closed file" |
