diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 88d120a427f..4e04371f626 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4961,7 +4961,6 @@ class OverrideBoth(OverrideNew, OverrideInit): self.assertRaises(TypeError, case, 1, 2, 3) self.assertRaises(TypeError, case, 1, 2, foo=3) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_subclassing_does_not_duplicate_dict_descriptors(self): class Base: pass diff --git a/Lib/test/test_file_eintr.py b/Lib/test/test_file_eintr.py index 55cc31dc59f..13260b8e498 100644 --- a/Lib/test/test_file_eintr.py +++ b/Lib/test/test_file_eintr.py @@ -152,7 +152,6 @@ def _test_reading(self, data_to_write, read_and_verify_code): '"got data %r\\nexpected %r" % (got, expected))' ) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readline(self): """readline() must handle signals and not lose data.""" self._test_reading( @@ -161,7 +160,6 @@ def test_readline(self): read_method_name='readline', expected=b'hello, world!\n')) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readlines(self): """readlines() must handle signals and not lose data.""" self._test_reading( @@ -170,7 +168,6 @@ def test_readlines(self): read_method_name='readlines', expected=[b'hello\n', b'world!\n'])) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readall(self): """readall() must handle signals and not lose data.""" self._test_reading( @@ -189,6 +186,19 @@ def test_readall(self): class CTestFileIOSignalInterrupt(TestFileIOSignalInterrupt, unittest.TestCase): modname = '_io' + # TODO: RUSTPYTHON - _io module uses _pyio internally, signal handling differs + @unittest.expectedFailure + def test_readline(self): + super().test_readline() + + @unittest.expectedFailure + def test_readlines(self): + super().test_readlines() + + @unittest.expectedFailure + def test_readall(self): + super().test_readall() + class PyTestFileIOSignalInterrupt(TestFileIOSignalInterrupt, unittest.TestCase): modname = '_pyio' @@ -200,7 +210,6 @@ def _generate_infile_setup_code(self): 'assert isinstance(infile, io.BufferedReader)' % self.modname) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readall(self): """BufferedReader.read() must handle signals and not lose data.""" self._test_reading( @@ -212,6 +221,19 @@ def test_readall(self): class CTestBufferedIOSignalInterrupt(TestBufferedIOSignalInterrupt, unittest.TestCase): modname = '_io' + # TODO: RUSTPYTHON - _io module uses _pyio internally, signal handling differs + @unittest.expectedFailure + def test_readline(self): + super().test_readline() + + @unittest.expectedFailure + def test_readlines(self): + super().test_readlines() + + @unittest.expectedFailure + def test_readall(self): + super().test_readall() + class PyTestBufferedIOSignalInterrupt(TestBufferedIOSignalInterrupt, unittest.TestCase): modname = '_pyio' @@ -224,7 +246,6 @@ def _generate_infile_setup_code(self): 'assert isinstance(infile, io.TextIOWrapper)' % self.modname) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readline(self): """readline() must handle signals and not lose data.""" self._test_reading( @@ -233,7 +254,6 @@ def test_readline(self): read_method_name='readline', expected='hello, world!\n')) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readlines(self): """readlines() must handle signals and not lose data.""" self._test_reading( @@ -242,7 +262,6 @@ def test_readlines(self): read_method_name='readlines', expected=['hello\n', 'world!\n'])) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_readall(self): """read() must handle signals and not lose data.""" self._test_reading( @@ -254,6 +273,19 @@ def test_readall(self): class CTestTextIOSignalInterrupt(TestTextIOSignalInterrupt, unittest.TestCase): modname = '_io' + # TODO: RUSTPYTHON - _io module uses _pyio internally, signal handling differs + @unittest.expectedFailure + def test_readline(self): + super().test_readline() + + @unittest.expectedFailure + def test_readlines(self): + super().test_readlines() + + @unittest.expectedFailure + def test_readall(self): + super().test_readall() + class PyTestTextIOSignalInterrupt(TestTextIOSignalInterrupt, unittest.TestCase): modname = '_pyio' diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 34ef13adf33..58b3e55d321 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -24,8 +24,6 @@ class GenericTests(unittest.TestCase): - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_enums(self): for name in dir(signal): sig = getattr(signal, name) @@ -763,8 +761,6 @@ def handler(signum, frame): % (exitcode, stdout)) return (exitcode == 3) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_without_siginterrupt(self): # If a signal handler is installed and siginterrupt is not called # at all, when that signal arrives, it interrupts a syscall that's in @@ -772,8 +768,6 @@ def test_without_siginterrupt(self): interrupted = self.readpipe_interrupted(None) self.assertTrue(interrupted) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_siginterrupt_on(self): # If a signal handler is installed and siginterrupt is called with # a true value for the second argument, when that signal arrives, it diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 5ccbfa7ff83..d5a35a3253e 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2052,8 +2052,6 @@ def test_socket_fileno_requires_socket_fd(self): fileno=afile.fileno()) self.assertEqual(cm.exception.errno, errno.ENOTSOCK) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_addressfamily_enum(self): import _socket, enum CheckedAddressFamily = enum._old_convert_( @@ -2063,8 +2061,6 @@ def test_addressfamily_enum(self): ) enum._test_simple_enum(CheckedAddressFamily, socket.AddressFamily) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_socketkind_enum(self): import _socket, enum CheckedSocketKind = enum._old_convert_( @@ -2074,8 +2070,6 @@ def test_socketkind_enum(self): ) enum._test_simple_enum(CheckedSocketKind, socket.SocketKind) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_msgflag_enum(self): import _socket, enum CheckedMsgFlag = enum._old_convert_( @@ -2085,8 +2079,6 @@ def test_msgflag_enum(self): ) enum._test_simple_enum(CheckedMsgFlag, socket.MsgFlag) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_addressinfo_enum(self): import _socket, enum CheckedAddressInfo = enum._old_convert_( diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index f073def5bc1..09d35a77a1c 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -5477,7 +5477,6 @@ class Checked_TLSMessageType(enum.IntEnum): CHANGE_CIPHER_SPEC = 0x0101 enum._test_simple_enum(Checked_TLSMessageType, _TLSMessageType) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_sslmethod(self): Checked_SSLMethod = enum._old_convert_( enum.IntEnum, '_SSLMethod', 'ssl', @@ -5488,7 +5487,6 @@ def test_sslmethod(self): Checked_SSLMethod.PROTOCOL_SSLv23 = Checked_SSLMethod.PROTOCOL_TLS enum._test_simple_enum(Checked_SSLMethod, ssl._SSLMethod) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_options(self): CheckedOptions = enum._old_convert_( enum.IntFlag, 'Options', 'ssl', @@ -5497,7 +5495,6 @@ def test_options(self): ) enum._test_simple_enum(CheckedOptions, ssl.Options) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_alertdescription(self): CheckedAlertDescription = enum._old_convert_( enum.IntEnum, 'AlertDescription', 'ssl', @@ -5506,7 +5503,6 @@ def test_alertdescription(self): ) enum._test_simple_enum(CheckedAlertDescription, ssl.AlertDescription) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_sslerrornumber(self): Checked_SSLErrorNumber = enum._old_convert_( enum.IntEnum, 'SSLErrorNumber', 'ssl', @@ -5515,7 +5511,6 @@ def test_sslerrornumber(self): ) enum._test_simple_enum(Checked_SSLErrorNumber, ssl.SSLErrorNumber) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_verifyflags(self): CheckedVerifyFlags = enum._old_convert_( enum.IntFlag, 'VerifyFlags', 'ssl', @@ -5524,7 +5519,6 @@ def test_verifyflags(self): ) enum._test_simple_enum(CheckedVerifyFlags, ssl.VerifyFlags) - @unittest.expectedFailure # TODO: RUSTPYTHON def test_verifymode(self): CheckedVerifyMode = enum._old_convert_( enum.IntEnum, 'VerifyMode', 'ssl', diff --git a/crates/vm/src/builtins/type.rs b/crates/vm/src/builtins/type.rs index de34678ae45..86d871fe30f 100644 --- a/crates/vm/src/builtins/type.rs +++ b/crates/vm/src/builtins/type.rs @@ -1499,9 +1499,15 @@ impl Constructor for PyType { // Only add if: // 1. base is not type (type subclasses inherit __dict__ from type) // 2. the class has HAS_DICT flag (i.e., __slots__ was not defined or __dict__ is in __slots__) + // 3. no base class in MRO already provides __dict__ descriptor if !base_is_type && typ.slots.flags.has_feature(PyTypeFlags::HAS_DICT) { let __dict__ = identifier!(vm, __dict__); - if !typ.attributes.read().contains_key(&__dict__) { + let has_inherited_dict = typ + .mro + .read() + .iter() + .any(|base| base.attributes.read().contains_key(&__dict__)); + if !typ.attributes.read().contains_key(&__dict__) && !has_inherited_dict { unsafe { let descriptor = vm.ctx diff --git a/crates/vm/src/stdlib/os.rs b/crates/vm/src/stdlib/os.rs index 87080ff8e0f..28d4aeb3755 100644 --- a/crates/vm/src/stdlib/os.rs +++ b/crates/vm/src/stdlib/os.rs @@ -274,12 +274,21 @@ pub(super) mod _os { } #[pyfunction] - fn read(fd: crt_fd::Borrowed<'_>, n: usize, vm: &VirtualMachine) -> io::Result { + fn read(fd: crt_fd::Borrowed<'_>, n: usize, vm: &VirtualMachine) -> PyResult { let mut buffer = vec![0u8; n]; - let n = crt_fd::read(fd, &mut buffer)?; - buffer.truncate(n); - - Ok(vm.ctx.new_bytes(buffer)) + loop { + match crt_fd::read(fd, &mut buffer) { + Ok(n) => { + buffer.truncate(n); + return Ok(vm.ctx.new_bytes(buffer)); + } + Err(e) if e.raw_os_error() == Some(libc::EINTR) => { + vm.check_signals()?; + continue; + } + Err(e) => return Err(e.into_pyexception(vm)), + } + } } #[pyfunction]