@@ -3,24 +3,131 @@ use crate::obj::objtraceback::PyTracebackRef;
3
3
use crate :: obj:: objtuple:: { PyTuple , PyTupleRef } ;
4
4
use crate :: obj:: objtype;
5
5
use crate :: obj:: objtype:: PyClassRef ;
6
- use crate :: pyobject:: { IdProtocol , PyContext , PyObjectRef , PyResult , TypeProtocol } ;
6
+ use crate :: pyobject:: {
7
+ IdProtocol , PyClassImpl , PyContext , PyObjectRef , PyRef , PyResult , PyValue , TypeProtocol ,
8
+ } ;
7
9
use crate :: types:: create_type;
8
10
use crate :: vm:: VirtualMachine ;
9
11
use itertools:: Itertools ;
12
+ use std:: cell:: { Cell , RefCell } ;
13
+ use std:: fmt;
10
14
use std:: fs:: File ;
11
15
use std:: io:: { self , BufRead , BufReader , Write } ;
12
16
13
- fn exception_init ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
14
- let exc_self = args. args [ 0 ] . clone ( ) ;
15
- let exc_args = vm. ctx . new_tuple ( args. args [ 1 ..] . to_vec ( ) ) ;
16
- vm. set_attr ( & exc_self, "args" , exc_args) ?;
17
-
18
- // TODO: have an actual `traceback` object for __traceback__
19
- vm. set_attr ( & exc_self, "__traceback__" , vm. get_none ( ) ) ?;
20
- vm. set_attr ( & exc_self, "__cause__" , vm. get_none ( ) ) ?;
21
- vm. set_attr ( & exc_self, "__context__" , vm. get_none ( ) ) ?;
22
- vm. set_attr ( & exc_self, "__suppress_context__" , vm. new_bool ( false ) ) ?;
23
- Ok ( vm. get_none ( ) )
17
+ #[ pyclass]
18
+ pub struct PyBaseException {
19
+ traceback : RefCell < Option < PyTracebackRef > > ,
20
+ cause : RefCell < Option < PyObjectRef > > ,
21
+ context : RefCell < Option < PyObjectRef > > ,
22
+ suppress_context : Cell < bool > ,
23
+ args : RefCell < PyObjectRef > ,
24
+ }
25
+
26
+ impl fmt:: Debug for PyBaseException {
27
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
28
+ // TODO: implement more detailed, non-recursive Debug formatter
29
+ f. write_str ( "PyBaseException" )
30
+ }
31
+ }
32
+
33
+ pub type PyBaseExceptionRef = PyRef < PyBaseException > ;
34
+
35
+ impl PyValue for PyBaseException {
36
+ const HAVE_DICT : bool = true ;
37
+
38
+ fn class ( vm : & VirtualMachine ) -> PyClassRef {
39
+ vm. ctx . exceptions . base_exception_type . clone ( )
40
+ }
41
+ }
42
+
43
+ #[ pyimpl]
44
+ impl PyBaseException {
45
+ #[ pyslot( new) ]
46
+ fn tp_new (
47
+ cls : PyClassRef ,
48
+ _args : PyFuncArgs ,
49
+ vm : & VirtualMachine ,
50
+ ) -> PyResult < PyBaseExceptionRef > {
51
+ PyBaseException {
52
+ traceback : RefCell :: new ( None ) ,
53
+ cause : RefCell :: new ( None ) ,
54
+ context : RefCell :: new ( None ) ,
55
+ suppress_context : Cell :: new ( false ) ,
56
+ args : RefCell :: new ( vm. ctx . new_tuple ( vec ! [ ] ) ) ,
57
+ }
58
+ . into_ref_with_type ( vm, cls)
59
+ }
60
+
61
+ #[ pymethod( name = "__init__" ) ]
62
+ fn init ( & self , args : PyFuncArgs , vm : & VirtualMachine ) -> PyResult < ( ) > {
63
+ self . args . replace ( vm. ctx . new_tuple ( args. args . to_vec ( ) ) ) ;
64
+ Ok ( ( ) )
65
+ }
66
+
67
+ #[ pyproperty]
68
+ fn args ( & self , _vm : & VirtualMachine ) -> PyObjectRef {
69
+ self . args . borrow ( ) . clone ( )
70
+ }
71
+
72
+ #[ pyproperty( setter) ]
73
+ fn set_args ( & self , args : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
74
+ self . args . replace ( args) ;
75
+ Ok ( vm. get_none ( ) )
76
+ }
77
+
78
+ #[ pyproperty( name = "__traceback__" ) ]
79
+ fn get_traceback ( & self , _vm : & VirtualMachine ) -> Option < PyTracebackRef > {
80
+ self . traceback . borrow ( ) . clone ( )
81
+ }
82
+
83
+ #[ pyproperty( name = "__traceback__" , setter) ]
84
+ fn set_traceback ( & self , traceback : Option < PyTracebackRef > , vm : & VirtualMachine ) -> PyResult {
85
+ self . traceback . replace ( traceback) ;
86
+ Ok ( vm. get_none ( ) )
87
+ }
88
+
89
+ #[ pyproperty( name = "__cause__" ) ]
90
+ fn get_cause ( & self , _vm : & VirtualMachine ) -> Option < PyObjectRef > {
91
+ self . cause . borrow ( ) . clone ( )
92
+ }
93
+
94
+ #[ pyproperty( name = "__cause__" , setter) ]
95
+ fn set_cause ( & self , cause : Option < PyObjectRef > , vm : & VirtualMachine ) -> PyResult {
96
+ self . cause . replace ( cause) ;
97
+ Ok ( vm. get_none ( ) )
98
+ }
99
+
100
+ #[ pyproperty( name = "__context__" ) ]
101
+ fn get_context ( & self , _vm : & VirtualMachine ) -> Option < PyObjectRef > {
102
+ self . context . borrow ( ) . clone ( )
103
+ }
104
+
105
+ #[ pyproperty( name = "__context__" , setter) ]
106
+ fn set_context ( & self , context : Option < PyObjectRef > , vm : & VirtualMachine ) -> PyResult {
107
+ self . context . replace ( context) ;
108
+ Ok ( vm. get_none ( ) )
109
+ }
110
+
111
+ #[ pyproperty( name = "__suppress_context__" ) ]
112
+ fn get_suppress_context ( & self , _vm : & VirtualMachine ) -> bool {
113
+ self . suppress_context . get ( )
114
+ }
115
+
116
+ #[ pyproperty( name = "__suppress_context__" , setter) ]
117
+ fn set_suppress_context ( & self , suppress_context : bool , vm : & VirtualMachine ) -> PyResult {
118
+ self . suppress_context . set ( suppress_context) ;
119
+ Ok ( vm. get_none ( ) )
120
+ }
121
+
122
+ #[ pymethod]
123
+ fn with_traceback (
124
+ zelf : PyRef < Self > ,
125
+ tb : Option < PyTracebackRef > ,
126
+ _vm : & VirtualMachine ,
127
+ ) -> PyResult {
128
+ zelf. traceback . replace ( tb) ;
129
+ Ok ( zelf. as_object ( ) . clone ( ) )
130
+ }
24
131
}
25
132
26
133
/// Print exception chain
@@ -208,19 +315,6 @@ fn exception_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
208
315
Ok ( vm. new_str ( joined_str) )
209
316
}
210
317
211
- fn exception_with_traceback (
212
- zelf : PyObjectRef ,
213
- tb : Option < PyTracebackRef > ,
214
- vm : & VirtualMachine ,
215
- ) -> PyResult {
216
- vm. set_attr (
217
- & zelf,
218
- "__traceback__" ,
219
- tb. map_or ( vm. get_none ( ) , |tb| tb. into_object ( ) ) ,
220
- ) ?;
221
- Ok ( zelf)
222
- }
223
-
224
318
#[ derive( Debug ) ]
225
319
pub struct ExceptionZoo {
226
320
pub arithmetic_error : PyClassRef ,
@@ -416,10 +510,9 @@ impl ExceptionZoo {
416
510
}
417
511
418
512
fn import_error_init ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
419
- // TODO: call super().__init__(*args) instead
420
- exception_init ( vm, args. clone ( ) ) ?;
421
-
422
513
let exc_self = args. args [ 0 ] . clone ( ) ;
514
+
515
+ vm. set_attr ( & exc_self, "args" , vm. ctx . new_tuple ( args. args [ 1 ..] . to_vec ( ) ) ) ?;
423
516
vm. set_attr (
424
517
& exc_self,
425
518
"name" ,
@@ -446,10 +539,7 @@ fn import_error_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
446
539
447
540
pub fn init ( context : & PyContext ) {
448
541
let base_exception_type = & context. exceptions . base_exception_type ;
449
- extend_class ! ( context, base_exception_type, {
450
- "__init__" => context. new_rustfunc( exception_init) ,
451
- "with_traceback" => context. new_rustfunc( exception_with_traceback)
452
- } ) ;
542
+ PyBaseException :: extend_class ( context, base_exception_type) ;
453
543
454
544
let exception_type = & context. exceptions . exception_type ;
455
545
extend_class ! ( context, exception_type, {
0 commit comments