Python: Maximum recursion depth exceeded when printing custom exception
custom-exceptions, python, recursion, repr
Solution
Your `super` invocation is wrong: `self` should not be supplied again, it's already injected by `super`. This way, `file_error.args[0] is file_error` because you pass `self` as an extra argument to the exception constructor. This should make it obvious why fix #1 (removing the super call altogether) helps, but of course the best fix is to pass the right arguments:
super(FileError, self).__init__(filename, *a, **k)
The reason for the infinite recursion: First off, only `object.__str__` delegates to `__repr__`; `BaseException` defines both `__str__` and `__repr__` separately, so `str()` of an exception calls that overload, not your `__repr__`. `BaseException.__str__` usually prints the args tuple (which would use `repr`), though when it contains a single argument, it prints the `str()` of that single argument.
This invokes `BaseException.__str__` again, and so on. Fix #2 prevents this cycle by not entering `BaseException.__str__` in the first place, instead using your `__repr__` which does not touch the args tuple at all.
Problem
The following code throws `RuntimeError: maximum recursion depth exceeded while getting the str of an object`. I can resolve the infinite recursion in two different ways, but I don't understand why each fix works and thus don't know which to use, or if either are correct. ``` class FileError( Exception ): def __init__( self, filename=None, *a, **k ): #Fix 1: remove super super( FileError, self ).__init__( self, *a, **k ) self.filename = filename def __repr__( self ): return "<{0} ({1})>".format( self.__class__.__name__, self.filename ) #Fix 2: explicitly define __str__ #__str__ = __repr__ print( FileError( "abc" ) ) ``` If I remove `super`, the code runs but doesn't print anything. This doesn't make sense since according to this post, Difference between __str__ and __repr__ in Python, omitting `__str__` will call `__repr__` but that doesn't seem to be happening here. If I, instead, keep the call to `super` and add `__str__ = __repr__`, then I get the expected output and there is no recursion. Can someone explain why the infinite recursion is present, why each change resolves the inifinte recursion, and why one fix might be preferred over the other?