the old and the __new__

I occasionally want to subclass str for one reason or another. A working toy example:

import colorama, enum

class ColorData(str):
    def __new__(cls, name, terminal_setup_code):
        self = super().__new__(cls,name)
        self.setup_code = terminal_setup_code
        self.reset_code = colorama.Style.RESET_ALL
        return self

    def print(self, *args, **kwargs):
        """Print text wrapped in the appropriate color codes."""

        file = kwargs.pop('file', None)
        flush = kwargs.pop('flush', None)

        print(self.setup_code, end='', file=file)
        print(*args, **kwargs)
        print(self.reset_code, end='', file=file, flush=flush)

class Color(ColorData, enum.ReprEnum):
    RED = R = 'red', colorama.Fore.LIGHTRED_EX
    BLUE = B = 'blue', colorama.Fore.LIGHTBLUE_EX
    ...

if __name__ == "__main__":
    for color in Color:
        color.print("This text is", color)

The thing is that I usually want to override __init__ rather than __new__:

class Subclass(str):
    def __init__(self, value, *args): # wrong!
        super().__init__(self, value)
        ... # do stuff with *args

This wrong code fails with the error

TypeError: decoding str is not supported

The issue is that the str constructor also takes arguments. The str documentation currently gives four calling signatures:

class str(*, encoding='utf-8', errors='strict')
class str(object)
class str(object, encoding, errors='strict')
class str(object, *, errors)

Additional arguments get passed to str.__new__, and the first one gets interpreted as the encoding. You have to override __new__ to prevent this.