Python's batteries could use some recharging
One of Python's original selling points was that it was "batteries included".
That is to say, its standard library was quite large. While it still has
an extensive standard library, the standard library seems to have ossified somewhat.
Since 2016, nearly all additions to the standard library have been either to the
typing
or asyncio
modules. While there have been a couple of new non-typing or async
modules since, those are unlikely to be found by new users (e.g importlib.resources
).
A slew of standard library modules have even been deprecated in python 3.9 or 3.10.
Meanwhile, modern languages often come with even larger standard libraries and/or
improved tooling.
If Python does not want to get outclassed by the new kids on the block, it could use some recharging of its batteries.
Here are a few suggestions I would like to see in the standard library, and/or bundled together with a regular python install. These are items that currently rely on extremely widespread third-party packages.
Modules
A TOML parser
I find it a little surprising there is no TOML parser in the standard library. After
all, TOML files are effectively required
for storing project metadata and build specs.
This means any modern python build system has a hard dependency on tomli
, which is a
bit of a circular dependency which has already left Linux distro maintainers up in arms
for good reason.
Requests
Let's be honest. What project does not depend on requests
, be it directly or
transitively? Making URL requests is just basic functionality for many tasks in 2022.
Of course urllib
exists, but it isn't as user-friendly, and its own documentation
already recommends the use of
requests
.
The usual arguments that the standard library is a place where packages go to die does not hold much water here as well. In all of 2021, there was just one release, and the just-released 2.27 release's main feature was python 3.10 support. It is already being developed under the auspices of the Python Software Foundation, so moving (part of) it to the standard library probably makes that less difficult than it would be for other packages.
A modern datetime module
While python has extensive support for handling dates and datetimes under the
datetime
module, use of this module is often a source of subtle bugs. There is good
reason why third-party packages such as pendulum are
so popular.
The use of naive datetimes by default may have made sense in the 1990s, but in today's
globalized world one cannot dispense with timezones. Not to mention the surprising
behaviour of things like datetime.datetime.utcnow()
returning a naive datetime
with a plainly wrong UNIX timestamp.
Python is of course not alone in this. Other languages have made the exact same
mistakes in the past. Changing the behaviour of such a fundamental module would
obviously lead to a world of pain for existing systems. A new,
timezone-aware-by-default datetime module living alongside or building on top of
datetime
therefore seems like a good idea. Inspiration could be taken from Java's
java.time,
Javascript's Temporal proposal,
Rust's chrono crate and Golang's time package.
Tooling
Surprisingly few development tools come out of the box with a standard python install. This is in stark contrast to newer languages such as Rust or Golang which come with a swiss army knife full of tools. Instead, python relies on third-party packages. I'd argue at least some of those could be part of the standard python install. Newcomers to Python cannot be assumed to be familiar with virtualenv, system vs user installs, pip, ensure-pip, site-packages, etc. Reducing the amount of third-party packages that must be correctly installed for effectively any and all projects would therefore make python less intimidating to newcomers.
Whether such tools would be subcommands to python
, modules enabled with -m
, or
separate executables is something I'd be ambivalent to.
A code formatter
Both Rust and Golang come with a code formatter out of the box, via cargo fmt
and go fmt
, respectively.
The python ecosystem of course has black
, which takes in the same role. This is
something I install for literally every project. Having an automatic code formatter
does away with bike-shedding arguments over which style is correct, which is
unfortunately all too common in projects that do not use a code formatter. In addition,
making sure there is just one obvious way of doing something also fits the Zen of Python.
Tests as first class citizens
You might say, we already have unittest
and doctest
, do we really need yet another
framework in the standard toolset? Yeah, maybe. This is again something both Rust
and Go do a lot better than Python. In Rust one simply writes a #[cfg(tests)]
block,
in Go one simply writes a function starting with Test
, and both languages'
toolsets (cargo test
and go test
) automatically pick up test cases. Both these
languages therefore make tests first class citizens.
Why can't I just type something like python -m test
and have something similar for
python, without having to first download and install a third-party package?
Like with the requests
module, the unittest
documentation
already mentions that third-party package, pytest
.
A type checker
In recent years, a lot of focus has been on the optional type hinting features. This has largely been very successful, with type hints being widespread in the community.
That said, making practical use of the type hints involves installing some type checker.
Again, these are third-party packages that do not come bundled with Python.
The current situation in the Python landscape is akin to Typescript not coming with
the tsc
command.
As the mypy
type checker is already being developed under the Python organization,
I feel it would make a lot of sense to distribute it along with a standard Python
installation.