0

I was testing some features in Python for fun ;) But I have a recursion error that I don't understand

class Test(float):
    def __new__(cls, value):
        return super().__new__(cls, value)

    def __str__(self):
        return super().__str__()
    
    def __repr__(self):
        return f'<value: {str(self)}>'


test = Test(12)
print(test)

Traceback:

Traceback (most recent call last):
  File "C:\temp\test_float.py", line 13, in <module>
    print(test)
  File "C:\temp\test_float.py", line 6, in __str__
    return super().__str__()
  File "C:\temp\test_float.py", line 9, in __repr__
    return f'<value: {str(self)}>'
  File "C:\temp\test_float.py", line 6, in __str__
    return super().__str__()
  File "C:\temp\test_float.py", line 9, in __repr__
    return f'<value: {str(self)}>'
...the above 2 errors repeated many times...
  File "C:\temp\test_float.py", line 6, in __str__
    return super().__str__()
RecursionError: maximum recursion depth exceeded

The line return super().__str__() should call float.__str__() and just returns '12'.

Do you have any ideas ?

2
  • 1
    Please post the full error traceback! Commented Jun 10, 2021 at 19:01
  • 7
    Your repr calls str, which calls float's str, which defers to repr, which is an infinite recursion. You could call super().__repr__ in your repr method, instead of calling str(self) Commented Jun 10, 2021 at 19:01

2 Answers 2

4

Your __repr__ calls your __str__, which calls the super's __str__, which defers to repr, which calls your __repr__, which is an infinite recursion. You could call super().__repr__ in your __repr__ method, instead of calling str(self).

class Test(float):
    def __new__(cls, value):
        return super().__new__(cls, value)

    def __str__(self):
        return super().__str__()
    
    def __repr__(self):
        return f'<value: {super().__repr__()}>'
>>> Test(12)
<value: 12.0>
Sign up to request clarification or add additional context in comments.

Comments

1

The core issue is that float.__str__(self) will call self.__repr__() rather than float.__repr__(self).

Not only does that mean that you have an infinite recursion from Test.__repr__ to Test.__str__ to float.__str__ back to Test.__repr__, it means that Test.__str__ is going to print the same thing as Test.__repr__, which I assume you don't want since you went to the effort of reimplementing it.

Instead I think you want:

class Test(float):
    def __str__(self):
        return super().__repr__()
    
    def __repr__(self):
        return f'<value: {super().__repr__()}>'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.