blob: 3c52bc6a1aa9454099bf9c26704935726014bfd7 [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):
83 # This checks that try .. except checks the concrete exception
84 # (FileNotFoundError) and not the base type specified when
85 # PyErr_SetFromErrnoWithFilenameObject was called.
86 # (it is therefore deliberate that it doesn't use assertRaises)
87 try:
88 open("some_hopefully_non_existing_file")
89 except FileNotFoundError:
90 pass
91 else:
92 self.fail("should have raised a FileNotFoundError")
93
Antoine Pitrou6b4883d2011-10-12 02:54:14 +020094
95class AttributesTest(unittest.TestCase):
96
97 def test_windows_error(self):
98 if os.name == "nt":
99 self.assertIn('winerror', dir(OSError))
100 else:
101 self.assertNotIn('winerror', dir(OSError))
102
103 def test_posix_error(self):
104 e = OSError(EEXIST, "File already exists", "foo.txt")
105 self.assertEqual(e.errno, EEXIST)
106 self.assertEqual(e.args[0], EEXIST)
107 self.assertEqual(e.strerror, "File already exists")
108 self.assertEqual(e.filename, "foo.txt")
109 if os.name == "nt":
110 self.assertEqual(e.winerror, None)
111
112 @unittest.skipUnless(os.name == "nt", "Windows-specific test")
113 def test_errno_translation(self):
114 # ERROR_ALREADY_EXISTS (183) -> EEXIST
115 e = OSError(0, "File already exists", "foo.txt", 183)
116 self.assertEqual(e.winerror, 183)
117 self.assertEqual(e.errno, EEXIST)
118 self.assertEqual(e.args[0], EEXIST)
119 self.assertEqual(e.strerror, "File already exists")
120 self.assertEqual(e.filename, "foo.txt")
121
122 def test_blockingioerror(self):
123 args = ("a", "b", "c", "d", "e")
124 for n in range(6):
125 e = BlockingIOError(*args[:n])
126 with self.assertRaises(AttributeError):
127 e.characters_written
128 e = BlockingIOError("a", "b", 3)
129 self.assertEqual(e.characters_written, 3)
130 e.characters_written = 5
131 self.assertEqual(e.characters_written, 5)
132
133 # XXX VMSError not tested
134
135
136def test_main():
137 support.run_unittest(__name__)
138
139if __name__=="__main__":
140 test_main()