Fri, 26 Jun 2026
# Upgrading this blog to Python 3.12
Pyblosxom 1.5.3 — the engine powering this
blog — was last released in 2013 and officially targets Python 2.7. It does
include a use_2to3 = True flag in its setup.py, which historically
instructed setuptools to auto-convert the source at install time. That
mechanism was removed from setuptools 58.0 (2021), so the package now installs
as raw Python 2 code on modern systems.
The upgrade path to Python 3.12 required two layers of fixes:
Automated conversion via 2to3
The Dockerfile runs 2to3 -w -n over the installed Pyblosxom package
directory at build time. This handles the bulk of the syntax differences
(print statements, has_key(), except E, e style, etc.).
Manual patches for removed APIs
2to3 converts syntax but does not know about API removals. A startup
script (patch_pyblosxom.py) applies targeted fixes each time the container
starts, covering:
__init__.py: implicit relative importfrom _version import→from ._version importcrashhandling.py:cgi.escaperemoved in 3.8 →html.escape;StringIO.lenattribute gone →len(output.getvalue())pyblosxom.py:entrylist.sort()on objects that only define__cmp__(ignored in Python 3) → explicitkey=lambdacache/base.py:2to3convertedself.has_key(key)calls tokey in self, which recurses infinitely because the class has no__contains__. Fixed by patching__getitem__to callisCached()directly and adding a proper__contains__method.plugins/markdown_parser.py:story.decode("utf-8").encode("utf-8")round-trip is meaningless on Python 3 strings → passstorydirectly.renderers/blosxom.py:"".join(content)fails when a stray bytes value slips through → decode any bytes items before joining.
The local plugins (bib.py, pycalendar.py, pyarchives.py, etc.) also
needed porting: print statements, dict.has_key(), mixed tab/space
indentation, and the _bibtex C extension (Python 2 only) was replaced with
the pure-Python bibtexparser package.
What's the point of this you might be asking? Experimenting with AI and what it is capable of. Most of this tedious back and forth work was done by Claude. It's a pretty powerful paradigm if you can point it to the output and iterate semi-autonomously.
Mailsink got a makeover as well.
Planning to move this to Hugo eventually, but for now this has to do.
posted at 14:00 | path: /python | permanent link to this entry
