bytes.removeprefix()
Added in 3.9 precisely because everyone kept misusing lstrip for this. Matches the exact sequence, once, and does nothing when it is absent.
Demo
When the data begins with the exact prefix it is removed; when it does not, the data comes back untouched with no error. A partial match is no match — pre_name does not start with prefix_, so nothing happens. The doubled case shows the "once" rule: xxname with prefix x loses one x and keeps the other. Removing a prefix equal to the whole data leaves empty bytes.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| prefix | bytes | yes | The exact byte sequence to remove from the start. An empty prefix is a harmless no-op. |
Return value
bytes — The data with prefix removed from the start if it is there — otherwise the data unchanged. Never raises for a missing prefix.
Common patterns
rest = url.removeprefix(b'https://')
token = value.removeprefix(b'Bearer ')
rest = data[len(p):] if data.startswith(p) else data
Examples
Pitfalls
b'xxname'.removeprefix(b'x')
while d.startswith(b'x'): d = d.removeprefix(b'x')
b'Bearer abc'.removeprefix(b'Bearer:')
if not v.startswith(b'Bearer '): raise ValueError('bad header')
b'ab'.removeprefix(b'a')
d[len(p):] if d.startswith(p) else d
When to use
- Removing a known scheme, root or tag from the start
- Anywhere lstrip was being misused for an exact prefix
- Optional prefixes where absence is normal
- Removing a SET of leading bytes → lstrip
- A prefix that must be present → check with startswith and raise
- Supporting Python 3.8 or older without a fallback
Notes
FAQ
Because lstrip strips a SET of bytes, not a sequence, and people misused it for prefixes constantly. b"https://x".lstrip(b"http://") gives b"s://x" — it strips h, t, t, p and stops at the s, which is not in the set. removeprefix matches the exact sequence, which is what everyone meant.
b'https://x'.removeprefix(b'http://') # b'https://x' — correctly unchanged