Misc changes; exception chaining, PyBytesLike::into_buffer

This commit is contained in:
Noah committed 2020-11-06 11:11:07 -06:00
1 parent 4db7a23064
commit 374a956d03
4 files changed
+70 -23

No files matched your search

+18 -2
View File
@@ -47,6 +47,12 @@ impl PyRwBytesLike {
}
}
impl PyBytesLike {
pub fn into_buffer(self) -> BufferRef {
self.0
}
}
impl TryFromObject for PyBytesLike {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let buffer = try_buffer_from_object(vm, &obj)?;
@@ -88,8 +94,8 @@ pub fn try_rw_bytes_like<R>(
.ok_or_else(|| vm.new_type_error("buffer is not a read-write bytes-like object".to_owned()))
}
impl TryFromObject for PyRwBytesLike {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
impl PyRwBytesLike {
pub fn new(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Self> {
let buffer = try_buffer_from_object(vm, &obj)?;
if !buffer.get_options().contiguous {
Err(vm.new_type_error("non-contiguous buffer is not a bytes-like object".to_owned()))
@@ -99,6 +105,16 @@ impl TryFromObject for PyRwBytesLike {
Ok(Self(buffer))
}
}
pub fn into_buffer(self) -> BufferRef {
self.0
}
}
impl TryFromObject for PyRwBytesLike {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
Self::new(vm, &obj)
}
}
impl<'a> BorrowValue<'a> for PyRwBytesLike {
+11
View File
@@ -152,6 +152,17 @@ impl PyBaseException {
}
}
pub fn chain<T>(e1: PyResult<()>, e2: PyResult<T>) -> PyResult<T> {
match (e1, e2) {
(Err(e1), Err(e)) => {
e.set_context(Some(e1));
Err(e)
}
(Err(e), Ok(_)) | (Ok(()), Err(e)) => Err(e),
(Ok(()), Ok(close_res)) => Ok(close_res),
}
}
/// Print exception chain by calling sys.excepthook
pub fn print_exception(vm: &VirtualMachine, exc: PyBaseExceptionRef) {
let write_fallback = |exc, errstr| {
+9 -1
View File
@@ -865,7 +865,15 @@ impl ExecutingFrame<'_> {
return Ok(None);
}
}
BlockType::FinallyHandler { .. } => {
BlockType::FinallyHandler {
reason: finally_reason,
} => {
if let Some(UnwindReason::Raising { exception }) = finally_reason {
let finally_exc = exception;
if let UnwindReason::Raising { exception } = &reason {
exception.set_context(Some(finally_exc))
}
}
self.pop_block();
}
BlockType::ExceptHandler => {
+32 -20
View File
@@ -187,25 +187,8 @@ impl FuncArgs {
/// during the conversion will halt the binding and return the error.
pub fn bind<T: FromArgs>(mut self, vm: &VirtualMachine) -> PyResult<T> {
let given_args = self.args.len();
let bound = T::from_args(vm, &mut self).map_err(|e| match e {
ArgumentError::TooFewArgs => vm.new_type_error(format!(
"Expected at least {} arguments ({} given)",
T::arity().start(),
given_args,
)),
ArgumentError::TooManyArgs => vm.new_type_error(format!(
"Expected at most {} arguments ({} given)",
T::arity().end(),
given_args,
)),
ArgumentError::InvalidKeywordArgument(name) => {
vm.new_type_error(format!("{} is an invalid keyword argument", name))
}
ArgumentError::RequiredKeywordArgument(name) => {
vm.new_type_error(format!("Required keyqord only argument {}", name))
}
ArgumentError::Exception(ex) => ex,
})?;
let bound = T::from_args(vm, &mut self)
.map_err(|e| e.into_exception(T::arity(), given_args, vm))?;
if !self.args.is_empty() {
Err(vm.new_type_error(format!(
@@ -243,6 +226,35 @@ impl From<PyBaseExceptionRef> for ArgumentError {
}
}
impl ArgumentError {
fn into_exception(
self,
arity: RangeInclusive<usize>,
num_given: usize,
vm: &VirtualMachine,
) -> PyBaseExceptionRef {
match self {
ArgumentError::TooFewArgs => vm.new_type_error(format!(
"Expected at least {} arguments ({} given)",
arity.start(),
num_given
)),
ArgumentError::TooManyArgs => vm.new_type_error(format!(
"Expected at most {} arguments ({} given)",
arity.end(),
num_given
)),
ArgumentError::InvalidKeywordArgument(name) => {
vm.new_type_error(format!("{} is an invalid keyword argument", name))
}
ArgumentError::RequiredKeywordArgument(name) => {
vm.new_type_error(format!("Required keyqord only argument {}", name))
}
ArgumentError::Exception(ex) => ex,
}
}
}
/// Implemented by any type that can be accepted as a parameter to a built-in
/// function.
///
@@ -439,7 +451,7 @@ impl OptionalArg<PyObjectRef> {
}
}
pub type OptionalOption<T> = OptionalArg<Option<T>>;
pub type OptionalOption<T = PyObjectRef> = OptionalArg<Option<T>>;
impl<T> OptionalOption<T> {
#[inline]