Changeset 772:2166f443d615
- Timestamp:
- 2009-04-05 16:28:42 (17 months ago)
- Author:
- Stefan Schwarzer <sschwarzer@…>
- Branch:
- default
- convert_revision:
- 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:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r768
|
r772
|
|
| 20 | 20 | setup.py |
| 21 | 21 | _test_base.py |
| | 22 | _test_ftp_error.py |
| 22 | 23 | _test_ftp_file.py |
| 23 | 24 | _test_ftp_path.py |
-
|
r719
|
r772
|
|
| 1 | | # Copyright (C) 2003-2008, Stefan Schwarzer <sschwarzer@sschwarzer.net> |
| | 1 | # Copyright (C) 2003-2009, Stefan Schwarzer <sschwarzer@sschwarzer.net> |
| 2 | 2 | # All rights reserved. |
| 3 | 3 | # |
| … |
… |
|
| 41 | 41 | import ftplib |
| 42 | 42 | import sys |
| | 43 | import warnings |
| 43 | 44 | |
| 44 | 45 | import ftputil_version |
| … |
… |
|
| 48 | 49 | """General error class.""" |
| 49 | 50 | |
| 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 = "" |
| 54 | 65 | try: |
| 55 | 66 | self.errno = int(self.strerror[:3]) |
| … |
… |
|
| 110 | 121 | pass |
| 111 | 122 | |
| | 123 | |
| 112 | 124 | #XXX Do you know better names for `_try_with_oserror` and |
| 113 | 125 | # `_try_with_ioerror`? |
| … |
… |
|
| 118 | 130 | derived classes. |
| 119 | 131 | """ |
| | 132 | # use `*exc.args` instead of `str(args)` because args might be |
| | 133 | # a unicode string with non-ascii characters |
| 120 | 134 | try: |
| 121 | 135 | 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) |
| 127 | 142 | else: |
| 128 | | raise PermanentError(obj) |
| | 143 | raise PermanentError(*exc.args) |
| 129 | 144 | 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) |
| 132 | 147 | |
| 133 | 148 | class FTPIOError(FTPError, IOError): |
| 134 | 149 | """Generic FTP error related to `IOError`.""" |
| 135 | 150 | pass |
| | 151 | |
| 136 | 152 | |
| 137 | 153 | def _try_with_ioerror(callee, *args, **kwargs): |
| … |
… |
|
| 143 | 159 | return callee(*args, **kwargs) |
| 144 | 160 | 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) |
| 147 | 165 | |