Why is the [:] included in `.removeprefix()` definition?

Question:

In PEP-616, the specification for removeprefix() includes this code block:

def removeprefix(self: str, prefix: str, /) -> str:
    if self.startswith(prefix):
        return self[len(prefix):]
    else:
        return self[:]

Why does the last line say return self[:], instead of just return self?

Asked By: Philip Massey

||

Answers:

[:] is an old idiom for copying sequences. Nowadays, we use the idiomatic .copy for lists; there isn’t normally a good reason to copy strings, since they are supposed to be immutable, so the str class doesn’t provide such a method. Furthermore, due to string interning, [:] may well return the same instance anyway.

So, why include it in code like this?

Because str can be subclassed. The clue is in the subsequent text:

When the arguments are instances of str subclasses, the methods should behave as though those arguments were first coerced to base str objects, and the return value should always be a base str.

Suppose we had a user-defined subclass:

class MyString(str):
    ...

Notice what happens when we slice an instance to copy it:

>>> type(MyString('xyz')[:])
<class 'str'>

In the example implementation, therefore, the [:] ensures that an instance of the base str type will be returned, conforming to the text specification.

Answered By: Karl Knechtel
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.