forked from Rust-related/RustPython
Merge pull request #4656 from dalinaum/with-type-error
Change error type for bad objects in "with" and "async with"
This commit is contained in:
4
Lib/test/test_contextlib.py
vendored
4
Lib/test/test_contextlib.py
vendored
@@ -545,8 +545,6 @@ class TestContextDecorator(unittest.TestCase):
|
||||
self.assertEqual(test.b, 2)
|
||||
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_typo_enter(self):
|
||||
class mycontext(ContextDecorator):
|
||||
def __unter__(self):
|
||||
@@ -559,8 +557,6 @@ class TestContextDecorator(unittest.TestCase):
|
||||
pass
|
||||
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_typo_exit(self):
|
||||
class mycontext(ContextDecorator):
|
||||
def __enter__(self):
|
||||
|
||||
6
Lib/test/test_with.py
vendored
6
Lib/test/test_with.py
vendored
@@ -109,8 +109,6 @@ class FailureTestCase(unittest.TestCase):
|
||||
with foo: pass
|
||||
self.assertRaises(NameError, fooNotDeclared)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testEnterAttributeError1(self):
|
||||
class LacksEnter(object):
|
||||
def __exit__(self, type, value, traceback):
|
||||
@@ -121,8 +119,6 @@ class FailureTestCase(unittest.TestCase):
|
||||
with foo: pass
|
||||
self.assertRaisesRegex(TypeError, 'the context manager', fooLacksEnter)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testEnterAttributeError2(self):
|
||||
class LacksEnterAndExit(object):
|
||||
pass
|
||||
@@ -132,8 +128,6 @@ class FailureTestCase(unittest.TestCase):
|
||||
with foo: pass
|
||||
self.assertRaisesRegex(TypeError, 'the context manager', fooLacksEnterAndExit)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testExitAttributeError(self):
|
||||
class LacksExit(object):
|
||||
def __enter__(self):
|
||||
|
||||
@@ -840,12 +840,24 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
bytecode::Instruction::SetupWith { end } => {
|
||||
let context_manager = self.pop_value();
|
||||
let enter_res = vm.call_special_method(
|
||||
context_manager.clone(),
|
||||
identifier!(vm, __enter__),
|
||||
(),
|
||||
)?;
|
||||
let exit = context_manager.get_attr(identifier!(vm, __exit__), vm)?;
|
||||
let error_string = || -> String {
|
||||
format!(
|
||||
"'{:.200}' object does not support the context manager protocol",
|
||||
context_manager.class().name(),
|
||||
)
|
||||
};
|
||||
let enter_res = vm
|
||||
.get_special_method(context_manager.clone(), identifier!(vm, __enter__))?
|
||||
.map_err(|_obj| vm.new_type_error(error_string()))?
|
||||
.invoke((), vm)?;
|
||||
|
||||
let exit = context_manager
|
||||
.get_attr(identifier!(vm, __exit__), vm)
|
||||
.map_err(|_exc| {
|
||||
vm.new_type_error({
|
||||
format!("'{} (missed __exit__ method)", error_string())
|
||||
})
|
||||
})?;
|
||||
self.push_value(exit);
|
||||
self.push_block(BlockType::Finally {
|
||||
handler: end.get(arg),
|
||||
@@ -855,9 +867,24 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
bytecode::Instruction::BeforeAsyncWith => {
|
||||
let mgr = self.pop_value();
|
||||
let aenter_res =
|
||||
vm.call_special_method(mgr.clone(), identifier!(vm, __aenter__), ())?;
|
||||
let aexit = mgr.get_attr(identifier!(vm, __aexit__), vm)?;
|
||||
let error_string = || -> String {
|
||||
format!(
|
||||
"'{:.200}' object does not support the asynchronous context manager protocol",
|
||||
mgr.class().name(),
|
||||
)
|
||||
};
|
||||
|
||||
let aenter_res = vm
|
||||
.get_special_method(mgr.clone(), identifier!(vm, __aenter__))?
|
||||
.map_err(|_obj| vm.new_type_error(error_string()))?
|
||||
.invoke((), vm)?;
|
||||
let aexit = mgr
|
||||
.get_attr(identifier!(vm, __aexit__), vm)
|
||||
.map_err(|_exc| {
|
||||
vm.new_type_error({
|
||||
format!("'{} (missed __aexit__ method)", error_string())
|
||||
})
|
||||
})?;
|
||||
self.push_value(aexit);
|
||||
self.push_value(aenter_res);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user