import builtins import os import select import socket import sys import unittest import errno from errno import EEXIST from test import support class SubOSError(OSError): pass class HierarchyTest(unittest.TestCase): def test_builtin_errors(self): self.assertEqual(OSError.__name__, 'OSError') self.assertIs(IOError, OSError) self.assertIs(EnvironmentError, OSError) def test_socket_errors(self): self.assertIs(socket.error, IOError) self.assertIs(socket.gaierror.__base__, OSError) self.assertIs(socket.herror.__base__, OSError) self.assertIs(socket.timeout.__base__, OSError) def test_select_error(self): self.assertIs(select.error, OSError) # mmap.error is tested in test_mmap _pep_map = """ +-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS +-- ChildProcessError ECHILD +-- ConnectionError +-- BrokenPipeError EPIPE, ESHUTDOWN +-- ConnectionAbortedError ECONNABORTED +-- ConnectionRefusedError ECONNREFUSED +-- ConnectionResetError ECONNRESET +-- FileExistsError EEXIST +-- FileNotFoundError ENOENT +-- InterruptedError EINTR +-- IsADirectoryError EISDIR +-- NotADirectoryError ENOTDIR +-- PermissionError EACCES, EPERM +-- ProcessLookupError ESRCH +-- TimeoutError ETIMEDOUT """ def _make_map(s): _map = {} for line in s.splitlines(): line = line.strip('+- ') if not line: continue excname, _, errnames = line.partition(' ') for errname in filter(None, errnames.strip().split(', ')): _map[getattr(errno, errname)] = getattr(builtins, excname) return _map _map = _make_map(_pep_map) def test_errno_mapping(self): # The OSError constructor maps errnos to subclasses # A sample test for the basic functionality e = OSError(EEXIST, "Bad file descriptor") self.assertIs(type(e), FileExistsError) # Exhaustive testing for errcode, exc in self._map.items(): e = OSError(errcode, "Some message") self.assertIs(type(e), exc) othercodes = set(errno.errorcode) - set(self._map) for errcode in othercodes: e = OSError(errcode, "Some message") self.assertIs(type(e), OSError) def test_OSError_subclass_mapping(self): # When constructing an OSError subclass, errno mapping isn't done e = SubOSError(EEXIST, "Bad file descriptor") self.assertIs(type(e), SubOSError) def test_try_except(self): # This checks that try .. except checks the concrete exception # (FileNotFoundError) and not the base type specified when # PyErr_SetFromErrnoWithFilenameObject was called. # (it is therefore deliberate that it doesn't use assertRaises) try: open("some_hopefully_non_existing_file") except FileNotFoundError: pass else: self.fail("should have raised a FileNotFoundError") class AttributesTest(unittest.TestCase): def test_windows_error(self): if os.name == "nt": self.assertIn('winerror', dir(OSError)) else: self.assertNotIn('winerror', dir(OSError)) def test_posix_error(self): e = OSError(EEXIST, "File already exists", "foo.txt") self.assertEqual(e.errno, EEXIST) self.assertEqual(e.args[0], EEXIST) self.assertEqual(e.strerror, "File already exists") self.assertEqual(e.filename, "foo.txt") if os.name == "nt": self.assertEqual(e.winerror, None) @unittest.skipUnless(os.name == "nt", "Windows-specific test") def test_errno_translation(self): # ERROR_ALREADY_EXISTS (183) -> EEXIST e = OSError(0, "File already exists", "foo.txt", 183) self.assertEqual(e.winerror, 183) self.assertEqual(e.errno, EEXIST) self.assertEqual(e.args[0], EEXIST) self.assertEqual(e.strerror, "File already exists") self.assertEqual(e.filename, "foo.txt") def test_blockingioerror(self): args = ("a", "b", "c", "d", "e") for n in range(6): e = BlockingIOError(*args[:n]) with self.assertRaises(AttributeError): e.characters_written e = BlockingIOError("a", "b", 3) self.assertEqual(e.characters_written, 3) e.characters_written = 5 self.assertEqual(e.characters_written, 5) # XXX VMSError not tested def test_main(): support.run_unittest(__name__) if __name__=="__main__": test_main()