File remove_six.patch of Package python-Genshi

---
 genshi/builder.py                 |   12 ++++------
 genshi/compat.py                  |    5 +---
 genshi/core.py                    |   33 ++++++++++++++---------------
 genshi/filters/html.py            |   15 ++++++-------
 genshi/filters/i18n.py            |   23 +++++++++-----------
 genshi/filters/tests/i18n.py      |    5 +---
 genshi/filters/tests/test_html.py |   43 ++++++++++++++++++--------------------
 genshi/filters/tests/transform.py |   17 +++++++--------
 genshi/filters/transform.py       |   10 +++-----
 genshi/input.py                   |   26 +++++++++++-----------
 genshi/output.py                  |    7 ++----
 genshi/path.py                    |    3 --
 genshi/template/base.py           |   16 ++++++--------
 genshi/template/directives.py     |    6 +----
 genshi/template/eval.py           |   20 +++++++----------
 genshi/template/loader.py         |    5 +---
 genshi/template/plugin.py         |    5 +---
 genshi/template/tests/markup.py   |    5 +---
 genshi/template/text.py           |    5 +---
 genshi/util.py                    |    7 ++----
 setup.cfg                         |    2 -
 21 files changed, 122 insertions(+), 148 deletions(-)

Index: Genshi-0.7.9/genshi/builder.py
===================================================================
--- Genshi-0.7.9.orig/genshi/builder.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/builder.py	2025-05-09 08:47:55.639423560 +0200
@@ -68,8 +68,6 @@
 Hello, <em>world</em>!
 """
 
-import six
-
 from genshi.compat import numeric_types
 from genshi.core import Attrs, Markup, Namespace, QName, Stream, \
                         START, END, TEXT
@@ -110,7 +108,7 @@
         return str(self.generate())
 
     def __unicode__(self):
-        return six.text_type(self.generate())
+        return str(self.generate())
 
     def __html__(self):
         return Markup(self.generate())
@@ -121,7 +119,7 @@
         :param node: the node to append; can be an `Element`, `Fragment`, or a
                      `Stream`, or a Python string or number
         """
-        simple_types = (Stream, Element) + six.string_types + numeric_types
+        simple_types = (Stream, Element, str) + numeric_types
         if isinstance(node, simple_types):
             # For objects of a known/primitive type, we avoid the check for
             # whether it is iterable for better performance
@@ -144,8 +142,8 @@
                 for event in child:
                     yield event
             else:
-                if not isinstance(child, six.string_types):
-                    child = six.text_type(child)
+                if not isinstance(child, str):
+                    child = str(child)
                 yield TEXT, child, (None, -1, -1)
 
     def generate(self):
@@ -162,7 +160,7 @@
     for name, value in kwargs.items():
         name = name.rstrip('_').replace('_', '-')
         if value is not None and name not in names:
-            attrs.append((QName(name), six.text_type(value)))
+            attrs.append((QName(name), str(value)))
             names.add(name)
     return Attrs(attrs)
 
Index: Genshi-0.7.9/genshi/compat.py
===================================================================
--- Genshi-0.7.9.orig/genshi/compat.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/compat.py	2025-05-09 08:33:55.950025453 +0200
@@ -23,11 +23,10 @@
 import warnings
 from types import CodeType
 
-import six
 
 IS_PYTHON2 = (sys.version_info[0] == 2)
 
-numeric_types = (float, ) + six.integer_types
+numeric_types = (float, int)
 
 # This function should only be called in Python 2, and will fail in Python 3
 
@@ -47,7 +46,7 @@
 # We need to test if an object is an instance of a string type in places
 
 def isstring(obj):
-    return isinstance(obj, six.string_types)
+    return isinstance(obj, str)
 
 # We need to differentiate between StringIO and BytesIO in places
 
Index: Genshi-0.7.9/genshi/core.py
===================================================================
--- Genshi-0.7.9.orig/genshi/core.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/core.py	2025-05-09 08:30:16.089149971 +0200
@@ -18,7 +18,6 @@
 from itertools import chain
 import operator
 
-import six
 
 from genshi.compat import stringrepr
 from genshi.util import stripentities, striptags
@@ -282,7 +281,7 @@
             if hasattr(event, 'totuple'):
                 event = event.totuple()
             else:
-                event = TEXT, six.text_type(event), (None, -1, -1)
+                event = TEXT, str(event), (None, -1, -1)
             yield event
         return
 
@@ -411,7 +410,7 @@
         :return: a new instance with the attribute removed
         :rtype: `Attrs`
         """
-        if isinstance(names, six.string_types):
+        if isinstance(names, str):
             names = (names,)
         return Attrs([(name, val) for name, val in self if name not in names])
 
@@ -445,17 +444,17 @@
         return TEXT, ''.join([x[1] for x in self]), (None, -1, -1)
 
 
-class Markup(six.text_type):
+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(six.text_type.__add__(self, escape(other)))
+        return Markup(str.__add__(self, escape(other)))
 
     def __radd__(self, other):
-        return Markup(six.text_type.__add__(escape(other), self))
+        return Markup(str.__add__(escape(other), self))
 
     def __mod__(self, args):
         if isinstance(args, dict):
@@ -464,14 +463,14 @@
             args = tuple(map(escape, args))
         else:
             args = escape(args)
-        return Markup(six.text_type.__mod__(self, args))
+        return Markup(str.__mod__(self, args))
 
     def __mul__(self, num):
-        return Markup(six.text_type.__mul__(self, num))
+        return Markup(str.__mul__(self, num))
     __rmul__ = __mul__
 
     def __repr__(self):
-        return "<%s %s>" % (type(self).__name__, six.text_type.__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
@@ -489,7 +488,7 @@
         :see: `escape`
         """
         escaped_items = [escape(item, quotes=escape_quotes) for item in seq]
-        return Markup(six.text_type.join(self, escaped_items))
+        return Markup(str.join(self, escaped_items))
 
     @classmethod
     def escape(cls, text, quotes=True):
@@ -538,7 +537,7 @@
         """
         if not self:
             return ''
-        return six.text_type(self).replace('&#34;', '"') \
+        return str(self).replace('&#34;', '"') \
                                   .replace('&gt;', '>') \
                                   .replace('&lt;', '<') \
                                   .replace('&amp;', '&')
@@ -652,7 +651,7 @@
         self.uri = uri
 
     def __init__(self, uri):
-        self.uri = six.text_type(uri)
+        self.uri = str(uri)
 
     def __contains__(self, qname):
         return qname.namespace == self.uri
@@ -691,7 +690,7 @@
 XML_NAMESPACE = Namespace('http://www.w3.org/XML/1998/namespace')
 
 
-class QName(six.text_type):
+class QName(str):
     """A qualified element or attribute name.
     
     The unicode value of instances of this class contains the qualified name of
@@ -729,11 +728,11 @@
         qname = qname.lstrip('{')
         parts = qname.split('}', 1)
         if len(parts) > 1:
-            self = six.text_type.__new__(cls, '{%s' % qname)
-            self.namespace, self.localname = map(six.text_type, parts)
+            self = str.__new__(cls, '{%s' % qname)
+            self.namespace, self.localname = map(str, parts)
         else:
-            self = six.text_type.__new__(cls, qname)
-            self.namespace, self.localname = None, six.text_type(qname)
+            self = str.__new__(cls, qname)
+            self.namespace, self.localname = None, str(qname)
         return self
 
     def __getnewargs__(self):
Index: Genshi-0.7.9/genshi/filters/html.py
===================================================================
--- Genshi-0.7.9.orig/genshi/filters/html.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/filters/html.py	2025-05-09 08:30:16.089433034 +0200
@@ -15,7 +15,6 @@
 
 import re
 
-import six
 
 from genshi.core import Attrs, QName, stripentities
 from genshi.core import END, START, TEXT, COMMENT
@@ -99,13 +98,13 @@
                                 checked = False
                                 if isinstance(value, (list, tuple)):
                                     if declval is not None:
-                                        u_vals = [six.text_type(v) for v in value]
+                                        u_vals = [str(v) for v in value]
                                         checked = declval in u_vals
                                     else:
                                         checked = any(value)
                                 else:
                                     if declval is not None:
-                                        checked = declval == six.text_type(value)
+                                        checked = declval == str(value)
                                     elif type == 'checkbox':
                                         checked = bool(value)
                                 if checked:
@@ -121,7 +120,7 @@
                                     value = value[0]
                                 if value is not None:
                                     attrs |= [
-                                        (QName('value'), six.text_type(value))
+                                        (QName('value'), str(value))
                                     ]
                     elif tagname == 'select':
                         name = attrs.get('name')
@@ -164,10 +163,10 @@
                     select_value = None
                 elif in_select and tagname == 'option':
                     if isinstance(select_value, (tuple, list)):
-                        selected = option_value in [six.text_type(v) for v
+                        selected = option_value in [str(v) for v
                                                     in select_value]
                     else:
-                        selected = option_value == six.text_type(select_value)
+                        selected = option_value == str(select_value)
                     okind, (tag, attrs), opos = option_start
                     if selected:
                         attrs |= [(QName('selected'), 'selected')]
@@ -183,7 +182,7 @@
                     option_text = []
                 elif in_textarea and tagname == 'textarea':
                     if textarea_value:
-                        yield TEXT, six.text_type(textarea_value), pos
+                        yield TEXT, str(textarea_value), pos
                         textarea_value = None
                     in_textarea = False
                 yield kind, data, pos
@@ -526,7 +525,7 @@
         def _repl(match):
             t = match.group(1)
             if t:
-                return six.unichr(int(t, 16))
+                return chr(int(t, 16))
             t = match.group(2)
             if t == '\\':
                 return r'\\'
Index: Genshi-0.7.9/genshi/filters/i18n.py
===================================================================
--- Genshi-0.7.9.orig/genshi/filters/i18n.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/filters/i18n.py	2025-05-09 08:30:16.089768807 +0200
@@ -24,7 +24,6 @@
 from functools import partial
 from types import FunctionType
 
-import six
 
 from genshi.core import Attrs, Namespace, QName, START, END, TEXT, \
                         XML_NAMESPACE, _ensure, StreamEventKind
@@ -801,7 +800,7 @@
             if kind is START:
                 tag, attrs = data
                 if tag in self.ignore_tags or \
-                        isinstance(attrs.get(xml_lang), six.string_types):
+                        isinstance(attrs.get(xml_lang), str):
                     skip += 1
                     yield kind, data, pos
                     continue
@@ -811,7 +810,7 @@
 
                 for name, value in attrs:
                     newval = value
-                    if isinstance(value, six.string_types):
+                    if isinstance(value, str):
                         text = value.strip()
                         if translate_attrs and name in include_attrs and text:
                             newval = gettext(text)
@@ -831,7 +830,7 @@
             elif translate_text and kind is TEXT:
                 text = data.strip()
                 if text:
-                    data = data.replace(text, six.text_type(gettext(text)))
+                    data = data.replace(text, str(gettext(text)))
                 yield kind, data, pos
 
             elif kind is SUB:
@@ -944,7 +943,7 @@
             if kind is START and not skip:
                 tag, attrs = data
                 if tag in self.ignore_tags or \
-                        isinstance(attrs.get(xml_lang), six.string_types):
+                        isinstance(attrs.get(xml_lang), str):
                     skip += 1
                     continue
 
@@ -1050,7 +1049,7 @@
 
     def _extract_attrs(self, event, gettext_functions, search_text):
         for name, value in event[1][1]:
-            if search_text and isinstance(value, six.string_types):
+            if search_text and isinstance(value, str):
                 if name in self.include_attrs:
                     text = value.strip()
                     if text:
@@ -1321,10 +1320,10 @@
             strings = []
             def _add(arg):
                 if isinstance(arg, _ast_Str) \
-                        and isinstance(_ast_Str_value(arg), six.text_type):
+                        and isinstance(_ast_Str_value(arg), str):
                     strings.append(_ast_Str_value(arg))
                 elif isinstance(arg, _ast_Str):
-                    strings.append(six.text_type(_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]
@@ -1365,22 +1364,22 @@
     :rtype: ``iterator``
     """
     template_class = options.get('template_class', MarkupTemplate)
-    if isinstance(template_class, six.string_types):
+    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, six.string_types):
+    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, six.string_types):
+    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, six.string_types):
+    if isinstance(include_attrs, str):
         include_attrs = include_attrs.split()
     include_attrs = [QName(attr) for attr in include_attrs]
 
Index: Genshi-0.7.9/genshi/filters/tests/i18n.py
===================================================================
--- Genshi-0.7.9.orig/genshi/filters/tests/i18n.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/filters/tests/i18n.py	2025-05-09 08:30:16.090147309 +0200
@@ -15,7 +15,6 @@
 from gettext import NullTranslations
 import unittest
 
-import six
 
 from genshi.core import Attrs
 from genshi.template import MarkupTemplate, Context
@@ -48,7 +47,7 @@
             if tmsg is missing:
                 if self._fallback:
                     return self._fallback.ugettext(message)
-                return six.text_type(message)
+                return str(message)
             return tmsg
     else:
         def gettext(self, message):
@@ -57,7 +56,7 @@
             if tmsg is missing:
                 if self._fallback:
                     return self._fallback.gettext(message)
-                return six.text_type(message)
+                return str(message)
             return tmsg
 
     if IS_PYTHON2:
Index: Genshi-0.7.9/genshi/filters/tests/test_html.py
===================================================================
--- Genshi-0.7.9.orig/genshi/filters/tests/test_html.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/filters/tests/test_html.py	2025-05-09 08:30:16.090568412 +0200
@@ -13,7 +13,6 @@
 
 import unittest
 
-import six
 
 from genshi.input import HTML, ParseError
 from genshi.filters.html import HTMLFormFiller, HTMLSanitizer
@@ -524,91 +523,91 @@
 
     def test_sanitize_expression(self):
         html = HTML(u'<div style="top:expression(alert())">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_capital_expression(self):
         html = HTML(u'<div style="top:EXPRESSION(alert())">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_url_with_javascript(self):
         html = HTML(u'<div style="background-image:url(javascript:alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_capital_url_with_javascript(self):
         html = HTML(u'<div style="background-image:URL(javascript:alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_unicode_escapes(self):
         html = HTML(u'<div style="top:exp\\72 ess\\000069 on(alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_backslash_without_hex(self):
         html = HTML(u'<div style="top:e\\xp\\ression(alert())">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
         input_str = u'<div style="top:e\\\\xp\\\\ression(alert())">XSS</div>'
         html = HTML(input_str)
-        self.assertEqual(input_str, six.text_type(html | StyleSanitizer()))
+        self.assertEqual(input_str, str(html | StyleSanitizer()))
 
     def test_sanitize_unsafe_props(self):
         html = HTML(u'<div style="POSITION:RELATIVE">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
         html = HTML(u'<div style="behavior:url(test.htc)">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
         html = HTML(u'<div style="-ms-behavior:url(test.htc) url(#obj)">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
         html = HTML(u"""<div style="-o-link:'javascript:alert(1)';"""
                     u"""-o-link-source:current">XSS</div>""")
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
         html = HTML(u"""<div style="-moz-binding:url(xss.xbl)">XSS</div>""")
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_negative_margin(self):
         html = HTML(u'<div style="margin-top:-9999px">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
         html = HTML(u'<div style="margin:0 -9999px">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_css_hack(self):
         html = HTML(u'<div style="*position:static">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
         html = HTML(u'<div style="_margin:-10px">XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_property_name(self):
         html = HTML(u'<div style="display:none;border-left-color:red;'
                     u'user_defined:1;-moz-user-selct:-moz-all">prop</div>')
         self.assertEqual('<div style="display:none; border-left-color:red'
                          '">prop</div>',
-                         six.text_type(html | StyleSanitizer()))
+                         str(html | StyleSanitizer()))
 
     def test_sanitize_unicode_expression(self):
         # Fullwidth small letters
         html = HTML(u'<div style="top:expression(alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
         # Fullwidth capital letters
         html = HTML(u'<div style="top:EXPRESSION(alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
         # IPA extensions
         html = HTML(u'<div style="top:expʀessɪoɴ(alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
     def test_sanitize_unicode_url(self):
         # IPA extensions
         html = HTML(u'<div style="background-image:uʀʟ(javascript:alert())">'
                     u'XSS</div>')
-        self.assertEqual('<div>XSS</div>', six.text_type(html | StyleSanitizer()))
+        self.assertEqual('<div>XSS</div>', str(html | StyleSanitizer()))
 
 
 def suite():
Index: Genshi-0.7.9/genshi/filters/tests/transform.py
===================================================================
--- Genshi-0.7.9.orig/genshi/filters/tests/transform.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/filters/tests/transform.py	2025-05-09 08:30:16.090861554 +0200
@@ -14,7 +14,6 @@
 import doctest
 import unittest
 
-import six
 
 from genshi import HTML
 from genshi.builder import Element
@@ -36,22 +35,22 @@
         for mark, (kind, data, pos) in stream:
             if kind is START:
                 if with_attrs:
-                    kv_attrs = dict((six.text_type(k), v) for k, v in data[1])
-                    data = (six.text_type(data[0]), kv_attrs)
+                    kv_attrs = dict((str(k), v) for k, v in data[1])
+                    data = (str(data[0]), kv_attrs)
                 else:
-                    data = six.text_type(data[0])
+                    data = str(data[0])
             elif kind is END:
-                data = six.text_type(data)
+                data = str(data)
             elif kind is ATTR:
                 kind = ATTR
-                data = dict((six.text_type(k), v) for k, v in data[1])
+                data = dict((str(k), v) for k, v in data[1])
             yield mark, kind, data
     return list(_generate())
 
 
 def _transform(html, transformer, with_attrs=False):
     """Apply transformation returning simplified marked stream."""
-    if isinstance(html, six.string_types):
+    if isinstance(html, str):
         html = HTML(html, encoding='utf-8')
     stream = transformer(html, keep_marks=True)
     return _simplify(stream, with_attrs)
@@ -61,7 +60,7 @@
     """Test .select()"""
     def _select(self, select):
         html = HTML(FOOBAR, encoding='utf-8')
-        if isinstance(select, six.string_types):
+        if isinstance(select, str):
             select = [select]
         transformer = Transformer(select[0])
         for sel in select[1:]:
@@ -668,7 +667,7 @@
             html = HTML(html)
         if content is None:
             content = Injector()
-        elif isinstance(content, six.string_types):
+        elif isinstance(content, str):
             content = HTML(content)
         return _transform(html, getattr(Transformer(select), self.operation)
                                 (content))
Index: Genshi-0.7.9/genshi/filters/transform.py
===================================================================
--- Genshi-0.7.9.orig/genshi/filters/transform.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/filters/transform.py	2025-05-09 08:30:16.091146631 +0200
@@ -33,7 +33,7 @@
 ...  </body>
 ... </html>''',
 ... encoding='utf-8')
->>> print(html | Transformer('body/em').map(six.text_type.upper, TEXT)
+>>> print(html | Transformer('body/em').map(str.upper, TEXT)
 ...                                    .unwrap().wrap(tag.u))
 <html>
   <head><title>Some Title</title></head>
@@ -51,7 +51,6 @@
 import re
 import sys
 
-import six
 
 from genshi.builder import Element
 from genshi.core import Stream, Attrs, QName, TEXT, START, END, _ensure, Markup
@@ -627,11 +626,10 @@
         """Applies a function to the ``data`` element of events of ``kind`` in
         the selection.
 
-        >>> import six
         >>> html = HTML('<html><head><title>Some Title</title></head>'
         ...               '<body>Some <em>body</em> text.</body></html>',
         ...             encoding='utf-8')
-        >>> print(html | Transformer('head/title').map(six.text_type.upper, TEXT))
+        >>> print(html | Transformer('head/title').map(str.upper, TEXT))
         <html><head><title>SOME TITLE</title></head><body>Some <em>body</em>
         text.</body></html>
 
@@ -767,7 +765,7 @@
                 yield OUTSIDE, result
             elif result:
                 # XXX Assume everything else is "text"?
-                yield None, (TEXT, six.text_type(result), (None, -1, -1))
+                yield None, (TEXT, str(result), (None, -1, -1))
             else:
                 yield None, event
 
@@ -993,7 +991,7 @@
         :param replace: Replacement pattern.
         :param count: Number of replacements to make in each text fragment.
         """
-        if isinstance(pattern, six.string_types):
+        if isinstance(pattern, str):
             self.pattern = re.compile(pattern)
         else:
             self.pattern = pattern
Index: Genshi-0.7.9/genshi/input.py
===================================================================
--- Genshi-0.7.9.orig/genshi/input.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/input.py	2025-05-09 08:30:16.091399898 +0200
@@ -19,8 +19,8 @@
 import codecs
 from xml.parsers import expat
 
-import six
-from six.moves import html_entities as entities, html_parser as html
+import html.entities
+import html.parser
 
 from genshi.core import Attrs, QName, Stream, stripentities
 from genshi.core import START, END, XML_DECL, DOCTYPE, TEXT, START_NS, \
@@ -92,7 +92,7 @@
     """
 
     _entitydefs = ['<!ENTITY %s "&#%d;">' % (name, value) for name, value in
-                   entities.name2codepoint.items()]
+                   html.entities.name2codepoint.items()]
     _external_dtd = u'\n'.join(_entitydefs).encode('utf-8')
 
     def __init__(self, source, filename=None, encoding=None):
@@ -157,7 +157,7 @@
                                 del self.expat # get rid of circular references
                             done = True
                         else:
-                            if isinstance(data, six.text_type):
+                            if isinstance(data, str):
                                 data = data.encode('utf-8')
                             self.expat.Parse(data, False)
                     for event in self._queue:
@@ -243,7 +243,7 @@
         if text.startswith('&'):
             # deal with undefined entities
             try:
-                text = six.unichr(entities.name2codepoint[text[1:-1]])
+                text = chr(html.entities.name2codepoint[text[1:-1]])
                 self._enqueue(TEXT, text)
             except KeyError:
                 filename, lineno, offset = self._getpos()
@@ -276,7 +276,7 @@
     return Stream(list(XMLParser(StringIO(text))))
 
 
-class HTMLParser(html.HTMLParser, object):
+class HTMLParser(html.parser.HTMLParser, object):
     """Parser for HTML input based on the Python `HTMLParser` module.
     
     This class provides the same interface for generating stream events as
@@ -305,7 +305,7 @@
         :param filename: the name of the file, if known
         :param filename: encoding of the file; ignored if the input is unicode
         """
-        html.HTMLParser.__init__(self)
+        html.parser.HTMLParser.__init__(self)
         self.source = source
         self.filename = filename
         self.encoding = encoding
@@ -334,7 +334,7 @@
                             self.close()
                             done = True
                         else:
-                            if not isinstance(data, six.text_type):
+                            if not isinstance(data, str):
                                 raise UnicodeError("source returned bytes, but no encoding specified")
                             self.feed(data)
                     for kind, data, pos in self._queue:
@@ -346,7 +346,7 @@
                         for tag in open_tags:
                             yield END, QName(tag), pos
                         break
-            except html.HTMLParseError as e:
+            except html.parser.HTMLParseError as e:
                 msg = '%s: line %d, column %d' % (e.msg, e.lineno, e.offset)
                 raise ParseError(msg, self.filename, e.lineno, e.offset)
         return Stream(_generate()).filter(_coalesce)
@@ -389,14 +389,14 @@
 
     def handle_charref(self, name):
         if name.lower().startswith('x'):
-            text = six.unichr(int(name[1:], 16))
+            text = chr(int(name[1:], 16))
         else:
-            text = six.unichr(int(name))
+            text = chr(int(name))
         self._enqueue(TEXT, text)
 
     def handle_entityref(self, name):
         try:
-            text = six.unichr(entities.name2codepoint[name])
+            text = chr(html.entities.name2codepoint[name])
         except KeyError:
             text = '&%s;' % name
         self._enqueue(TEXT, text)
@@ -435,7 +435,7 @@
     :raises ParseError: if the HTML text is not well-formed, and error recovery
                         fails
     """
-    if isinstance(text, six.text_type):
+    if isinstance(text, str):
         # If it's unicode text the encoding should be set to None.
         # The option to pass in an incorrect encoding is for ease
         # of writing doctests that work in both Python 2.x and 3.x.
Index: Genshi-0.7.9/genshi/output.py
===================================================================
--- Genshi-0.7.9.orig/genshi/output.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/output.py	2025-05-09 08:30:16.091646863 +0200
@@ -18,7 +18,6 @@
 from itertools import chain
 import re
 
-import six
 
 from genshi.core import escape, Attrs, Markup, QName, StreamEventKind
 from genshi.core import START, END, TEXT, XML_DECL, DOCTYPE, START_NS, END_NS, \
@@ -73,7 +72,7 @@
     :see: `XMLSerializer`, `XHTMLSerializer`, `HTMLSerializer`, `TextSerializer`
     :since: version 0.4.1
     """
-    if isinstance(method, six.string_types):
+    if isinstance(method, str):
         method = {'xml':   XMLSerializer,
                   'xhtml': XHTMLSerializer,
                   'html':  HTMLSerializer,
@@ -583,7 +582,7 @@
                 data = event[1]
                 if strip_markup and type(data) is Markup:
                     data = data.striptags().stripentities()
-                yield six.text_type(data)
+                yield str(data)
 
 
 class EmptyTagFilter(object):
@@ -825,7 +824,7 @@
 
         :param doctype: DOCTYPE as a string or DocType object.
         """
-        if isinstance(doctype, six.string_types):
+        if isinstance(doctype, str):
             doctype = DocType.get(doctype)
         self.doctype_event = (DOCTYPE, doctype, (None, -1, -1))
 
Index: Genshi-0.7.9/genshi/path.py
===================================================================
--- Genshi-0.7.9.orig/genshi/path.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/path.py	2025-05-09 08:30:16.092083005 +0200
@@ -45,7 +45,6 @@
 import re
 from itertools import chain
 
-import six
 
 from genshi.compat import IS_PYTHON2
 from genshi.core import Stream, Attrs, Namespace, QName
@@ -939,7 +938,7 @@
     value = as_scalar(value)
     if value is False:
         return ''
-    return six.text_type(value)
+    return str(value)
 
 def as_bool(value):
     return bool(as_scalar(value))
Index: Genshi-0.7.9/genshi/template/base.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/base.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/base.py	2025-05-09 08:30:16.092500501 +0200
@@ -16,7 +16,6 @@
 from collections import deque
 import os
 
-import six
 
 from genshi.compat import numeric_types, StringIO, BytesIO
 from genshi.core import Attrs, Stream, StreamEventKind, START, TEXT, _ensure
@@ -322,8 +321,7 @@
         return type.__new__(cls, name, bases, d)
 
 
-@six.add_metaclass(DirectiveFactoryMeta)
-class DirectiveFactory(object):
+class DirectiveFactory(metaclass=DirectiveFactoryMeta):
     """Base for classes that provide a set of template directives.
     
     :since: version 0.6
@@ -380,7 +378,7 @@
     """
 
     serializer = None
-    _number_conv = six.text_type # function used to convert numbers to event data
+    _number_conv = str # function used to convert numbers to event data
 
     def __init__(self, source, filepath=None, filename=None, loader=None,
                  encoding=None, lookup='strict', allow_exec=True):
@@ -412,7 +410,7 @@
         self._prepared = False
 
         if not isinstance(source, Stream) and not hasattr(source, 'read'):
-            if isinstance(source, six.text_type):
+            if isinstance(source, str):
                 source = StringIO(source)
             else:
                 source = BytesIO(source)
@@ -504,7 +502,7 @@
                 if kind is INCLUDE:
                     href, cls, fallback = data
                     tmpl_inlined = False
-                    if (isinstance(href, six.string_types) and
+                    if (isinstance(href, str) and
                             not getattr(self.loader, 'auto_reload', True)):
                         # If the path to the included template is static, and
                         # auto-reloading is disabled on the template loader,
@@ -603,7 +601,7 @@
                         # First check for a string, otherwise the iterable test
                         # below succeeds, and the string will be chopped up into
                         # individual characters
-                        if isinstance(result, six.string_types):
+                        if isinstance(result, str):
                             yield TEXT, result, pos
                         elif isinstance(result, numeric_types):
                             yield TEXT, number_conv(result), pos
@@ -612,7 +610,7 @@
                             stream = _ensure(result)
                             break
                         else:
-                            yield TEXT, six.text_type(result), pos
+                            yield TEXT, str(result), pos
 
                 elif kind is SUB:
                     # This event is a list of directives and a list of nested
@@ -641,7 +639,7 @@
         for event in stream:
             if event[0] is INCLUDE:
                 href, cls, fallback = event[1]
-                if not isinstance(href, six.string_types):
+                if not isinstance(href, str):
                     parts = []
                     for subkind, subdata, subpos in self._flatten(href, ctxt,
                                                                   **vars):
Index: Genshi-0.7.9/genshi/template/directives.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/directives.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/directives.py	2025-05-09 08:30:16.092811998 +0200
@@ -13,7 +13,6 @@
 
 """Implementation of the various template directives."""
 
-import six
 
 from genshi.core import QName, Stream
 from genshi.path import Path
@@ -36,8 +35,7 @@
         return type.__new__(cls, name, bases, d)
 
 
-@six.add_metaclass(DirectiveMeta)
-class Directive(object):
+class Directive(metaclass=DirectiveMeta):
     """Abstract base class for template directives.
     
     A directive is basically a callable that takes three positional arguments:
@@ -177,7 +175,7 @@
                 elif not isinstance(attrs, list): # assume it's a dict
                     attrs = attrs.items()
                 attrib |= [
-                    (QName(n), v is not None and six.text_type(v).strip() or None)
+                    (QName(n), v is not None and str(v).strip() or None)
                     for n, v in attrs
                 ]
             yield kind, (tag, attrib), pos
Index: Genshi-0.7.9/genshi/template/eval.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/eval.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/eval.py	2025-05-09 08:46:35.444265640 +0200
@@ -13,12 +13,10 @@
 
 """Support for "safe" evaluation of Python expressions."""
 
+import builtins
 from textwrap import dedent
 from types import CodeType
 
-import six
-from six.moves import builtins
-
 from genshi.core import Markup
 from genshi.template.astutil import ASTTransformer, ASTCodeGenerator, parse
 from genshi.template.base import TemplateRuntimeError
@@ -53,7 +51,7 @@
                       if `None`, the appropriate transformation is chosen
                       depending on the mode
         """
-        if isinstance(source, six.string_types):
+        if isinstance(source, str):
             self.source = source
             node = _parse(source, mode=self.mode)
         else:
@@ -72,7 +70,7 @@
                              filename=filename, lineno=lineno, xform=xform)
         if lookup is None:
             lookup = LenientLookup
-        elif isinstance(lookup, six.string_types):
+        elif isinstance(lookup, str):
             lookup = {'lenient': LenientLookup, 'strict': StrictLookup}[lookup]
         self._globals = lookup.globals
 
@@ -178,7 +176,7 @@
         """
         __traceback_hide__ = 'before_and_this'
         _globals = self._globals(data)
-        six.exec_(self.code, _globals, data)
+        exec(self.code, _globals, data)
 
 
 UNDEFINED = object()
@@ -317,7 +315,7 @@
         try:
             return obj[key]
         except (AttributeError, KeyError, IndexError, TypeError) as e:
-            if isinstance(key, six.string_types):
+            if isinstance(key, str):
                 val = getattr(obj, key, UNDEFINED)
                 if val is UNDEFINED:
                     val = cls.undefined(key, owner=obj)
@@ -407,7 +405,7 @@
             if first.rstrip().endswith(':') and not rest[0].isspace():
                 rest = '\n'.join(['    %s' % line for line in rest.splitlines()])
             source = '\n'.join([first, rest])
-    if isinstance(source, six.text_type):
+    if isinstance(source, str):
         source = (u'\ufeff' + source).encode('utf-8')
     return parse(source, mode)
 
@@ -418,11 +416,11 @@
         filename = '<string>'
     if IS_PYTHON2:
         # Python 2 requires non-unicode filenames
-        if isinstance(filename, six.text_type):
+        if isinstance(filename, str):
             filename = filename.encode('utf-8', 'replace')
     else:
         # Python 3 requires unicode filenames
-        if not isinstance(filename, six.text_type):
+        if not isinstance(filename, str):
             filename = filename.decode('utf-8', 'replace')
     if lineno <= 0:
         lineno = 1
@@ -510,7 +508,7 @@
         return names
 
     def visit_Str(self, node):
-        if not isinstance(node.s, six.text_type):
+        if not isinstance(node.s, str):
             try: # If the string is ASCII, return a `str` object
                 node.s.decode('ascii')
             except ValueError: # Otherwise return a `unicode` object
Index: Genshi-0.7.9/genshi/template/loader.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/loader.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/loader.py	2025-05-09 08:30:16.093319313 +0200
@@ -19,7 +19,6 @@
 except ImportError:
     import dummy_threading as threading
 
-import six
 
 from genshi.template.base import TemplateError
 from genshi.util import LRUCache
@@ -219,7 +218,7 @@
                 raise TemplateError('Search path for templates not configured')
 
             for loadfunc in search_path:
-                if isinstance(loadfunc, six.string_types):
+                if isinstance(loadfunc, str):
                     loadfunc = directory(loadfunc)
                 try:
                     filepath, filename, fileobj, uptodate = loadfunc(filename)
@@ -331,7 +330,7 @@
         def _dispatch_by_prefix(filename):
             for prefix, delegate in delegates.items():
                 if filename.startswith(prefix):
-                    if isinstance(delegate, six.string_types):
+                    if isinstance(delegate, str):
                         delegate = directory(delegate)
                     filepath, _, fileobj, uptodate = delegate(
                         filename[len(prefix):].lstrip('/\\')
Index: Genshi-0.7.9/genshi/template/plugin.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/plugin.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/plugin.py	2025-05-09 08:30:16.093507047 +0200
@@ -16,7 +16,6 @@
 CherryPy/Buffet.
 """
 
-import six
 
 from genshi.input import ET, HTML, XML
 from genshi.output import DocType
@@ -48,7 +47,7 @@
 
         self.default_encoding = options.get('genshi.default_encoding', None)
         auto_reload = options.get('genshi.auto_reload', '1')
-        if isinstance(auto_reload, six.string_types):
+        if isinstance(auto_reload, str):
             auto_reload = auto_reload.lower() in ('1', 'on', 'yes', 'true')
         search_path = [p for p in
                        options.get('genshi.search_path', '').split(':') if p]
@@ -170,7 +169,7 @@
             options = {}
 
         new_syntax = options.get('genshi.new_text_syntax')
-        if isinstance(new_syntax, six.string_types):
+        if isinstance(new_syntax, str):
             new_syntax = new_syntax.lower() in ('1', 'on', 'yes', 'true')
         if new_syntax:
             self.template_class = NewTextTemplate
Index: Genshi-0.7.9/genshi/template/tests/markup.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/tests/markup.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/tests/markup.py	2025-05-09 08:30:16.093698697 +0200
@@ -19,7 +19,6 @@
 import tempfile
 import unittest
 
-import six
 
 from genshi.compat import BytesIO, StringIO
 from genshi.core import Markup
@@ -199,7 +198,7 @@
         </div>""".encode('iso-8859-1'), encoding='iso-8859-1')
         self.assertEqual(u"""<?xml version="1.0" encoding="iso-8859-1"?>\n<div>
           \xf6
-        </div>""", six.text_type(tmpl.generate()))
+        </div>""", str(tmpl.generate()))
 
     def test_latin1_encoded_explicit_encoding(self):
         tmpl = MarkupTemplate(u"""<div xmlns:py="http://genshi.edgewall.org/">
@@ -207,7 +206,7 @@
         </div>""".encode('iso-8859-1'), encoding='iso-8859-1')
         self.assertEqual(u"""<div>
           \xf6
-        </div>""", six.text_type(tmpl.generate()))
+        </div>""", str(tmpl.generate()))
 
     def test_exec_with_trailing_space(self):
         """
Index: Genshi-0.7.9/genshi/template/text.py
===================================================================
--- Genshi-0.7.9.orig/genshi/template/text.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/template/text.py	2025-05-09 08:30:16.093948257 +0200
@@ -28,7 +28,6 @@
 
 import re
 
-import six
 
 from genshi.core import TEXT
 from genshi.template.base import BadDirectiveError, Template, \
@@ -163,7 +162,7 @@
         depth = 0
 
         source = source.read()
-        if not isinstance(source, six.text_type):
+        if not isinstance(source, str):
             source = source.decode(encoding or 'utf-8', 'replace')
         offset = 0
         lineno = 1
@@ -280,7 +279,7 @@
         depth = 0
 
         source = source.read()
-        if not isinstance(source, six.text_type):
+        if not isinstance(source, str):
             source = source.decode(encoding or 'utf-8', 'replace')
         offset = 0
         lineno = 1
Index: Genshi-0.7.9/genshi/util.py
===================================================================
--- Genshi-0.7.9.orig/genshi/util.py	2024-06-16 01:52:43.000000000 +0200
+++ Genshi-0.7.9/genshi/util.py	2025-05-09 08:30:16.094135209 +0200
@@ -15,9 +15,8 @@
 
 import re
 
-from six.moves import html_entities as entities
+import html.entities
 
-import six
 
 __docformat__ = 'restructuredtext en'
 
@@ -212,13 +211,13 @@
                 ref = int(ref[1:], 16)
             else:
                 ref = int(ref, 10)
-            return six.unichr(ref)
+            return chr(ref)
         else: # character entity
             ref = match.group(2)
             if keepxmlentities and ref in ('amp', 'apos', 'gt', 'lt', 'quot'):
                 return '&%s;' % ref
             try:
-                return six.unichr(entities.name2codepoint[ref])
+                return chr(html.entities.name2codepoint[ref])
             except KeyError:
                 if keepxmlentities:
                     return '&amp;%s;' % ref
Index: Genshi-0.7.9/setup.cfg
===================================================================
--- Genshi-0.7.9.orig/setup.cfg	2024-06-16 01:52:56.000000000 +0200
+++ Genshi-0.7.9/setup.cfg	2025-05-09 08:30:26.396346827 +0200
@@ -39,8 +39,6 @@
 	genshi.filters.tests
 	genshi.template.tests
 	genshi.template.tests.templates
-install_requires = 
-	six
 setup_requires = 
 	setuptools
 
openSUSE Build Service is sponsored by