# TypeError: catching classes that do not inherit from BaseException is not allowed

**URL:** <https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800>\
**Category:** Python Help\
**Tags:** help\
**Created:** [December 30, 2021, 1:12pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800 "2021-12-30T13:12:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![hongyi-zhao](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hongyi-zhao/32/1981_2.png) [@hongyi-zhao](https://discuss.python.org/u/hongyi-zhao)\
**Post date:** [December 30, 2021, 1:12pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800/1 "2021-12-30T13:12:21Z")

</div>

I try to compute the factorial of a large number with tail-recursion optimization decorator in Python3. The test python code is as follows:

```auto
# 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.

```

The above code snippet is converted from the example code given here [1] by the following steps:

```auto
$ pyenv shell datasci
$ python --version
Python 3.9.1
$ pip install 2to3
$ 2to3 -w this-script.py

```

However, when I try to test the above script, the following error will be triggered:

```auto
$ 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] [Tail-Recursion Optimization Decorator in Python - Stack Overflow](https://stackoverflow.com/q/27417874)

Regards,  
HZ

---

<div class="post-metadata">

**Author:** ![aroberge](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/aroberge/32/6200_2.png) [@aroberge](https://discuss.python.org/u/aroberge)\
**Post date:** [December 30, 2021, 1:22pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800/2 "2021-12-30T13:22:28Z")

</div>

Please, try to write code in a code block so that the indentation is not lost.

To solve your problem, make sure that your custom exception class inherits from `BaseException`:

```python
class TailRecurseException(BaseException):
   ...

```

---

<div class="post-metadata">

**Author:** ![hongyi-zhao](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hongyi-zhao/32/1981_2.png) [@hongyi-zhao](https://discuss.python.org/u/hongyi-zhao)\
**Post date:** [December 30, 2021, 2:12pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800/3 "2021-12-30T14:12:10Z")

</div>

> [@aroberge](#):
>
> Please, try to write code in a code block so that the indentation is not lost.

Thank you for your reminder. These codes are already formatted by the code block marker. This problem is caused by my pasting code from the posts of Google Group which caused the indentation to go wrong.

> [@aroberge](#):
>
> `class TailRecurseException(BaseException):`

Thank you again. It solves the problem.

HZ

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [December 30, 2021, 8:35pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800/4 "2021-12-30T20:35:02Z")

</div>

The most important hint to solving problems when programming is to read  
the error messages. Python tells you twice what the problem is, once  
when you try to raise the exception, and then again when you try to  
catch it:

```
TypeError: exceptions must derive from BaseException

TypeError: catching classes that do not inherit from BaseException is not allowed

```

To fix that, make sure that your error class inherits from  
BaseException, or even better, Exception.

```
class TailRecurseException(Exception)
```

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [December 30, 2021, 8:39pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800/5 "2021-12-30T20:39:42Z")

</div>

It is better to inherit from Exception rather than BaseException  
directly. Or even from one of the more specialised exception classes.

The docs say:

“programmers are encouraged to derive new exceptions from the Exception  
class or one of its subclasses, and not from BaseException.”

[https://docs.python.org/3/library/exceptions.html](https://docs.python.org/3/library/exceptions.html)

---

<div class="post-metadata">

**Author:** ![aroberge](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/aroberge/32/6200_2.png) [@aroberge](https://discuss.python.org/u/aroberge)\
**Post date:** [December 30, 2021, 8:45pm UTC](https://discuss.python.org/t/typeerror-catching-classes-that-do-not-inherit-from-baseexception-is-not-allowed/12800/6 "2021-12-30T20:45:00Z")

</div>

> [@steven.daprano](#):
>
> It is better to inherit from Exception rather than BaseException  
> directly. Or even from one of the more specialised exception classes.
> 
> The docs say:
> 
> “programmers are encouraged to derive new exceptions from the Exception  
> class or one of its subclasses, and not from BaseException.”

Thanks. I was just using the info from the traceback; I should have search before answering. (And I should probably add this case to friendly-traceback…)
