markupsafe
markupsafe copied to clipboard
Python 3.14: SystemError: <built-in function _escape_inner> returned NULL without setting an exception
Environment: macOS Apple silicon
- Python version: 3.14.0b3
- MarkupSafe version: 3.0.2
from markupsafe import escape
print(escape(828))
Gives:
❯ python3.14 1.py
Traceback (most recent call last):
File "/Users/hugo/github/devguide/1.py", line 3, in <module>
print(escape(828))
~~~~~~^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/site-packages/markupsafe/__init__.py", line 45, in escape
return Markup(_escape_inner(str(s)))
~~~~~~~~~~~~~^^^^^^^^
SystemError: <built-in function _escape_inner> returned NULL without setting an exception
It prints out 828 as expected with:
- Python 3.14 and MarkupSafe 3.0.1
- Python 3.13 and MarkupSafe 3.0.1
- Python 3.13 and MarkupSafe 3.0.2
I can't reproduce this issue. I installed 3.14.0b3 from python.org, and ran the following:
$ uv run --python /Library/Frameworks/Python.framework/Versions/3.14/bin/python3 --with markupsafe==3.0.2 example.py
828
Your traceback looks like the bug that was fixed in 3.0.1 and 3.0.2. Are you sure you're on 3.0.2?
Still reproducible with the uv command.
And adding a version print:
import sys
from markupsafe import escape
print(sys.version)
print(escape("828"))
❯ uv run --python /Library/Frameworks/Python.framework/Versions/3.14/bin/python3 --with markupsafe==3.0.2 1.py
3.14.0b3 (v3.14.0b3:26d485d1225, Jun 17 2025, 12:48:06) [Clang 16.0.0 (clang-1600.0.26.6)]
Traceback (most recent call last):
File "/private/tmp/1.py", line 5, in <module>
print(escape("828"))
~~~~~~^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/site-packages/markupsafe/__init__.py", line 40, in escape
return Markup(_escape_inner(s))
~~~~~~~~~~~~~^^^
SystemError: <built-in function _escape_inner> returned NULL without setting an exception
Same error with:
import sys
import markupsafe
print(sys.version)
print(markupsafe.escape("828"))
And:
import sys
from markupsafe import escape
import markupsafe
print(sys.version)
print(markupsafe.escape("828"))
Hmm, but this works:
import sys
from markupsafe import escape
import markupsafe
print(sys.version)
print(escape("828"))
All those work for me. Printing the version, and renaming to 1.py:
uv run --python /Library/Frameworks/Python.framework/Versions/3.14/bin/python3 --with markupsafe==3.0.2 1.py
3.14.0b3 (v3.14.0b3:26d485d1225, Jun 17 2025, 12:48:06) [Clang 16.0.0 (clang-1600.0.26.6)]
828
I'm on another Mac right now and they also all work here too...
❯ uv run --python /Library/Frameworks/Python.framework/Versions/3.14/bin/python3 --with markupsafe==3.0.2 1.py
3.14.0b3 (v3.14.0b3:26d485d1225, Jun 17 2025, 12:48:06) [Clang 16.0.0 (clang-1600.0.26.6)]
828
Perhaps uv built and cached a MarkupSafe wheel compiled against a previous 3.14 version. The wheel name would look correct to the installer, but might have incompatible compiled C code. Try running with a different --cache-dir to force it to recompile MarkupSafe.
Thanks, it was indeed some old cached files. Comparing the problematic machine (left) with the working one (right) shows files were built in April and May respectively:
And the WHEEL file shows the problematic one was built with an older setuptools giving an older tag:
(--cache-dir and --no-cache didn't actually help, I instead did a full uv cache clean)
Thanks again for the help!