1 import builtins
2 import os
3 import select
4 import socket
5 import unittest
6 import errno
7 from errno import EEXIST
8
9
10 class ESC[4;38;5;81mSubOSError(ESC[4;38;5;149mOSError):
11 pass
12
13 class ESC[4;38;5;81mSubOSErrorWithInit(ESC[4;38;5;149mOSError):
14 def __init__(self, message, bar):
15 self.bar = bar
16 super().__init__(message)
17
18 class ESC[4;38;5;81mSubOSErrorWithNew(ESC[4;38;5;149mOSError):
19 def __new__(cls, message, baz):
20 self = super().__new__(cls, message)
21 self.baz = baz
22 return self
23
24 class ESC[4;38;5;81mSubOSErrorCombinedInitFirst(ESC[4;38;5;149mSubOSErrorWithInit, ESC[4;38;5;149mSubOSErrorWithNew):
25 pass
26
27 class ESC[4;38;5;81mSubOSErrorCombinedNewFirst(ESC[4;38;5;149mSubOSErrorWithNew, ESC[4;38;5;149mSubOSErrorWithInit):
28 pass
29
30 class ESC[4;38;5;81mSubOSErrorWithStandaloneInit(ESC[4;38;5;149mOSError):
31 def __init__(self):
32 pass
33
34
35 class ESC[4;38;5;81mHierarchyTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
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, OSError)
44 self.assertIs(socket.gaierror.__base__, OSError)
45 self.assertIs(socket.herror.__base__, OSError)
46 self.assertIs(socket.timeout, TimeoutError)
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, ENOTCAPABLE
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 if errname == "ENOTCAPABLE" and not hasattr(errno, errname):
79 continue
80 _map[getattr(errno, errname)] = getattr(builtins, excname)
81 return _map
82 _map = _make_map(_pep_map)
83
84 def test_errno_mapping(self):
85 # The OSError constructor maps errnos to subclasses
86 # A sample test for the basic functionality
87 e = OSError(EEXIST, "Bad file descriptor")
88 self.assertIs(type(e), FileExistsError)
89 # Exhaustive testing
90 for errcode, exc in self._map.items():
91 e = OSError(errcode, "Some message")
92 self.assertIs(type(e), exc)
93 othercodes = set(errno.errorcode) - set(self._map)
94 for errcode in othercodes:
95 e = OSError(errcode, "Some message")
96 self.assertIs(type(e), OSError, repr(e))
97
98 def test_try_except(self):
99 filename = "some_hopefully_non_existing_file"
100
101 # This checks that try .. except checks the concrete exception
102 # (FileNotFoundError) and not the base type specified when
103 # PyErr_SetFromErrnoWithFilenameObject was called.
104 # (it is therefore deliberate that it doesn't use assertRaises)
105 try:
106 open(filename)
107 except FileNotFoundError:
108 pass
109 else:
110 self.fail("should have raised a FileNotFoundError")
111
112 # Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
113 self.assertFalse(os.path.exists(filename))
114 try:
115 os.unlink(filename)
116 except FileNotFoundError:
117 pass
118 else:
119 self.fail("should have raised a FileNotFoundError")
120
121
122 class ESC[4;38;5;81mAttributesTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
123
124 def test_windows_error(self):
125 if os.name == "nt":
126 self.assertIn('winerror', dir(OSError))
127 else:
128 self.assertNotIn('winerror', dir(OSError))
129
130 def test_posix_error(self):
131 e = OSError(EEXIST, "File already exists", "foo.txt")
132 self.assertEqual(e.errno, EEXIST)
133 self.assertEqual(e.args[0], EEXIST)
134 self.assertEqual(e.strerror, "File already exists")
135 self.assertEqual(e.filename, "foo.txt")
136 if os.name == "nt":
137 self.assertEqual(e.winerror, None)
138
139 @unittest.skipUnless(os.name == "nt", "Windows-specific test")
140 def test_errno_translation(self):
141 # ERROR_ALREADY_EXISTS (183) -> EEXIST
142 e = OSError(0, "File already exists", "foo.txt", 183)
143 self.assertEqual(e.winerror, 183)
144 self.assertEqual(e.errno, EEXIST)
145 self.assertEqual(e.args[0], EEXIST)
146 self.assertEqual(e.strerror, "File already exists")
147 self.assertEqual(e.filename, "foo.txt")
148
149 def test_blockingioerror(self):
150 args = ("a", "b", "c", "d", "e")
151 for n in range(6):
152 e = BlockingIOError(*args[:n])
153 with self.assertRaises(AttributeError):
154 e.characters_written
155 with self.assertRaises(AttributeError):
156 del e.characters_written
157 e = BlockingIOError("a", "b", 3)
158 self.assertEqual(e.characters_written, 3)
159 e.characters_written = 5
160 self.assertEqual(e.characters_written, 5)
161 del e.characters_written
162 with self.assertRaises(AttributeError):
163 e.characters_written
164
165
166 class ESC[4;38;5;81mExplicitSubclassingTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
167
168 def test_errno_mapping(self):
169 # When constructing an OSError subclass, errno mapping isn't done
170 e = SubOSError(EEXIST, "Bad file descriptor")
171 self.assertIs(type(e), SubOSError)
172
173 def test_init_overridden(self):
174 e = SubOSErrorWithInit("some message", "baz")
175 self.assertEqual(e.bar, "baz")
176 self.assertEqual(e.args, ("some message",))
177
178 def test_init_kwdargs(self):
179 e = SubOSErrorWithInit("some message", bar="baz")
180 self.assertEqual(e.bar, "baz")
181 self.assertEqual(e.args, ("some message",))
182
183 def test_new_overridden(self):
184 e = SubOSErrorWithNew("some message", "baz")
185 self.assertEqual(e.baz, "baz")
186 self.assertEqual(e.args, ("some message",))
187
188 def test_new_kwdargs(self):
189 e = SubOSErrorWithNew("some message", baz="baz")
190 self.assertEqual(e.baz, "baz")
191 self.assertEqual(e.args, ("some message",))
192
193 def test_init_new_overridden(self):
194 e = SubOSErrorCombinedInitFirst("some message", "baz")
195 self.assertEqual(e.bar, "baz")
196 self.assertEqual(e.baz, "baz")
197 self.assertEqual(e.args, ("some message",))
198 e = SubOSErrorCombinedNewFirst("some message", "baz")
199 self.assertEqual(e.bar, "baz")
200 self.assertEqual(e.baz, "baz")
201 self.assertEqual(e.args, ("some message",))
202
203 def test_init_standalone(self):
204 # __init__ doesn't propagate to OSError.__init__ (see issue #15229)
205 e = SubOSErrorWithStandaloneInit()
206 self.assertEqual(e.args, ())
207 self.assertEqual(str(e), '')
208
209
210 if __name__ == "__main__":
211 unittest.main()