blob: 2792c10f9892c68e369ee6d8645e02444b9e902d [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 Pitrouf87289b2012-06-30 23:37:47 +020032class SubOSErrorWithStandaloneInit(OSError):
33 def __init__(self):
34 pass
35
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020036
37class HierarchyTest(unittest.TestCase):
38
39 def test_builtin_errors(self):
40 self.assertEqual(OSError.__name__, 'OSError')
41 self.assertIs(IOError, OSError)
42 self.assertIs(EnvironmentError, OSError)
43
44 def test_socket_errors(self):
45 self.assertIs(socket.error, IOError)
46 self.assertIs(socket.gaierror.__base__, OSError)
47 self.assertIs(socket.herror.__base__, OSError)
48 self.assertIs(socket.timeout.__base__, OSError)
49
50 def test_select_error(self):
51 self.assertIs(select.error, OSError)
52
53 # mmap.error is tested in test_mmap
54
55 _pep_map = """
56 +-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
57 +-- ChildProcessError ECHILD
58 +-- ConnectionError
59 +-- BrokenPipeError EPIPE, ESHUTDOWN
60 +-- ConnectionAbortedError ECONNABORTED
61 +-- ConnectionRefusedError ECONNREFUSED
62 +-- ConnectionResetError ECONNRESET
63 +-- FileExistsError EEXIST
64 +-- FileNotFoundError ENOENT
65 +-- InterruptedError EINTR
66 +-- IsADirectoryError EISDIR
67 +-- NotADirectoryError ENOTDIR
68 +-- PermissionError EACCES, EPERM
69 +-- ProcessLookupError ESRCH
70 +-- TimeoutError ETIMEDOUT
71 """
72 def _make_map(s):
73 _map = {}
74 for line in s.splitlines():
75 line = line.strip('+- ')
76 if not line:
77 continue
78 excname, _, errnames = line.partition(' ')
79 for errname in filter(None, errnames.strip().split(', ')):
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)
97
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020098 def test_try_except(self):
Victor Stinner9ea8e4c2011-10-17 20:18:58 +020099 filename = "some_hopefully_non_existing_file"
100
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +0200101 # 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:
Victor Stinner9ea8e4c2011-10-17 20:18:58 +0200106 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)
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +0200116 except FileNotFoundError:
117 pass
118 else:
119 self.fail("should have raised a FileNotFoundError")
120
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200121
122class AttributesTest(unittest.TestCase):
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 e = BlockingIOError("a", "b", 3)
156 self.assertEqual(e.characters_written, 3)
157 e.characters_written = 5
158 self.assertEqual(e.characters_written, 5)
159
160 # XXX VMSError not tested
161
162
Antoine Pitroue0e27352011-12-15 14:31:28 +0100163class ExplicitSubclassingTest(unittest.TestCase):
164
165 def test_errno_mapping(self):
166 # When constructing an OSError subclass, errno mapping isn't done
167 e = SubOSError(EEXIST, "Bad file descriptor")
168 self.assertIs(type(e), SubOSError)
169
170 def test_init_overriden(self):
171 e = SubOSErrorWithInit("some message", "baz")
172 self.assertEqual(e.bar, "baz")
173 self.assertEqual(e.args, ("some message",))
174
175 def test_init_kwdargs(self):
176 e = SubOSErrorWithInit("some message", bar="baz")
177 self.assertEqual(e.bar, "baz")
178 self.assertEqual(e.args, ("some message",))
179
180 def test_new_overriden(self):
181 e = SubOSErrorWithNew("some message", "baz")
182 self.assertEqual(e.baz, "baz")
183 self.assertEqual(e.args, ("some message",))
184
185 def test_new_kwdargs(self):
186 e = SubOSErrorWithNew("some message", baz="baz")
187 self.assertEqual(e.baz, "baz")
188 self.assertEqual(e.args, ("some message",))
189
190 def test_init_new_overriden(self):
191 e = SubOSErrorCombinedInitFirst("some message", "baz")
192 self.assertEqual(e.bar, "baz")
193 self.assertEqual(e.baz, "baz")
194 self.assertEqual(e.args, ("some message",))
195 e = SubOSErrorCombinedNewFirst("some message", "baz")
196 self.assertEqual(e.bar, "baz")
197 self.assertEqual(e.baz, "baz")
198 self.assertEqual(e.args, ("some message",))
199
Antoine Pitrouf87289b2012-06-30 23:37:47 +0200200 def test_init_standalone(self):
201 # __init__ doesn't propagate to OSError.__init__ (see issue #15229)
202 e = SubOSErrorWithStandaloneInit()
203 self.assertEqual(e.args, ())
204 self.assertEqual(str(e), '')
205
Antoine Pitroue0e27352011-12-15 14:31:28 +0100206
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200207def test_main():
208 support.run_unittest(__name__)
209
210if __name__=="__main__":
211 test_main()