mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			211 lines
		
	
	
	
		
			7.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
	
		
			7.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import builtins
 | 
						|
import os
 | 
						|
import select
 | 
						|
import socket
 | 
						|
import unittest
 | 
						|
import errno
 | 
						|
from errno import EEXIST
 | 
						|
 | 
						|
 | 
						|
class SubOSError(OSError):
 | 
						|
    pass
 | 
						|
 | 
						|
class SubOSErrorWithInit(OSError):
 | 
						|
    def __init__(self, message, bar):
 | 
						|
        self.bar = bar
 | 
						|
        super().__init__(message)
 | 
						|
 | 
						|
class SubOSErrorWithNew(OSError):
 | 
						|
    def __new__(cls, message, baz):
 | 
						|
        self = super().__new__(cls, message)
 | 
						|
        self.baz = baz
 | 
						|
        return self
 | 
						|
 | 
						|
class SubOSErrorCombinedInitFirst(SubOSErrorWithInit, SubOSErrorWithNew):
 | 
						|
    pass
 | 
						|
 | 
						|
class SubOSErrorCombinedNewFirst(SubOSErrorWithNew, SubOSErrorWithInit):
 | 
						|
    pass
 | 
						|
 | 
						|
class SubOSErrorWithStandaloneInit(OSError):
 | 
						|
    def __init__(self):
 | 
						|
        pass
 | 
						|
 | 
						|
 | 
						|
class HierarchyTest(unittest.TestCase):
 | 
						|
 | 
						|
    def test_builtin_errors(self):
 | 
						|
        self.assertEqual(OSError.__name__, 'OSError')
 | 
						|
        self.assertIs(IOError, OSError)
 | 
						|
        self.assertIs(EnvironmentError, OSError)
 | 
						|
 | 
						|
    def test_socket_errors(self):
 | 
						|
        self.assertIs(socket.error, OSError)
 | 
						|
        self.assertIs(socket.gaierror.__base__, OSError)
 | 
						|
        self.assertIs(socket.herror.__base__, OSError)
 | 
						|
        self.assertIs(socket.timeout, TimeoutError)
 | 
						|
 | 
						|
    def test_select_error(self):
 | 
						|
        self.assertIs(select.error, OSError)
 | 
						|
 | 
						|
    # mmap.error is tested in test_mmap
 | 
						|
 | 
						|
    _pep_map = """
 | 
						|
        +-- BlockingIOError        EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
 | 
						|
        +-- ChildProcessError                                          ECHILD
 | 
						|
        +-- ConnectionError
 | 
						|
            +-- BrokenPipeError                              EPIPE, ESHUTDOWN
 | 
						|
            +-- ConnectionAbortedError                           ECONNABORTED
 | 
						|
            +-- ConnectionRefusedError                           ECONNREFUSED
 | 
						|
            +-- ConnectionResetError                               ECONNRESET
 | 
						|
        +-- FileExistsError                                            EEXIST
 | 
						|
        +-- FileNotFoundError                                          ENOENT
 | 
						|
        +-- InterruptedError                                            EINTR
 | 
						|
        +-- IsADirectoryError                                          EISDIR
 | 
						|
        +-- NotADirectoryError                                        ENOTDIR
 | 
						|
        +-- PermissionError                        EACCES, EPERM, ENOTCAPABLE
 | 
						|
        +-- ProcessLookupError                                          ESRCH
 | 
						|
        +-- TimeoutError                                            ETIMEDOUT
 | 
						|
    """
 | 
						|
    def _make_map(s):
 | 
						|
        _map = {}
 | 
						|
        for line in s.splitlines():
 | 
						|
            line = line.strip('+- ')
 | 
						|
            if not line:
 | 
						|
                continue
 | 
						|
            excname, _, errnames = line.partition(' ')
 | 
						|
            for errname in filter(None, errnames.strip().split(', ')):
 | 
						|
                if errname == "ENOTCAPABLE" and not hasattr(errno, errname):
 | 
						|
                    continue
 | 
						|
                _map[getattr(errno, errname)] = getattr(builtins, excname)
 | 
						|
        return _map
 | 
						|
    _map = _make_map(_pep_map)
 | 
						|
 | 
						|
    def test_errno_mapping(self):
 | 
						|
        # The OSError constructor maps errnos to subclasses
 | 
						|
        # A sample test for the basic functionality
 | 
						|
        e = OSError(EEXIST, "Bad file descriptor")
 | 
						|
        self.assertIs(type(e), FileExistsError)
 | 
						|
        # Exhaustive testing
 | 
						|
        for errcode, exc in self._map.items():
 | 
						|
            e = OSError(errcode, "Some message")
 | 
						|
            self.assertIs(type(e), exc)
 | 
						|
        othercodes = set(errno.errorcode) - set(self._map)
 | 
						|
        for errcode in othercodes:
 | 
						|
            e = OSError(errcode, "Some message")
 | 
						|
            self.assertIs(type(e), OSError, repr(e))
 | 
						|
 | 
						|
    def test_try_except(self):
 | 
						|
        filename = "some_hopefully_non_existing_file"
 | 
						|
 | 
						|
        # This checks that try .. except checks the concrete exception
 | 
						|
        # (FileNotFoundError) and not the base type specified when
 | 
						|
        # PyErr_SetFromErrnoWithFilenameObject was called.
 | 
						|
        # (it is therefore deliberate that it doesn't use assertRaises)
 | 
						|
        try:
 | 
						|
            open(filename)
 | 
						|
        except FileNotFoundError:
 | 
						|
            pass
 | 
						|
        else:
 | 
						|
            self.fail("should have raised a FileNotFoundError")
 | 
						|
 | 
						|
        # Another test for PyErr_SetExcFromWindowsErrWithFilenameObject()
 | 
						|
        self.assertFalse(os.path.exists(filename))
 | 
						|
        try:
 | 
						|
            os.unlink(filename)
 | 
						|
        except FileNotFoundError:
 | 
						|
            pass
 | 
						|
        else:
 | 
						|
            self.fail("should have raised a FileNotFoundError")
 | 
						|
 | 
						|
 | 
						|
class AttributesTest(unittest.TestCase):
 | 
						|
 | 
						|
    def test_windows_error(self):
 | 
						|
        if os.name == "nt":
 | 
						|
            self.assertIn('winerror', dir(OSError))
 | 
						|
        else:
 | 
						|
            self.assertNotIn('winerror', dir(OSError))
 | 
						|
 | 
						|
    def test_posix_error(self):
 | 
						|
        e = OSError(EEXIST, "File already exists", "foo.txt")
 | 
						|
        self.assertEqual(e.errno, EEXIST)
 | 
						|
        self.assertEqual(e.args[0], EEXIST)
 | 
						|
        self.assertEqual(e.strerror, "File already exists")
 | 
						|
        self.assertEqual(e.filename, "foo.txt")
 | 
						|
        if os.name == "nt":
 | 
						|
            self.assertEqual(e.winerror, None)
 | 
						|
 | 
						|
    @unittest.skipUnless(os.name == "nt", "Windows-specific test")
 | 
						|
    def test_errno_translation(self):
 | 
						|
        # ERROR_ALREADY_EXISTS (183) -> EEXIST
 | 
						|
        e = OSError(0, "File already exists", "foo.txt", 183)
 | 
						|
        self.assertEqual(e.winerror, 183)
 | 
						|
        self.assertEqual(e.errno, EEXIST)
 | 
						|
        self.assertEqual(e.args[0], EEXIST)
 | 
						|
        self.assertEqual(e.strerror, "File already exists")
 | 
						|
        self.assertEqual(e.filename, "foo.txt")
 | 
						|
 | 
						|
    def test_blockingioerror(self):
 | 
						|
        args = ("a", "b", "c", "d", "e")
 | 
						|
        for n in range(6):
 | 
						|
            e = BlockingIOError(*args[:n])
 | 
						|
            with self.assertRaises(AttributeError):
 | 
						|
                e.characters_written
 | 
						|
            with self.assertRaises(AttributeError):
 | 
						|
                del e.characters_written
 | 
						|
        e = BlockingIOError("a", "b", 3)
 | 
						|
        self.assertEqual(e.characters_written, 3)
 | 
						|
        e.characters_written = 5
 | 
						|
        self.assertEqual(e.characters_written, 5)
 | 
						|
        del e.characters_written
 | 
						|
        with self.assertRaises(AttributeError):
 | 
						|
            e.characters_written
 | 
						|
 | 
						|
 | 
						|
class ExplicitSubclassingTest(unittest.TestCase):
 | 
						|
 | 
						|
    def test_errno_mapping(self):
 | 
						|
        # When constructing an OSError subclass, errno mapping isn't done
 | 
						|
        e = SubOSError(EEXIST, "Bad file descriptor")
 | 
						|
        self.assertIs(type(e), SubOSError)
 | 
						|
 | 
						|
    def test_init_overridden(self):
 | 
						|
        e = SubOSErrorWithInit("some message", "baz")
 | 
						|
        self.assertEqual(e.bar, "baz")
 | 
						|
        self.assertEqual(e.args, ("some message",))
 | 
						|
 | 
						|
    def test_init_kwdargs(self):
 | 
						|
        e = SubOSErrorWithInit("some message", bar="baz")
 | 
						|
        self.assertEqual(e.bar, "baz")
 | 
						|
        self.assertEqual(e.args, ("some message",))
 | 
						|
 | 
						|
    def test_new_overridden(self):
 | 
						|
        e = SubOSErrorWithNew("some message", "baz")
 | 
						|
        self.assertEqual(e.baz, "baz")
 | 
						|
        self.assertEqual(e.args, ("some message",))
 | 
						|
 | 
						|
    def test_new_kwdargs(self):
 | 
						|
        e = SubOSErrorWithNew("some message", baz="baz")
 | 
						|
        self.assertEqual(e.baz, "baz")
 | 
						|
        self.assertEqual(e.args, ("some message",))
 | 
						|
 | 
						|
    def test_init_new_overridden(self):
 | 
						|
        e = SubOSErrorCombinedInitFirst("some message", "baz")
 | 
						|
        self.assertEqual(e.bar, "baz")
 | 
						|
        self.assertEqual(e.baz, "baz")
 | 
						|
        self.assertEqual(e.args, ("some message",))
 | 
						|
        e = SubOSErrorCombinedNewFirst("some message", "baz")
 | 
						|
        self.assertEqual(e.bar, "baz")
 | 
						|
        self.assertEqual(e.baz, "baz")
 | 
						|
        self.assertEqual(e.args, ("some message",))
 | 
						|
 | 
						|
    def test_init_standalone(self):
 | 
						|
        # __init__ doesn't propagate to OSError.__init__ (see issue #15229)
 | 
						|
        e = SubOSErrorWithStandaloneInit()
 | 
						|
        self.assertEqual(e.args, ())
 | 
						|
        self.assertEqual(str(e), '')
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    unittest.main()
 |