Most small dependencies in a Python project are replacing something already
installed. Six modules cover the majority of it, and each of them is one import
with no version to pin and nothing to break on the day it is unmaintained.
argparse turns a script into a command.ap.add_argument("--limit", type=int, default=50) and a bad value
exits with invalid int value: 'many' after printing the usage line,
before your code runs at all. action="store_true" gives a--dry-run flag, and parsing["shelves", "--dry-run"] answersNamespace(folder='shelves', dry_run=True, limit=50). Note the
underscore: a dash in the flag becomes an underscore on the attribute.
zoneinfo handles the part of time that is not arithmetic.ZoneInfo("Asia/Tehran") on a September morning gives2026-09-02T09:30:00+03:30, and converting to UTC gives2026-09-02T06:00:00+00:00. The half hour offset is the reason to
use a real timezone database and never an integer of hours, and it has been in
the standard library since Python 3.9.
Three that replace a loop you were about to write
itertools.groupby collapses a grouping loop, with one
condition attached that catches everybody: it groups only runs that are
already adjacent, so the rows must be sorted by the same key first. On sorted
choir rows it yields alto with ['Ladan', 'Simin'] and then bass.
Unsorted input silently produces the same key twice.
itertools.pairwise gives consecutive pairs:[(1, 4), (4, 9), (9, 16)] from four readings, which is every
difference-between-consecutive-values loop ever written, in one call, since
Python 3.10. itertools.batched chunks a sequence:[('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)], and the short last
batch is the case a hand written chunker gets wrong.
One that is a security decision rather than a convenience
secrets is the one to know by name.secrets.token_urlsafe(16) returns a 22 character string safe to put
in a URL, drawn from the operating system's cryptographic source. Therandom module is not that: it is fast, reproducible and predictable
from its output, which is exactly right for shuffling a deck and exactly wrong
for a password reset link. Using random where secrets
belongs is a real vulnerability that no test fails on, and it is the reason the
two modules exist separately.
textwrap and shutil fill the gaps around
those. textwrap.shorten(text, width=24, placeholder=" ...") givesa very long shelf ..., cutting on a word boundary rather than
mid-word, and shutil.disk_usage("/").free answers in bytes, which
is the check a script that writes files should do before it starts rather than
after it fails.
What to run in 2026
The standard library documentation's module index is the tool, free, and the
habit worth building is to open it before adding a dependency rather than after.
It replaced searching for a package first, which reliably finds one, because
somebody has published a package for everything in this list.
Python 3.14 is what these versions assume, free and open source. Three of the
six modules above gained the specific function named here after 2020, so a
codebase pinned to an old interpreter has fewer of these than this page
suggests, and checking the version note in the docs is a ten second habit that
prevents a confusing import error.
Where this stalls people
The stall is not knowing what to look for, which no amount of reading fixes
directly. Nobody searches for pairwise without knowing the word,
and the loop that computes differences between consecutive readings gets written
by hand a hundred times because it is easy enough to write.
What does work is reading one module's index page whenever you write a loop
that feels generic. A loop that groups, chunks, pairs, counts or flattens is one
of eight functions in itertools and collections, and
fifteen minutes with those two indexes is the highest return reading in this
language. The idioms those functions replace are
syntax, types and the
standard idioms, and what to do when the answer genuinely is a dependency is
pip, venv, and
keeping projects apart. Both sit under
readable, everywhere, and the usual
first language.