The Python programmer is given a lot of flexibility with respect to exceptions that can be raised from user code. However, that flexibility doesn't mean that "anything goes." From the version 3 documentation for the Python standard library, the article 5. Built-in Exceptions offers this general guidance.
On what exceptions a programmer can raise:
User code can raise built-in exceptions. This can be used to test an
exception handler or to report an error condition “just like” the
situation in which the interpreter raises the same exception; but
beware that there is nothing to prevent user code from raising an
inappropriate error. (emphasis mine)
On programmer-defined exceptions:
The built-in exception classes can be subclassed to define new
exceptions; programmers are encouraged to derive new exceptions from
the Exception class or one of its subclasses, and not from
BaseException. More information on defining exceptions is
available in the Python Tutorial under User-defined Exceptions.
Clause 5.1. Base classes suggests that base class exceptions should not typically be raised:
The following exceptions are used mostly as base classes for other
exceptions.
BaseException, Exception, ArithmeticError, BufferError, LookupError
Instead, per the guidance in Clause 5.2. Concrete exceptions, it is concrete exceptions that should typically be raised:
The following exceptions are the exceptions that are usually raised.
AssertionError, AttributeError, EOFError, ... OSError, ..., ZeroDivisionError
So, for instance, instead of raising ArithmeticError, consider raising one of its derived classes: FloatingPointError, OverflowError, and ZeroDivisionError. (Or, perhaps a class that you derive from ArithmeticError.)
(And see clause 5.2.1. OS exceptions for more on OSError.)
And finally, on warning messages from the article 29.5. warnings — Warning control:
Warning messages are typically issued in situations where it is useful
to alert the user of some condition in a program, where that condition
(normally) doesn’t warrant raising an exception and terminating the
program. For example, one might want to issue a warning when a program
uses an obsolete module.
...
User code can define additional warning categories by subclassing one
of the standard warning categories. A warning category must always be
a subclass of the Warning class.