ImportError: cannot import name 'etree' from 'lxml'
Fixes pyquery failing on Python 3.12 because the installed lxml is too old. Use when `from pyquery import PyQuery` raises `ImportError: cannot import name 'etree' from 'lxml'`. Not for missing pyquery or missing lxml.
Your lxml predates Python 3.12 support, so its compiled modules do not expose etree properly on 3.12 and pyquery's import dies. Upgrade with python -m pip install -U lxml pyquery. The import works once lxml is 4.9.3 or newer.
The error
ImportError: cannot import name 'etree' from 'lxml'Fix it
- Check the versions
python --version
python -m pip show lxml | head -2Expected: Python 3.12+ with lxml older than 4.9.3. That combination is the broken one.
- Upgrade lxml and pyquery
python -m pip install -U lxml pyqueryExpected: lxml 4.9.3+ (or 5.x) installs with a proper 3.12 wheel.
- Confirm
python -c "from pyquery import PyQuery; print('ok')"Expected: prints ok.
When this applies
- the ImportError names
etreefromlxmlwhen importing pyquery - you are on Python 3.12+ with an old lockfile
- it worked on 3.11 and broke after the interpreter upgrade
When it does NOT apply
No module named 'lxml'means lxml is absent entirelyNo module named 'pyquery'is the missing install
Compatibility
Python 3.12+ requires lxml 4.9.3+. pyquery 2.x with older lxml on 3.12 is the reported combination (gh:gawel/pyquery#255).
Why it happens
lxml is a C extension and each release supports a fixed set of Python versions. lxml 4.9.2 and older have no Python 3.12 support; on 3.12 the old binary misbehaves and the etree submodule import fails. pyquery does from lxml import etree at its own import time, so the version skew surfaces as a pyquery import error.
Edge cases
- If your lockfile pins
lxml==4.9.2, bump the pin. There is no workaround that keeps old lxml on 3.12. - Conda users:
conda update lxmlfrom conda-forge gets a 3.12-compatible build. - The same skew breaks plain
from lxml import etreetoo. The fix is identical with or without pyquery.