summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2018-01-25 22:10:14 +0100
committerStefan Behnel <stefan_ml@behnel.de>2018-01-25 22:10:14 +0100
commit6d54319c91193af2e9eb24f28309c5512f3d734a (patch)
tree577e5f148a57f414669e323d610f8851a612db04
parenta4e0fedda8e3461af7bcd46c084ecebf1f604d58 (diff)
downloadpython-lxml-6d54319c91193af2e9eb24f28309c5512f3d734a.tar.gz
Use f-strings for all string formatting for which it makes sense (i.e. does not look unreadable).
-rw-r--r--src/lxml/apihelpers.pxi34
-rw-r--r--src/lxml/classlookup.pxi13
-rw-r--r--src/lxml/debug.pxi4
-rw-r--r--src/lxml/etree.pyx53
-rw-r--r--src/lxml/extensions.pxi16
-rw-r--r--src/lxml/objectify.pyx16
-rw-r--r--src/lxml/objectpath.pxi12
-rw-r--r--src/lxml/parser.pxi13
-rw-r--r--src/lxml/proxy.pxi2
-rw-r--r--src/lxml/readonlytree.pxi20
-rw-r--r--src/lxml/saxparser.pxi5
-rw-r--r--src/lxml/serializer.pxi21
-rw-r--r--src/lxml/xmlerror.pxi9
-rw-r--r--src/lxml/xslt.pxi10
-rw-r--r--src/lxml/xsltext.pxi6
15 files changed, 104 insertions, 130 deletions
diff --git a/src/lxml/apihelpers.pxi b/src/lxml/apihelpers.pxi
index 0a1c88e3..eb122a21 100644
--- a/src/lxml/apihelpers.pxi
+++ b/src/lxml/apihelpers.pxi
@@ -38,11 +38,9 @@ cdef _Document _documentOrRaise(object input):
elif isinstance(input, _Document):
doc = <_Document>input
else:
- raise TypeError, u"Invalid input object: %s" % \
- python._fqtypename(input).decode('utf8')
+ raise TypeError, f"Invalid input object: {python._fqtypename(input).decode('utf8')}"
if doc is None:
- raise ValueError, u"Input object has no document: %s" % \
- python._fqtypename(input).decode('utf8')
+ raise ValueError, f"Input object has no document: {python._fqtypename(input).decode('utf8')}"
_assertValidDoc(doc)
return doc
@@ -60,12 +58,10 @@ cdef _Element _rootNodeOrRaise(object input):
elif isinstance(input, _Document):
node = (<_Document>input).getroot()
else:
- raise TypeError, u"Invalid input object: %s" % \
- python._fqtypename(input).decode('utf8')
+ raise TypeError, f"Invalid input object: {python._fqtypename(input).decode('utf8')}"
if (node is None or not node._c_node or
node._c_node.type != tree.XML_ELEMENT_NODE):
- raise ValueError, u"Input object is not an XML element: %s" % \
- python._fqtypename(input).decode('utf8')
+ raise ValueError, f"Input object is not an XML element: {python._fqtypename(input).decode('utf8')}"
_assertValidNode(node)
return node
@@ -291,8 +287,7 @@ cdef _initNodeAttributes(xmlNode* c_node, _Document doc, attrib, dict extra):
cdef bint is_html
cdef xmlNs* c_ns
if attrib is not None and not hasattr(attrib, u'items'):
- raise TypeError, u"Invalid attribute dictionary: %s" % \
- python._fqtypename(attrib).decode('utf8')
+ raise TypeError, f"Invalid attribute dictionary: {python._fqtypename(attrib).decode('utf8')}"
if not attrib and not extra:
return # nothing to do
is_html = doc._parser._for_html
@@ -1170,8 +1165,8 @@ cdef int _replaceSlice(_Element parent, xmlNode* c_node,
# *replacing* children stepwise with list => check size!
seqlength = len(elements)
if seqlength != slicelength:
- raise ValueError, u"attempt to assign sequence of size %d " \
- u"to extended slice of size %d" % (seqlength, slicelength)
+ raise ValueError, f"attempt to assign sequence of size {seqlength} " \
+ f"to extended slice of size {slicelength}"
if c_node is NULL:
# no children yet => add all elements straight away
@@ -1628,33 +1623,28 @@ cdef bint _characterReferenceIsValid(const_xmlChar* c_name):
cdef int _tagValidOrRaise(tag_utf) except -1:
if not _pyXmlNameIsValid(tag_utf):
- raise ValueError(u"Invalid tag name %r" %
- (<bytes>tag_utf).decode('utf8'))
+ raise ValueError(f"Invalid tag name {(<bytes>tag_utf).decode('utf8')!r}")
return 0
cdef int _htmlTagValidOrRaise(tag_utf) except -1:
if not _pyHtmlNameIsValid(tag_utf):
- raise ValueError(u"Invalid HTML tag name %r" %
- (<bytes>tag_utf).decode('utf8'))
+ raise ValueError(f"Invalid HTML tag name {(<bytes>tag_utf).decode('utf8')!r}")
return 0
cdef int _attributeValidOrRaise(name_utf) except -1:
if not _pyXmlNameIsValid(name_utf):
- raise ValueError(u"Invalid attribute name %r" %
- (<bytes>name_utf).decode('utf8'))
+ raise ValueError(f"Invalid attribute name {(<bytes>name_utf).decode('utf8')!r}")
return 0
cdef int _prefixValidOrRaise(tag_utf) except -1:
if not _pyXmlNameIsValid(tag_utf):
- raise ValueError(u"Invalid namespace prefix %r" %
- (<bytes>tag_utf).decode('utf8'))
+ raise ValueError(f"Invalid namespace prefix {(<bytes>tag_utf).decode('utf8')!r}")
return 0
cdef int _uriValidOrRaise(uri_utf) except -1:
cdef uri.xmlURI* c_uri = uri.xmlParseURI(_cstr(uri_utf))
if c_uri is NULL:
- raise ValueError(u"Invalid namespace URI %r" %
- (<bytes>uri_utf).decode('utf8'))
+ raise ValueError(f"Invalid namespace URI {(<bytes>uri_utf).decode('utf8')!r}")
uri.xmlFreeURI(c_uri)
return 0
diff --git a/src/lxml/classlookup.pxi b/src/lxml/classlookup.pxi
index da3f4d83..f4f15f3f 100644
--- a/src/lxml/classlookup.pxi
+++ b/src/lxml/classlookup.pxi
@@ -92,7 +92,7 @@ cdef public class ElementBase(_Element) [ type LxmlElementBaseType,
last_child = child()
_appendChild(self, last_child)
else:
- raise TypeError, "Invalid child type: %r" % type(child)
+ raise TypeError, f"Invalid child type: {type(child)!r}"
cdef class CommentBase(_Comment):
u"""All custom Comment classes must inherit from this one.
@@ -173,9 +173,9 @@ cdef class EntityBase(_Entity):
c_name = _xcstr(name_utf)
if c_name[0] == c'#':
if not _characterReferenceIsValid(c_name + 1):
- raise ValueError, u"Invalid character reference: '%s'" % name
+ raise ValueError, f"Invalid character reference: '{name}'"
elif not _xmlNameIsValid(c_name):
- raise ValueError, u"Invalid entity reference: '%s'" % name
+ raise ValueError, f"Invalid entity reference: '{name}'"
c_doc = _newXMLDoc()
doc = _documentFactory(c_doc, None)
self._c_node = _createEntity(c_doc, c_name)
@@ -196,12 +196,11 @@ cdef int _validateNodeClass(xmlNode* c_node, cls) except -1:
elif c_node.type == tree.XML_PI_NODE:
expected = PIBase
else:
- assert 0, u"Unknown node type: %s" % c_node.type
+ assert 0, f"Unknown node type: {c_node.type}"
if not (isinstance(cls, type) and issubclass(cls, expected)):
raise TypeError(
- "result of class lookup must be subclass of %s, got %s"
- % (type(expected), type(cls)))
+ f"result of class lookup must be subclass of {type(expected)}, got {type(cls)}")
return 0
@@ -334,7 +333,7 @@ cdef object _lookupDefaultElementClass(state, _Document _doc, xmlNode* c_node):
else:
return (<ElementDefaultClassLookup>state).pi_class
else:
- assert 0, u"Unknown node type: %s" % c_node.type
+ assert 0, f"Unknown node type: {c_node.type}"
################################################################################
diff --git a/src/lxml/debug.pxi b/src/lxml/debug.pxi
index 47b8497b..a0dc62e9 100644
--- a/src/lxml/debug.pxi
+++ b/src/lxml/debug.pxi
@@ -53,7 +53,7 @@ cdef class _MemDebug:
f = stdio.fopen(output_file, "w")
if f is NULL:
- raise IOError("Failed to create file %s" % output_file.decode(sys.getfilesystemencoding()))
+ raise IOError(f"Failed to create file {output_file.decode(sys.getfilesystemencoding())}")
try:
if byte_count is None:
tree.xmlMemDisplay(f)
@@ -82,7 +82,7 @@ cdef class _MemDebug:
f = stdio.fopen(output_file, "w")
if f is NULL:
- raise IOError("Failed to create file %s" % output_file.decode(sys.getfilesystemencoding()))
+ raise IOError(f"Failed to create file {output_file.decode(sys.getfilesystemencoding())}")
try:
tree.xmlMemShow(f, block_count if block_count is not None else tree.xmlMemBlocks())
finally:
diff --git a/src/lxml/etree.pyx b/src/lxml/etree.pyx
index 0b64f04a..d7e4e65e 100644
--- a/src/lxml/etree.pyx
+++ b/src/lxml/etree.pyx
@@ -553,7 +553,7 @@ cdef class DocInfo:
if value is not None:
match = _find_invalid_public_id_characters(value)
if match:
- raise ValueError('Invalid character(s) %r in public_id.' % match.group(0))
+ raise ValueError, f'Invalid character(s) {match.group(0)!r} in public_id.'
value = _utf8(value)
c_value = tree.xmlStrdup(_xcstr(value))
if not c_value:
@@ -647,23 +647,20 @@ cdef class DocInfo:
# contains both a single quote and a double quote, XML
# standard is being violated.
if '"' in system_url:
- quoted_system_url = u"'%s'" % system_url
+ quoted_system_url = f"'{system_url}'"
else:
- quoted_system_url = u'"%s"' % system_url
+ quoted_system_url = f'"{system_url}"'
if public_id:
if system_url:
- return u'<!DOCTYPE %s PUBLIC "%s" %s>' % (
- root_name, public_id, quoted_system_url)
+ return f'<!DOCTYPE {root_name} PUBLIC "{public_id}" {quoted_system_url}>'
else:
- return u'<!DOCTYPE %s PUBLIC "%s">' % (
- root_name, public_id)
+ return f'<!DOCTYPE {root_name} PUBLIC "{public_id}">'
elif system_url:
- return u'<!DOCTYPE %s SYSTEM %s>' % (
- root_name, quoted_system_url)
+ return f'<!DOCTYPE {root_name} SYSTEM {quoted_system_url}>'
elif self._doc.hasdoctype():
- return u'<!DOCTYPE %s>' % root_name
+ return f'<!DOCTYPE {root_name}>'
else:
- return u""
+ return u''
property internalDTD:
u"Returns a DTD validator based on the internal subset of the document."
@@ -772,7 +769,7 @@ cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
# item deletion
c_node = _findChild(self._c_node, x)
if c_node is NULL:
- raise IndexError, u"index out of range: %d" % x
+ raise IndexError, f"index out of range: {x}"
_removeText(c_node.next)
_removeNode(self._doc, c_node)
@@ -1757,7 +1754,7 @@ cdef class _Entity(__ContentOnlyElement):
_assertValidNode(self)
value_utf = _utf8(value)
if b'&' in value_utf or b';' in value_utf:
- raise ValueError(u"Invalid entity name '%s'" % value)
+ raise ValueError, f"Invalid entity name '{value}'"
tree.xmlNodeSetName(self._c_node, _xcstr(value_utf))
property text:
@@ -1765,7 +1762,7 @@ cdef class _Entity(__ContentOnlyElement):
# entity value ?
def __get__(self):
_assertValidNode(self)
- return u'&%s;' % funicode(self._c_node.name)
+ return f'&{funicode(self._c_node.name)};'
def __repr__(self):
return "&%s;" % strrepr(self.name)
@@ -1803,15 +1800,13 @@ cdef class QName:
if isinstance(text_or_uri_or_element, _Element):
text_or_uri_or_element = (<_Element>text_or_uri_or_element).tag
if not _isString(text_or_uri_or_element):
- raise ValueError, (u"Invalid input tag of type %r" %
- type(text_or_uri_or_element))
+ raise ValueError, f"Invalid input tag of type {type(text_or_uri_or_element)!r}"
elif isinstance(text_or_uri_or_element, QName):
text_or_uri_or_element = (<QName>text_or_uri_or_element).text
elif text_or_uri_or_element is not None:
text_or_uri_or_element = unicode(text_or_uri_or_element)
else:
- raise ValueError, (u"Invalid input tag of type %r" %
- type(text_or_uri_or_element))
+ raise ValueError, f"Invalid input tag of type {type(text_or_uri_or_element)!r}"
ns_utf, tag_utf = _getNsTag(text_or_uri_or_element)
if tag is not None:
@@ -2118,7 +2113,7 @@ cdef public class _ElementTree [ type LxmlElementTreeType,
count += 1
c_node = c_node.prev
if count:
- tag = '%s[%d]' % (tag, count+1)
+ tag = f'{tag}[{count+1}]'
else:
# use tag[1] if there are following siblings with the same tag
c_node = c_element.next
@@ -2416,8 +2411,7 @@ cdef class _Attrib:
def pop(self, key, *default):
if len(default) > 1:
- raise TypeError, u"pop expected at most 2 arguments, got %d" % (
- len(default)+1)
+ raise TypeError, f"pop expected at most 2 arguments, got {len(default)+1}"
_assertValidNode(self._element)
result = _getAttributeValue(self._element, key, None)
if result is None:
@@ -3037,14 +3031,14 @@ def ProcessingInstruction(target, text=None):
target = _utf8(target)
_tagValidOrRaise(target)
if target.lower() == b'xml':
- raise ValueError("Invalid PI name '%s'" % target)
+ raise ValueError, f"Invalid PI name '{target}'"
if text is None:
text = b''
else:
text = _utf8(text)
if b'?>' in text:
- raise ValueError("PI text must not contain '?>'")
+ raise ValueError, "PI text must not contain '?>'"
c_doc = _newXMLDoc()
doc = _documentFactory(c_doc, None)
@@ -3073,7 +3067,7 @@ cdef class CDATA:
def __cinit__(self, data):
_utf8_data = _utf8(data)
if b']]>' in _utf8_data:
- raise ValueError("']]>' not allowed inside CDATA")
+ raise ValueError, "']]>' not allowed inside CDATA"
self._utf8_data = _utf8_data
@@ -3093,9 +3087,9 @@ def Entity(name):
c_name = _xcstr(name_utf)
if c_name[0] == c'#':
if not _characterReferenceIsValid(c_name + 1):
- raise ValueError, u"Invalid character reference: '%s'" % name
+ raise ValueError, f"Invalid character reference: '{name}'"
elif not _xmlNameIsValid(c_name):
- raise ValueError, u"Invalid entity reference: '%s'" % name
+ raise ValueError, f"Invalid entity reference: '{name}'"
c_doc = _newXMLDoc()
doc = _documentFactory(c_doc, None)
c_node = _createEntity(c_doc, c_name)
@@ -3348,8 +3342,8 @@ def tostring(element_or_tree, *, encoding=None, method="xml",
encoding, doctype, method, write_declaration, 1,
pretty_print, with_tail, is_standalone)
else:
- raise TypeError, u"Type '%s' cannot be serialized." % \
- python._fqtypename(element_or_tree).decode('utf8')
+ raise TypeError, f"Type '{python._fqtypename(element_or_tree).decode('utf8')}' cannot be serialized."
+
def tostringlist(element_or_tree, *args, **kwargs):
@@ -3395,8 +3389,7 @@ def tounicode(element_or_tree, *, method=u"xml", bint pretty_print=False,
unicode, doctype, method, 0, 1, pretty_print,
with_tail, -1)
else:
- raise TypeError, u"Type '%s' cannot be serialized." % \
- type(element_or_tree)
+ raise TypeError, f"Type '{type(element_or_tree)}' cannot be serialized."
def parse(source, _BaseParser parser=None, *, base_url=None):
diff --git a/src/lxml/extensions.pxi b/src/lxml/extensions.pxi
index b6d5d485..d2d059c4 100644
--- a/src/lxml/extensions.pxi
+++ b/src/lxml/extensions.pxi
@@ -581,7 +581,7 @@ cdef xpath.xmlXPathObject* _wrapXPathObject(object obj, _Document doc,
else:
if context is None or doc is None:
raise XPathResultError, \
- u"Non-Element values not supported at this point - got %r" % value
+ f"Non-Element values not supported at this point - got {value!r}"
# support strings by appending text nodes to an Element
if isinstance(value, unicode):
value = _utf8(value)
@@ -604,13 +604,12 @@ cdef xpath.xmlXPathObject* _wrapXPathObject(object obj, _Document doc,
xpath.xmlXPathNodeSetAdd(resultSet, c_node)
else:
raise XPathResultError, \
- u"This is not a supported node-set result: %r" % value
+ f"This is not a supported node-set result: {value!r}"
except:
xpath.xmlXPathFreeNodeSet(resultSet)
raise
else:
- raise XPathResultError, u"Unknown return type: %s" % \
- python._fqtypename(obj).decode('utf8')
+ raise XPathResultError, f"Unknown return type: {python._fqtypename(obj).decode('utf8')}"
return xpath.xmlXPathWrapNodeSet(resultSet)
cdef object _unwrapXPathObject(xpath.xmlXPathObject* xpathObj,
@@ -640,7 +639,7 @@ cdef object _unwrapXPathObject(xpath.xmlXPathObject* xpathObj,
elif xpathObj.type == xpath.XPATH_XSLT_TREE:
return _createNodeSetResult(xpathObj, doc, context)
else:
- raise XPathResultError, u"Unknown xpath result %s" % unicode(xpathObj.type)
+ raise XPathResultError, f"Unknown xpath result {xpathObj.type}"
cdef object _createNodeSetResult(xpath.xmlXPathObject* xpathObj, _Document doc,
_BaseContext context):
@@ -690,7 +689,7 @@ cdef _unpackNodeSetEntry(list results, xmlNode* c_node, _Document doc,
pass
else:
raise NotImplementedError, \
- u"Not yet implemented result node type: %d" % c_node.type
+ f"Not yet implemented result node type: {c_node.type}"
cdef void _freeXPathObject(xpath.xmlXPathObject* xpathObj):
u"""Free the XPath object, but *never* free the *content* of node sets.
@@ -862,9 +861,8 @@ cdef void _xpath_function_call(xpath.xmlXPathParserContext* ctxt,
_extension_function_call(context, function, ctxt, nargs)
else:
xpath.xmlXPathErr(ctxt, xpath.XPATH_UNKNOWN_FUNC_ERROR)
- context._exc._store_exception(
- XPathFunctionError(u"XPath function '%s' not found" %
- _namespacedNameFromNsName(rctxt.functionURI, rctxt.function)))
+ context._exc._store_exception(XPathFunctionError(
+ f"XPath function '{_namespacedNameFromNsName(rctxt.functionURI, rctxt.function)}' not found"))
except:
# may not be the right error, but we need to tell libxml2 *something*
xpath.xmlXPathErr(ctxt, xpath.XPATH_UNKNOWN_FUNC_ERROR)
diff --git a/src/lxml/objectify.pyx b/src/lxml/objectify.pyx
index 766d422a..369ff8f8 100644
--- a/src/lxml/objectify.pyx
+++ b/src/lxml/objectify.pyx
@@ -238,8 +238,7 @@ cdef class ObjectifiedElement(ElementBase):
# properties are looked up /after/ __setattr__, so we must emulate them
if tag == u'text' or tag == u'pyval':
# read-only !
- raise TypeError, u"attribute '%s' of '%s' objects is not writable" % \
- (tag, _typename(self))
+ raise TypeError, f"attribute '{tag}' of '{_typename(self)}' objects is not writable"
elif tag == u'tail':
cetree.setTailText(self._c_node, value)
return
@@ -547,8 +546,7 @@ cdef _setSlice(sliceobject, _Element target, items):
# sanity check - raise what a list would raise
if c_step != 1 and len(del_items) != len(new_items):
raise ValueError, \
- u"attempt to assign sequence of size %d to extended slice of size %d" % (
- len(new_items), len(del_items))
+ f"attempt to assign sequence of size {len(new_items)} to extended slice of size {len(del_items)}"
# replace existing items
pos = 0
@@ -848,7 +846,7 @@ cpdef bint __parseBool(s) except -1:
return False
value = __parseBoolAsInt(s)
if value == -1:
- raise ValueError, u"Invalid boolean value: '%s'" % s
+ raise ValueError, f"Invalid boolean value: '{s}'"
return value
cdef inline int __parseBoolAsInt(text) except -2:
@@ -1254,8 +1252,7 @@ cdef class ElementMaker:
if makeelement is not None:
if not callable(makeelement):
raise TypeError(
- "argument of 'makeelement' parameter must be callable, got %s" %
- type(makeelement))
+ f"argument of 'makeelement' parameter must be callable, got {type(makeelement)}")
self._makeelement = makeelement
else:
self._makeelement = None
@@ -1325,8 +1322,7 @@ cdef object _dump(_Element element, int indent):
value = None
else:
value = repr(value)
- result = u"%s%s = %s [%s]\n" % (indentstr, element.tag,
- value, _typename(element))
+ result = f"{indentstr}{element.tag} = {value} [{_typename(element)}]\n"
xsi_ns = u"{%s}" % XML_SCHEMA_INSTANCE_NS
pytype_ns = u"{%s}" % PYTYPE_NAMESPACE
for name, value in cetree.iterattributes(element, 3):
@@ -1337,7 +1333,7 @@ cdef object _dump(_Element element, int indent):
else:
name = name.replace(pytype_ns, u'py:')
name = name.replace(xsi_ns, u'xsi:')
- result += u"%s * %s = %r\n" % (indentstr, name, value)
+ result += f"{indentstr} * {name} = {value!r}\n"
indent += 1
for child in element.iterchildren():
diff --git a/src/lxml/objectpath.pxi b/src/lxml/objectpath.pxi
index 44272e1f..2e8d1922 100644
--- a/src/lxml/objectpath.pxi
+++ b/src/lxml/objectpath.pxi
@@ -190,8 +190,8 @@ cdef _find_object_path(_Element root, _ObjectPath* c_path, Py_ssize_t c_path_len
if default_value is not _NO_DEFAULT:
return default_value
else:
- raise ValueError(u"root element does not match: need %s, got %s" %
- (cetree.namespacedNameFromNsName(c_href, c_name), root.tag))
+ raise ValueError(
+ f"root element does not match: need {cetree.namespacedNameFromNsName(c_href, c_name)}, got {root.tag}")
while c_node is not NULL:
c_path_len -= 1
@@ -216,7 +216,7 @@ cdef _find_object_path(_Element root, _ObjectPath* c_path, Py_ssize_t c_path_len
return default_value
else:
tag = cetree.namespacedNameFromNsName(c_href, c_name)
- raise AttributeError, u"no such child: " + tag
+ raise AttributeError, f"no such child: {tag}"
cdef _create_object_path(_Element root, _ObjectPath* c_path,
@@ -238,8 +238,8 @@ cdef _create_object_path(_Element root, _ObjectPath* c_path,
if c_href is NULL or c_href[0] == c'\0':
c_href = tree._getNs(c_node)
if not cetree.tagMatches(c_node, c_href, c_name):
- raise ValueError(u"root element does not match: need %s, got %s" %
- (cetree.namespacedNameFromNsName(c_href, c_name), root.tag))
+ raise ValueError(
+ f"root element does not match: need {cetree.namespacedNameFromNsName(c_href, c_name)}, got {root.tag}")
while c_path_len > 1:
c_path_len -= 1
@@ -324,7 +324,7 @@ cdef int _recursive_build_descendant_paths(tree.xmlNode* c_node,
tags[tag] = 1
else:
tags[tag] = count + 1
- tag += u'[%d]' % count
+ tag += f'[{count}]'
path.append(tag)
_recursive_build_descendant_paths(c_child, path, path_list)
del path[-1]
diff --git a/src/lxml/parser.pxi b/src/lxml/parser.pxi
index 0c6da653..04a287b8 100644
--- a/src/lxml/parser.pxi
+++ b/src/lxml/parser.pxi
@@ -630,10 +630,9 @@ cdef int _raiseParseError(xmlparser.xmlParserCtxt* ctxt, filename,
except UnicodeDecodeError:
# the filename may be in there => play it safe
message = (ctxt.lastError.message).decode('iso8859-1')
- message = u"Error reading file '%s': %s" % (
- filename, message.strip())
+ message = f"Error reading file '{filename}': {message.strip()}"
else:
- message = u"Error reading '%s'" % filename
+ message = f"Error reading '{filename}'"
raise IOError, message
elif error_log:
raise error_log._buildParseException(
@@ -644,7 +643,7 @@ cdef int _raiseParseError(xmlparser.xmlParserCtxt* ctxt, filename,
line = ctxt.lastError.line
column = ctxt.lastError.int2
if ctxt.lastError.line > 0:
- message = u"line %d: %s" % (line, message)
+ message = f"line {line}: {message}"
raise XMLSyntaxError(message, code, line, column, filename)
else:
raise XMLSyntaxError(None, xmlerror.XML_ERR_INTERNAL_ERROR, 0, 0,
@@ -819,7 +818,7 @@ cdef class _BaseParser:
encoding = _utf8(encoding)
enchandler = tree.xmlFindCharEncodingHandler(_cstr(encoding))
if enchandler is NULL:
- raise LookupError, u"unknown encoding: '%s'" % encoding
+ raise LookupError, f"unknown encoding: '{encoding}'"
tree.xmlCharEncCloseFunc(enchandler)
self._default_encoding = encoding
@@ -1036,7 +1035,7 @@ cdef class _BaseParser:
else:
c_encoding = 'UCS-4LE'
else:
- assert False, "Illegal Unicode kind %d" % c_kind
+ assert False, f"Illegal Unicode kind {c_kind}"
else:
py_buffer_len = python.PyUnicode_GET_DATA_SIZE(utext)
c_text = python.PyUnicode_AS_DATA(utext)
@@ -1855,7 +1854,7 @@ cdef _Document _parseDocument(source, _BaseParser parser, base_url):
if hasattr(source, u'read'):
return _parseFilelikeDocument(source, url, parser)
- raise TypeError, u"cannot parse from '%s'" % python._fqtypename(source).decode('UTF-8')
+ raise TypeError, f"cannot parse from '{python._fqtypename(source).decode('UTF-8')}'"
cdef _Document _parseDocumentFromURL(url, _BaseParser parser):
c_doc = _parseDocFromFile(url, parser)
diff --git a/src/lxml/proxy.pxi b/src/lxml/proxy.pxi
index 48919084..2b948f26 100644
--- a/src/lxml/proxy.pxi
+++ b/src/lxml/proxy.pxi
@@ -568,7 +568,7 @@ cdef _Document _adoptForeignDoc(xmlDoc* c_doc, _BaseParser parser=None, bint is_
doc_type = c_doc.type
if is_owned:
tree.xmlFreeDoc(c_doc)
- raise ValueError("Illegal document provided: expected XML or HTML, found %s" % doc_type)
+ raise ValueError(f"Illegal document provided: expected XML or HTML, found {doc_type}")
cdef xmlNode* c_node = <xmlNode*>c_doc
diff --git a/src/lxml/readonlytree.pxi b/src/lxml/readonlytree.pxi
index 238300e2..e532895c 100644
--- a/src/lxml/readonlytree.pxi
+++ b/src/lxml/readonlytree.pxi
@@ -19,7 +19,7 @@ cdef class _ReadOnlyProxy:
return 0
cdef int _raise_unsupported_type(self) except -1:
- raise TypeError("Unsupported node type: %d" % self._c_node.type)
+ raise TypeError(f"Unsupported node type: {self._c_node.type}")
cdef void free_after_use(self):
u"""Should the xmlNode* be freed when releasing the proxy?
@@ -57,7 +57,7 @@ cdef class _ReadOnlyProxy:
else:
return funicode(self._c_node.content)
elif self._c_node.type == tree.XML_ENTITY_REF_NODE:
- return u'&%s;' % funicode(self._c_node.name)
+ return f'&{funicode(self._c_node.name)};'
else:
self._raise_unsupported_type()
@@ -263,12 +263,12 @@ cdef class _ReadOnlyEntityProxy(_ReadOnlyProxy):
def __set__(self, value):
value_utf = _utf8(value)
if u'&' in value or u';' in value:
- raise ValueError(u"Invalid entity name '%s'" % value)
+ raise ValueError(f"Invalid entity name '{value}'")
tree.xmlNodeSetName(self._c_node, _xcstr(value_utf))
property text:
def __get__(self):
- return u'&%s;' % funicode(self._c_node.name)
+ return f'&{funicode(self._c_node.name)};'
@cython.internal
@@ -328,7 +328,7 @@ cdef _ReadOnlyProxy _newReadOnlyProxy(
tree.XML_ENTITY_REF_NODE):
el = _ReadOnlyProxy.__new__(_ReadOnlyProxy)
else:
- raise TypeError("Unsupported element type: %d" % c_node.type)
+ raise TypeError(f"Unsupported element type: {c_node.type}")
el._c_node = c_node
_initReadOnlyProxy(el, source_proxy)
return el
@@ -387,7 +387,7 @@ cdef class _OpaqueDocumentWrapper(_OpaqueNodeWrapper):
if tree.xmlDocGetRootElement(<tree.xmlDoc*>self._c_node) is not NULL:
raise ValueError, u"cannot append, document already has a root element"
elif c_node.type not in (tree.XML_PI_NODE, tree.XML_COMMENT_NODE):
- raise TypeError, u"unsupported element type for top-level node: %d" % c_node.type
+ raise TypeError, f"unsupported element type for top-level node: {c_node.type}"
c_node = _copyNodeToDoc(c_node, <tree.xmlDoc*>self._c_node)
c_next = c_node.next
tree.xmlAddChild(self._c_node, c_node)
@@ -462,7 +462,7 @@ cdef class _ModifyContentOnlyEntityProxy(_ModifyContentOnlyProxy):
def __set__(self, value):
value = _utf8(value)
assert u'&' not in value and u';' not in value, \
- u"Invalid entity name '%s'" % value
+ f"Invalid entity name '{value}'"
c_text = _xcstr(value)
tree.xmlNodeSetName(self._c_node, c_text)
@@ -518,7 +518,7 @@ cdef _ReadOnlyProxy _newAppendOnlyProxy(
elif c_node.type == tree.XML_COMMENT_NODE:
el = _ModifyContentOnlyProxy.__new__(_ModifyContentOnlyProxy)
else:
- raise TypeError("Unsupported element type: %d" % c_node.type)
+ raise TypeError(f"Unsupported element type: {c_node.type}")
el._c_node = c_node
_initReadOnlyProxy(el, source_proxy)
return el
@@ -532,7 +532,7 @@ cdef xmlNode* _roNodeOf(element) except NULL:
elif isinstance(element, _OpaqueNodeWrapper):
c_node = (<_OpaqueNodeWrapper>element)._c_node
else:
- raise TypeError, u"invalid argument type %s" % type(element)
+ raise TypeError, f"invalid argument type {type(element)}"
if c_node is NULL:
raise TypeError, u"invalid element"
@@ -547,7 +547,7 @@ cdef xmlNode* _nonRoNodeOf(element) except NULL:
elif isinstance(element, _OpaqueNodeWrapper):
c_node = (<_OpaqueNodeWrapper>element)._c_node
else:
- raise TypeError, u"invalid argument type %s" % type(element)
+ raise TypeError, f"invalid argument type {type(element)}"
if c_node is NULL:
raise TypeError, u"invalid element"
diff --git a/src/lxml/saxparser.pxi b/src/lxml/saxparser.pxi
index 6541349a..6121de03 100644
--- a/src/lxml/saxparser.pxi
+++ b/src/lxml/saxparser.pxi
@@ -34,7 +34,7 @@ cdef int _buildParseEventFilter(events) except -1:
elif event == 'pi':
event_filter |= PARSE_EVENT_FILTER_PI
else:
- raise ValueError, u"invalid event name '%s'" % event
+ raise ValueError, f"invalid event name '{event}'"
return event_filter
@@ -752,8 +752,7 @@ cdef class TreeBuilder(_SaxParserTarget):
"""
element = self._handleSaxEnd(tag)
assert self._last.tag == tag,\
- u"end tag mismatch (expected %s, got %s)" % (
- self._last.tag, tag)
+ f"end tag mismatch (expected {self._last.tag}, got {tag})"
return element
def pi(self, target, data):
diff --git a/src/lxml/serializer.pxi b/src/lxml/serializer.pxi
index 604fbc27..40a0f75d 100644
--- a/src/lxml/serializer.pxi
+++ b/src/lxml/serializer.pxi
@@ -14,6 +14,7 @@ cdef enum _OutputMethods:
OUTPUT_METHOD_HTML
OUTPUT_METHOD_TEXT
+
cdef int _findOutputMethod(method) except -1:
if method is None:
return OUTPUT_METHOD_XML
@@ -24,7 +25,8 @@ cdef int _findOutputMethod(method) except -1:
return OUTPUT_METHOD_HTML
if method == "text":
return OUTPUT_METHOD_TEXT
- raise ValueError(u"unknown output method %r" % method)
+ raise ValueError(f"unknown output method {method!r}")
+
cdef _textToString(xmlNode* c_node, encoding, bint with_tail):
cdef bint needs_conversion
@@ -115,7 +117,7 @@ cdef _tostring(_Element element, encoding, doctype, method,
if enchandler is NULL and c_enc is not NULL:
if encoding is not None:
encoding = encoding.decode('UTF-8')
- raise LookupError, u"unknown encoding: '%s'" % encoding
+ raise LookupError, f"unknown encoding: '{encoding}'"
c_buffer = tree.xmlAllocOutputBuffer(enchandler)
if c_buffer is NULL:
tree.xmlCharEncCloseFunc(enchandler)
@@ -193,7 +195,7 @@ cdef _raiseSerialisationError(int error_result):
raise MemoryError()
message = ErrorTypes._getName(error_result)
if message is None:
- message = u"unknown error %d" % error_result
+ message = f"unknown error {error_result}"
raise SerialisationError, message
############################################################
@@ -590,7 +592,7 @@ cdef _write_attr_string(tree.xmlOutputBuffer* buf, const char *string):
l = 1
if ((l == 1) or (not tree.xmlIsCharQ(val))):
- raise ValueError("Invalid character: %X" % val)
+ raise ValueError(f"Invalid character: {val:X}")
# We could do multiple things here. Just save
# as a char ref
@@ -758,7 +760,7 @@ cdef _FilelikeWriter _create_output_buffer(
enchandler = tree.xmlFindCharEncodingHandler(c_enc)
if enchandler is NULL:
raise LookupError(u"unknown encoding: '%s'" %
- c_enc.decode(u'UTF-8') if c_enc is not NULL else u'')
+ c_enc.decode('UTF-8') if c_enc is not NULL else u'')
try:
if _isString(f):
filename8 = _encodeFilename(f)
@@ -772,8 +774,7 @@ cdef _FilelikeWriter _create_output_buffer(
c_buffer = writer._createOutputBuffer(enchandler)
else:
raise TypeError(
- u"File or filename expected, got '%s'" %
- python._fqtypename(f).decode('UTF-8'))
+ f"File or filename expected, got '{python._fqtypename(f).decode('UTF-8')}'")
except:
tree.xmlCharEncCloseFunc(enchandler)
raise
@@ -837,8 +838,7 @@ cdef _tofilelikeC14N(f, _Element element, bint exclusive, bint with_comments,
if bytes_count < 0:
error = bytes_count
else:
- raise TypeError(u"File or filename expected, got '%s'" %
- python._fqtypename(f).decode('UTF-8'))
+ raise TypeError(f"File or filename expected, got '{python._fqtypename(f).decode('UTF-8')}'")
finally:
_destroyFakeDoc(c_base_doc, c_doc)
if c_inclusive_ns_prefixes is not NULL:
@@ -1227,7 +1227,8 @@ cdef class _IncrementalFileWriter:
self._status = WRITER_FINISHED
elif content is not None:
- raise TypeError("got invalid input value of type %s, expected string or Element" % type(content))
+ raise TypeError(
+ f"got invalid input value of type {type(content)}, expected string or Element")
self._handle_error(self._c_out.error)
if not self._buffered:
tree.xmlOutputBufferFlush(self._c_out)
diff --git a/src/lxml/xmlerror.pxi b/src/lxml/xmlerror.pxi
index 108f0069..a57ff975 100644
--- a/src/lxml/xmlerror.pxi
+++ b/src/lxml/xmlerror.pxi
@@ -244,9 +244,9 @@ cdef class _BaseErrorLog:
filename = self._first_error.filename
if line > 0:
if column > 0:
- message = u"%s, line %d, column %d" % (message, line, column)
+ message = f"{message}, line {line}, column {column}"
else:
- message = u"%s, line %d" % (message, line)
+ message = f"{message}, line {line}"
return exctype(message, code, line, column, filename)
@cython.final
@@ -261,10 +261,9 @@ cdef class _BaseErrorLog:
message = default_message
if self._first_error.line > 0:
if self._first_error.column > 0:
- message = u"%s, line %d, column %d" % (
- message, self._first_error.line, self._first_error.column)
+ message = f"{message}, line {self._first_error.line}, column {self._first_error.column}"
else:
- message = u"%s, line %d" % (message, self._first_error.line)
+ message = f"{message}, line {self._first_error.line}"
return message
cdef class _ListErrorLog(_BaseErrorLog):
diff --git a/src/lxml/xslt.pxi b/src/lxml/xslt.pxi
index 7f81b729..0372db04 100644
--- a/src/lxml/xslt.pxi
+++ b/src/lxml/xslt.pxi
@@ -113,7 +113,7 @@ cdef xmlDoc* _xslt_resolve_from_python(const_xmlChar* c_uri, void* c_context,
cdef void _xslt_store_resolver_exception(const_xmlChar* c_uri, void* context,
xslt.xsltLoadType c_type) with gil:
try:
- message = u"Cannot resolve URI %s" % _decodeFilename(c_uri)
+ message = f"Cannot resolve URI {_decodeFilename(c_uri)}"
if c_type == xslt.XSLT_LOAD_DOCUMENT:
exception = XSLTApplyError(message)
else:
@@ -382,7 +382,7 @@ cdef class XSLT:
# make sure we always have a stylesheet URL
if c_doc.URL is NULL:
doc_url_utf = python.PyUnicode_AsASCIIString(
- u"string://__STRING__XSLT__/%d.xslt" % id(self))
+ f"string://__STRING__XSLT__/{id(self)}.xslt")
c_doc.URL = tree.xmlStrdup(_xcstr(doc_url_utf))
self._error_log = _ErrorLog()
@@ -586,11 +586,11 @@ cdef class XSLT:
error = self._error_log.last_error
if error is not None and error.message:
if error.line > 0:
- message = u"%s, line %d" % (error.message, error.line)
+ message = f"{error.message}, line {error.line}"
else:
message = error.message
elif error is not None and error.line > 0:
- message = u"Error applying stylesheet, line %d" % error.line
+ message = f"Error applying stylesheet, line {error.line}"
else:
message = u"Error applying stylesheet"
raise XSLTApplyError(message, self._error_log)
@@ -959,7 +959,7 @@ cdef class _XSLTProcessingInstruction(PIBase):
elif u'"' in value or u'>' in value:
raise ValueError, u"Invalid URL, must not contain '\"' or '>'"
else:
- attrib = u' href="%s"' % value
+ attrib = f' href="{value}"'
text = u' ' + self.text
if _FIND_PI_HREF(text):
self.text = _REPLACE_PI_HREF(attrib, text)
diff --git a/src/lxml/xsltext.pxi b/src/lxml/xsltext.pxi
index 92c50edf..6ed819b6 100644
--- a/src/lxml/xsltext.pxi
+++ b/src/lxml/xsltext.pxi
@@ -147,7 +147,7 @@ cdef class XSLTExtension:
proxy.free_after_use()
else:
raise TypeError, \
- u"unsupported XSLT result type: %d" % c_node.type
+ f"unsupported XSLT result type: {c_node.type}"
c_node = c_next
return results
@@ -182,7 +182,7 @@ cdef void _callExtensionElement(xslt.xsltTransformContext* c_ctxt,
dict_result = python.PyDict_GetItem(
context._extension_elements, (c_uri, c_inst_node.name))
if dict_result is NULL:
- raise KeyError, u"extension element %s not found" % funicode(c_inst_node.name)
+ raise KeyError, f"extension element {funicode(c_inst_node.name)} not found"
extension = <object>dict_result
try:
@@ -206,7 +206,7 @@ cdef void _callExtensionElement(xslt.xsltTransformContext* c_ctxt,
# this isn't easy to support using read-only
# nodes, as the smart-string factory must
# instantiate the parent proxy somehow...
- raise TypeError("Unsupported element type: %d" % c_context_node.type)
+ raise TypeError(f"Unsupported element type: {c_context_node.type}")
else:
context_node = _newReadOnlyProxy(self_node, c_context_node)