V
Victor Stinner
vstinner.github.io · Personal blog · on HN since 2018
Victor Stinner, a CPython core developer, writes about Python internals, the C API, Unicode handling, subinterpreters, and bug fixes.
What HN saysHN commenters recommend it for understanding why Python 3 handles Unicode and OS encodings as it does, and cite his PEP 383 surrogateescape write-up.
15HN people shared it
7linked it in comments
9stories submitted
25story points
12 months agolast shared
2018people per year2026
Most-shared posts
- 1The History and rationale of the Python 3 Unicode model for the operating system3 people · 9 points · first shared 2021 · discussion on HN
- 2Python C API: Add functions to access PyObject2 people · 4 points · first shared 2021 · 1 comments on HN
- 3Python 3.7 UTF-8 Mode2 people · 2 points · first shared 2018 · discussion on HN
- 4Isolate Python Subinterpreters1 people · 4 points · first shared 2020 · discussion on HN
- 5Pass the Python thread state explicitly1 people · 3 points · first shared 2020 · discussion on HN
- 6Remove private C API functions1 people · 2 points · first shared 2023 · discussion on HN
- 7How Victor Stinner fixed a very old GIL race condition in Python 3.71 people · 1 points · first shared 2018 · discussion on HN
- 8Painful history python filesystem encoding1 people · first shared 2023
- 9Journey to stable benchmark system1 people · first shared 2020
- 10Journey to stable benchmark deadcode1 people · first shared 2020
- 11Posix locale1 people · first shared 2019
- 12Journey to stable benchmark average1 people · first shared 2020
- 13Homepage1 people · first shared 2018
- 14Pep 3831 people · first shared 2025
What HN people wrote when they linked it
nicolaslem · 2018-10-06
For anyone interested in learning why Python 3 works this way I highly recommend the blog of Victor Stinner[0].
As for the article, this is nothing new. The problem is similar to the issues raised by Armin Ronacher[1]. These problems are well known and Python developers address them one at a time. Issues around these egde cases have improved since the initial release of Python 3.0.
[0] http://vstinner.github.io
[1] http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/
sametmax · 2018-05-04
Funnily, because of the 2/3 transition, Python became a language obsessed with encoding correctness. Hence the team spent a great deal improving the situation, from version to version during the last 10 years.
For a fantastic read (from Victor Stinner himself) on all the work done and get how twisted this get when you want to be cross plateform and abstract it:
https://vstinner.github.io/python37-new-utf8-mode.html
Windows and Linux FS encoding, of course, are at the center of the challenge.
It's also the reason why we now have a __fspath__ protocol that allows any object to be converted to a file system path instead of having pathlib.Path inheriting from string.
saurik · 2021-01-21
So, my favorite thought process from the Python 2 to 3 transition comes from staring deeply into the hubris of the Python 3000 effort itself as wanting to insist "everything is Unicode"; on the one hand they were trying to shame developers using Python 2 for using it incorrectly (even though it was totally possible to handle Unicode correctly with that stack), yet on the other they were pumping out ridiculous unavoidable security SNAFUs in their API surface by assuming that filenames on disk are UTF-8 :/.
To tell another story of the importance of reading the--in this case, not even long!--specification: on Windows, filenames are stored as UCS-2 (as it all predates UTF-16), and is most likely most correctly modeled as an arbitrary sequence of non-0 16-bit values; meanwhile, on Unix systems, a filename is pretty much just an arbitrary sequence of non-0 8-bit values (with some weirdness around the slash character... the API surface doesn't support it really but sometimes the filesystem does). The premise that filenames have a display encoding mostly comes from the software rendering the strings and is then defined in terms of a bunch of hacks involving "locales", and isn't a property of the underlying API or storage semantics.
You can't assume in either case that they are canonical Unicode representations, and so storing them as "strings" in your program is super wrong and can lead to anything from data storage mistakes to security vulnerabilities. The Python 3 API…
nilslindemann · 2025-11-05
But isn't 'surrogateescape' supposed to address this? (no expert)
https://vstinner.github.io/pep-383.html
chubot · 2023-06-07
Thanks, yeah that's basically what I thought, but it's nice to know it was the same year!
If only UTF-8 had been invented a little earlier, we could have avoided so much pain :-(
The idea of global varables like LANG= and LC_TYPE= in C is utterly incoherent.
Python's notion of "default file system encoding" is likewise incoherent.
You can obviously process strings with two different encodings in the same program !!! Encodings are metadata, and metadata should be attached to data. Encodings shouldn't be global variables!
Python 3 made things worse in many ways, largely due to adherence to Windows legacy, and then finally introduced UTF-8 mode:
https://vstinner.github.io/painful-history-python-filesystem-encoding.…
jefftk · 2022-08-15
Found some history: https://vstinner.github.io/python30-listdir-undecodable-filenames.html
Includes "Modify os.listdir(str) to ignore silently undecodable filenames, instead of returning them as bytes", but not later work where apparently this was changed to use surrogates.
__s · 2020-01-18
Victor Stinner (python dev) wrote a good series on trying to get stable benchmarks in python:
https://vstinner.github.io/journey-to-stable-benchmark-system.html
https://vstinner.github.io/journey-to-stable-benchmark-deadcode.html
https://vstinner.github.io/journey-to-stable-benchmark-average.html