Arguments in favor of specific errors -------------------------------------
Using specific errors avoids the need of "import errno". The import is sometimes done in the except block, which may raise a new error (and may be slow). I like specific exceptions because it avoids the need of re-raise unwanted exception. It makes the code more readable: we ignore explicitly specific errors instead of re-raised unwanted exceptions and implicitly ignore some errors. For example: try: os.mkdir(dir) except OSError as err: if err.errno != errno.EEXIST: raise becomes try: os.mkdir(dir) except FileExistsError: pass By the way, is it faster to not handle and than re-raise unwanted exceptions? (I don't like tests like "err.errno != errno.EEXIST", it's confusing to me. It uses errno identifier twice: once as an attribute, once as a module name.) Make specific errors builtins ----------------------------- I agree that it's better to make specific errors builtins. If we move exceptions to more specific modules, like io and socket, you have to load these modules to catch an exception and remember in which module the exception is. An advantage of builtin specific exceptions is to avoid an import (import errno). Making them builtin may also avoid a bootstrap issue (catch a specific error at startup). Choice of the specific errors ----------------------------- I don't understand how Antoine decided which errno should have an exception or not. For example, EINTR and EPIPE are handled in many modules of the standard library but don't have their exception, whereas EISDIR (IsADirectoryError) and ENOTDIR (NotADirectoryError) are very rare (EISDIR is never handled in the standard library) but have their exception. If we add EINTR, I don't know if it's better to add it to BlockingIOError or to create a new exception (InterruptError?). Another good candidate is EINVAL. Would it be possible to have an (exhaustive?) list of errno with their popularity? At least, their popularity in the Python standard library? Raise a specific error ---------------------- Does raising a specific error (e.g. raise FileNotFound()) set errno and message attributes (to something different than None)? If we provide an error message error: should it be localized? The description of FileDescriptorError tells about the "default error message". It we use a localized message, it's not possible to preallocate or cache instances. I don't see how we could choose a default errno value, because some exceptions handle multiple errno. For example, PermissionError.errno can be EACCES or EPERM. Do specific errors slows down raising exceptions? Do raising an IOError (or a "legacy" error) use a O(1) lookup to choose the exception class? PermissionError --------------- EACCES and EPERM have a different meaning. Even that they are very similar, we might provide two different exceptions. EPERM is only used once in the Python stdlib, so we might only provide AccesError. On Linux, EPERM usually indicates an operation requiring root priviledge. EACCES can be related to filesystem permissions (read-only, user is not allowed to write, etc.) or can be an mmap error. Deprecation ----------- Because IOError, OSError, select.error, etc. are well known exceptions, I'm not in favor of removing them from Python 3. It would make porting from Python 2 worse. If we don't remove them, they should not be deprecated. I'm in favor of adding a note in the documentation of all legacy exceptions to advice to use IOError or specific exceptions instead. I suppose that these notes will have to indicate a Python version. Test the implementation ----------------------- Did someone test Blender, Django or another major applications on the implementation of the PEP 3151? -1 on FileSystemError --------------------- I'm not sure that we need FileSystemError or ConnectionError. Careless code will use IOError, whereas careful code will use an explicit list like (ConnectionAbortedError, ConnectionRefusedError, ConnectionResetError). If we remove IsADirectoryError and NotADirectoryError, FileSystemError only contains FileExistsError and FileNotFoundError. I don't think that these errors can occur on a same function. For example, rmdir() only raises ENOTDIR. I only see one advantage of FileSystemError: it doesn't handle FileDescriptorError. Advice usage of FileSystemError would avoid to hide real bugs like FileDescriptorError. I don't really care of ConnectionError. Anyway, FileSystemError and ConnectionError can be added later if needed. WindowsError and winerror attribute ----------------------------------- I don't like the idea of having a winerror attribute platforms other than Windows. Why not using hasattr(err, "winerror") instead? WindowsError is already specific to Windows. I don't see any usage of the winerror attribute in the Python stdlib. shutil module uses: try: WindowsError except NameError: WindowsError = None (...) try: copystat(src, dst) except OSError as why: if WindowsError is not None and isinstance(why, WindowsError): # Copying file access times may fail on Windows pass else: errors.extend((src, dst, str(why))) Misc ---- Lock.acquire() doesn't raise an exception on timeout: just remove "(for example in Lock.acquire())". Should FileNotFound handle ENODEV? (see test_ossaudiodev) Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com