blob: 8649596790945bc91f3a4c90ce2734b82e8f200c [file] [log] [blame]
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02001import builtins
2import os
3import select
4import socket
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02005import unittest
6import errno
7from errno import EEXIST
8
Antoine Pitrou6b4883d2011-10-12 02:54:14 +02009
10class SubOSError(OSError):
11 pass
12
Antoine Pitroue0e27352011-12-15 14:31:28 +010013class SubOSErrorWithInit(OSError):
14 def __init__(self, message, bar):
15 self.bar = bar
16 super().__init__(message)
17
18class SubOSErrorWithNew(OSError):
19 def __new__(cls, message, baz):
20 self = super().__new__(cls, message)
21 self.baz = baz
22 return self
23
24class SubOSErrorCombinedInitFirst(SubOSErrorWithInit, SubOSErrorWithNew):
25 pass
26
27class SubOSErrorCombinedNewFirst(SubOSErrorWithNew, SubOSErrorWithInit):
28 pass
29
Antoine Pitrouf87289b2012-06-30 23:37:47 +020030class SubOSErrorWithStandaloneInit(OSError):
31 def __init__(self):
32 pass
33
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020034
35class HierarchyTest(unittest.TestCase):
36
37 def test_builtin_errors(self):
38 self.assertEqual(OSError.__name__, 'OSError')
39 self.assertIs(IOError, OSError)
40 self.assertIs(EnvironmentError, OSError)
41
42 def test_socket_errors(self):
43 self.assertIs(socket.error, IOError)
44 self.assertIs(socket.gaierror.__base__, OSError)
45 self.assertIs(socket.herror.__base__, OSError)
46 self.assertIs(socket.timeout.__base__, OSError)
47
48 def test_select_error(self):
49 self.assertIs(select.error, OSError)
50
51 # mmap.error is tested in test_mmap
52
53 _pep_map = """
54 +-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
55 +-- ChildProcessError ECHILD
56 +-- ConnectionError
57 +-- BrokenPipeError EPIPE, ESHUTDOWN
58 +-- ConnectionAbortedError ECONNABORTED
59 +-- ConnectionRefusedError ECONNREFUSED
60 +-- ConnectionResetError ECONNRESET
61 +-- FileExistsError EEXIST
62 +-- FileNotFoundError ENOENT
63 +-- InterruptedError EINTR
64 +-- IsADirectoryError EISDIR
65 +-- NotADirectoryError ENOTDIR
66 +-- PermissionError EACCES, EPERM
67 +-- ProcessLookupError ESRCH
68 +-- TimeoutError ETIMEDOUT
69 """
70 def _make_map(s):
71 _map = {}
72 for line in s.splitlines():
73 line = line.strip('+- ')
74 if not line:
75 continue
76 excname, _, errnames = line.partition(' ')
77 for errname in filter(None, errnames.strip().split(', ')):
78 _map[getattr(errno, errname)] = getattr(builtins, excname)
79 return _map
80 _map = _make_map(_pep_map)
81
82 def test_errno_mapping(self):
83 # The OSError constructor maps errnos to subclasses
84 # A sample test for the basic functionality
85 e = OSError(EEXIST, "Bad file descriptor")
86 self.assertIs(type(e), FileExistsError)
87 # Exhaustive testing
88 for errcode, exc in self._map.items():
89 e = OSError(errcode, "Some message")
90 self.assertIs(type(e), exc)
91 othercodes = set(errno.errorcode) - set(self._map)
92 for errcode in othercodes:
93 e = OSError(errcode, "Some message")
94 self.assertIs(type(e), OSError)
95
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020096 def test_try_except(self):
Victor Stinner9ea8e4c2011-10-17 20:18:58 +020097 filename = "some_hopefully_non_existing_file"
98
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020099 # This checks that try .. except checks the concrete exception
100 # (FileNotFoundError) and not the base type specified when
101 # PyErr_SetFromErrnoWithFilenameObject was called.
102 # (it is therefore deliberate that it doesn't use assertRaises)
103 try:
Victor Stinner9ea8e4c2011-10-17 20:18:58 +0200104 open(filename)
105 except FileNotFoundError:
106 pass
107 else:
108 self.fail("should have raised a FileNotFoundError")
109
110 # Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
111 self.assertFalse(os.path.exists(filename))
112 try:
113 os.unlink(filename)
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +0200114 except FileNotFoundError:
115 pass
116 else:
117 self.fail("should have raised a FileNotFoundError")
118
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200119
120class AttributesTest(unittest.TestCase):
121
122 def test_windows_error(self):
123 if os.name == "nt":
124 self.assertIn('winerror', dir(OSError))
125 else:
126 self.assertNotIn('winerror', dir(OSError))
127
128 def test_posix_error(self):
129 e = OSError(EEXIST, "File already exists", "foo.txt")
130 self.assertEqual(e.errno, EEXIST)
131 self.assertEqual(e.args[0], EEXIST)
132 self.assertEqual(e.strerror, "File already exists")
133 self.assertEqual(e.filename, "foo.txt")
134 if os.name == "nt":
135 self.assertEqual(e.winerror, None)
136
137 @unittest.skipUnless(os.name == "nt", "Windows-specific test")
138 def test_errno_translation(self):
139 # ERROR_ALREADY_EXISTS (183) -> EEXIST
140 e = OSError(0, "File already exists", "foo.txt", 183)
141 self.assertEqual(e.winerror, 183)
142 self.assertEqual(e.errno, EEXIST)
143 self.assertEqual(e.args[0], EEXIST)
144 self.assertEqual(e.strerror, "File already exists")
145 self.assertEqual(e.filename, "foo.txt")
146
147 def test_blockingioerror(self):
148 args = ("a", "b", "c", "d", "e")
149 for n in range(6):
150 e = BlockingIOError(*args[:n])
151 with self.assertRaises(AttributeError):
152 e.characters_written
153 e = BlockingIOError("a", "b", 3)
154 self.assertEqual(e.characters_written, 3)
155 e.characters_written = 5
156 self.assertEqual(e.characters_written, 5)
157
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200158
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
Martin Pantere26da7c2016-06-02 10:07:09 +0000166 def test_init_overridden(self):
Antoine Pitroue0e27352011-12-15 14:31:28 +0100167 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
Martin Pantere26da7c2016-06-02 10:07:09 +0000176 def test_new_overridden(self):
Antoine Pitroue0e27352011-12-15 14:31:28 +0100177 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
Martin Pantere26da7c2016-06-02 10:07:09 +0000186 def test_init_new_overridden(self):
Antoine Pitroue0e27352011-12-15 14:31:28 +0100187 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
Antoine Pitrouf87289b2012-06-30 23:37:47 +0200196 def test_init_standalone(self):
197 # __init__ doesn't propagate to OSError.__init__ (see issue #15229)
198 e = SubOSErrorWithStandaloneInit()
199 self.assertEqual(e.args, ())
200 self.assertEqual(str(e), '')
201
Antoine Pitroue0e27352011-12-15 14:31:28 +0100202
Zachary Ware38c707e2015-04-13 15:00:43 -0500203if __name__ == "__main__":
204 unittest.main()