Skip to content

Commit 8ad3f3f

Browse files
committed
Fill OSError attributes
1 parent 3301220 commit 8ad3f3f

File tree

5 files changed

+59
-12
lines changed

5 files changed

+59
-12
lines changed

Lib/test/test_exception_hierarchy.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import unittest
66
import errno
77
from errno import EEXIST
8+
import sys
89

910

1011
class SubOSError(OSError):
@@ -130,8 +131,8 @@ def test_windows_error(self):
130131
else:
131132
self.assertNotIn('winerror', dir(OSError))
132133

133-
# TODO: RUSTPYTHON
134-
@unittest.expectedFailure
134+
@unittest.skip("TODO: RUSTPYTHON")
135+
@unittest.skipIf(sys.platform == 'win32', 'winerror not filled yet')
135136
def test_posix_error(self):
136137
e = OSError(EEXIST, "File already exists", "foo.txt")
137138
self.assertEqual(e.errno, EEXIST)

Lib/test/test_exceptions.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,32 @@ def test_WindowsError(self):
410410
self.assertEqual(w.strerror, 'foo')
411411
self.assertEqual(w.filename, None)
412412
self.assertEqual(w.filename2, None)
413+
self.assertEqual(str(w), "[Errno bar] foo")
414+
415+
# Unexpected number of arguments
416+
w = OSError(0)
417+
self.assertEqual(w.errno, None)
418+
self.assertEqual(w.winerror, None)
419+
self.assertEqual(w.strerror, None)
420+
self.assertEqual(w.filename, None)
421+
self.assertEqual(w.filename2, None)
422+
self.assertEqual(str(w), "0")
423+
424+
w = OSError('foo')
425+
self.assertEqual(w.errno, None)
426+
self.assertEqual(w.winerror, None)
427+
self.assertEqual(w.strerror, None)
428+
self.assertEqual(w.filename, None)
429+
self.assertEqual(w.filename2, None)
430+
self.assertEqual(str(w), "foo")
431+
432+
w = OSError('a', 'b', 'c', 'd', 'e', 'f')
433+
self.assertEqual(w.errno, None)
434+
self.assertEqual(w.winerror, None)
435+
self.assertEqual(w.strerror, None)
436+
self.assertEqual(w.filename, None)
437+
self.assertEqual(w.filename2, None)
438+
self.assertEqual(str(w), "('a', 'b', 'c', 'd', 'e', 'f')")
413439

414440
@unittest.skipUnless(sys.platform == 'win32',
415441
'test specific to Windows')
@@ -435,6 +461,9 @@ def testAttributes(self):
435461
{'args' : ('foo', 1)}),
436462
(SystemExit, ('foo',),
437463
{'args' : ('foo',), 'code' : 'foo'}),
464+
(OSError, (),
465+
{'args' : (), 'filename' : None, 'filename2' : None,
466+
'errno' : None, 'strerror' : None}),
438467
(OSError, ('foo',),
439468
{'args' : ('foo',), 'filename' : None, 'filename2' : None,
440469
'errno' : None, 'strerror' : None}),
@@ -456,6 +485,9 @@ def testAttributes(self):
456485
{'args' : (1, 'strErrorStr'), 'errno' : 1,
457486
'strerror' : 'strErrorStr',
458487
'filename' : 'filenameStr', 'filename2' : None}),
488+
(OSError, ('a', 'b', 'c', 'd', 'e', 'f'),
489+
{'args' : ('a', 'b', 'c', 'd', 'e', 'f'), 'filename' : None, 'filename2' : None,
490+
'errno' : None, 'strerror' : None}),
459491
(SyntaxError, (), {'msg' : None, 'text' : None,
460492
'filename' : None, 'lineno' : None, 'offset' : None,
461493
'end_offset': None, 'print_file_and_line' : None}),

Lib/test/test_fileio.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,6 @@ class PyAutoFileTests(AutoFileTests, unittest.TestCase):
391391
FileIO = _pyio.FileIO
392392
modulename = '_pyio'
393393

394-
# TODO: RUSTPYTHON
395-
@unittest.expectedFailure
396394
def testOpendir(self):
397395
super().testOpendir()
398396

Lib/test/test_subprocess.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,8 +1547,6 @@ def test_failed_child_execute_fd_leak(self):
15471547
fds_after_exception = os.listdir(fd_directory)
15481548
self.assertEqual(fds_before_popen, fds_after_exception)
15491549

1550-
# TODO: RUSTPYTHON
1551-
@unittest.expectedFailure
15521550
@unittest.skipIf(mswindows, "behavior currently not supported on Windows")
15531551
def test_file_not_found_includes_filename(self):
15541552
with self.assertRaises(FileNotFoundError) as c:

vm/src/exceptions.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -752,13 +752,22 @@ impl ExceptionZoo {
752752
let errno_getter =
753753
ctx.new_readonly_getset("errno", excs.os_error, |exc: PyBaseExceptionRef| {
754754
let args = exc.args();
755-
args.get(0).filter(|_| args.len() > 1).cloned()
755+
args.get(0)
756+
.filter(|_| args.len() > 1 && args.len() <= 5)
757+
.cloned()
758+
});
759+
let strerror_getter =
760+
ctx.new_readonly_getset("strerror", excs.os_error, |exc: PyBaseExceptionRef| {
761+
let args = exc.args();
762+
args.get(1)
763+
.filter(|_| args.len() >= 2 && args.len() <= 5)
764+
.cloned()
756765
});
757766
extend_exception!(PyOSError, ctx, excs.os_error, {
758767
// POSIX exception code
759768
"errno" => errno_getter.clone(),
760769
// exception strerror
761-
"strerror" => ctx.new_readonly_getset("strerror", excs.os_error, make_arg_getter(1)),
770+
"strerror" => strerror_getter.clone(),
762771
// exception filename
763772
"filename" => ctx.none(),
764773
// second exception filename
@@ -1260,15 +1269,15 @@ pub(super) mod types {
12601269
os_error,
12611270
"Base class for I/O related errors.",
12621271
os_error_new,
1263-
base_exception_init,
1272+
os_error_init,
12641273
}
12651274
#[cfg(not(target_arch = "wasm32"))]
12661275
fn os_error_optional_new(
12671276
args: Vec<PyObjectRef>,
12681277
vm: &VirtualMachine,
12691278
) -> Option<PyBaseExceptionRef> {
12701279
let len = args.len();
1271-
if len >= 2 {
1280+
if (2..=5).contains(&len) {
12721281
let errno = &args[0];
12731282
errno
12741283
.payload_if_subclass::<PyInt>(vm)
@@ -1297,9 +1306,18 @@ pub(super) mod types {
12971306
fn os_error_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
12981307
PyBaseException::slot_new(cls, args, vm)
12991308
}
1309+
fn os_error_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
1310+
let len = args.args.len();
1311+
let mut new_args = args;
1312+
if (3..=5).contains(&len) {
1313+
zelf.set_attr("filename", new_args.args[2].clone(), vm)?;
1314+
if len == 5 {
1315+
zelf.set_attr("filename2", new_args.args[4].clone(), vm)?;
1316+
}
13001317

1301-
fn base_exception_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
1302-
PyBaseException::init(zelf, args, vm)
1318+
new_args.args.truncate(2);
1319+
}
1320+
PyBaseException::init(zelf, new_args, vm)
13031321
}
13041322

13051323
define_exception! {

0 commit comments

Comments
 (0)