Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Lib/test/test_exception_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import unittest
import errno
from errno import EEXIST
import sys


class SubOSError(OSError):
Expand Down Expand Up @@ -130,8 +131,8 @@ def test_windows_error(self):
else:
self.assertNotIn('winerror', dir(OSError))

# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.skip("TODO: RUSTPYTHON")
@unittest.skipIf(sys.platform == 'win32', 'winerror not filled yet')
def test_posix_error(self):
e = OSError(EEXIST, "File already exists", "foo.txt")
self.assertEqual(e.errno, EEXIST)
Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,6 @@ class PyAutoFileTests(AutoFileTests, unittest.TestCase):
FileIO = _pyio.FileIO
modulename = '_pyio'

# TODO: RUSTPYTHON
@unittest.expectedFailure
def testOpendir(self):
super().testOpendir()

Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -1547,8 +1547,6 @@ def test_failed_child_execute_fd_leak(self):
fds_after_exception = os.listdir(fd_directory)
self.assertEqual(fds_before_popen, fds_after_exception)

# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.skipIf(mswindows, "behavior currently not supported on Windows")
def test_file_not_found_includes_filename(self):
with self.assertRaises(FileNotFoundError) as c:
Expand Down
34 changes: 34 additions & 0 deletions extra_tests/snippets/builtin_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,40 @@ class SubError(MyError):
assert OSError(1, 2).errno
assert OSError(1, 2).strerror


# OSError Unexpected number of arguments
w = OSError()
assert w.errno == None
assert not sys.platform.startswith("win") or w.winerror == None
assert w.strerror == None
assert w.filename == None
assert w.filename2 == None
assert str(w) == ""

w = OSError(0)
assert w.errno == None
assert not sys.platform.startswith("win") or w.winerror == None
assert w.strerror == None
assert w.filename == None
assert w.filename2 == None
assert str(w) == "0"

w = OSError('foo')
assert w.errno == None
assert not sys.platform.startswith("win") or w.winerror == None
assert w.strerror == None
assert w.filename == None
assert w.filename2 == None
assert str(w) == "foo"

w = OSError('a', 'b', 'c', 'd', 'e', 'f')
assert w.errno == None
assert not sys.platform.startswith("win") or w.winerror == None
assert w.strerror == None
assert w.filename == None
assert w.filename2 == None
assert str(w) == "('a', 'b', 'c', 'd', 'e', 'f')"

# Custom `__new__` and `__init__`:
assert ImportError.__init__.__qualname__ == 'ImportError.__init__'
assert ImportError(name='a').name == 'a'
Expand Down
30 changes: 24 additions & 6 deletions vm/src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -752,13 +752,22 @@ impl ExceptionZoo {
let errno_getter =
ctx.new_readonly_getset("errno", excs.os_error, |exc: PyBaseExceptionRef| {
let args = exc.args();
args.get(0).filter(|_| args.len() > 1).cloned()
args.get(0)
.filter(|_| args.len() > 1 && args.len() <= 5)
.cloned()
});
let strerror_getter =
ctx.new_readonly_getset("strerror", excs.os_error, |exc: PyBaseExceptionRef| {
let args = exc.args();
args.get(1)
.filter(|_| args.len() >= 2 && args.len() <= 5)
.cloned()
});
extend_exception!(PyOSError, ctx, excs.os_error, {
// POSIX exception code
"errno" => errno_getter.clone(),
// exception strerror
"strerror" => ctx.new_readonly_getset("strerror", excs.os_error, make_arg_getter(1)),
"strerror" => strerror_getter.clone(),
// exception filename
"filename" => ctx.none(),
// second exception filename
Expand Down Expand Up @@ -1260,15 +1269,15 @@ pub(super) mod types {
os_error,
"Base class for I/O related errors.",
os_error_new,
base_exception_init,
os_error_init,
}
#[cfg(not(target_arch = "wasm32"))]
fn os_error_optional_new(
args: Vec<PyObjectRef>,
vm: &VirtualMachine,
) -> Option<PyBaseExceptionRef> {
let len = args.len();
if len >= 2 {
if (2..=5).contains(&len) {
let errno = &args[0];
errno
.payload_if_subclass::<PyInt>(vm)
Expand Down Expand Up @@ -1297,9 +1306,18 @@ pub(super) mod types {
fn os_error_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
PyBaseException::slot_new(cls, args, vm)
}
fn os_error_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
let len = args.args.len();
let mut new_args = args;
if (3..=5).contains(&len) {
zelf.set_attr("filename", new_args.args[2].clone(), vm)?;
if len == 5 {
zelf.set_attr("filename2", new_args.args[4].clone(), vm)?;
}

fn base_exception_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
PyBaseException::init(zelf, args, vm)
new_args.args.truncate(2);
}
PyBaseException::init(zelf, new_args, vm)
}

define_exception! {
Expand Down