This repository has been archived by the owner on Mar 4, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errno_exceptions.py
72 lines (59 loc) · 1.65 KB
/
errno_exceptions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import errno
import os
import string
class ErrnoException(Exception):
"""
Base class for all errno-based exceptions.
"""
def __init__(self, original):
self.original = original
self.args = original.args
self.filename = original.filename
def __str__(self):
return os.strerror(self.errno)
_ALLOWED = string.ascii_letters + string.digits
def _munge_name(s):
result = ''.join(
''.join(c for c in word if c in _ALLOWED).capitalize()
for word in s.split(None)
)
return result
def _init(errors):
for num, abbrev in errors.items():
errstr = os.strerror(num)
classname = '%sError' % _munge_name(errstr)
class_ = type(
classname,
(ErrnoException,),
dict(
errno=num,
strerror=errstr
),
)
globals()[classname] = class_
globals()['%s_Error' % abbrev] = class_
_init(errno.errorcode)
def adapt(e):
if not isinstance(e, EnvironmentError):
# we only handle exceptions known to always have errno
return e
if isinstance(e, ErrnoException):
# already wrapped
return e
abbrev = errno.errorcode.get(e.errno)
if abbrev is None:
# dunno what happened, but can't map it
return e
class_ = globals().get('%s_Error' % abbrev)
if class_ is None:
# dunno what happened, but can't map it
return e
new = class_(e)
return new
def wrap(fn):
def handle(*a, **kw):
try:
return fn(*a, **kw)
except EnvironmentError, e:
raise adapt(e)
return handle