Build1 publisher3 min readPublished
Python's proposed std namespace protects only the imports that use its prefix
Pablo Galindo Salgado proposed a std namespace at the 2026 Python Language Summit that guarantees import std.json reaches the standard library. Because bare import json keeps working, a project with a stray random.py stays exposed until its own imports change.
The Engineer · Build desk

What happened
- The -P flag has kept that path off sys.path since Python 3.11, but most users do not run with it or rely on importing from the working directory.
- Taken PyPI names have pushed new standard library modules toward names like tomllib, graphlib and zoneinfo instead of timezone.
- A reserved std namespace could also let standard library modules be unbundled and upgraded apart from the interpreter, likely through PyPI.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint The protection covers only code already written with std., so a beginner who names a file random.py gains nothing over running without -P today.
- decision Core developers would have to decide whether new modules ship only under std, and that choice, more than the alias, would determine whether the prefix spreads.
- contradiction Unbundling is pitched partly on faster out-of-band security fixes, yet the one precedent cited, Ruby's gemified library, left a uri gem CVE unpatched.
Run game.py from a directory that also holds random.py and the local file wins. It sits at a higher-precedence location in sys.path than the standard library [3]. Python imports that file, looks for randint, and raises AttributeError on a name the user knows is correct [2]. The traceback is accurate: that random module really has no randint. Galindo Salgado, a Steering Council member and Release Manager, put the cause in the language itself. He pointed to a flat module namespace with no line between the standard library, dependencies and project code [1][4].
A fix already exists. Since Python 3.11 the -P option, in the documentation's words, "doesn't prepend a potentially unsafe path to sys.path" [5]. Most users do not pass it. Many also depend on the working directory being importable, because they never install their own project code into the environment [6].
The std proposal moves the guarantee off the command line and into the import statement. Code that writes import std.json or from std import json gets the standard library module [9]. The alias is well designed. std.json is json evaluates to True, and json.__name__ stays 'json' [11]. One module object answers to both names, so code that records a module's name sees the same string it always did. Bare imports stay. "We can't break the world, that would be bad," Galindo Salgado said [10].
That promise also sets the limit. The guarantee attaches to the std. prefix, and the summit write-up does not describe any change to what a bare import random finds when random.py sits in the project [9][10]. The student who wrote game.py would need to know about the trap before writing import std.random. The -P flag asks for the same foreknowledge today [1].
I think std is still the better tradeoff for library code. A library author who writes std.json fixes the import once, in the source, for every caller, whatever flags those callers start Python with [1].
Naming is the stronger argument. Core developers pick "awkward" names for new modules because top-level names are already taken on PyPI. The restriction holds even when adopting a PyPI project such as PyYAML, which provides yaml [7]. The results include tomllib, graphlib, and zoneinfo where timezone was the obvious word [8]. I'd expect std-only modules, more than the alias, to decide whether anyone types the prefix. Galindo Salgado did not rule them out. In his example, import std.new_stdlib_module works and a bare import new_stdlib_module raises ImportError [12].
Reserving std also makes the standard library easier to unbundle. Modules could then be upgraded separately from the interpreter and from each other, likely through PyPI [13]. The pitch includes security fixes shipped out of band, without waiting for a Python release [14]. The one precedent the post cites went the other way on security. Ruby "gemified" its standard library, and a CVE in the uri gem went unpatched [15]. Ruby's deprecation of require took three release cycles, and users got warnings from transitive dependencies [15].
What to watch
- Whether the std proposal becomes a PEP, and whether that text commits new standard library modules to std-only names.
- How the interpreter resolves std itself when a project contains its own std.py or std/ directory.
- Whether any unbundling plan pairs PyPI-shipped stdlib modules with a security-maintenance rule that answers Ruby's unpatched uri gem.