Mercurial > p > roundup > code
annotate roundup/cgi/TAL/TALParser.py @ 8446:14c7c07b32d8
feature: add thread local trace_id and trace_reason to logging.
Added trace_id to default logging so that all logs for a given request
share the same trace_id.
This allows correlation of logs across a request.
admin_guide.txt, upgrading.txt:
add docs
update sample configs to include trace_id.
rewrite logging docs in admin_guide. Hopefully they are clearer now.
clean up some stuff in the logging config file docs.
admin.py:
add decorators to run_command to enable trace_id.
change calls to db.commit() to use run_command to get trace_id.
configuration.py:
clean up imports.
update docstrings, comments and inline docs.
add trace_id to default log format.
add function for testing decorated with trace_id.
add support for dumping stack trace in logging.
add check for pytest in sys.modules to enable log propagation when
pytest is running. Otherwise tests fail as the caplog logger doesn't
see the roundup logs.
logcontext.py:
new file to handle thread local contextvar mangement.
mailgw.py:
add decorators for trace_id etc.
scripts/roundup_xlmrpc_server.py:
add decorators for trace_id etc.
fix encoding bug turning bytes into a string.
fix command line issue where we can't set encoding. (not sure if
changing encoding via command line even works)
cgi/client.py
decorate two entry points for trace_id etc.
cgi/wsgi_handler.py:
decorate entry point for trace_id etc.
test/test_config.py:
add test for trace_id in new log format.
test various cases for sinfo and errors in formating msg.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 16 Sep 2025 22:53:00 -0400 |
| parents | 23b8e6067f7c |
| children |
| 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 ############################################################################## |
| 14 """ | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
15 Parse XML and compile to TALInterpreter intermediate code. |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
16 """ |
| 1049 | 17 |
|
5388
d26921b851c3
Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5377
diff
changeset
|
18 from .XMLParser import XMLParser |
|
d26921b851c3
Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5377
diff
changeset
|
19 from .TALDefs import XML_NS, ZOPE_I18N_NS, ZOPE_METAL_NS, ZOPE_TAL_NS |
|
d26921b851c3
Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5377
diff
changeset
|
20 from .TALGenerator import TALGenerator |
| 1049 | 21 |
| 22 class TALParser(XMLParser): | |
| 23 | |
| 24 ordered_attributes = 1 | |
| 25 | |
| 26 def __init__(self, gen=None): # Override | |
| 27 XMLParser.__init__(self) | |
| 28 if gen is None: | |
| 29 gen = TALGenerator() | |
| 30 self.gen = gen | |
| 31 self.nsStack = [] | |
| 32 self.nsDict = {XML_NS: 'xml'} | |
| 33 self.nsNew = [] | |
| 34 | |
| 35 def getCode(self): | |
| 36 return self.gen.getCode() | |
| 37 | |
| 38 def getWarnings(self): | |
| 39 return () | |
| 40 | |
| 41 def StartNamespaceDeclHandler(self, prefix, uri): | |
| 42 self.nsStack.append(self.nsDict.copy()) | |
| 43 self.nsDict[uri] = prefix | |
| 44 self.nsNew.append((prefix, uri)) | |
| 45 | |
| 46 def EndNamespaceDeclHandler(self, prefix): | |
| 47 self.nsDict = self.nsStack.pop() | |
| 48 | |
| 49 def StartElementHandler(self, name, attrs): | |
| 50 if self.ordered_attributes: | |
| 51 # attrs is a list of alternating names and values | |
| 52 attrlist = [] | |
| 53 for i in range(0, len(attrs), 2): | |
| 54 key = attrs[i] | |
| 55 value = attrs[i+1] | |
| 56 attrlist.append((key, value)) | |
| 57 else: | |
| 58 # attrs is a dict of {name: value} | |
|
5395
23b8e6067f7c
Python 3 preparation: update calls to dict methods.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5388
diff
changeset
|
59 attrlist = sorted(attrs.items()) # Sorted for definiteness |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
60 name, attrlist, taldict, metaldict, i18ndict \ |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
61 = self.process_ns(name, attrlist) |
| 1049 | 62 attrlist = self.xmlnsattrs() + attrlist |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
63 self.gen.emitStartElement(name, attrlist, taldict, metaldict, i18ndict) |
| 1049 | 64 |
| 65 def process_ns(self, name, attrlist): | |
| 66 taldict = {} | |
| 67 metaldict = {} | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
68 i18ndict = {} |
| 1049 | 69 fixedattrlist = [] |
| 70 name, namebase, namens = self.fixname(name) | |
| 71 for key, value in attrlist: | |
| 72 key, keybase, keyns = self.fixname(key) | |
| 73 ns = keyns or namens # default to tag namespace | |
| 74 item = key, value | |
| 75 if ns == 'metal': | |
| 76 metaldict[keybase] = value | |
| 77 item = item + ("metal",) | |
| 78 elif ns == 'tal': | |
| 79 taldict[keybase] = value | |
| 80 item = item + ("tal",) | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
81 elif ns == 'i18n': |
|
5377
12fe83f90f0d
Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents:
2348
diff
changeset
|
82 assert 0, "dealing with i18n: " + repr((keybase, value)) |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
83 i18ndict[keybase] = value |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
84 item = item + ('i18n',) |
| 1049 | 85 fixedattrlist.append(item) |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
86 if namens in ('metal', 'tal', 'i18n'): |
| 1049 | 87 taldict['tal tag'] = namens |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
88 return name, fixedattrlist, taldict, metaldict, i18ndict |
| 1049 | 89 |
| 90 def xmlnsattrs(self): | |
| 91 newlist = [] | |
| 92 for prefix, uri in self.nsNew: | |
| 93 if prefix: | |
| 94 key = "xmlns:" + prefix | |
| 95 else: | |
| 96 key = "xmlns" | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
97 if uri in (ZOPE_METAL_NS, ZOPE_TAL_NS, ZOPE_I18N_NS): |
| 1049 | 98 item = (key, uri, "xmlns") |
| 99 else: | |
| 100 item = (key, uri) | |
| 101 newlist.append(item) | |
| 102 self.nsNew = [] | |
| 103 return newlist | |
| 104 | |
| 105 def fixname(self, name): | |
| 106 if ' ' in name: | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
107 uri, name = name.split(' ') |
| 1049 | 108 prefix = self.nsDict[uri] |
| 109 prefixed = name | |
| 110 if prefix: | |
| 111 prefixed = "%s:%s" % (prefix, name) | |
| 112 ns = 'x' | |
| 113 if uri == ZOPE_TAL_NS: | |
| 114 ns = 'tal' | |
| 115 elif uri == ZOPE_METAL_NS: | |
| 116 ns = 'metal' | |
|
2348
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
117 elif uri == ZOPE_I18N_NS: |
|
8c2402a78bb0
beginning getting ZPT up to date: TAL first
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
118 ns = 'i18n' |
| 1049 | 119 return (prefixed, name, ns) |
| 120 return (name, name, None) | |
| 121 | |
| 122 def EndElementHandler(self, name): | |
| 123 name = self.fixname(name)[0] | |
| 124 self.gen.emitEndElement(name) | |
| 125 | |
| 126 def DefaultHandler(self, text): | |
| 127 self.gen.emitRawText(text) | |
| 128 | |
| 129 def test(): | |
| 130 import sys | |
| 131 p = TALParser() | |
| 132 file = "tests/input/test01.xml" | |
| 133 if sys.argv[1:]: | |
| 134 file = sys.argv[1] | |
| 135 p.parseFile(file) | |
| 136 program, macros = p.getCode() | |
|
5388
d26921b851c3
Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5377
diff
changeset
|
137 from .TALInterpreter import TALInterpreter |
|
d26921b851c3
Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5377
diff
changeset
|
138 from .DummyEngine import DummyEngine |
| 1049 | 139 engine = DummyEngine(macros) |
| 140 TALInterpreter(program, macros, engine, sys.stdout, wrap=0)() | |
| 141 | |
| 142 if __name__ == "__main__": | |
| 143 test() |
