blob: 8af9e0c5f650b5c32a99e03003dcd10be262e165 [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
Antoine Pitroue0e27352011-12-15 14:31:28 +010015class SubOSErrorWithInit(OSError):
16 def __init__(self, message, bar):
17 self.bar = bar
18 super().__init__(message)
19
20class SubOSErrorWithNew(OSError):
21 def __new__(cls, message, baz):
22 self = super().__new__(cls, message)
23 self.baz = baz
24 return self
25
26class SubOSErrorCombinedInitFirst(SubOSErrorWithInit, SubOSErrorWithNew):
27 pass
28
29class SubOSErrorCombinedNewFirst(SubOSErrorWithNew, SubOSErrorWithInit):
30 pass
31
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020032
33class HierarchyTest(unittest.TestCase):
34
35 def test_builtin_errors(self):
36 self.assertEqual(OSError.__name__, 'OSError')
37 self.assertIs(IOError, OSError)
38 self.assertIs(EnvironmentError, OSError)
39
40 def test_socket_errors(self):
41 self.assertIs(socket.error, IOError)
42 self.assertIs(socket.gaierror.__base__, OSError)
43 self.assertIs(socket.herror.__base__, OSError)
44 self.assertIs(socket.timeout.__base__, OSError)
45
46 def test_select_error(self):
47 self.assertIs(select.error, OSError)
48
49 # mmap.error is tested in test_mmap
50
51 _pep_map = """
52 +-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
53 +-- ChildProcessError ECHILD
54 +-- ConnectionError
55 +-- BrokenPipeError EPIPE, ESHUTDOWN
56 +-- ConnectionAbortedError ECONNABORTED
57 +-- ConnectionRefusedError ECONNREFUSED
58 +-- ConnectionResetError ECONNRESET
59 +-- FileExistsError EEXIST
60 +-- FileNotFoundError ENOENT
61 +-- InterruptedError EINTR
62 +-- IsADirectoryError EISDIR
63 +-- NotADirectoryError ENOTDIR
64 +-- PermissionError EACCES, EPERM
65 +-- ProcessLookupError ESRCH
66 +-- TimeoutError ETIMEDOUT
67 """
68 def _make_map(s):
69 _map = {}
70 for line in s.splitlines():
71 line = line.strip('+- ')
72 if not line:
73 continue
74 excname, _, errnames = line.partition(' ')
75 for errname in filter(None, errnames.strip().split(', ')):
76 _map[getattr(errno, errname)] = getattr(builtins, excname)
77 return _map
78 _map = _make_map(_pep_map)
79
80 def test_errno_mapping(self):
81 # The OSError constructor maps errnos to subclasses
82 # A sample test for the basic functionality
83 e = OSError(EEXIST, "Bad file descriptor")
84 self.assertIs(type(e), FileExistsError)
85 # Exhaustive testing
86 for errcode, exc in self._map.items():
87 e = OSError(errcode, "Some message")
88 self.assertIs(type(e), exc)
89 othercodes = set(errno.errorcode) - set(self._map)
90 for errcode in othercodes:
91 e = OSError(errcode, "Some message")
92 self.assertIs(type(e), OSError)
93
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020094 def test_try_except(self):
Victor Stinner9ea8e4c2011-10-17 20:18:58 +020095 filename = "some_hopefully_non_existing_file"
96
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020097 # This checks that try .. except checks the concrete exception
98 # (FileNotFoundError) and not the base type specified when
99 # PyErr_SetFromErrnoWithFilenameObject was called.
100 # (it is therefore deliberate that it doesn't use assertRaises)
101 try:
Victor Stinner9ea8e4c2011-10-17 20:18:58 +0200102 open(filename)
103 except FileNotFoundError:
104 pass
105 else:
106 self.fail("should have raised a FileNotFoundError")
107
108 # Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
109 self.assertFalse(os.path.exists(filename))
110 try:
111 os.unlink(filename)
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +0200112 except FileNotFoundError:
113 pass
114 else:
115 self.fail("should have raised a FileNotFoundError")
116
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200117
118class AttributesTest(unittest.TestCase):
119
120 def test_windows_error(self):
121 if os.name == "nt":
122 self.assertIn('winerror', dir(OSError))
123 else:
124 self.assertNotIn('winerror', dir(OSError))
125
126 def test_posix_error(self):
127 e = OSError(EEXIST, "File already exists", "foo.txt")
128 self.assertEqual(e.errno, EEXIST)
129 self.assertEqual(e.args[0], EEXIST)
130 self.assertEqual(e.strerror, "File already exists")
131 self.assertEqual(e.filename, "foo.txt")
132 if os.name == "nt":
133 self.assertEqual(e.winerror, None)
134
135 @unittest.skipUnless(os.name == "nt", "Windows-specific test")
136 def test_errno_translation(self):
137 # ERROR_ALREADY_EXISTS (183) -> EEXIST
138 e = OSError(0, "File already exists", "foo.txt", 183)
139 self.assertEqual(e.winerror, 183)
140 self.assertEqual(e.errno, EEXIST)
141 self.assertEqual(e.args[0], EEXIST)
142 self.assertEqual(e.strerror, "File already exists")
143 self.assertEqual(e.filename, "foo.txt")
144
145 def test_blockingioerror(self):
146 args = ("a", "b", "c", "d", "e")
147 for n in range(6):
148 e = BlockingIOError(*args[:n])
149 with self.assertRaises(AttributeError):
150 e.characters_written
151 e = BlockingIOError("a", "b", 3)
152 self.assertEqual(e.characters_written, 3)
153 e.characters_written = 5
154 self.assertEqual(e.characters_written, 5)
155
156 # XXX VMSError not tested
157
158
Antoine Pitroue0e27352011-12-15 14:31:28 +0100159class ExplicitSubclassingTest(unittest.TestCase):
160
161 def test_errno_mapping(self):
162 # When constructing an OSError subclass, errno mapping isn't done
163 e = SubOSError(EEXIST, "Bad file descriptor")
164 self.assertIs(type(e), SubOSError)
165
166 def test_init_overriden(self):
167 e = SubOSErrorWithInit("some message", "baz")
168 self.assertEqual(e.bar, "baz")
169 self.assertEqual(e.args, ("some message",))
170
171 def test_init_kwdargs(self):
172 e = SubOSErrorWithInit("some message", bar="baz")
173 self.assertEqual(e.bar, "baz")
174 self.assertEqual(e.args, ("some message",))
175
176 def test_new_overriden(self):
177 e = SubOSErrorWithNew("some message", "baz")
178 self.assertEqual(e.baz, "baz")
179 self.assertEqual(e.args, ("some message",))
180
181 def test_new_kwdargs(self):
182 e = SubOSErrorWithNew("some message", baz="baz")
183 self.assertEqual(e.baz, "baz")
184 self.assertEqual(e.args, ("some message",))
185
186 def test_init_new_overriden(self):
187 e = SubOSErrorCombinedInitFirst("some message", "baz")
188 self.assertEqual(e.bar, "baz")
189 self.assertEqual(e.baz, "baz")
190 self.assertEqual(e.args, ("some message",))
191 e = SubOSErrorCombinedNewFirst("some message", "baz")
192 self.assertEqual(e.bar, "baz")
193 self.assertEqual(e.baz, "baz")
194 self.assertEqual(e.args, ("some message",))
195
196
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200197def test_main():
198 support.run_unittest(__name__)
199
200if __name__=="__main__":
201 test_main()