blob: e327f42301498e2a3865a7cbd02cafe46f895286 [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
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020082 def test_try_except(self):
Victor Stinner9ea8e4c2011-10-17 20:18:58 +020083 filename = "some_hopefully_non_existing_file"
84
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +020085 # This checks that try .. except checks the concrete exception
86 # (FileNotFoundError) and not the base type specified when
87 # PyErr_SetFromErrnoWithFilenameObject was called.
88 # (it is therefore deliberate that it doesn't use assertRaises)
89 try:
Victor Stinner9ea8e4c2011-10-17 20:18:58 +020090 open(filename)
91 except FileNotFoundError:
92 pass
93 else:
94 self.fail("should have raised a FileNotFoundError")
95
96 # Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
97 self.assertFalse(os.path.exists(filename))
98 try:
99 os.unlink(filename)
Antoine Pitrou5d6fbe82011-10-12 19:39:57 +0200100 except FileNotFoundError:
101 pass
102 else:
103 self.fail("should have raised a FileNotFoundError")
104
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200105
106class AttributesTest(unittest.TestCase):
107
108 def test_windows_error(self):
109 if os.name == "nt":
110 self.assertIn('winerror', dir(OSError))
111 else:
112 self.assertNotIn('winerror', dir(OSError))
113
114 def test_posix_error(self):
115 e = OSError(EEXIST, "File already exists", "foo.txt")
116 self.assertEqual(e.errno, EEXIST)
117 self.assertEqual(e.args[0], EEXIST)
118 self.assertEqual(e.strerror, "File already exists")
119 self.assertEqual(e.filename, "foo.txt")
120 if os.name == "nt":
121 self.assertEqual(e.winerror, None)
122
123 @unittest.skipUnless(os.name == "nt", "Windows-specific test")
124 def test_errno_translation(self):
125 # ERROR_ALREADY_EXISTS (183) -> EEXIST
126 e = OSError(0, "File already exists", "foo.txt", 183)
127 self.assertEqual(e.winerror, 183)
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
133 def test_blockingioerror(self):
134 args = ("a", "b", "c", "d", "e")
135 for n in range(6):
136 e = BlockingIOError(*args[:n])
137 with self.assertRaises(AttributeError):
138 e.characters_written
139 e = BlockingIOError("a", "b", 3)
140 self.assertEqual(e.characters_written, 3)
141 e.characters_written = 5
142 self.assertEqual(e.characters_written, 5)
143
144 # XXX VMSError not tested
145
146
147def test_main():
148 support.run_unittest(__name__)
149
150if __name__=="__main__":
151 test_main()