From nobody Fri Mar 25 13:51:10 2022 X-Original-To: dev-commits-ports-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 0030A1A349F4; Fri, 25 Mar 2022 13:51:11 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KQ3Ql0blsz3hMy; Fri, 25 Mar 2022 13:51:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648216271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=v1iDdY15HFFEc/ClxhnMy4xoqqpjLB9UljWC8AcFRTc=; b=cxoP8ijaAx8YGYwvucnZ2b6v/bahLs0JCdrLtsqH/Gh526xtZ247Iyv5WPF5/HTV/WRnQ+ KSJoso84PGF/SABiY06ZcFG3CaORj5vopJs0j8hddGi0Kci7oYUBcyfbG90x3f2WwsVgrv N1Pe0AGrlSLj4kI8VJ0ptDIeJsXCSuAYngLcRtVBeeUldqXottqT/uEZ2790YHLFHKJUZM I4HKECfgNNqryLzZEEyCBhqyRZQZMyKvhhdFKKAV+bLlUPcf4QK/BTIG3avG+dGq87/DHP PkYjeZ+dpm8LlAcJivWrJjgKrEtMWNQh+pol+A6Kvk5A6J1ZkN1kFVgKphdWFg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 77D0556C2; Fri, 25 Mar 2022 13:51:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 22PDpArB037915; Fri, 25 Mar 2022 13:51:10 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22PDpAuw037914; Fri, 25 Mar 2022 13:51:10 GMT (envelope-from git) Date: Fri, 25 Mar 2022 13:51:10 GMT Message-Id: <202203251351.22PDpAuw037914@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Po-Chuan Hsieh Subject: git: 7730e6639858 - main - textproc/py-zope.tal: Fix build with setuptools 58.0.0+ List-Id: Commit messages for all branches of the ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-ports-all@freebsd.org X-BeenThere: dev-commits-ports-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: sunpoet X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7730e66398589a02fe3fd201f153a816027ef6f4 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648216271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=v1iDdY15HFFEc/ClxhnMy4xoqqpjLB9UljWC8AcFRTc=; b=qy1SZ26ENoM6ZIaqxOlHDB7YXOFvOhIRCxSE889kIYjcAOuriqdhgWl5OauNGxC3VXNuCA DZN2gaJAWnKQDzCA2i77tQ+6lJtfE4FTssMcnYo0IqhIDio526YwFavr/sLgtKNkUmrAKd FIymSh9a6YJXEB1jjbVGTrriZ6vwqrY1q+KgNtvOQAYVHwFQWPun37jKiYm3p2MboF5KFM iXVnfotb06AyL/2YmLKbXEojXL9fLhZZxPPU7tTMTZJzFTvnV78rqwEt0+NJjF7laUAwpx GIKxUHR0YV4nSFnOseBhIHvdmrf/D09NswDZ2dKqSUbDNFQeVUVtDOVmE928xQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1648216271; a=rsa-sha256; cv=none; b=EeaD0yUmAHiJt9qM5nth+WLR135qUVV1REbBhQXeg2RNnNUyRDOnp8vz3ZdWHpxrpeA9c2 EQDx4eREDnwQLiZRestt/qBR0qdBrKckDrnkD5vd0mMrlkCuYiIbZtx2/8SfUioBigvS7G JqFoDAZ2BVB6A3pfvI0wYx6PcdQI8CF58rWxZFYeacdzuW9RFM/dAvd/I5KjhVlPnjyV6Z FbohbXmfNHrkrjsEiIQO1jlyJIaWS5nHyTrvckV2+v5uIKZ2BvQm6gB1gcitorl39X/Nr0 62Und5T5QPdHZXEWKpD7ey08rI8Mg7icwWCjYSuHv8VmSb6DvsnQWp6gy6BT5A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by sunpoet: URL: https://cgit.FreeBSD.org/ports/commit/?id=7730e66398589a02fe3fd201f153a816027ef6f4 commit 7730e66398589a02fe3fd201f153a816027ef6f4 Author: Po-Chuan Hsieh AuthorDate: 2022-03-25 13:34:59 +0000 Commit: Po-Chuan Hsieh CommitDate: 2022-03-25 13:38:23 +0000 textproc/py-zope.tal: Fix build with setuptools 58.0.0+ With hat: python --- textproc/py-zope.tal/files/patch-2to3 | 1119 +++++++++++++++++++++++++++++++++ 1 file changed, 1119 insertions(+) diff --git a/textproc/py-zope.tal/files/patch-2to3 b/textproc/py-zope.tal/files/patch-2to3 new file mode 100644 index 000000000000..406cba687986 --- /dev/null +++ b/textproc/py-zope.tal/files/patch-2to3 @@ -0,0 +1,1119 @@ +--- src/zope/tal/driver.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/driver.py +@@ -43,7 +43,7 @@ import sys + import getopt + + if __name__ == "__main__": +- import setpath # Local hack to tweak sys.path etc. ++ from . import setpath # Local hack to tweak sys.path etc. + + # Import local classes + import zope.tal.taldefs +@@ -104,9 +104,9 @@ ENGINES = {'test23.html': TestEngine, + } + + def usage(code, msg=''): +- print >> sys.stderr, __doc__ ++ print(__doc__, file=sys.stderr) + if msg: +- print >> sys.stderr, msg ++ print(msg, file=sys.stderr) + sys.exit(code) + + def main(): +@@ -120,7 +120,7 @@ def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "hHxlmstia", + ['help', 'html', 'xml']) +- except getopt.error, msg: ++ except getopt.error as msg: + usage(2, msg) + for opt, arg in opts: + if opt in ('-h', '--help'): +--- src/zope/tal/dummyengine.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/dummyengine.py +@@ -100,12 +100,12 @@ class DummyEngine(object): + if type == "not": + return not self.evaluate(expr) + if type == "exists": +- return self.locals.has_key(expr) or self.globals.has_key(expr) ++ return expr in self.locals or expr in self.globals + if type == "python": + try: + return eval(expr, self.globals, self.locals) + except: +- raise TALExpressionError("evaluation error in %s" % `expr`) ++ raise TALExpressionError("evaluation error in %s" % repr(expr)) + if type == "position": + # Insert the current source file name, line number, + # and column offset. +@@ -114,17 +114,17 @@ class DummyEngine(object): + else: + lineno, offset = None, None + return '%s (%s,%s)' % (self.source_file, lineno, offset) +- raise TALExpressionError("unrecognized expression: " + `expression`) ++ raise TALExpressionError("unrecognized expression: " + repr(expression)) + + # implementation; can be overridden + def evaluatePathOrVar(self, expr): + expr = expr.strip() +- if self.locals.has_key(expr): ++ if expr in self.locals: + return self.locals[expr] +- elif self.globals.has_key(expr): ++ elif expr in self.globals: + return self.globals[expr] + else: +- raise TALExpressionError("unknown variable: %s" % `expr`) ++ raise TALExpressionError("unknown variable: %s" % repr(expr)) + + def evaluateValue(self, expr): + return self.evaluate(expr) +@@ -134,7 +134,7 @@ class DummyEngine(object): + + def evaluateText(self, expr): + text = self.evaluate(expr) +- if isinstance(text, (str, unicode, Message)): ++ if isinstance(text, (str, Message)): + return text + if text is not None and text is not Default: + text = str(text) +@@ -159,7 +159,7 @@ class DummyEngine(object): + macro = self.macros[localName] + else: + # External macro +- import driver ++ from . import driver + program, macros = driver.compilefile(file) + macro = macros.get(localName) + if not macro: +@@ -208,7 +208,7 @@ class DummyEngine(object): + locals = self.locals.copy() + + assert lang == 'text/server-python' +- import sys, StringIO ++ import sys, io + + # Removing probable comments + if code.strip().startswith(''): +@@ -216,15 +216,15 @@ class DummyEngine(object): + + # Prepare code. + lines = code.split('\n') +- lines = filter(lambda l: l.strip() != '', lines) ++ lines = [l for l in lines if l.strip() != ''] + code = '\n'.join(lines) + # This saves us from all indentation issues :) + if code.startswith(' ') or code.startswith('\t'): + code = 'if 1 == 1:\n' + code + '\n' + tmp = sys.stdout +- sys.stdout = StringIO.StringIO() ++ sys.stdout = io.StringIO() + try: +- exec code in globals, locals ++ exec(code, globals, locals) + finally: + result = sys.stdout + sys.stdout = tmp +@@ -246,7 +246,7 @@ class Iterator(object): + self.engine = engine + self.nextIndex = 0 + +- def next(self): ++ def __next__(self): + i = self.nextIndex + try: + item = self.seq[i] +@@ -264,7 +264,7 @@ class DummyTranslationDomain(object): + msgids = {} + + def appendMsgid(self, domain, data): +- if not self.msgids.has_key(domain): ++ if domain not in self.msgids: + self.msgids[domain] = [] + self.msgids[domain].append(data) + +@@ -308,7 +308,7 @@ class DummyTranslationDomain(object): + self.appendMsgid(domain, (msgid, mapping)) + + def repl(m): +- return unicode(mapping[m.group(m.lastindex).lower()]) ++ return str(mapping[m.group(m.lastindex).lower()]) + cre = re.compile(r'\$(?:([_A-Za-z][-\w]*)|\{([_A-Za-z][-\w]*)\})') + return cre.sub(repl, text) + +--- src/zope/tal/htmltalparser.py.orig 2012-02-14 09:53:32 UTC ++++ src/zope/tal/htmltalparser.py +@@ -14,7 +14,7 @@ + """Parse HTML and compile to TALInterpreter intermediate code. + """ + +-from HTMLParser import HTMLParser, HTMLParseError ++from html.parser import HTMLParser, HTMLParseError + + from zope.tal.taldefs import (ZOPE_METAL_NS, ZOPE_TAL_NS, ZOPE_I18N_NS, + METALError, TALError, I18NError) +@@ -118,7 +118,7 @@ class HTMLTALParser(HTMLParser): + f.close() + try: + self.parseString(data) +- except TALError, e: ++ except TALError as e: + e.setFile(file) + raise + +@@ -141,7 +141,7 @@ class HTMLTALParser(HTMLParser): + = self.process_ns(tag, attrs) + if tag in EMPTY_HTML_TAGS and "content" in taldict: + raise TALError( +- "empty HTML tags cannot use tal:content: %s" % `tag`, ++ "empty HTML tags cannot use tal:content: %s" % repr(tag), + self.getpos()) + # Support for inline Python code. + if tag == 'script': +@@ -163,7 +163,7 @@ class HTMLTALParser(HTMLParser): + if "content" in taldict: + if tag in EMPTY_HTML_TAGS: + raise TALError( +- "empty HTML tags cannot use tal:content: %s" % `tag`, ++ "empty HTML tags cannot use tal:content: %s" % repr(tag), + self.getpos()) + self.gen.emitStartElement(tag, attrlist, taldict, metaldict, + i18ndict, self.getpos()) +--- src/zope/tal/interfaces.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/interfaces.py +@@ -61,13 +61,14 @@ class ITALExpressionEngine(Interface): + using the 'is' operator in Python. + """ + +- def setPosition((lineno, offset)): ++ def setPosition(xxx_todo_changeme): + """Inform the engine of the current position in the source file. + + This is used to allow the evaluation engine to report + execution errors so that site developers can more easily + locate the offending expression. + """ ++ (lineno, offset) = xxx_todo_changeme + + def setSourceFile(filename): + """Inform the engine of the name of the current source file. +@@ -128,12 +129,13 @@ class ITALExpressionEngine(Interface): + No constraints are imposed on the return value. + """ + +- def createErrorInfo(exception, (lineno, offset)): ++ def createErrorInfo(exception, xxx_todo_changeme1): + """Returns an ITALExpressionErrorInfo object. + + The returned object is used to provide information about the + error condition for the on-error handler. + """ ++ (lineno, offset) = xxx_todo_changeme1 + + def setGlobal(name, value): + """Set a global variable. +--- src/zope/tal/ndiff.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/ndiff.py +@@ -114,6 +114,7 @@ TRACE = 0 + + # define what "junk" means + import re ++from functools import reduce + + def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): + return pat(line) is not None +@@ -209,7 +210,7 @@ class SequenceMatcher(object): + b = self.b + self.b2j = b2j = {} + self.b2jhas = b2jhas = b2j.has_key +- for i in xrange(len(b)): ++ for i in range(len(b)): + elt = b[i] + if b2jhas(elt): + b2j[elt].append(i) +@@ -222,7 +223,7 @@ class SequenceMatcher(object): + # saved. + isjunk, junkdict = self.isjunk, {} + if isjunk: +- for elt in b2j.keys(): ++ for elt in list(b2j.keys()): + if isjunk(elt): + junkdict[elt] = 1 # value irrelevant; it's a set + del b2j[elt] +@@ -281,7 +282,7 @@ class SequenceMatcher(object): + # junk-free match ending with a[i-1] and b[j] + j2len = {} + nothing = [] +- for i in xrange(alo, ahi): ++ for i in range(alo, ahi): + # look at all instances of a[i] in b; note that because + # b2j has no junk keys, the loop is skipped if a[i] is junk + j2lenget = j2len.get +@@ -314,8 +315,8 @@ class SequenceMatcher(object): + bestsize = bestsize + 1 + + if TRACE: +- print "get_matching_blocks", alo, ahi, blo, bhi +- print " returns", besti, bestj, bestsize ++ print("get_matching_blocks", alo, ahi, blo, bhi) ++ print(" returns", besti, bestj, bestsize) + return besti, bestj, bestsize + + def get_matching_blocks(self): +@@ -326,7 +327,7 @@ class SequenceMatcher(object): + self.__helper(0, la, 0, lb, self.matching_blocks) + self.matching_blocks.append((la, lb, 0)) + if TRACE: +- print '*** matching blocks', self.matching_blocks ++ print('*** matching blocks', self.matching_blocks) + return self.matching_blocks + + # builds list of matching blocks covering a[alo:ahi] and +@@ -417,8 +418,8 @@ class SequenceMatcher(object): + + # meant for dumping lines + def dump(tag, x, lo, hi): +- for i in xrange(lo, hi): +- print tag, x[i], ++ for i in range(lo, hi): ++ print(tag, x[i], end=' ') + + def plain_replace(a, alo, ahi, b, blo, bhi): + assert alo < ahi and blo < bhi +@@ -438,7 +439,7 @@ def plain_replace(a, alo, ahi, b, blo, bhi): + + def fancy_replace(a, alo, ahi, b, blo, bhi): + if TRACE: +- print '*** fancy_replace', alo, ahi, blo, bhi ++ print('*** fancy_replace', alo, ahi, blo, bhi) + dump('>', a, alo, ahi) + dump('<', b, blo, bhi) + +@@ -451,10 +452,10 @@ def fancy_replace(a, alo, ahi, b, blo, bhi): + # search for the pair that matches best without being identical + # (identical lines must be junk lines, & we don't want to synch up + # on junk -- unless we have to) +- for j in xrange(blo, bhi): ++ for j in range(blo, bhi): + bj = b[j] + cruncher.set_seq2(bj) +- for i in xrange(alo, ahi): ++ for i in range(alo, ahi): + ai = a[i] + if ai == bj: + if eqi is None: +@@ -486,7 +487,7 @@ def fancy_replace(a, alo, ahi, b, blo, bhi): + # a[best_i] very similar to b[best_j]; eqi is None iff they're not + # identical + if TRACE: +- print '*** best_ratio', best_ratio, best_i, best_j ++ print('*** best_ratio', best_ratio, best_i, best_j) + dump('>', a, best_i, best_i+1) + dump('<', b, best_j, best_j+1) + +@@ -512,11 +513,11 @@ def fancy_replace(a, alo, ahi, b, blo, bhi): + atags = atags + ' ' * la + btags = btags + ' ' * lb + else: +- raise ValueError('unknown tag ' + `tag`) ++ raise ValueError('unknown tag ' + repr(tag)) + printq(aelt, belt, atags, btags) + else: + # the synch pair is identical +- print ' ', aelt, ++ print(' ', aelt, end=' ') + + # pump out diffs from after the synch point + fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi) +@@ -537,12 +538,12 @@ def printq(aline, bline, atags, btags): + common = min(count_leading(aline, "\t"), + count_leading(bline, "\t")) + common = min(common, count_leading(atags[:common], " ")) +- print "-", aline, ++ print("-", aline, end=' ') + if count_leading(atags, " ") < len(atags): +- print "?", "\t" * common + atags[common:] +- print "+", bline, ++ print("?", "\t" * common + atags[common:]) ++ print("+", bline, end=' ') + if count_leading(btags, " ") < len(btags): +- print "?", "\t" * common + btags[common:] ++ print("?", "\t" * common + btags[common:]) + + def count_leading(line, ch): + i, n = 0, len(line) +@@ -562,7 +563,7 @@ def fail(msg): + def fopen(fname): + try: + return open(fname, 'r') +- except IOError, detail: ++ except IOError as detail: + return fail("couldn't open " + fname + ": " + str(detail)) + + # open two files & spray the diff to stdout; return false iff a problem +@@ -586,7 +587,7 @@ def fcompare(f1name, f2name): + elif tag == 'equal': + dump(' ', a, alo, ahi) + else: +- raise ValueError('unknown tag ' + `tag`) ++ raise ValueError('unknown tag ' + repr(tag)) + + return 1 + +@@ -597,7 +598,7 @@ def main(args): + import getopt + try: + opts, args = getopt.getopt(args, "qr:") +- except getopt.error, detail: ++ except getopt.error as detail: + return fail(str(detail)) + noisy = 1 + qseen = rseen = 0 +@@ -621,8 +622,8 @@ def main(args): + return fail("need 2 filename args") + f1name, f2name = args + if noisy: +- print '-:', f1name +- print '+:', f2name ++ print('-:', f1name) ++ print('+:', f2name) + return fcompare(f1name, f2name) + + def restore(which): +@@ -631,7 +632,7 @@ def restore(which): + prefixes = (" ", tag) + for line in sys.stdin.readlines(): + if line[:2] in prefixes: +- print line[2:], ++ print(line[2:], end=' ') + + if __name__ == '__main__': + import sys +--- src/zope/tal/runtest.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/runtest.py +@@ -19,24 +19,24 @@ import os + import sys + import traceback + +-from cStringIO import StringIO ++from io import StringIO + + if __name__ == "__main__": +- import setpath # Local hack to tweak sys.path etc. ++ from . import setpath # Local hack to tweak sys.path etc. + + import zope.tal.driver + import zope.tal.tests.utils + + def showdiff(a, b): +- import ndiff ++ from . import ndiff + cruncher = ndiff.SequenceMatcher(ndiff.IS_LINE_JUNK, a, b) + for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): + if tag == "equal": + continue +- print nicerange(alo, ahi) + tag[0] + nicerange(blo, bhi) ++ print(nicerange(alo, ahi) + tag[0] + nicerange(blo, bhi)) + ndiff.dump('<', a, alo, ahi) + if a and b: +- print '---' ++ print('---') + ndiff.dump('>', b, blo, bhi) + + def nicerange(lo, hi): +@@ -80,10 +80,10 @@ def main(): + if arg.find("_sa") >= 0 and "-a" not in opts: + locopts.append("-a") + if not unittesting: +- print arg, ++ print(arg, end=' ') + sys.stdout.flush() + if zope.tal.tests.utils.skipxml and arg.endswith(".xml"): +- print "SKIPPED (XML parser not available)" ++ print("SKIPPED (XML parser not available)") + continue + save = sys.stdout, sys.argv + try: +@@ -98,13 +98,13 @@ def main(): + except: + errors = 1 + if quiet: +- print sys.exc_type ++ print(sys.exc_info()[0]) + sys.stdout.flush() + else: + if unittesting: +- print ++ print() + else: +- print "Failed:" ++ print("Failed:") + sys.stdout.flush() + traceback.print_exc() + continue +@@ -116,7 +116,7 @@ def main(): + f = open(outfile) + except IOError: + expected = None +- print "(missing file %s)" % outfile, ++ print("(missing file %s)" % outfile, end=' ') + else: + expected = f.readlines() + f.close() +@@ -127,12 +127,12 @@ def main(): + actual = readlines(stdout) + if actual == expected: + if not unittesting: +- print "OK" ++ print("OK") + else: + if unittesting: +- print ++ print() + else: +- print "not OK" ++ print("not OK") + errors = 1 + if not quiet and expected is not None: + showdiff(expected, actual) +--- src/zope/tal/talgenerator.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/talgenerator.py +@@ -69,7 +69,7 @@ class TALGenerator(object): + output = [] + collect = [] + cursor = 0 +- for cursor in xrange(len(program)+1): ++ for cursor in range(len(program)+1): + try: + item = program[cursor] + except IndexError: +@@ -197,8 +197,8 @@ class TALGenerator(object): + def compileExpression(self, expr): + try: + return self.expressionCompiler.compile(expr) +- except self.CompilerError, err: +- raise TALError('%s in expression %s' % (err.args[0], `expr`), ++ except self.CompilerError as err: ++ raise TALError('%s in expression %s' % (err.args[0], repr(expr)), + self.position) + + def pushProgram(self): +@@ -259,7 +259,7 @@ class TALGenerator(object): + m = re.match( + r"(?s)\s*(?:(global|local)\s+)?(%s)\s+(.*)\Z" % NAME_RE, part) + if not m: +- raise TALError("invalid define syntax: " + `part`, ++ raise TALError("invalid define syntax: " + repr(part), + self.position) + scope, name, expr = m.group(1, 2, 3) + scope = scope or "local" +@@ -293,7 +293,7 @@ class TALGenerator(object): + def emitRepeat(self, arg): + m = re.match("(?s)\s*(%s)\s+(.*)\Z" % NAME_RE, arg) + if not m: +- raise TALError("invalid repeat syntax: " + `arg`, ++ raise TALError("invalid repeat syntax: " + repr(arg), + self.position) + name, expr = m.group(1, 2) + cexpr = self.compileExpression(expr) +@@ -346,11 +346,11 @@ class TALGenerator(object): + def emitDefineMacro(self, macroName): + program = self.popProgram() + macroName = macroName.strip() +- if self.macros.has_key(macroName): +- raise METALError("duplicate macro definition: %s" % `macroName`, ++ if macroName in self.macros: ++ raise METALError("duplicate macro definition: %s" % repr(macroName), + self.position) + if not re.match('%s$' % NAME_RE, macroName): +- raise METALError("invalid macro name: %s" % `macroName`, ++ raise METALError("invalid macro name: %s" % repr(macroName), + self.position) + self.macros[macroName] = program + self.inMacroDef = self.inMacroDef - 1 +@@ -374,18 +374,18 @@ class TALGenerator(object): + program = self.popProgram() + slotName = slotName.strip() + if not re.match('%s$' % NAME_RE, slotName): +- raise METALError("invalid slot name: %s" % `slotName`, ++ raise METALError("invalid slot name: %s" % repr(slotName), + self.position) + self.emit("defineSlot", slotName, program) + + def emitFillSlot(self, slotName): + program = self.popProgram() + slotName = slotName.strip() +- if self.slots.has_key(slotName): +- raise METALError("duplicate fill-slot name: %s" % `slotName`, ++ if slotName in self.slots: ++ raise METALError("duplicate fill-slot name: %s" % repr(slotName), + self.position) + if not re.match('%s$' % NAME_RE, slotName): +- raise METALError("invalid slot name: %s" % `slotName`, ++ raise METALError("invalid slot name: %s" % repr(slotName), + self.position) + self.slots[slotName] = program + self.inMacroUse = 1 +@@ -449,13 +449,13 @@ class TALGenerator(object): + newlist = [] + for item in attrlist: + key = item[0] +- if repldict.has_key(key): ++ if key in repldict: + expr, xlat, msgid = repldict[key] + item = item[:2] + ("replace", expr, xlat, msgid) + del repldict[key] + newlist.append(item) + # Add dynamic-only attributes +- for key, (expr, xlat, msgid) in repldict.items(): ++ for key, (expr, xlat, msgid) in list(repldict.items()): + newlist.append((key, None, "insert", expr, xlat, msgid)) + return newlist + +@@ -482,25 +482,25 @@ class TALGenerator(object): + taldict["content"] = taldict.pop("replace") + replaced = True + +- for key, value in taldict.items(): ++ for key, value in list(taldict.items()): + if key not in taldefs.KNOWN_TAL_ATTRIBUTES: +- raise TALError("bad TAL attribute: " + `key`, position) ++ raise TALError("bad TAL attribute: " + repr(key), position) + if not (value or key == 'omit-tag'): + raise TALError("missing value for TAL attribute: " + +- `key`, position) +- for key, value in metaldict.items(): ++ repr(key), position) ++ for key, value in list(metaldict.items()): + if key not in taldefs.KNOWN_METAL_ATTRIBUTES: +- raise METALError("bad METAL attribute: " + `key`, ++ raise METALError("bad METAL attribute: " + repr(key), + position) + if not value: + raise TALError("missing value for METAL attribute: " + +- `key`, position) +- for key, value in i18ndict.items(): ++ repr(key), position) ++ for key, value in list(i18ndict.items()): + if key not in taldefs.KNOWN_I18N_ATTRIBUTES: +- raise I18NError("bad i18n attribute: " + `key`, position) ++ raise I18NError("bad i18n attribute: " + repr(key), position) + if not value and key in ("attributes", "data", "id"): + raise I18NError("missing value for i18n attribute: " + +- `key`, position) ++ repr(key), position) + + todo = {} + defineMacro = metaldict.get("define-macro") +@@ -681,7 +681,7 @@ class TALGenerator(object): + i18nattrs = {} + # Convert repldict's name-->expr mapping to a + # name-->(compiled_expr, translate) mapping +- for key, value in repldict.items(): ++ for key, value in list(repldict.items()): + if i18nattrs.get(key, None): + raise I18NError( + "attribute [%s] cannot both be part of tal:attributes" +--- src/zope/tal/talgettext.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/talgettext.py +@@ -62,16 +62,16 @@ NLSTR = '"\n"' + + def usage(code, msg=''): + # Python 2.1 required +- print >> sys.stderr, __doc__ ++ print(__doc__, file=sys.stderr) + if msg: +- print >> sys.stderr, msg ++ print(msg, file=sys.stderr) + sys.exit(code) + + + class POTALInterpreter(TALInterpreter): + def translate(self, msgid, default=None, i18ndict=None, obj=None): + if default is None: +- default = getattr(msgid, 'default', unicode(msgid)) ++ default = getattr(msgid, 'default', str(msgid)) + # If no i18n dict exists yet, create one. + if i18ndict is None: + i18ndict = {} +@@ -126,15 +126,15 @@ class POEngine(DummyEngine): + if msgid not in domain: + domain[msgid] = [] + else: +- msgids = domain.keys() ++ msgids = list(domain.keys()) + idx = msgids.index(msgid) + existing_msgid = msgids[idx] + if msgid.default != existing_msgid.default: + references = '\n'.join([location[0]+':'+str(location[1]) for location in domain[msgid]]) +- print >> sys.stderr, (u"Warning: msgid '%s' in %s already exists " \ ++ print(("Warning: msgid '%s' in %s already exists " \ + "with a different default (bad: %s, should be: %s)\n" \ + "The references for the existent value are:\n%s\n" % \ +- (msgid, self.file+':'+str(position), msgid.default.encode('utf-8'), existing_msgid.default.encode('utf-8'), references)).encode('utf-8') ++ (msgid, self.file+':'+str(position), msgid.default.encode('utf-8'), existing_msgid.default.encode('utf-8'), references)).encode('utf-8'), file=sys.stderr) + domain[msgid].append((self.file, position)) + return 'x' + +@@ -170,8 +170,8 @@ class UpdatePOEngine(POEngine): + + try: + lines = open(self._filename).readlines() +- except IOError, msg: +- print >> sys.stderr, msg ++ except IOError as msg: ++ print(msg, file=sys.stderr) + sys.exit(1) + + section = None +@@ -213,9 +213,9 @@ class UpdatePOEngine(POEngine): + elif section == STR: + msgstr += '%s\n' % l + else: +- print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ +- 'before:' +- print >> sys.stderr, l ++ print('Syntax error on %s:%d' % (infile, lno), \ ++ 'before:', file=sys.stderr) ++ print(l, file=sys.stderr) + sys.exit(1) + # Add last entry + if section == STR: +@@ -243,7 +243,7 @@ def main(): + sys.argv[1:], + 'ho:u:', + ['help', 'output=', 'update=']) +- except getopt.error, msg: ++ except getopt.error as msg: + usage(1, msg) + + outfile = None +@@ -261,7 +261,7 @@ def main(): + engine = UpdatePOEngine(filename=arg) + + if not args: +- print 'nothing to do' ++ print('nothing to do') + return + + # We don't care about the rendered output of the .pt file +@@ -284,7 +284,7 @@ def main(): + POTALInterpreter(program, macros, engine, stream=Devnull(), + metal=False)() + except: # Hee hee, I love bare excepts! +- print 'There was an error processing', filename ++ print('There was an error processing', filename) + traceback.print_exc() + + # Now output the keys in the engine. Write them to a file if --output or +@@ -295,7 +295,7 @@ def main(): + outfile = file(outfile, update_mode and "a" or "w") + + catalog = {} +- for domain in engine.catalog.keys(): ++ for domain in list(engine.catalog.keys()): + catalog.update(engine.catalog[domain]) + + messages = catalog.copy() +@@ -304,10 +304,10 @@ def main(): + except AttributeError: + pass + if '' not in messages: +- print >> outfile, pot_header % {'time': time.ctime(), +- 'version': __version__} ++ print(pot_header % {'time': time.ctime(), ++ 'version': __version__}, file=outfile) + +- msgids = catalog.keys() ++ msgids = list(catalog.keys()) + # TODO: You should not sort by msgid, but by filename and position. (SR) + msgids.sort() + for msgid in msgids: +--- src/zope/tal/talinterpreter.py.orig 2012-02-14 07:21:28 UTC ++++ src/zope/tal/talinterpreter.py +@@ -29,7 +29,7 @@ from zope.tal.translationcontext import TranslationCon + # Avoid constructing this tuple over and over + I18nMessageTypes = (Message,) + +-TypesToTranslate = I18nMessageTypes + (str, unicode) ++TypesToTranslate = I18nMessageTypes + (str, str) + + BOOLEAN_HTML_ATTRS = frozenset([ + # List of Boolean attributes in HTML that should be rendered in +@@ -251,7 +251,7 @@ class TALInterpreter(object): + def pushMacro(self, macroName, slots, definingName, extending): + if len(self.macroStack) >= self.stackLimit: + raise METALError("macro nesting limit (%d) exceeded " +- "by %s" % (self.stackLimit, `macroName`)) ++ "by %s" % (self.stackLimit, repr(macroName))) + self.macroStack.append( + MacroStackItem((macroName, slots, definingName, extending, + True, self.i18nContext))) +@@ -371,12 +371,13 @@ class TALInterpreter(object): + self.do_startTag(stuff, self.endsep, self.endlen) + bytecode_handlers["startEndTag"] = do_startEndTag + +- def do_startTag(self, (name, attrList), ++ def do_startTag(self, xxx_todo_changeme, + end=">", endlen=1, _len=len): + # The bytecode generator does not cause calls to this method + # for start tags with no attributes; those are optimized down + # to rawtext events. Hence, there is no special "fast path" + # for that case. ++ (name, attrList) = xxx_todo_changeme + self._currentTag = name + L = ["<", name] + append = L.append +@@ -507,8 +508,9 @@ class TALInterpreter(object): + self.restoreOutputState(state) + self.interpret(program) + +- def do_optTag(self, (name, cexpr, tag_ns, isend, start, program), ++ def do_optTag(self, xxx_todo_changeme1, + omit=0): ++ (name, cexpr, tag_ns, isend, start, program) = xxx_todo_changeme1 + if tag_ns and not self.showtal: + return self.no_tag(start, program) + +@@ -528,7 +530,8 @@ class TALInterpreter(object): + self.do_optTag(stuff) + bytecode_handlers["optTag"] = do_optTag + +- def do_rawtextBeginScope(self, (s, col, position, closeprev, dict)): ++ def do_rawtextBeginScope(self, xxx_todo_changeme2): ++ (s, col, position, closeprev, dict) = xxx_todo_changeme2 + self._stream_write(s) + self.col = col + self.do_setPosition(position) +@@ -540,7 +543,8 @@ class TALInterpreter(object): + self.engine.beginScope() + self.scopeLevel = self.scopeLevel + 1 + +- def do_rawtextBeginScope_tal(self, (s, col, position, closeprev, dict)): ++ def do_rawtextBeginScope_tal(self, xxx_todo_changeme3): ++ (s, col, position, closeprev, dict) = xxx_todo_changeme3 + self._stream_write(s) + self.col = col + engine = self.engine +@@ -574,11 +578,13 @@ class TALInterpreter(object): + def do_setLocal(self, notused): + pass + +- def do_setLocal_tal(self, (name, expr)): ++ def do_setLocal_tal(self, xxx_todo_changeme4): ++ (name, expr) = xxx_todo_changeme4 + self.engine.setLocal(name, self.engine.evaluateValue(expr)) + bytecode_handlers["setLocal"] = do_setLocal + +- def do_setGlobal_tal(self, (name, expr)): ++ def do_setGlobal_tal(self, xxx_todo_changeme5): ++ (name, expr) = xxx_todo_changeme5 + self.engine.setGlobal(name, self.engine.evaluateValue(expr)) + bytecode_handlers["setGlobal"] = do_setLocal + +@@ -670,7 +676,7 @@ class TALInterpreter(object): + value = self.translate(value) + + if not structure: +- value = cgi.escape(unicode(value)) ++ value = cgi.escape(str(value)) + + # Either the i18n:name tag is nested inside an i18n:translate in which + # case the last item on the stack has the i18n dictionary and string +@@ -733,7 +739,8 @@ class TALInterpreter(object): + bytecode_handlers["insertStructure"] = do_insertStructure + bytecode_handlers["insertI18nStructure"] = do_insertStructure + +- def do_insertStructure_tal(self, (expr, repldict, block)): ++ def do_insertStructure_tal(self, xxx_todo_changeme6): ++ (expr, repldict, block) = xxx_todo_changeme6 + structure = self.engine.evaluateStructure(expr) + if structure is None: + return +@@ -743,7 +750,7 @@ class TALInterpreter(object): + if isinstance(structure, I18nMessageTypes): + text = self.translate(structure) + else: +- text = unicode(structure) ++ text = str(structure) + if not (repldict or self.strictinsert): + # Take a shortcut, no error checking + self.stream_write(text) +@@ -753,15 +760,16 @@ class TALInterpreter(object): + else: + self.insertXMLStructure(text, repldict) + +- def do_insertI18nStructure_tal(self, (expr, repldict, block)): ++ def do_insertI18nStructure_tal(self, xxx_todo_changeme7): + # TODO: Code duplication is BAD, we need to fix it later ++ (expr, repldict, block) = xxx_todo_changeme7 + structure = self.engine.evaluateStructure(expr) + if structure is not None: + if structure is self.Default: + self.interpret(block) + else: + if not isinstance(structure, TypesToTranslate): +- structure = unicode(structure) ++ structure = str(structure) + text = self.translate(structure) + if not (repldict or self.strictinsert): + # Take a shortcut, no error checking +@@ -807,19 +815,21 @@ class TALInterpreter(object): + self._stream_write(output) + bytecode_handlers["evaluateCode"] = do_evaluateCode + +- def do_loop(self, (name, expr, block)): ++ def do_loop(self, xxx_todo_changeme8): ++ (name, expr, block) = xxx_todo_changeme8 + self.interpret(block) + +- def do_loop_tal(self, (name, expr, block)): ++ def do_loop_tal(self, xxx_todo_changeme9): ++ (name, expr, block) = xxx_todo_changeme9 + iterator = self.engine.setRepeat(name, expr) +- while iterator.next(): ++ while next(iterator): + self.interpret(block) + bytecode_handlers["loop"] = do_loop + + def translate(self, msgid, default=None, i18ndict=None, + obj=None, domain=None): + if default is None: +- default = getattr(msgid, 'default', unicode(msgid)) ++ default = getattr(msgid, 'default', str(msgid)) + if i18ndict is None: + i18ndict = {} + if domain is None: +@@ -832,30 +842,35 @@ class TALInterpreter(object): + return self.engine.translate(msgid, self.i18nContext.domain, + i18ndict, default=default) + +- def do_rawtextColumn(self, (s, col)): ++ def do_rawtextColumn(self, xxx_todo_changeme10): ++ (s, col) = xxx_todo_changeme10 + self._stream_write(s) + self.col = col + bytecode_handlers["rawtextColumn"] = do_rawtextColumn + +- def do_rawtextOffset(self, (s, offset)): ++ def do_rawtextOffset(self, xxx_todo_changeme11): ++ (s, offset) = xxx_todo_changeme11 + self._stream_write(s) + self.col = self.col + offset + bytecode_handlers["rawtextOffset"] = do_rawtextOffset + +- def do_condition(self, (condition, block)): ++ def do_condition(self, xxx_todo_changeme12): ++ (condition, block) = xxx_todo_changeme12 + if not self.tal or self.engine.evaluateBoolean(condition): + self.interpret(block) + bytecode_handlers["condition"] = do_condition + +- def do_defineMacro(self, (macroName, macro)): ++ def do_defineMacro(self, xxx_todo_changeme13): ++ (macroName, macro) = xxx_todo_changeme13 + wasInUse = self.inUseDirective + self.inUseDirective = False + self.interpret(macro) + self.inUseDirective = wasInUse + bytecode_handlers["defineMacro"] = do_defineMacro + +- def do_useMacro(self, (macroName, macroExpr, compiledSlots, block), ++ def do_useMacro(self, xxx_todo_changeme14, + definingName=None, extending=False): ++ (macroName, macroExpr, compiledSlots, block) = xxx_todo_changeme14 + if not self.metal: + self.interpret(block) + return +@@ -865,12 +880,12 @@ class TALInterpreter(object): + else: + if not isCurrentVersion(macro): + raise METALError("macro %s has incompatible version %s" % +- (`macroName`, `getProgramVersion(macro)`), ++ (repr(macroName), repr(getProgramVersion(macro))), + self.position) + mode = getProgramMode(macro) + if mode != (self.html and "html" or "xml"): + raise METALError("macro %s has incompatible mode %s" % +- (`macroName`, `mode`), self.position) ++ (repr(macroName), repr(mode)), self.position) + self.pushMacro(macroName, compiledSlots, definingName, extending) + + # We want 'macroname' name to be always available as a variable +@@ -891,23 +906,26 @@ class TALInterpreter(object): + self.engine.setLocal('macroname', outer) + bytecode_handlers["useMacro"] = do_useMacro + +- def do_extendMacro(self, (macroName, macroExpr, compiledSlots, block, +- definingName)): ++ def do_extendMacro(self, xxx_todo_changeme15): + # extendMacro results from a combination of define-macro and + # use-macro. definingName has the value of the + # metal:define-macro attribute. ++ (macroName, macroExpr, compiledSlots, block, ++ definingName) = xxx_todo_changeme15 + extending = self.metal and self.inUseDirective + self.do_useMacro((macroName, macroExpr, compiledSlots, block), + definingName, extending) + bytecode_handlers["extendMacro"] = do_extendMacro + +- def do_fillSlot(self, (slotName, block)): ++ def do_fillSlot(self, xxx_todo_changeme16): + # This is only executed if the enclosing 'use-macro' evaluates + # to 'default'. *** 155 LINES SKIPPED ***