from collections import UserString class ustr2(UserString): def __mod__(self, other): print('ustr2.__mod__ was called') return super().__mod__(other) class ustr3(ustr2): def __mod__(self, other): print('ustr3.__mod__ was called') return super().__mod__(other) def __rmod__(self, other): print('ustr3.__rmod__ was called') return super().__rmod__(other) fmt2 = ustr2('value is %s') fmt3 = ustr3('value is %s') str3 = ustr3('TEST') print('Trying simple case of ustr3 instance % ustr3 instance...') # This will call ustr3.__mod__, which will call ustr2.__mod__, which will # call UserString.__mod__, which will return 'value is TEST' without error print(fmt3 % str3) print('Now trying case of ustr2 instance % ustr3 instance...') # Here, the % operator allows the subclass to override the method, and # thus delegates to ustr3.__rmod__. This calls UserString.__rmod__, which # throws the error. print(fmt2 % str3)