git: 7084790175b0 - main - textproc/py-genshi: update to 0.7.7

From: Nicola Vitale <nivit_at_FreeBSD.org>
Date: Mon, 26 Sep 2022 15:44:56 UTC
The branch main has been updated by nivit:

URL: https://cgit.FreeBSD.org/ports/commit/?id=7084790175b0cf0578c35f8080153f8280ee191e

commit 7084790175b0cf0578c35f8080153f8280ee191e
Author:     Nicola Vitale <nivit@FreeBSD.org>
AuthorDate: 2022-09-26 15:41:21 +0000
Commit:     Nicola Vitale <nivit@FreeBSD.org>
CommitDate: 2022-09-26 15:44:13 +0000

    textproc/py-genshi: update to 0.7.7
    
    - Remove files/patch-2to3 because the module supports Python 3 now
    - Remove NO_ARCH because the module install a shared library
    - Add a post-install target to strip such library
---
 textproc/py-genshi/Makefile         |    9 +-
 textproc/py-genshi/distinfo         |    6 +-
 textproc/py-genshi/files/patch-2to3 | 5818 -----------------------------------
 3 files changed, 8 insertions(+), 5825 deletions(-)

diff --git a/textproc/py-genshi/Makefile b/textproc/py-genshi/Makefile
index 6d4b0e44f90f..fba3d0399c41 100644
--- a/textproc/py-genshi/Makefile
+++ b/textproc/py-genshi/Makefile
@@ -1,5 +1,5 @@
 PORTNAME=	Genshi
-PORTVERSION=	0.7.3
+PORTVERSION=	0.7.7
 CATEGORIES=	textproc www python
 MASTER_SITES=	CHEESESHOP
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -12,16 +12,17 @@ LICENSE=	BSD3CLAUSE
 LICENSE_FILE=	${WRKSRC}/COPYING
 
 USES=		python:3.6+
-USE_PYTHON=	distutils autoplist
+USE_PYTHON=	autoplist distutils
 
 OPTIONS_DEFINE=	BABEL
 BABEL_DESC=	I18n support through the Babel plugin
 
 BABEL_RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}Babel>=0.8:devel/py-babel@${PY_FLAVOR}
 
+post-install:
+	@${STRIP_CMD} ${STAGEDIR}${PYTHON_SITELIBDIR}/genshi/_speedups${PYTHON_EXT_SUFFIX}.so
+
 do-test:
 	@cd ${WRKSRC} && ${PYTHON_CMD} ${PYDISTUTILS_SETUP} test
 
-NO_ARCH=	yes
-
 .include <bsd.port.mk>
diff --git a/textproc/py-genshi/distinfo b/textproc/py-genshi/distinfo
index 468327f873ab..9de867152159 100644
--- a/textproc/py-genshi/distinfo
+++ b/textproc/py-genshi/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1576467154
-SHA256 (Genshi-0.7.3.tar.gz) = 7933c95151d7dd2124a2b4c8dd85bb6aec881ca17c0556da0b40e56434b313a0
-SIZE (Genshi-0.7.3.tar.gz) = 271238
+TIMESTAMP = 1664204725
+SHA256 (Genshi-0.7.7.tar.gz) = c100520862cd69085d10ee1a87e91289e7f59f6b3d9bd622bf58b2804e6b9aab
+SIZE (Genshi-0.7.7.tar.gz) = 267206
diff --git a/textproc/py-genshi/files/patch-2to3 b/textproc/py-genshi/files/patch-2to3
deleted file mode 100644
index 1764fbffbda4..000000000000
--- a/textproc/py-genshi/files/patch-2to3
+++ /dev/null
@@ -1,5818 +0,0 @@
---- examples/basic/kidrun.py.orig	2019-05-27 21:03:08 UTC
-+++ examples/basic/kidrun.py
-@@ -17,11 +17,11 @@ def test():
- 
-     start = time.clock()
-     template = kid.Template(file='test.kid', **ctxt)
--    print ' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000)
-+    print(' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000))
- 
-     for output in template.generate():
-         sys.stdout.write(output)
--    print
-+    print()
- 
-     times = []
-     for i in range(1000):
-@@ -30,10 +30,10 @@ def test():
-         times.append(time.clock() - start)
-         sys.stdout.write('.')
-         sys.stdout.flush()
--    print
-+    print()
- 
--    print ' --> render stage: %s ms (average)' % (
--          (sum(times) / len(times) * 1000))
-+    print(' --> render stage: %s ms (average)' % (
-+          (sum(times) / len(times) * 1000)))
- 
- if __name__ == '__main__':
-     if '-p' in sys.argv:
---- examples/basic/run.py.orig	2019-05-27 21:03:08 UTC
-+++ examples/basic/run.py
-@@ -13,13 +13,13 @@ def test():
- 
-     start = time.clock()
-     tmpl = loader.load('test.html')
--    print ' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000)
-+    print(' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000))
- 
-     data = dict(hello='<world>', skin='default', hey='ZYX', bozz=None,
-                 items=['Number %d' % num for num in range(1, 15)],
-                 prefix='#')
- 
--    print tmpl.generate(**data).render(method='html')
-+    print(tmpl.generate(**data).render(method='html'))
- 
-     times = []
-     for i in range(1000):
-@@ -28,10 +28,10 @@ def test():
-         times.append(time.clock() - start)
-         sys.stdout.write('.')
-         sys.stdout.flush()
--    print
-+    print()
- 
--    print ' --> render stage: %s ms (average)' % (
--          (sum(times) / len(times) * 1000))
-+    print(' --> render stage: %s ms (average)' % (
-+          (sum(times) / len(times) * 1000)))
- 
- if __name__ == '__main__':
-     if '-p' in sys.argv:
---- examples/bench/basic.py.orig	2019-05-27 21:03:08 UTC
-+++ examples/bench/basic.py
-@@ -5,7 +5,7 @@
- 
- from cgi import escape
- import os
--from StringIO import StringIO
-+from io import StringIO
- import sys
- import timeit
- 
-@@ -22,7 +22,7 @@ def genshi(dirname, verbose=False):
-         return template.generate(**data).render('xhtml')
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def genshi_text(dirname, verbose=False):
-@@ -36,14 +36,14 @@ def genshi_text(dirname, verbose=False):
-         return template.generate(**data).render('text')
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def mako(dirname, verbose=False):
-     try:
-         from mako.lookup import TemplateLookup
-     except ImportError:
--        print>>sys.stderr, 'Mako not installed, skipping'
-+        print('Mako not installed, skipping', file=sys.stderr)
-         return lambda: None
-     lookup = TemplateLookup(directories=[dirname], filesystem_checks=False)
-     template = lookup.get_template('template.html')
-@@ -52,7 +52,7 @@ def mako(dirname, verbose=False):
-                     list_items=['Number %d' % num for num in range(1, 15)])
-         return template.render(**data)
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def cheetah(dirname, verbose=False):
-@@ -60,7 +60,7 @@ def cheetah(dirname, verbose=False):
-     try:
-         from Cheetah.Template import Template
-     except ImportError:
--        print>>sys.stderr, 'Cheetah not installed, skipping'
-+        print('Cheetah not installed, skipping', file=sys.stderr)
-         return lambda: None
-     class MyTemplate(Template):
-         def serverSidePath(self, path): return os.path.join(dirname, path)
-@@ -70,18 +70,18 @@ def cheetah(dirname, verbose=False):
-     def render():
-         template = MyTemplate(file=filename,
-                               searchList=[{'title': 'Just a test', 'user': 'joe',
--                                           'items': [u'Number %d' % num for num in range(1, 15)]}])
-+                                           'items': ['Number %d' % num for num in range(1, 15)]}])
-         return template.respond()
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def clearsilver(dirname, verbose=False):
-     try:
-         import neo_cgi
-     except ImportError:
--        print>>sys.stderr, 'ClearSilver not installed, skipping'
-+        print('ClearSilver not installed, skipping', file=sys.stderr)
-         return lambda: None
-     neo_cgi.update()
-     import neo_util
-@@ -98,7 +98,7 @@ def clearsilver(dirname, verbose=False):
-         return cs.render()
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def django(dirname, verbose=False):
-@@ -106,7 +106,7 @@ def django(dirname, verbose=False):
-         from django.conf import settings
-         settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')])
-     except ImportError:
--        print>>sys.stderr, 'Django not installed, skipping'
-+        print('Django not installed, skipping', file=sys.stderr)
-         return lambda: None
-     from django import template, templatetags
-     from django.template import loader
-@@ -119,14 +119,14 @@ def django(dirname, verbose=False):
-         return tmpl.render(template.Context(data))
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def kid(dirname, verbose=False):
-     try:
-         import kid
-     except ImportError:
--        print>>sys.stderr, "Kid not installed, skipping"
-+        print("Kid not installed, skipping", file=sys.stderr)
-         return lambda: None
-     kid.path = kid.TemplatePath([dirname])
-     template = kid.load_template('template.kid').Template
-@@ -137,14 +137,14 @@ def kid(dirname, verbose=False):
-         ).serialize(output='xhtml')
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def simpletal(dirname, verbose=False):
-     try:
-         from simpletal import simpleTAL, simpleTALES
-     except ImportError:
--        print>>sys.stderr, "SimpleTAL not installed, skipping"
-+        print("SimpleTAL not installed, skipping", file=sys.stderr)
-         return lambda: None
-     fileobj = open(os.path.join(dirname, 'base.html'))
-     base = simpleTAL.compileHTMLTemplate(fileobj)
-@@ -163,7 +163,7 @@ def simpletal(dirname, verbose=False):
-         return buf.getvalue()
- 
-     if verbose:
--        print render()
-+        print(render())
-     return render
- 
- def run(engines, number=2000, verbose=False):
-@@ -171,19 +171,19 @@ def run(engines, number=2000, verbose=False):
-     for engine in engines:
-         dirname = os.path.join(basepath, engine)
-         if verbose:
--            print '%s:' % engine.capitalize()
--            print '--------------------------------------------------------'
-+            print('%s:' % engine.capitalize())
-+            print('--------------------------------------------------------')
-         else:
--            print '%s:' % engine.capitalize(),
-+            print('%s:' % engine.capitalize(), end=' ')
-         t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)'
-                                % (engine, engine, dirname, verbose),
-                          stmt='render()')
-         time = t.timeit(number=number) / number
-         if verbose:
--            print '--------------------------------------------------------'
--        print '%.2f ms' % (1000 * time)
-+            print('--------------------------------------------------------')
-+        print('%.2f ms' % (1000 * time))
-         if verbose:
--            print '--------------------------------------------------------'
-+            print('--------------------------------------------------------')
- 
- 
- if __name__ == '__main__':
---- examples/bench/bigtable.py.orig	2019-05-27 21:03:08 UTC
-+++ examples/bench/bigtable.py
-@@ -8,7 +8,7 @@
- import cgi
- import sys
- import timeit
--from StringIO import StringIO
-+from io import StringIO
- from genshi.builder import tag
- from genshi.template import MarkupTemplate, NewTextTemplate
- 
-@@ -111,7 +111,7 @@ def test_genshi_text():
- def test_genshi_builder():
-     """Genshi template + tag builder"""
-     stream = tag.TABLE([
--        tag.tr([tag.td(c) for c in row.values()])
-+        tag.tr([tag.td(c) for c in list(row.values())])
-         for row in table
-     ]).generate()
-     stream = genshi_tmpl2.generate(table=stream)
-@@ -121,7 +121,7 @@ def test_builder():
-     """Genshi tag builder"""
-     stream = tag.TABLE([
-         tag.tr([
--            tag.td(c) for c in row.values()
-+            tag.td(c) for c in list(row.values())
-         ])
-         for row in table
-     ]).generate()
-@@ -151,7 +151,7 @@ if kid:
-             _table = cet.Element('table')
-             for row in table:
-                 td = cet.SubElement(_table, 'tr')
--                for c in row.values():
-+                for c in list(row.values()):
-                     cet.SubElement(td, 'td').text=str(c)
-             kid_tmpl2.table = _table
-             kid_tmpl2.serialize(output='html')
-@@ -162,7 +162,7 @@ if et:
-         _table = et.Element('table')
-         for row in table:
-             tr = et.SubElement(_table, 'tr')
--            for c in row.values():
-+            for c in list(row.values()):
-                 et.SubElement(tr, 'td').text=str(c)
-         et.tostring(_table)
- 
-@@ -172,7 +172,7 @@ if cet:
-         _table = cet.Element('table')
-         for row in table:
-             tr = cet.SubElement(_table, 'tr')
--            for c in row.values():
-+            for c in list(row.values()):
-                 cet.SubElement(tr, 'td').text=str(c)
-         cet.tostring(_table)
- 
-@@ -201,7 +201,7 @@ def run(which=None, number=10):
-              'test_et', 'test_cet', 'test_clearsilver', 'test_django']
- 
-     if which:
--        tests = filter(lambda n: n[5:] in which, tests)
-+        tests = [n for n in tests if n[5:] in which]
- 
-     for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
-         t = timeit.Timer(setup='from __main__ import %s;' % test,
-@@ -212,7 +212,7 @@ def run(which=None, number=10):
-             result = '   (not installed?)'
-         else:
-             result = '%16.2f ms' % (1000 * time)
--        print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
-+        print('%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result))
- 
- 
- if __name__ == '__main__':
---- examples/bench/xpath.py.orig	2019-05-27 21:03:08 UTC
-+++ examples/bench/xpath.py
-@@ -32,7 +32,7 @@ def benchmark(f, acurate_time=1):
-     runs = 1
-     while True:
-         start_time = time_func()
--        for _ in xrange(runs):
-+        for _ in range(runs):
-             f()
-         dt = time_func() - start_time
-         if dt >= acurate_time:
-@@ -61,23 +61,23 @@ def spell(t):
- 
- def test_paths_in_streams(exprs, streams, test_strategies=False):
-     for expr in exprs:
--        print "Testing path %r" % expr
-+        print("Testing path %r" % expr)
-         for stream, sname in streams:
--            print '\tRunning on "%s" example:' % sname
-+            print('\tRunning on "%s" example:' % sname)
- 
-             path = Path(expr)
-             def f():
-                 for e in path.select(stream):
-                     pass
-             t = spell(benchmark(f))
--            print "\t\tselect:\t\t%s" % t
-+            print("\t\tselect:\t\t%s" % t)
- 
-             def f():
-                 path = Path(expr)
-                 for e in path.select(stream):
-                     pass
-             t = spell(benchmark(f))
--            print "\t\tinit + select:\t%s" % t
-+            print("\t\tinit + select:\t%s" % t)
- 
-             if test_strategies and len(path.paths) == 1:
-                 from genshi.path import GenericStrategy, SingleStepStrategy, \
-@@ -88,13 +88,13 @@ def test_paths_in_streams(exprs, streams, test_strateg
-                 for strategy in strategies:
-                     if not strategy.supports(path.paths[0]):
-                         continue
--                    print "\t\t%s Strategy"%strategy.__name__
-+                    print("\t\t%s Strategy"%strategy.__name__)
-                     fp = FakePath(strategy(path.paths[0]))
-                     def f():
-                         for e in fp.select(stream):
-                             pass
-                     t = spell(benchmark(f))
--                    print "\t\t\tselect:\t\t%s"%t
-+                    print("\t\t\tselect:\t\t%s"%t)
- 
- 
- def test_documents(test_strategies=False):
---- examples/tutorial/geddit/controller.py.orig	2019-05-27 21:03:08 UTC
-+++ examples/tutorial/geddit/controller.py
-@@ -20,7 +20,7 @@ class Root(object):
-     @cherrypy.expose
-     @template.output('index.html')
-     def index(self):
--        links = sorted(self.data.values(), key=operator.attrgetter('time'))
-+        links = sorted(list(self.data.values()), key=operator.attrgetter('time'))
-         return template.render(links=links)
- 
-     @cherrypy.expose
-@@ -35,7 +35,7 @@ class Root(object):
-                 link = Link(**data)
-                 self.data[link.id] = link
-                 raise cherrypy.HTTPRedirect('/')
--            except Invalid, e:
-+            except Invalid as e:
-                 errors = e.unpack_errors()
-         else:
-             errors = {}
-@@ -69,7 +69,7 @@ class Root(object):
-                     raise cherrypy.HTTPRedirect('/info/%s' % link.id)
-                 return template.render('_comment.html', comment=comment,
-                                        num=len(link.comments))
--            except Invalid, e:
-+            except Invalid as e:
-                 errors = e.unpack_errors()
-         else:
-             errors = {}
-@@ -89,7 +89,7 @@ class Root(object):
-                 raise cherrypy.NotFound()
-             return template.render('info.xml', link=link)
-         else:
--            links = sorted(self.data.values(), key=operator.attrgetter('time'))
-+            links = sorted(list(self.data.values()), key=operator.attrgetter('time'))
-             return template.render(links=links)
- 
- 
---- genshi/builder.py.orig	2019-05-27 21:03:08 UTC
-+++ genshi/builder.py
-@@ -107,7 +107,7 @@ class Fragment(object):
-         return str(self.generate())
- 
-     def __unicode__(self):
--        return unicode(self.generate())
-+        return str(self.generate())
- 
-     def __html__(self):
-         return Markup(self.generate())
-@@ -118,7 +118,7 @@ class Fragment(object):
-         :param node: the node to append; can be an `Element`, `Fragment`, or a
-                      `Stream`, or a Python string or number
-         """
--        if isinstance(node, (Stream, Element, basestring, int, float, long)):
-+        if isinstance(node, (Stream, Element, str, int, float)):
-             # For objects of a known/primitive type, we avoid the check for
-             # whether it is iterable for better performance
-             self.children.append(node)
-@@ -140,8 +140,8 @@ class Fragment(object):
-                 for event in child:
-                     yield event
-             else:
--                if not isinstance(child, basestring):
--                    child = unicode(child)
-+                if not isinstance(child, str):
-+                    child = str(child)
-                 yield TEXT, child, (None, -1, -1)
- 
-     def generate(self):
-@@ -155,10 +155,10 @@ class Fragment(object):
- def _kwargs_to_attrs(kwargs):
-     attrs = []
-     names = set()
--    for name, value in kwargs.items():
-+    for name, value in list(kwargs.items()):
-         name = name.rstrip('_').replace('_', '-')
-         if value is not None and name not in names:
--            attrs.append((QName(name), unicode(value)))
-+            attrs.append((QName(name), str(value)))
-             names.add(name)
-     return Attrs(attrs)
- 
---- genshi/compat.py.orig	2019-05-27 21:03:08 UTC
-+++ genshi/compat.py
-@@ -40,7 +40,7 @@ else:
- 
- if IS_PYTHON2:
-     def isstring(obj):
--        return isinstance(obj, basestring)
-+        return isinstance(obj, str)
- else:
-     def isstring(obj):
-         return isinstance(obj, str)
-@@ -48,9 +48,9 @@ else:
- # We need to differentiate between StringIO and BytesIO in places
- 
- if IS_PYTHON2:
--    from StringIO import StringIO
-+    from io import StringIO
-     try:
--        from cStringIO import StringIO as BytesIO
-+        from io import StringIO as BytesIO
-     except ImportError:
-         BytesIO = StringIO
- else:
-@@ -124,7 +124,7 @@ try:
-     next = next
- except NameError:
-     def next(iterator):
--        return iterator.next()
-+        return iterator.__next__()
- 
- # Compatibility fallback implementations for Python < 2.5
- 
---- genshi/core.py.orig	2019-05-27 21:03:08 UTC
-+++ genshi/core.py
-@@ -271,7 +271,7 @@ def _ensure(stream):
-     """Ensure that every item on the stream is actually a markup event."""
-     stream = iter(stream)
-     try:
--        event = stream.next()
-+        event = next(stream)
-     except StopIteration:
-         return
- 
-@@ -282,7 +282,7 @@ def _ensure(stream):
-             if hasattr(event, 'totuple'):
-                 event = event.totuple()
-             else:
--                event = TEXT, unicode(event), (None, -1, -1)
-+                event = TEXT, str(event), (None, -1, -1)
-             yield event
-         return
- 
-@@ -411,7 +411,7 @@ class Attrs(tuple):
-         :return: a new instance with the attribute removed
-         :rtype: `Attrs`
-         """
--        if isinstance(names, basestring):
-+        if isinstance(names, str):
-             names = (names,)
-         return Attrs([(name, val) for name, val in self if name not in names])
- 
-@@ -445,33 +445,33 @@ class Attrs(tuple):
-         return TEXT, ''.join([x[1] for x in self]), (None, -1, -1)
- 
- 
--class Markup(unicode):
-+class Markup(str):
-     """Marks a string as being safe for inclusion in HTML/XML output without
-     needing to be escaped.
-     """
-     __slots__ = []
- 
-     def __add__(self, other):
--        return Markup(unicode.__add__(self, escape(other)))
-+        return Markup(str.__add__(self, escape(other)))
- 
-     def __radd__(self, other):
--        return Markup(unicode.__add__(escape(other), self))
-+        return Markup(str.__add__(escape(other), self))
- 
-     def __mod__(self, args):
-         if isinstance(args, dict):
--            args = dict(zip(args.keys(), map(escape, args.values())))
-+            args = dict(list(zip(list(args.keys()), list(map(escape, list(args.values()))))))
-         elif isinstance(args, (list, tuple)):
-             args = tuple(map(escape, args))
-         else:
-             args = escape(args)
--        return Markup(unicode.__mod__(self, args))
-+        return Markup(str.__mod__(self, args))
- 
-     def __mul__(self, num):
--        return Markup(unicode.__mul__(self, num))
-+        return Markup(str.__mul__(self, num))
-     __rmul__ = __mul__
- 
-     def __repr__(self):
--        return "<%s %s>" % (type(self).__name__, unicode.__repr__(self))
-+        return "<%s %s>" % (type(self).__name__, str.__repr__(self))
- 
-     def join(self, seq, escape_quotes=True):
-         """Return a `Markup` object which is the concatenation of the strings
-@@ -488,7 +488,7 @@ class Markup(unicode):
-         :rtype: `Markup`
-         :see: `escape`
-         """
--        return Markup(unicode.join(self, [escape(item, quotes=escape_quotes)
-+        return Markup(str.join(self, [escape(item, quotes=escape_quotes)
-                                           for item in seq]))
- 
-     @classmethod
-@@ -538,7 +538,7 @@ class Markup(unicode):
-         """
-         if not self:
-             return ''
--        return unicode(self).replace('&#34;', '"') \
-+        return str(self).replace('&#34;', '"') \
-                             .replace('&gt;', '>') \
-                             .replace('&lt;', '<') \
-                             .replace('&amp;', '&')
-@@ -652,7 +652,7 @@ class Namespace(object):
-         self.uri = uri
- 
-     def __init__(self, uri):
--        self.uri = unicode(uri)
-+        self.uri = str(uri)
- 
-     def __contains__(self, qname):
-         return qname.namespace == self.uri
-@@ -691,7 +691,7 @@ class Namespace(object):
- XML_NAMESPACE = Namespace('http://www.w3.org/XML/1998/namespace')
- 
- 
--class QName(unicode):
-+class QName(str):
-     """A qualified element or attribute name.
-     
-     The unicode value of instances of this class contains the qualified name of
-@@ -729,11 +729,11 @@ class QName(unicode):
-         qname = qname.lstrip('{')
-         parts = qname.split('}', 1)
-         if len(parts) > 1:
--            self = unicode.__new__(cls, '{%s' % qname)
--            self.namespace, self.localname = map(unicode, parts)
-+            self = str.__new__(cls, '{%s' % qname)
-+            self.namespace, self.localname = list(map(str, parts))
-         else:
--            self = unicode.__new__(cls, qname)
--            self.namespace, self.localname = None, unicode(qname)
-+            self = str.__new__(cls, qname)
-+            self.namespace, self.localname = None, str(qname)
-         return self
- 
-     def __getnewargs__(self):
---- genshi/filters/html.py.orig	2019-05-27 21:03:08 UTC
-+++ genshi/filters/html.py
-@@ -101,13 +101,13 @@ class HTMLFormFiller(object):
-                                 checked = False
-                                 if isinstance(value, (list, tuple)):
-                                     if declval is not None:
--                                        checked = declval in [unicode(v) for v
-+                                        checked = declval in [str(v) for v
-                                                               in value]
-                                     else:
-                                         checked = any(value)
-                                 else:
-                                     if declval is not None:
--                                        checked = declval == unicode(value)
-+                                        checked = declval == str(value)
-                                     elif type == 'checkbox':
-                                         checked = bool(value)
-                                 if checked:
-@@ -123,7 +123,7 @@ class HTMLFormFiller(object):
-                                     value = value[0]
-                                 if value is not None:
-                                     attrs |= [
--                                        (QName('value'), unicode(value))
-+                                        (QName('value'), str(value))
-                                     ]
-                     elif tagname == 'select':
-                         name = attrs.get('name')
-@@ -166,10 +166,10 @@ class HTMLFormFiller(object):
-                     select_value = None
-                 elif in_select and tagname == 'option':
-                     if isinstance(select_value, (tuple, list)):
--                        selected = option_value in [unicode(v) for v
-+                        selected = option_value in [str(v) for v
-                                                     in select_value]
-                     else:
--                        selected = option_value == unicode(select_value)
-+                        selected = option_value == str(select_value)
-                     okind, (tag, attrs), opos = option_start
-                     if selected:
-                         attrs |= [(QName('selected'), 'selected')]
-@@ -185,7 +185,7 @@ class HTMLFormFiller(object):
-                     option_text = []
-                 elif in_textarea and tagname == 'textarea':
-                     if textarea_value:
--                        yield TEXT, unicode(textarea_value), pos
-+                        yield TEXT, str(textarea_value), pos
-                         textarea_value = None
-                     in_textarea = False
-                 yield kind, data, pos
-@@ -311,7 +311,7 @@ class HTMLSanitizer(object):
-         # The set of URI schemes that are considered safe.
- 
-     # IE6 <http://heideri.ch/jso/#80>
--    _EXPRESSION_SEARCH = re.compile(u"""
-+    _EXPRESSION_SEARCH = re.compile("""
-         [eE
-          \uFF25 # FULLWIDTH LATIN CAPITAL LETTER E
-          \uFF45 # FULLWIDTH LATIN SMALL LETTER E
-@@ -356,7 +356,7 @@ class HTMLSanitizer(object):
-     # IE6 <http://openmya.hacker.jp/hasegawa/security/expression.txt>
-     #     7) Particular bit of Unicode characters
-     _URL_FINDITER = re.compile(
--        u'[Uu][Rr\u0280][Ll\u029F]\s*\(([^)]+)').finditer
-+        '[Uu][Rr\u0280][Ll\u029F]\s*\(([^)]+)').finditer
- 
-     def __call__(self, stream):
-         """Apply the filter to the given stream.
-@@ -528,7 +528,7 @@ class HTMLSanitizer(object):
-         def _repl(match):
-             t = match.group(1)
-             if t:
--                return unichr(int(t, 16))
-+                return chr(int(t, 16))
-             t = match.group(2)
-             if t == '\\':
-                 return r'\\'
---- genshi/filters/i18n.py.orig	2019-05-27 21:03:08 UTC
-+++ genshi/filters/i18n.py
-@@ -163,12 +163,12 @@ class MsgDirective(ExtractableI18NDirective):
- 
-         def _generate():
-             msgbuf = MessageBuffer(self)
--            previous = stream.next()
-+            previous = next(stream)
-             if previous[0] is START:
-                 yield previous
-             else:
-                 msgbuf.append(*previous)
--            previous = stream.next()
-+            previous = next(stream)
-             for kind, data, pos in stream:
-                 msgbuf.append(*previous)
-                 previous = kind, data, pos
-@@ -188,13 +188,13 @@ class MsgDirective(ExtractableI18NDirective):
-         strip = False
- 
-         stream = iter(stream)
--        previous = stream.next()
-+        previous = next(stream)
-         if previous[0] is START:
-             for message in translator._extract_attrs(previous,
-                                                      gettext_functions,
-                                                      search_text=search_text):
-                 yield message
--            previous = stream.next()
-+            previous = next(stream)
-             strip = True
-         for event in stream:
-             if event[0] is START:
-@@ -218,14 +218,14 @@ class ChooseBranchDirective(I18NDirective):
-         msgbuf = MessageBuffer(self)
-         stream = _apply_directives(stream, directives, ctxt, vars)
- 
--        previous = stream.next()
-+        previous = next(stream)
-         if previous[0] is START:
-             yield previous
-         else:
-             msgbuf.append(*previous)
- 
-         try:
--            previous = stream.next()
-+            previous = next(stream)
-         except StopIteration:
-             # For example <i18n:singular> or <i18n:plural> directives
-             yield MSGBUF, (), -1 # the place holder for msgbuf output
-@@ -246,7 +246,7 @@ class ChooseBranchDirective(I18NDirective):
-     def extract(self, translator, stream, gettext_functions=GETTEXT_FUNCTIONS,
-                 search_text=True, comment_stack=None, msgbuf=None):
-         stream = iter(stream)
--        previous = stream.next()
-+        previous = next(stream)
- 
-         if previous[0] is START:
-             # skip the enclosing element
-@@ -254,7 +254,7 @@ class ChooseBranchDirective(I18NDirective):
-                                                      gettext_functions,
-                                                      search_text=search_text):
-                 yield message
--            previous = stream.next()
-+            previous = next(stream)
- 
-         for event in stream:
-             if previous[0] is START:
-@@ -427,7 +427,7 @@ class ChooseDirective(ExtractableI18NDirective):
-                 search_text=True, comment_stack=None):
-         strip = False
-         stream = iter(stream)
--        previous = stream.next()
-+        previous = next(stream)
- 
-         if previous[0] is START:
-             # skip the enclosing element
-@@ -435,7 +435,7 @@ class ChooseDirective(ExtractableI18NDirective):
-                                                      gettext_functions,
-                                                      search_text=search_text):
-                 yield message
--            previous = stream.next()
-+            previous = next(stream)
-             strip = True
- 
-         singular_msgbuf = MessageBuffer(self)
-@@ -480,8 +480,8 @@ class ChooseDirective(ExtractableI18NDirective):
-         # XXX: should we test which form was chosen like this!?!?!?
-         # There should be no match in any catalogue for these singular and
-         # plural test strings
--        singular = u'O\x85\xbe\xa9\xa8az\xc3?\xe6\xa1\x02n\x84\x93'
--        plural = u'\xcc\xfb+\xd3Pn\x9d\tT\xec\x1d\xda\x1a\x88\x00'
-+        singular = 'O\x85\xbe\xa9\xa8az\xc3?\xe6\xa1\x02n\x84\x93'
-+        plural = '\xcc\xfb+\xd3Pn\x9d\tT\xec\x1d\xda\x1a\x88\x00'
-         return ngettext(singular, plural, numeral) == plural
- 
- 
-@@ -703,7 +703,7 @@ class Translator(DirectiveFactory):
-             if kind is START:
-                 tag, attrs = data
-                 if tag in self.ignore_tags or \
--                        isinstance(attrs.get(xml_lang), basestring):
-+                        isinstance(attrs.get(xml_lang), str):
-                     skip += 1
-                     yield kind, data, pos
-                     continue
-@@ -713,7 +713,7 @@ class Translator(DirectiveFactory):
- 
-                 for name, value in attrs:
-                     newval = value
--                    if isinstance(value, basestring):
-+                    if isinstance(value, str):
-                         if translate_attrs and name in include_attrs:
-                             newval = gettext(value)
-                     else:
-@@ -732,7 +732,7 @@ class Translator(DirectiveFactory):
-             elif translate_text and kind is TEXT:
-                 text = data.strip()
-                 if text:
--                    data = data.replace(text, unicode(gettext(text)))
-+                    data = data.replace(text, str(gettext(text)))
-                 yield kind, data, pos
- 
-             elif kind is SUB:
-@@ -830,7 +830,7 @@ class Translator(DirectiveFactory):
-             if kind is START and not skip:
-                 tag, attrs = data
-                 if tag in self.ignore_tags or \
--                        isinstance(attrs.get(xml_lang), basestring):
-+                        isinstance(attrs.get(xml_lang), str):
-                     skip += 1
-                     continue
- 
-@@ -917,7 +917,7 @@ class Translator(DirectiveFactory):
- 
-     def _extract_attrs(self, event, gettext_functions, search_text):
-         for name, value in event[1][1]:
--            if search_text and isinstance(value, basestring):
-+            if search_text and isinstance(value, str):
-                 if name in self.include_attrs:
-                     text = value.strip()
-                     if text:
-@@ -1188,10 +1188,10 @@ def extract_from_code(code, gettext_functions):
-             strings = []
-             def _add(arg):
-                 if isinstance(arg, _ast_Str) \
--                        and isinstance(_ast_Str_value(arg), unicode):
-+                        and isinstance(_ast_Str_value(arg), str):
-                     strings.append(_ast_Str_value(arg))
-                 elif isinstance(arg, _ast_Str):
--                    strings.append(unicode(_ast_Str_value(arg), 'utf-8'))
-+                    strings.append(str(_ast_Str_value(arg), 'utf-8'))
-                 elif arg:
-                     strings.append(None)
-             [_add(arg) for arg in node.args]
-@@ -1232,22 +1232,22 @@ def extract(fileobj, keywords, comment_tags, options):
-     :rtype: ``iterator``
-     """
-     template_class = options.get('template_class', MarkupTemplate)
--    if isinstance(template_class, basestring):
-+    if isinstance(template_class, str):
-         module, clsname = template_class.split(':', 1)
-         template_class = getattr(__import__(module, {}, {}, [clsname]), clsname)
-     encoding = options.get('encoding', None)
- 
-     extract_text = options.get('extract_text', True)
--    if isinstance(extract_text, basestring):
-+    if isinstance(extract_text, str):
-         extract_text = extract_text.lower() in ('1', 'on', 'yes', 'true')
- 
-     ignore_tags = options.get('ignore_tags', Translator.IGNORE_TAGS)
--    if isinstance(ignore_tags, basestring):
-+    if isinstance(ignore_tags, str):
-         ignore_tags = ignore_tags.split()
-     ignore_tags = [QName(tag) for tag in ignore_tags]
- 
-     include_attrs = options.get('include_attrs', Translator.INCLUDE_ATTRS)
--    if isinstance(include_attrs, basestring):
-+    if isinstance(include_attrs, str):
-         include_attrs = include_attrs.split()
-     include_attrs = [QName(attr) for attr in include_attrs]
- 
---- genshi/filters/tests/i18n.py.orig	2019-05-27 21:03:08 UTC
-+++ genshi/filters/tests/i18n.py
-@@ -46,7 +46,7 @@ class DummyTranslations(NullTranslations):
-             if tmsg is missing:
-                 if self._fallback:
-                     return self._fallback.ugettext(message)
--                return unicode(message)
-+                return str(message)
-             return tmsg
-     else:
-         def gettext(self, message):
-@@ -55,7 +55,7 @@ class DummyTranslations(NullTranslations):
-             if tmsg is missing:
-                 if self._fallback:
-                     return self._fallback.gettext(message)
--                return unicode(message)
-+                return str(message)
-             return tmsg
- 
-     if IS_PYTHON2:
-@@ -94,10 +94,10 @@ class TranslatorTestCase(unittest.TestCase):
-         """
-         Verify that translated attributes end up in a proper `Attrs` instance.
-         """
--        html = HTML(u"""<html>
-+        html = HTML("""<html>
-           <span title="Foo"></span>
-         </html>""")
--        translator = Translator(lambda s: u"Voh")
-+        translator = Translator(lambda s: "Voh")
-         stream = list(html.filter(translator))
-         kind, data, pos = stream[2]
-         assert isinstance(data[1], Attrs)
-@@ -139,7 +139,7 @@ class TranslatorTestCase(unittest.TestCase):
-         translator = Translator()
-         messages = list(translator.extract(tmpl.stream))
-         self.assertEqual(1, len(messages))
--        self.assertEqual((2, 'gettext', u'Gr\xfc\xdfe', []), messages[0])
-+        self.assertEqual((2, 'gettext', 'Gr\xfc\xdfe', []), messages[0])
- 
-     def test_extract_included_attribute_text(self):
-         tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/">
-@@ -237,10 +237,10 @@ class MsgDirectiveTestCase(unittest.TestCase):
-             Please see <a href="help.html">Help</a> for details.
-           </p>
-         </html>""")
--        gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]."
-+        gettext = lambda s: "Für Details siehe bitte [1:Hilfe]."
-         translator = Translator(gettext)
-         translator.setup(tmpl)
--        self.assertEqual(u"""<html>
-+        self.assertEqual("""<html>
-           <p>Für Details siehe bitte <a href="help.html">Hilfe</a>.</p>
-         </html>""".encode('utf-8'), tmpl.generate().render(encoding='utf-8'))
- 
-@@ -260,10 +260,10 @@ class MsgDirectiveTestCase(unittest.TestCase):
-             xmlns:i18n="http://genshi.edgewall.org/i18n">
-           <p i18n:msg="">Please see <a href="help.html">Help</a></p>
-         </html>""")
--        gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]"
-+        gettext = lambda s: "Für Details siehe bitte [1:Hilfe]"
-         translator = Translator(gettext)
-         translator.setup(tmpl)
--        self.assertEqual(u"""<html>
-+        self.assertEqual("""<html>
-           <p>Für Details siehe bitte <a href="help.html">Hilfe</a></p>
-         </html>""", tmpl.generate().render())
- 
*** 4901 LINES SKIPPED ***