Several of these `else: return` blocks are redundant.  There could just be one:  `return self.__class__(...)` at the end of the method and drop most of the `else` statements.