(
&self,
exc_type: PyObjectRef,
exc_val: OptionalArg,
exc_tb: OptionalArg,
vm: &VirtualMachine,
)
| 1002 | |
| 1003 | #[pymethod] |
| 1004 | fn throw( |
| 1005 | &self, |
| 1006 | exc_type: PyObjectRef, |
| 1007 | exc_val: OptionalArg, |
| 1008 | exc_tb: OptionalArg, |
| 1009 | vm: &VirtualMachine, |
| 1010 | ) -> PyResult { |
| 1011 | // Warn about deprecated (type, val, tb) signature |
| 1012 | if exc_val.is_present() || exc_tb.is_present() { |
| 1013 | warn::warn( |
| 1014 | vm.ctx |
| 1015 | .new_str( |
| 1016 | "the (type, val, tb) signature of throw() is deprecated, \ |
| 1017 | use throw(val) instead", |
| 1018 | ) |
| 1019 | .into(), |
| 1020 | Some(vm.ctx.exceptions.deprecation_warning.to_owned()), |
| 1021 | 1, |
| 1022 | None, |
| 1023 | vm, |
| 1024 | )?; |
| 1025 | } |
| 1026 | |
| 1027 | *self.future.write() = None; |
| 1028 | |
| 1029 | // Validate tb if present |
| 1030 | if let OptionalArg::Present(ref tb) = exc_tb |
| 1031 | && !vm.is_none(tb) |
| 1032 | && !tb.fast_isinstance(vm.ctx.types.traceback_type) |
| 1033 | { |
| 1034 | return Err(vm.new_type_error(format!( |
| 1035 | "throw() third argument must be a traceback object, not '{}'", |
| 1036 | tb.class().name() |
| 1037 | ))); |
| 1038 | } |
| 1039 | |
| 1040 | let exc = if exc_type.fast_isinstance(vm.ctx.types.type_type) { |
| 1041 | // exc_type is a class |
| 1042 | let exc_class: PyTypeRef = exc_type.clone().downcast().unwrap(); |
| 1043 | // Must be a subclass of BaseException |
| 1044 | if !exc_class.fast_issubclass(vm.ctx.exceptions.base_exception_type) { |
| 1045 | return Err(vm.new_type_error( |
| 1046 | "exceptions must be classes or instances deriving from BaseException, not type" |
| 1047 | )); |
| 1048 | } |
| 1049 | |
| 1050 | let val = exc_val.unwrap_or_none(vm); |
| 1051 | if vm.is_none(&val) { |
| 1052 | exc_type.call((), vm)? |
| 1053 | } else if val.fast_isinstance(&exc_class) { |
| 1054 | val |
| 1055 | } else { |
| 1056 | exc_type.call((val,), vm)? |
| 1057 | } |
| 1058 | } else if exc_type.fast_isinstance(vm.ctx.exceptions.base_exception_type) { |
| 1059 | // exc_type is an exception instance |
| 1060 | if let OptionalArg::Present(ref val) = exc_val |
| 1061 | && !vm.is_none(val) |
nothing calls this directly
no test coverage detected