The conversion job was one line
that anybody would write.
Take each export,
drop the extension,
add a new one.
name.rstrip(".csv") + ".parquet"
It ran every night for a year.
The files were called things like
orders_2026_10.csv
and stock_2026_10.csv,
and every one of them
came out exactly right.
Then the analytics team
added two new exports.
metrics.csv.
logistics.csv.
The next morning
there were two new files
in the bucket.
metri.parquet.
logisti.parquet.
The loader looked for metrics.parquet,
found nothing,
and the dashboard kept showing
the last numbers it had,
which looked perfectly normal
for nine days.
Here is the mechanism.
rstrip does not take a suffix.
It takes a set of characters.
Dot, c, s, v.
It walks backwards from the end
and removes every character
that is anywhere in that set,
in any order,
until it meets one that is not.
metrics ends in s.
Gone.
Then c.
Gone.
Then i,
which is not in the set,
so it stops.
Your old filenames
ended in digits,
and digits were never in the set,
so the bug was there
from the first night
and simply had nothing to eat.
The same trap waits on the other side.
"www.wikipedia.org".lstrip("www.")
gives you ikipedia.org,
because w was in the set too.
In JavaScript and Java,
trim takes no argument
and only removes whitespace,
so the idea feels familiar
and the argument here
quietly means something else.
Python 3.9 added
the methods you actually wanted.
removesuffix(".csv")
takes off that exact ending
if it is there,
and nothing else.
removeprefix does the same at the front.
For filenames,
go one step further.
pathlib's with_suffix(".parquet")
knows what an extension is,
so you never touch the characters at all.
Then write the test
with a name that ends
in one of the letters you strip.
basics.csv
is a good one.
It comes back as basi.
A test full of names
that end in digits
only proves the digits
were never in danger.
When a function reads like English,
check what the argument means,
not what it looks like.
A string can be a word.
To rstrip,
it is just a bag of letters.
– Serguey Asael Shinder
Top comments (0)