If + silently gets translated to adding 2 numbers or joining 2 strings that is operator overloading, no matter how it's done under the hood.
If python had you write e1.__add__(e2) Or S1.__join__(s2)
Then you would have 2 distinct operators, therefore no overloading.
Re classes.
Foo.len() and bar.len() are different. You can tell that when you are using them.
It's no different to I_add() and f_add() they are both different functions.
If you automatically called one of those depending on whether the arguments were floats or ints, that would be overloading.
I suppose you could take it further and say that it's overloading if you have different int sizes.
But then we don't really class that as overloading, which I suppose demonstrates that it isn't a very precise term so there isn't much point getting particularly pedantic about it.