def startElementNS(self, name, qname, attributes=None):
        """
        Start a sub-element. `name` must be a tuple of ``(namespace_uri,
        localname)`` and `qname` is ignored. `attributes` must be a dictionary
        mapping attribute tag tuples (``(namespace_uri, attribute_name)``) to
        string values. To use unnamespaced attributes, `namespace_uri` can be
        false (e.g. :data:`None` or the empty string).

        To use unnamespaced elements, `namespace_uri` in `name` must be false
        **and** no namespace without prefix must be currently active. If a
        namespace without prefix is active and `namespace_uri` in `name` is
        false, :class:`ValueError` is raised.

        Attribute values are of course automatically escaped.
        """
        self._finish_pending_start_element()
        old_counter = self._ns_counter

        qname = self._qname(name)
        if attributes:
            attrib = [
                (self._qname(attrname, attr=True), value)
                for attrname, value in attributes.items()
            ]
            for attrqname, _ in attrib:
                if attrqname == "xmlns":
                    raise ValueError("xmlns not allowed as attribute name")
        else:
            attrib = []

        pending_prefixes = self._pin_floating_ns_decls(old_counter)

        self._write(b"<")
        self._write(qname.encode("utf-8"))

        if None in pending_prefixes:
            uri = pending_prefixes.pop(None)
            self._write(b" xmlns=")
            self._write(xml.sax.saxutils.quoteattr(uri).encode("utf-8"))

        for prefix, uri in sorted(pending_prefixes.items()):
            self._write(b" xmlns")
            if prefix:
                self._write(b":")
                self._write(prefix.encode("utf-8"))
            self._write(b"=")
            self._write(
                xml.sax.saxutils.quoteattr(uri).encode("utf-8")
            )

        if self._sorted_attributes:
            attrib.sort()

        for attrname, value in attrib:
            self._write(b" ")
            self._write(attrname.encode("utf-8"))
            self._write(b"=")
            self._write(
                xml.sax.saxutils.quoteattr(
                    value,
                    self._additional_escapes,
                ).encode("utf-8")
            )

        if self._short_empty_elements:
            self._pending_start_element = name
        else:
            self._write(b">")
Start a sub-element. `name` must be a tuple of ``(namespace_uri,
        localname)`` and `qname` is ignored. `attributes` must be a dictionary
        mapping attribute tag tuples (``(namespace_uri, attribute_name)``) to
        string values. To use unnamespaced attributes, `namespace_uri` can be
        false (e.g. :data:`None` or the empty string).

        To use unnamespaced elements, `namespace_uri` in `name` must be false
        **and** no namespace without prefix must be currently active. If a
        namespace without prefix is active and `namespace_uri` in `name` is
        false, :class:`ValueError` is raised.

        Attribute values are of course automatically escaped.