builtins.TypeError: catching classes that do not inherit from BaseException is not allowed
Marco Sulla
Marco.Sulla.Python at gmail.com
Fri Dec 31 03:17:29 EST 2021
It was already done: https://pypi.org/project/tail-recursive/
On Thu, 30 Dec 2021 at 16:00, hongy... at gmail.com <hongyi.zhao at gmail.com> wrote:
>
> I try to compute the factorial of a large number with tail-recursion optimization decorator in Python3. The following code snippet is converted from the code snippet given here [1] by the following steps:
>
> $ pyenv shell datasci
> $ python --version
> Python 3.9.1
> $ pip install 2to3
> $ 2to3 -w this-script.py
>
> ```
> # This program shows off a python decorator(
> # which implements tail call optimization. It
> # does this by throwing an exception if it is
> # its own grandparent, and catching such
> # exceptions to recall the stack.
>
> import sys
>
> class TailRecurseException:
> def __init__(self, args, kwargs):
> self.args = args
> self.kwargs = kwargs
>
> def tail_call_optimized(g):
> """
> This function decorates a function with tail call
> optimization. It does this by throwing an exception
> if it is its own grandparent, and catching such
> exceptions to fake the tail call optimization.
>
> This function fails if the decorated
> function recurses in a non-tail context.
> """
> def func(*args, **kwargs):
> f = sys._getframe()
> if f.f_back and f.f_back.f_back \
> and f.f_back.f_back.f_code == f.f_code:
> raise TailRecurseException(args, kwargs)
> else:
> while 1:
> try:
> return g(*args, **kwargs)
> except TailRecurseException as e:
> args = e.args
> kwargs = e.kwargs
> func.__doc__ = g.__doc__
> return func
>
> @tail_call_optimized
> def factorial(n, acc=1):
> "calculate a factorial"
> if n == 0:
> return acc
> return factorial(n-1, n*acc)
>
> print(factorial(10000))
> # prints a big, big number,
> # but doesn't hit the recursion limit.
>
> @tail_call_optimized
> def fib(i, current = 0, next = 1):
> if i == 0:
> return current
> else:
> return fib(i - 1, next, current + next)
>
> print(fib(10000))
> # also prints a big number,
> # but doesn't hit the recursion limit.
> ```
> However, when I try to test the above script, the following error will be triggered:
> ```
> $ python this-script.py
> Traceback (most recent call last):
> File "/home/werner/this-script.py", line 32, in func
> return g(*args, **kwargs)
> File "/home/werner/this-script.py", line 44, in factorial
> return factorial(n-1, n*acc)
> File "/home/werner/this-script.py", line 28, in func
> raise TailRecurseException(args, kwargs)
> TypeError: exceptions must derive from BaseException
>
> During handling of the above exception, another exception occurred:
>
> Traceback (most recent call last):
> File "/home/werner/this-script.py", line 46, in <module>
> print(factorial(10000))
> File "/home/werner/this-script.py", line 33, in func
> except TailRecurseException as e:
> TypeError: catching classes that do not inherit from BaseException is not allowed
> ```
>
> Any hints for fixing this problem will be highly appreciated.
>
> [1] https://stackoverflow.com/q/27417874
>
> Regards,
> HZ
> --
> https://mail.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list