blob: 9d92425ac2924134f43300ddb080362bd89c9456 [file] [log] [blame]
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001import builtins
2import os
3import select
4import socket
5import sys
6import unittest
7import errno
8from errno import EEXIST
9
10from test import support
11
12class SubOSError(OSError):
13 pass
14
15
16class HierarchyTest(unittest.TestCase):
17
18 def test_builtin_errors(self):
19 self.assertEqual(OSError.__name__, 'OSError')
20 self.assertIs(IOError, OSError)
21 self.assertIs(EnvironmentError, OSError)
22
23 def test_socket_errors(self):
24 self.assertIs(socket.error, IOError)
25 self.assertIs(socket.gaierror.__base__, OSError)
26 self.assertIs(socket.herror.__base__, OSError)
27 self.assertIs(socket.timeout.__base__, OSError)
28
29 def test_select_error(self):
30 self.assertIs(select.error, OSError)
31
32 # mmap.error is tested in test_mmap
33
34 _pep_map = """
35 +-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
36 +-- ChildProcessError ECHILD
37 +-- ConnectionError
38 +-- BrokenPipeError EPIPE, ESHUTDOWN
39 +-- ConnectionAbortedError ECONNABORTED
40 +-- ConnectionRefusedError ECONNREFUSED
41 +-- ConnectionResetError ECONNRESET
42 +-- FileExistsError EEXIST
43 +-- FileNotFoundError ENOENT
44 +-- InterruptedError EINTR
45 +-- IsADirectoryError EISDIR
46 +-- NotADirectoryError ENOTDIR
47 +-- PermissionError EACCES, EPERM
48 +-- ProcessLookupError ESRCH
49 +-- TimeoutError ETIMEDOUT
50 """
51 def _make_map(s):
52 _map = {}
53 for line in s.splitlines():
54 line = line.strip('+- ')
55 if not line:
56 continue
57 excname, _, errnames = line.partition(' ')
58 for errname in filter(None, errnames.strip().split(', ')):
59 _map[getattr(errno, errname)] = getattr(builtins, excname)
60 return _map
61 _map = _make_map(_pep_map)
62
63 def test_errno_mapping(self):
64 # The OSError constructor maps errnos to subclasses
65 # A sample test for the basic functionality
66 e = OSError(EEXIST, "Bad file descriptor")
67 self.assertIs(type(e), FileExistsError)
68 # Exhaustive testing
69 for errcode, exc in self._map.items():
70 e = OSError(errcode, "Some message")
71 self.assertIs(type(e), exc)
72 othercodes = set(errno.errorcode) - set(self._map)
73 for errcode in othercodes:
74 e = OSError(errcode, "Some message")
75 self.assertIs(type(e), OSError)
76
77 def test_OSError_subclass_mapping(self):
78 # When constructing an OSError subclass, errno mapping isn't done
79 e = SubOSError(EEXIST, "Bad file descriptor")
80 self.assertIs(type(e), SubOSError)
81
82
83class AttributesTest(unittest.TestCase):
84
85 def test_windows_error(self):
86 if os.name == "nt":
87 self.assertIn('winerror', dir(OSError))
88 else:
89 self.assertNotIn('winerror', dir(OSError))
90
91 def test_posix_error(self):
92 e = OSError(EEXIST, "File already exists", "foo.txt")
93 self.assertEqual(e.errno, EEXIST)
94 self.assertEqual(e.args[0], EEXIST)
95 self.assertEqual(e.strerror, "File already exists")
96 self.assertEqual(e.filename, "foo.txt")
97 if os.name == "nt":
98 self.assertEqual(e.winerror, None)
99
100 @unittest.skipUnless(os.name == "nt", "Windows-specific test")
101 def test_errno_translation(self):
102 # ERROR_ALREADY_EXISTS (183) -> EEXIST
103 e = OSError(0, "File already exists", "foo.txt", 183)
104 self.assertEqual(e.winerror, 183)
105 self.assertEqual(e.errno, EEXIST)
106 self.assertEqual(e.args[0], EEXIST)
107 self.assertEqual(e.strerror, "File already exists")
108 self.assertEqual(e.filename, "foo.txt")
109
110 def test_blockingioerror(self):
111 args = ("a", "b", "c", "d", "e")
112 for n in range(6):
113 e = BlockingIOError(*args[:n])
114 with self.assertRaises(AttributeError):
115 e.characters_written
116 e = BlockingIOError("a", "b", 3)
117 self.assertEqual(e.characters_written, 3)
118 e.characters_written = 5
119 self.assertEqual(e.characters_written, 5)
120
121 # XXX VMSError not tested
122
123
124def test_main():
125 support.run_unittest(__name__)
126
127if __name__=="__main__":
128 test_main()