Upgrading lxml 4 to 5
Breaking4.9.4 → 5.4.0Breaking2Security3Platform2Deprecated1New2Changed16Fixed24Other9
BreakingUpgrade verdict
2 breaking changes and 2 platform requirement changes and 3 security fixes.
In plain terms
- Three old methods that were deprecated for a long time have been deleted, so code calling them will break.
- The HTML cleaning feature has been moved out of lxml into its own package. If you use it, you need to install it separately or switch to the lxml[html_clean] extra.
- This version no longer runs on Python 2.7 or any Python older than 3.6.
- The library can now be used with the early Python 3.13 alpha 2 release.
Must act Top 5 of 8 that need code or config changes
Python requirement changed in 5.1.0: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.* → >=3.6.
What you must change
Breaking2
Removes the long deprecated methods parser.setElementClassLookup(), xslt_transform.apply() and xpath.evaluate().
parser.setElementClassLookup()xslt_transform.apply()xpath.evaluate()Extracts lxml.html.clean into a separate library due to past security issues; projects using it must change requirements.
lxml.html.cleanlxml[html_clean]Security3
Binary wheels use libxml2 2.13.8 and libxslt 1.1.43 to resolve several CVEs.
Resolves CVE-2025-24928 as described in the libxml2 issue 847.
lxml no longer expands external entities (XXE) by default; enable with resolve_entities=True.
resolve_entitiesPlatform2
Removes support for Python 2.7 and Python versions below 3.6.
Adds early support for Python 3.13a2.
Deprecations to plan for
Deprecated1
Deprecates the strip_cdata option in HTMLParser(), which turned out to be useless.
strip_cdataHTMLParser()API changes
Generated by DepDelta from published Python source. Not mixed with prose notes.
- changed:
class ElementMaker(object) → class ElementMaker
- removed:
class Cleaner(object) - removed:
constructor Cleaner(**kw) - removed:
field Cleaner.add_nofollow - removed:
field Cleaner.allow_tags - removed:
field Cleaner.annoying_tags - removed:
field Cleaner.comments - removed:
field Cleaner.embedded - removed:
field Cleaner.forms - removed:
field Cleaner.frames - removed:
field Cleaner.host_whitelist - removed:
field Cleaner.inline_style - removed:
field Cleaner.javascript - removed:
field Cleaner.kill_tags - removed:
field Cleaner.links - removed:
field Cleaner.meta - removed:
field Cleaner.page_structure - removed:
field Cleaner.processing_instructions - removed:
field Cleaner.remove_tags - removed:
field Cleaner.remove_unknown_tags - removed:
field Cleaner.safe_attrs - removed:
field Cleaner.safe_attrs_only - removed:
field Cleaner.scripts - removed:
field Cleaner.style - removed:
field Cleaner.whitelist_tags - removed:
function autolink(el, link_regexes=…, avoid_elements=…, avoid_hosts=…, avoid_classes=…) - removed:
function autolink_html(html, *args, **kw) - removed:
function word_break(el, max_width=…, avoid_elements=…, avoid_classes=…, break_character=…) - removed:
function word_break_html(html, *args, **kw) - removed:
method Cleaner.allow_element(el) - removed:
method Cleaner.allow_embedded_url(el, url) - removed:
method Cleaner.allow_follow(anchor) - removed:
method Cleaner.clean_html(html) - removed:
method Cleaner.kill_conditional_comments(doc) - removed:
variable clean - removed:
variable clean_html
- changed:
class DefaultErrorCreator(object) → class DefaultErrorCreator
- changed:
constructor Schematron(etree=…, file=…, include=…, expand=…, include_params=…, expand_params=…, compile_params=…, store_schematron=…, store_xslt=…, store_report=…, phase=…, error_finder=…) → constructor Schematron(etree=…, file=…, include=…, expand=…, include_params=…, expand_params=…, compile_params=…, store_schematron=…, store_xslt=…, store_report=…, phase=…, error_finder=…, validate_schema=…) - added:
function schematron_schema_valid(arg)
- changed:
class ElementTreeProducer(object) → class ElementTreeProducer