1use crate::{
2 AsObject, Py, PyObject, PyObjectRef, PyRef, PyResult,
3 builtins::{
4 PyBaseException, PyBaseExceptionRef, PyBytesRef, PyDictRef, PyModule, PyOSError, PyStrRef,
5 PyType, PyTypeRef,
6 builtin_func::PyNativeFunction,
7 descriptor::PyMethodDescriptor,
8 tuple::{IntoPyTuple, PyTupleRef},
9 },
10 convert::{ToPyException, ToPyObject},
11 exceptions::OSErrorBuilder,
12 function::{IntoPyNativeFn, PyMethodFlags},
13 scope::Scope,
14 vm::VirtualMachine,
15};
16use rustpython_common::wtf8::Wtf8Buf;
17use rustpython_compiler_core::SourceLocation;
18
19macro_rules! define_exception_fn {
20 (
21 fn $fn_name:ident, $attr:ident, $python_repr:ident
22 ) => {
23 #[doc = concat!(
24 "Create a new python ",
25 stringify!($python_repr),
26 " object.\nUseful for raising errors from python functions implemented in rust."
27 )]
28 pub fn $fn_name(&self, msg: impl Into<Wtf8Buf>) -> PyBaseExceptionRef
29 {
30 let err = self.ctx.exceptions.$attr.to_owned();
31 self.new_exception_msg(err, msg.into())
32 }
33 };
34}
35
36impl VirtualMachine {
38 pub fn new_pyobj(&self, value: impl ToPyObject) -> PyObjectRef {
40 value.to_pyobject(self)
41 }
42
43 pub fn new_tuple(&self, value: impl IntoPyTuple) -> PyTupleRef {
44 value.into_pytuple(self)
45 }
46
47 pub fn new_module(
48 &self,
49 name: &str,
50 dict: PyDictRef,
51 doc: Option<PyStrRef>,
52 ) -> PyRef<PyModule> {
53 let module = PyRef::new_ref(
54 PyModule::new(),
55 self.ctx.types.module_type.to_owned(),
56 Some(dict),
57 );
58 module.init_dict(self.ctx.intern_str(name), doc, self);
59 module
60 }
61
62 pub fn new_scope_with_builtins(&self) -> Scope {
63 Scope::with_builtins(None, self.ctx.new_dict(), self)
64 }
65
66 pub fn new_scope_with_main(&self) -> PyResult<Scope> {
67 let scope = self.new_scope_with_builtins();
68 let main_module = self.new_module("__main__", scope.globals.clone(), None);
69
70 self.sys_module.get_attr("modules", self)?.set_item(
71 "__main__",
72 main_module.into(),
73 self,
74 )?;
75
76 Ok(scope)
77 }
78
79 pub fn new_function<F, FKind>(&self, name: &'static str, f: F) -> PyRef<PyNativeFunction>
80 where
81 F: IntoPyNativeFn<FKind>,
82 {
83 let def = self
84 .ctx
85 .new_method_def(name, f, PyMethodFlags::empty(), None);
86 def.build_function(self)
87 }
88
89 pub fn new_method<F, FKind>(
90 &self,
91 name: &'static str,
92 class: &'static Py<PyType>,
93 f: F,
94 ) -> PyRef<PyMethodDescriptor>
95 where
96 F: IntoPyNativeFn<FKind>,
97 {
98 let def = self
99 .ctx
100 .new_method_def(name, f, PyMethodFlags::METHOD, None);
101 def.build_method(class, self)
102 }
103
104 pub fn new_exception(&self, exc_type: PyTypeRef, args: Vec<PyObjectRef>) -> PyBaseExceptionRef {
110 debug_assert_eq!(
111 exc_type.slots.basicsize,
112 core::mem::size_of::<PyBaseException>(),
113 "vm.new_exception() is only for exception types without additional payload. The given type '{}' is not allowed. Use vm.new_os_subtype_error() for OSError subtypes.",
114 exc_type.name()
115 );
116
117 PyRef::new_ref(
118 PyBaseException::new(args, self),
119 exc_type,
120 Some(self.ctx.new_dict()),
121 )
122 }
123
124 pub fn new_os_error(&self, msg: impl ToPyObject) -> PyRef<PyBaseException> {
125 self.new_os_subtype_error(self.ctx.exceptions.os_error.to_owned(), None, msg)
126 .upcast()
127 }
128
129 pub fn new_os_subtype_error(
130 &self,
131 exc_type: PyTypeRef,
132 errno: Option<i32>,
133 msg: impl ToPyObject,
134 ) -> PyRef<PyOSError> {
135 debug_assert_eq!(exc_type.slots.basicsize, core::mem::size_of::<PyOSError>());
136
137 OSErrorBuilder::with_subtype(exc_type, errno, msg, self).build(self)
138 }
139
140 pub fn new_exception_empty(&self, exc_type: PyTypeRef) -> PyBaseExceptionRef {
146 self.new_exception(exc_type, vec![])
147 }
148
149 pub fn new_exception_msg(&self, exc_type: PyTypeRef, msg: Wtf8Buf) -> PyBaseExceptionRef {
155 self.new_exception(exc_type, vec![self.ctx.new_str(msg).into()])
156 }
157
158 pub fn new_exception_msg_dict(
164 &self,
165 exc_type: PyTypeRef,
166 msg: Wtf8Buf,
167 dict: PyDictRef,
168 ) -> PyBaseExceptionRef {
169 PyRef::new_ref(
170 PyBaseException::new(vec![self.ctx.new_str(msg).into()], self),
174 exc_type,
175 Some(dict),
176 )
177 }
178
179 pub fn new_no_attribute_error(&self, obj: PyObjectRef, name: PyStrRef) -> PyBaseExceptionRef {
180 let msg = format!(
181 "'{}' object has no attribute '{}'",
182 obj.class().name(),
183 name
184 );
185 let attribute_error = self.new_attribute_error(msg);
186
187 self.set_attribute_error_context(&attribute_error, obj, name);
189
190 attribute_error
191 }
192
193 pub fn new_name_error(&self, msg: impl Into<Wtf8Buf>, name: PyStrRef) -> PyBaseExceptionRef {
194 let name_error_type = self.ctx.exceptions.name_error.to_owned();
195 let name_error = self.new_exception_msg(name_error_type, msg.into());
196 name_error.as_object().set_attr("name", name, self).unwrap();
197 name_error
198 }
199
200 pub fn new_unsupported_unary_error(&self, a: &PyObject, op: &str) -> PyBaseExceptionRef {
201 self.new_type_error(format!(
202 "bad operand type for {}: '{}'",
203 op,
204 a.class().name()
205 ))
206 }
207
208 pub fn new_unsupported_bin_op_error(
209 &self,
210 a: &PyObject,
211 b: &PyObject,
212 op: &str,
213 ) -> PyBaseExceptionRef {
214 self.new_type_error(format!(
215 "unsupported operand type(s) for {}: '{}' and '{}'",
216 op,
217 a.class().name(),
218 b.class().name()
219 ))
220 }
221
222 pub fn new_unsupported_ternary_op_error(
223 &self,
224 a: &PyObject,
225 b: &PyObject,
226 c: &PyObject,
227 op: &str,
228 ) -> PyBaseExceptionRef {
229 self.new_type_error(format!(
230 "Unsupported operand types for '{}': '{}', '{}', and '{}'",
231 op,
232 a.class().name(),
233 b.class().name(),
234 c.class().name()
235 ))
236 }
237
238 pub fn new_last_os_error(&self) -> PyBaseExceptionRef {
243 let err = std::io::Error::last_os_error();
244 err.to_pyexception(self)
245 }
246
247 pub fn new_last_errno_error(&self) -> PyBaseExceptionRef {
252 let err = crate::common::os::errno_io_error();
253 err.to_pyexception(self)
254 }
255
256 pub fn new_errno_error(&self, errno: i32, msg: impl ToPyObject) -> PyRef<PyOSError> {
257 let exc_type = crate::exceptions::errno_to_exc_type(errno, self)
258 .unwrap_or(self.ctx.exceptions.os_error);
259
260 self.new_os_subtype_error(exc_type.to_owned(), Some(errno), msg)
261 }
262
263 pub fn new_unicode_decode_error_real(
264 &self,
265 encoding: PyStrRef,
266 object: PyBytesRef,
267 start: usize,
268 end: usize,
269 reason: PyStrRef,
270 ) -> PyBaseExceptionRef {
271 let start = self.ctx.new_int(start);
272 let end = self.ctx.new_int(end);
273 let exc = self.new_exception(
274 self.ctx.exceptions.unicode_decode_error.to_owned(),
275 vec![
276 encoding.clone().into(),
277 object.clone().into(),
278 start.clone().into(),
279 end.clone().into(),
280 reason.clone().into(),
281 ],
282 );
283 exc.as_object()
284 .set_attr("encoding", encoding, self)
285 .unwrap();
286 exc.as_object().set_attr("object", object, self).unwrap();
287 exc.as_object().set_attr("start", start, self).unwrap();
288 exc.as_object().set_attr("end", end, self).unwrap();
289 exc.as_object().set_attr("reason", reason, self).unwrap();
290 exc
291 }
292
293 pub fn new_unicode_encode_error_real(
294 &self,
295 encoding: PyStrRef,
296 object: PyStrRef,
297 start: usize,
298 end: usize,
299 reason: PyStrRef,
300 ) -> PyBaseExceptionRef {
301 let start = self.ctx.new_int(start);
302 let end = self.ctx.new_int(end);
303 let exc = self.new_exception(
304 self.ctx.exceptions.unicode_encode_error.to_owned(),
305 vec![
306 encoding.clone().into(),
307 object.clone().into(),
308 start.clone().into(),
309 end.clone().into(),
310 reason.clone().into(),
311 ],
312 );
313 exc.as_object()
314 .set_attr("encoding", encoding, self)
315 .unwrap();
316 exc.as_object().set_attr("object", object, self).unwrap();
317 exc.as_object().set_attr("start", start, self).unwrap();
318 exc.as_object().set_attr("end", end, self).unwrap();
319 exc.as_object().set_attr("reason", reason, self).unwrap();
320 exc
321 }
322
323 pub fn new_key_error(&self, obj: PyObjectRef) -> PyBaseExceptionRef {
325 let key_error = self.ctx.exceptions.key_error.to_owned();
326 self.new_exception(key_error, vec![obj])
327 }
328
329 #[cfg(any(feature = "parser", feature = "compiler"))]
330 pub fn new_syntax_error_maybe_incomplete(
331 &self,
332 error: &crate::compiler::CompileError,
333 source: Option<&str>,
334 allow_incomplete: bool,
335 ) -> PyBaseExceptionRef {
336 let incomplete_or_syntax = |allow| -> &'static Py<crate::builtins::PyType> {
337 if allow {
338 self.ctx.exceptions.incomplete_input_error
339 } else {
340 self.ctx.exceptions.syntax_error
341 }
342 };
343
344 let syntax_error_type = match &error {
345 #[cfg(feature = "parser")]
346 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
347 error:
348 ruff_python_parser::ParseErrorType::Lexical(
349 ruff_python_parser::LexicalErrorType::IndentationError,
350 ),
351 ..
352 }) => {
353 let is_tab_error = source.is_some_and(|source| {
356 let mut has_space_indent = false;
357 let mut has_tab_indent = false;
358 for line in source.lines() {
359 let indent: Vec<u8> = line
360 .bytes()
361 .take_while(|&b| b == b' ' || b == b'\t')
362 .collect();
363 if indent.is_empty() {
364 continue;
365 }
366 if indent.contains(&b' ') && indent.contains(&b'\t') {
367 return true;
368 }
369 if indent.contains(&b' ') {
370 has_space_indent = true;
371 }
372 if indent.contains(&b'\t') {
373 has_tab_indent = true;
374 }
375 }
376 has_space_indent && has_tab_indent
377 });
378 if is_tab_error {
379 self.ctx.exceptions.tab_error
380 } else {
381 self.ctx.exceptions.indentation_error
382 }
383 }
384 #[cfg(feature = "parser")]
385 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
386 error: ruff_python_parser::ParseErrorType::UnexpectedIndentation,
387 ..
388 }) => self.ctx.exceptions.indentation_error,
389 #[cfg(feature = "parser")]
390 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
391 error:
392 ruff_python_parser::ParseErrorType::Lexical(
393 ruff_python_parser::LexicalErrorType::Eof,
394 ),
395 ..
396 }) => incomplete_or_syntax(allow_incomplete),
397 #[cfg(feature = "parser")]
399 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
400 is_unclosed_bracket: true,
401 ..
402 }) => incomplete_or_syntax(allow_incomplete),
403 #[cfg(feature = "parser")]
404 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
405 error:
406 ruff_python_parser::ParseErrorType::Lexical(
407 ruff_python_parser::LexicalErrorType::FStringError(
408 ruff_python_parser::InterpolatedStringErrorType::UnterminatedTripleQuotedString,
409 ),
410 ),
411 ..
412 }) => incomplete_or_syntax(allow_incomplete),
413 #[cfg(feature = "parser")]
414 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
415 error:
416 ruff_python_parser::ParseErrorType::Lexical(
417 ruff_python_parser::LexicalErrorType::UnclosedStringError,
418 ),
419 raw_location,
420 ..
421 }) => {
422 if allow_incomplete {
423 let mut is_incomplete = false;
424
425 if let Some(source) = source {
426 let loc = raw_location.start().to_usize();
427 let mut iter = source.chars();
428 if let Some(quote) = iter.nth(loc)
429 && iter.next() == Some(quote)
430 && iter.next() == Some(quote)
431 {
432 is_incomplete = true;
433 }
434 }
435
436 incomplete_or_syntax(is_incomplete)
437 } else {
438 self.ctx.exceptions.syntax_error
439 }
440 }
441 #[cfg(feature = "parser")]
442 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
443 error: ruff_python_parser::ParseErrorType::OtherError(s),
444 raw_location,
445 ..
446 }) => {
447 if s.starts_with("Expected an indented block after") {
448 if allow_incomplete {
449 let mut is_incomplete = true;
453 if let Some(source) = source {
454 let start = raw_location.start().to_usize();
455 let end = raw_location.end().to_usize();
456 let mut iter = source.chars();
457 iter.nth(start);
458 for _ in start..end {
459 if let Some(c) = iter.next() {
460 if !c.is_ascii_whitespace() {
461 is_incomplete = false;
462 }
463 } else {
464 break;
465 }
466 }
467 }
468
469 if is_incomplete {
470 self.ctx.exceptions.incomplete_input_error
471 } else {
472 self.ctx.exceptions.indentation_error }
474 } else {
475 self.ctx.exceptions.indentation_error
476 }
477 } else {
478 self.ctx.exceptions.syntax_error
479 }
480 }
481 _ => self.ctx.exceptions.syntax_error,
482 }
483 .to_owned();
484
485 fn get_statement(source: &str, loc: Option<SourceLocation>) -> Option<String> {
487 let line = source
488 .split('\n')
489 .nth(loc?.line.to_zero_indexed())?
490 .trim_end_matches('\r')
491 .to_owned();
492 Some(line + "\n")
493 }
494
495 let statement = if let Some(source) = source {
496 get_statement(source, error.location())
497 } else {
498 None
499 };
500
501 let mut msg = error.to_string();
502 if let Some(msg) = msg.get_mut(..1) {
503 msg.make_ascii_lowercase();
504 }
505 let mut narrow_caret = false;
506 match error {
507 #[cfg(feature = "parser")]
508 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
509 error:
510 ruff_python_parser::ParseErrorType::FStringError(
511 ruff_python_parser::InterpolatedStringErrorType::UnterminatedString,
512 )
513 | ruff_python_parser::ParseErrorType::Lexical(
514 ruff_python_parser::LexicalErrorType::FStringError(
515 ruff_python_parser::InterpolatedStringErrorType::UnterminatedString,
516 ),
517 ),
518 ..
519 }) => {
520 msg = "unterminated f-string literal".to_owned();
521 }
522 #[cfg(feature = "parser")]
523 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
524 error:
525 ruff_python_parser::ParseErrorType::FStringError(
526 ruff_python_parser::InterpolatedStringErrorType::UnterminatedTripleQuotedString,
527 )
528 | ruff_python_parser::ParseErrorType::Lexical(
529 ruff_python_parser::LexicalErrorType::FStringError(
530 ruff_python_parser::InterpolatedStringErrorType::UnterminatedTripleQuotedString,
531 ),
532 ),
533 ..
534 }) => {
535 msg = "unterminated triple-quoted f-string literal".to_owned();
536 }
537 #[cfg(feature = "parser")]
538 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
539 error:
540 ruff_python_parser::ParseErrorType::FStringError(_)
541 | ruff_python_parser::ParseErrorType::Lexical(
542 ruff_python_parser::LexicalErrorType::FStringError(_),
543 ),
544 ..
545 }) => {
546 msg = msg.replace('`', "'");
548 msg.insert_str(0, "invalid syntax: ");
549 }
550 #[cfg(feature = "parser")]
551 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
552 error: ruff_python_parser::ParseErrorType::UnexpectedExpressionToken,
553 ..
554 }) => msg.insert_str(0, "invalid syntax: "),
555 #[cfg(feature = "parser")]
556 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
557 error:
558 ruff_python_parser::ParseErrorType::Lexical(
559 ruff_python_parser::LexicalErrorType::UnrecognizedToken { .. },
560 )
561 | ruff_python_parser::ParseErrorType::SimpleStatementsOnSameLine
562 | ruff_python_parser::ParseErrorType::SimpleAndCompoundStatementOnSameLine
563 | ruff_python_parser::ParseErrorType::ExpectedToken { .. }
564 | ruff_python_parser::ParseErrorType::ExpectedExpression,
565 ..
566 }) => {
567 msg = "invalid syntax".to_owned();
568 }
569 #[cfg(feature = "parser")]
570 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
571 error: ruff_python_parser::ParseErrorType::InvalidStarredExpressionUsage,
572 ..
573 }) => {
574 msg = "invalid syntax".to_owned();
575 narrow_caret = true;
576 }
577 #[cfg(feature = "parser")]
578 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
579 error: ruff_python_parser::ParseErrorType::InvalidDeleteTarget,
580 ..
581 }) => {
582 msg = "invalid syntax".to_owned();
583 }
584 #[cfg(feature = "parser")]
585 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
586 error:
587 ruff_python_parser::ParseErrorType::Lexical(
588 ruff_python_parser::LexicalErrorType::LineContinuationError,
589 ),
590 ..
591 }) => {
592 msg = "unexpected character after line continuation".to_owned();
593 }
594 #[cfg(feature = "parser")]
595 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
596 error:
597 ruff_python_parser::ParseErrorType::Lexical(
598 ruff_python_parser::LexicalErrorType::UnclosedStringError,
599 ),
600 ..
601 }) => {
602 msg = "unterminated string".to_owned();
603 }
604 #[cfg(feature = "parser")]
605 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
606 error: ruff_python_parser::ParseErrorType::OtherError(s),
607 ..
608 }) if s.eq_ignore_ascii_case("bytes literal cannot be mixed with non-bytes literals") => {
609 msg = "cannot mix bytes and nonbytes literals".to_owned();
610 }
611 #[cfg(feature = "parser")]
612 crate::compiler::CompileError::Parse(rustpython_compiler::ParseError {
613 error: ruff_python_parser::ParseErrorType::OtherError(s),
614 ..
615 }) if s.starts_with("Expected an identifier, but found a keyword") => {
616 msg = "invalid syntax".to_owned();
617 }
618 _ => {}
619 }
620 if syntax_error_type.is(self.ctx.exceptions.tab_error) {
621 msg = "inconsistent use of tabs and spaces in indentation".to_owned();
622 }
623 let syntax_error = self.new_exception_msg(syntax_error_type, msg.into());
624 let (lineno, offset) = error.python_location();
625 let lineno = self.ctx.new_int(lineno);
626 let offset = self.ctx.new_int(offset);
627 syntax_error
628 .as_object()
629 .set_attr("lineno", lineno, self)
630 .unwrap();
631 syntax_error
632 .as_object()
633 .set_attr("offset", offset, self)
634 .unwrap();
635
636 if let Some((end_lineno, end_offset)) = error.python_end_location() {
638 let (end_lineno, end_offset) = if narrow_caret {
639 let (l, o) = error.python_location();
640 (l, o + 1)
641 } else {
642 (end_lineno, end_offset)
643 };
644 let end_lineno = self.ctx.new_int(end_lineno);
645 let end_offset = self.ctx.new_int(end_offset);
646 syntax_error
647 .as_object()
648 .set_attr("end_lineno", end_lineno, self)
649 .unwrap();
650 syntax_error
651 .as_object()
652 .set_attr("end_offset", end_offset, self)
653 .unwrap();
654 }
655
656 syntax_error
657 .as_object()
658 .set_attr("text", statement.to_pyobject(self), self)
659 .unwrap();
660 syntax_error
661 .as_object()
662 .set_attr("filename", self.ctx.new_str(error.source_path()), self)
663 .unwrap();
664
665 if let Some(source) = source {
670 let metadata = self.ctx.new_tuple(vec![
671 self.ctx.new_int(0).into(),
672 self.ctx.new_int(0).into(),
673 self.ctx.new_str(source).into(),
674 ]);
675 syntax_error
676 .as_object()
677 .set_attr("_metadata", metadata, self)
678 .unwrap();
679 }
680
681 syntax_error
682 }
683
684 #[cfg(any(feature = "parser", feature = "compiler"))]
685 pub fn new_syntax_error(
686 &self,
687 error: &crate::compiler::CompileError,
688 source: Option<&str>,
689 ) -> PyBaseExceptionRef {
690 self.new_syntax_error_maybe_incomplete(error, source, false)
691 }
692
693 pub fn new_import_error(
694 &self,
695 msg: impl Into<Wtf8Buf>,
696 name: impl Into<PyStrRef>,
697 ) -> PyBaseExceptionRef {
698 let import_error = self.ctx.exceptions.import_error.to_owned();
699 let exc = self.new_exception_msg(import_error, msg.into());
700 exc.as_object().set_attr("name", name.into(), self).unwrap();
701 exc
702 }
703
704 pub fn new_stop_iteration(&self, value: Option<PyObjectRef>) -> PyBaseExceptionRef {
705 let dict = self.ctx.new_dict();
706 let args = if let Some(value) = value {
707 dict.set_item("value", value.clone(), self)
709 .expect("dict.__setitem__ never fails");
710 vec![value]
711 } else {
712 Vec::new()
713 };
714
715 PyRef::new_ref(
716 PyBaseException::new(args, self),
717 self.ctx.exceptions.stop_iteration.to_owned(),
718 Some(dict),
719 )
720 }
721
722 fn new_downcast_error(
723 &self,
724 msg: &'static str,
725 error_type: &'static Py<PyType>,
726 class: &Py<PyType>,
727 obj: &PyObject, ) -> PyBaseExceptionRef {
729 let actual_class = obj.class();
730 let actual_type = &*actual_class.name();
731 let expected_type = &*class.name();
732 let msg = format!("Expected {msg} '{expected_type}' but '{actual_type}' found.");
733 #[cfg(debug_assertions)]
734 let msg = if class.get_id() == actual_class.get_id() {
735 let mut msg = msg;
736 msg += " It might mean this type doesn't support subclassing very well. e.g. Did you forget to add `#[pyclass(with(Constructor))]`?";
737 msg
738 } else {
739 msg
740 };
741 self.new_exception_msg(error_type.to_owned(), msg.into())
742 }
743
744 pub(crate) fn new_downcast_runtime_error(
745 &self,
746 class: &Py<PyType>,
747 obj: &impl AsObject,
748 ) -> PyBaseExceptionRef {
749 self.new_downcast_error(
750 "payload",
751 self.ctx.exceptions.runtime_error,
752 class,
753 obj.as_object(),
754 )
755 }
756
757 pub(crate) fn new_downcast_type_error(
758 &self,
759 class: &Py<PyType>,
760 obj: &impl AsObject,
761 ) -> PyBaseExceptionRef {
762 self.new_downcast_error(
763 "type",
764 self.ctx.exceptions.type_error,
765 class,
766 obj.as_object(),
767 )
768 }
769
770 define_exception_fn!(fn new_lookup_error, lookup_error, LookupError);
771 define_exception_fn!(fn new_eof_error, eof_error, EOFError);
772 define_exception_fn!(fn new_attribute_error, attribute_error, AttributeError);
773 define_exception_fn!(fn new_type_error, type_error, TypeError);
774 define_exception_fn!(fn new_system_error, system_error, SystemError);
775
776 define_exception_fn!(fn new_unicode_decode_error, unicode_decode_error, UnicodeDecodeError);
778
779 define_exception_fn!(fn new_unicode_encode_error, unicode_encode_error, UnicodeEncodeError);
781
782 define_exception_fn!(fn new_value_error, value_error, ValueError);
783
784 define_exception_fn!(fn new_buffer_error, buffer_error, BufferError);
785 define_exception_fn!(fn new_index_error, index_error, IndexError);
786 define_exception_fn!(
787 fn new_not_implemented_error,
788 not_implemented_error,
789 NotImplementedError
790 );
791 define_exception_fn!(fn new_recursion_error, recursion_error, RecursionError);
792 define_exception_fn!(fn new_zero_division_error, zero_division_error, ZeroDivisionError);
793 define_exception_fn!(fn new_overflow_error, overflow_error, OverflowError);
794 define_exception_fn!(fn new_runtime_error, runtime_error, RuntimeError);
795 define_exception_fn!(fn new_python_finalization_error, python_finalization_error, PythonFinalizationError);
796 define_exception_fn!(fn new_memory_error, memory_error, MemoryError);
797}