eggs/py-1.4.0-py2.6.egg/py/_error.py
changeset 307 c6bca38c1cbf
equal deleted inserted replaced
306:5ff1fc726848 307:c6bca38c1cbf
       
     1 """
       
     2 create errno-specific classes for IO or os calls.
       
     3 
       
     4 """
       
     5 import sys, os, errno
       
     6 
       
     7 class Error(EnvironmentError):
       
     8     def __repr__(self):
       
     9         return "%s.%s %r: %s " %(self.__class__.__module__,
       
    10                                self.__class__.__name__,
       
    11                                self.__class__.__doc__,
       
    12                                " ".join(map(str, self.args)),
       
    13                                #repr(self.args)
       
    14                                 )
       
    15 
       
    16     def __str__(self):
       
    17         s = "[%s]: %s" %(self.__class__.__doc__,
       
    18                           " ".join(map(str, self.args)),
       
    19                           )
       
    20         return s
       
    21 
       
    22 _winerrnomap = {
       
    23     2: errno.ENOENT,
       
    24     3: errno.ENOENT,
       
    25     17: errno.EEXIST,
       
    26     22: errno.ENOTDIR,
       
    27     267: errno.ENOTDIR,
       
    28     5: errno.EACCES,  # anything better?
       
    29 }
       
    30 
       
    31 class ErrorMaker(object):
       
    32     """ lazily provides Exception classes for each possible POSIX errno
       
    33         (as defined per the 'errno' module).  All such instances
       
    34         subclass EnvironmentError.
       
    35     """
       
    36     Error = Error
       
    37     _errno2class = {}
       
    38 
       
    39     def __getattr__(self, name):
       
    40         eno = getattr(errno, name)
       
    41         cls = self._geterrnoclass(eno)
       
    42         setattr(self, name, cls)
       
    43         return cls
       
    44 
       
    45     def _geterrnoclass(self, eno):
       
    46         try:
       
    47             return self._errno2class[eno]
       
    48         except KeyError:
       
    49             clsname = errno.errorcode.get(eno, "UnknownErrno%d" %(eno,))
       
    50             errorcls = type(Error)(clsname, (Error,),
       
    51                     {'__module__':'py.error',
       
    52                      '__doc__': os.strerror(eno)})
       
    53             self._errno2class[eno] = errorcls
       
    54             return errorcls
       
    55 
       
    56     def checked_call(self, func, *args, **kwargs):
       
    57         """ call a function and raise an errno-exception if applicable. """
       
    58         __tracebackhide__ = True
       
    59         try:
       
    60             return func(*args, **kwargs)
       
    61         except self.Error:
       
    62             raise
       
    63         except EnvironmentError:
       
    64             cls, value, tb = sys.exc_info()
       
    65             if not hasattr(value, 'errno'):
       
    66                 raise
       
    67             __tracebackhide__ = False
       
    68             errno = value.errno
       
    69             try:
       
    70                 if not isinstance(value, WindowsError):
       
    71                     raise NameError
       
    72             except NameError:
       
    73                 # we are not on Windows, or we got a proper OSError
       
    74                 cls = self._geterrnoclass(errno)
       
    75             else:
       
    76                 try:
       
    77                     cls = self._geterrnoclass(_winerrnomap[errno])
       
    78                 except KeyError:
       
    79                     raise value
       
    80             raise cls("%s%r" % (func.__name__, args))
       
    81             __tracebackhide__ = True
       
    82 
       
    83 error = ErrorMaker()