[Tutor] custom error classes: how many of them does one need?

Albert-Jan Roskam fomcl at yahoo.com
Mon Jul 8 22:51:10 CEST 2013


----- Original Message -----

> From: eryksun <eryksun at gmail.com>
> To: Albert-Jan Roskam <fomcl at yahoo.com>
> Cc: "tutor at python.org" <tutor at python.org>
> Sent: Monday, July 8, 2013 8:28 AM
> Subject: Re: [Tutor] custom error classes: how many of them does one need?
> 
> On Sun, Jul 7, 2013 at 2:37 PM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>>  # this is a global variable (perhaps in __init__.py)
>>  # if warningsAsErrors > 0, even warnings will  raise an error.
>>  import operator
>>  warningsAsErrors = bool(os.getenv("warningsAsErrors"))
> 
> I'd use uppercase for the environment variable, with the application
> name as a prefix, and only require that it's defined (i.e. check if
> it's in os.environ).
> 
> For a library you can leave it for the user to decide how to handle warnings:
> 
> http://docs.python.org/2/library/warnings
> 
>     >>> class MyWarning(UserWarning): pass
>     ...
>     >>> warnings.warn('the sky is falling', MyWarning)
>     __main__:1: MyWarning: the sky is falling
> 
>     >>> warnings.simplefilter('error', MyWarning)
>     >>> warnings.warn('the sky is REALLY falling', MyWarning)
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     __main__.MyWarning: the sky is REALLY falling
> 
>     >>> warnings.simplefilter('ignore', MyWarning)
>     >>> warnings.warn('Listen! The sky is falling!', MyWarning)
>     >>> # crickets

Awesome. Exactly what I need! I really should try each and every module of the standard library as it contains so much cool stuff.

import warnings
import os
import ctypes

# __init__.py
retcodes = {i: "%s %s" % ("warning" if i < 0 else "error", i)
            for i in range(-10, 10)}
MYAPP_WARNINGS_AS_ERRORS = bool(os.environ.get("MYAPP_WARNINGS_AS_ERRORS"))

# error.py (should actually be named exception.py now)
class CustomWarning(UserWarning): pass

action = "error" if MYAPP_WARNINGS_AS_ERRORS else "default"
warnings.simplefilter(action, CustomWarning)

class CustomError(Exception):
    def __init__(self, retcode, msg):
        self.retcode = retcode
        Exception.__init__(self, msg)

def possiblyThrow(retcode, msg):
    """Throws a warning if retcode < 0 (and warnings are not ignored),
    and throws an error if retcode > 0. Returns None if retcode == 0"""
    msg += " [%s]" % retcodes.get(retcode, retcode)
    if retcode > 0:
        raise CustomError(retcode, msg)
    elif retcode < 0:
        warnings.warn(msg, CustomWarning, stacklevel=2)

# myapp.py
# bogus example, works only on windows.
libc = ctypes.cdll.msvcrt 
retcode = libc.printf("Ooooh %s", "lala!") # retcode > 0 is not even an error here
#retcode = -1
possiblyThrow(retcode, "Problem with libc.printf")

 
>>>  SpoonError
>>>  +-- TeaspoonError
>>>  +-- SoupSpoonError
>>>  +-- DesertSpoonError
>> 
>>  DesertSpoonError? LOL! ;-)
> 
> During handling of the above exception, another exception occurred:
> 
> Traceback (most recent call last):
>   File "<stdin>", line 2, in <module>
> SpellingError: No dessert for you!

haha, I hadn't even noticed the 'speling eror'. I was just thinking 'what the heck is a desert spoon'? ;-) 


More information about the Tutor mailing list