Python distinguishes between the +
and +=
operators and provides separate hooks for these; __add__ and __iadd__. The list()
type simply provides a different implementation for the latter.
It is more efficient for lists to implement these separately; __add__
has to return a completely new list, while __iadd__
can just extend self
then return self
.
In the C code, __iadd__
is implemented by list_inplace_concat(), which simply calls listextend()
, or, in python code, [].extend()
. The latter takes any sequence, by design.
The __add__
method on the other hand, represented in C by list_concat, only takes a list
as input, probably for efficiency's sake; it can loop directly over the internal C array and copy items over to the new list.
In conclusion, the reason __iadd__
accepts any sequence is because when PEP 203 (the Augmented Add proposal) was implemented, for lists it was simplest just to reuse the .extend()
method.