Changeset 772:2166f443d615


Ignore:
Timestamp:
Apr 5, 2009, 6:28:42 PM (12 years ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
Convert:
svn:778c30c8-61e0-0310-89d4-fe2f97a467b2/trunk@809
Message:
Make the `ftp_error` module more robust with respect to `ftplib`
exceptions containing bytestrings or unicode strings or no strings
at all. Normally, `ftplib` exceptions will only contain bytestrings
but that may not be true for subclasses of `ftplib` exception
classes in third-party modules.
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • MANIFEST

    r768 r772  
    2020setup.py
    2121_test_base.py
     22_test_ftp_error.py
    2223_test_ftp_file.py
    2324_test_ftp_path.py
  • ftp_error.py

    r719 r772  
    1 # Copyright (C) 2003-2008, Stefan Schwarzer <sschwarzer@sschwarzer.net>
     1# Copyright (C) 2003-2009, Stefan Schwarzer <sschwarzer@sschwarzer.net>
    22# All rights reserved.
    33#
     
    4141import ftplib
    4242import sys
     43import warnings
    4344
    4445import ftputil_version
     
    4849    """General error class."""
    4950
    50     def __init__(self, ftp_exception):
    51         super(FTPError, self).__init__(ftp_exception)
    52         # `message` is set by the base class
    53         self.strerror = self.message
     51    def __init__(self, *args):
     52        # contrary to what `ftplib`'s documentation says, `all_errors`
     53        #  does _not_ contain the subclasses, so I explicitly add them
     54        if args and args[0].__class__ in ftplib.all_errors + \
     55                                         tuple(ftplib.Error.__subclasses__()):
     56            warnings.warn(("Passing exception objects into the FTPError "
     57              "constructor is deprecated and will be disabled in ftputil 2.6"),
     58              DeprecationWarning, stacklevel=2)
     59        super(FTPError, self).__init__(*args)
     60        # don't use `args[0]` because `args` may be empty
     61        if args:
     62            self.strerror = self.args[0]
     63        else:
     64            self.strerror = ""
    5465        try:
    5566            self.errno = int(self.strerror[:3])
     
    110121    pass
    111122
     123
    112124#XXX Do you know better names for `_try_with_oserror` and
    113125#    `_try_with_ioerror`?
     
    118130    derived classes.
    119131    """
     132    # use `*exc.args` instead of `str(args)` because args might be
     133    #  a unicode string with non-ascii characters
    120134    try:
    121135        return callee(*args, **kwargs)
    122     except ftplib.error_temp, obj:
    123         raise TemporaryError(obj)
    124     except ftplib.error_perm, obj:
    125         if str(obj).startswith("502"):
    126             raise CommandNotImplementedError(obj)
     136    except ftplib.error_temp, exc:
     137        raise TemporaryError(*exc.args)
     138    except ftplib.error_perm, exc:
     139        # if `exc.args` is present, assume it's a byte or unicode string
     140        if exc.args and exc.args[0].startswith("502"):
     141            raise CommandNotImplementedError(*exc.args)
    127142        else:
    128             raise PermanentError(obj)
     143            raise PermanentError(*exc.args)
    129144    except ftplib.all_errors:
    130         ftp_error = sys.exc_info()[1]
    131         raise FTPOSError(ftp_error)
     145        exc = sys.exc_info()[1]
     146        raise FTPOSError(*exc.args)
    132147
    133148class FTPIOError(FTPError, IOError):
    134149    """Generic FTP error related to `IOError`."""
    135150    pass
     151
    136152
    137153def _try_with_ioerror(callee, *args, **kwargs):
     
    143159        return callee(*args, **kwargs)
    144160    except ftplib.all_errors:
    145         ftp_error = sys.exc_info()[1]
    146         raise FTPIOError(ftp_error)
     161        exc = sys.exc_info()[1]
     162        # use `*exc.args` instead of `str(args)` because args might be
     163        #  a unicode string with non-ascii characters
     164        raise FTPIOError(*exc.args)
    147165
Note: See TracChangeset for help on using the changeset viewer.