1+ use std:: convert:: TryInto ;
2+
13use crate :: {
24 builtins:: { PyDict , PyDictRef , PyListRef , PyStrRef , PyTuple , PyTupleRef , PyType , PyTypeRef } ,
35 convert:: { IntoObject , TryFromObject } ,
6+ types:: PyComparisonOp ,
47 AsObject , Context , Py , PyObjectRef , PyResult , VirtualMachine ,
58} ;
69
710pub struct WarningsState {
811 filters : PyListRef ,
912 _once_registry : PyDictRef ,
10- _default_action : PyStrRef ,
13+ default_action : PyStrRef ,
1114 filters_version : usize ,
1215}
1316
@@ -26,12 +29,25 @@ impl WarningsState {
2629 WarningsState {
2730 filters : Self :: create_filter ( ctx) ,
2831 _once_registry : PyDict :: new_ref ( ctx) ,
29- _default_action : ctx. new_str ( "default" ) ,
32+ default_action : ctx. new_str ( "default" ) ,
3033 filters_version : 0 ,
3134 }
3235 }
3336}
3437
38+ fn check_matched ( obj : & PyObjectRef , arg : & PyObjectRef , vm : & VirtualMachine ) -> PyResult < bool > {
39+ if obj. class ( ) . is ( vm. ctx . types . none_type ) {
40+ return Ok ( true ) ;
41+ }
42+
43+ if obj. rich_compare_bool ( arg, PyComparisonOp :: Eq , vm) ? {
44+ return Ok ( false ) ;
45+ }
46+
47+ let result = vm. invoke ( obj, ( arg. to_owned ( ) , ) ) ?;
48+ result. is_true ( vm)
49+ }
50+
3551pub fn py_warn (
3652 category : & Py < PyType > ,
3753 message : String ,
@@ -60,14 +76,28 @@ pub fn warn(
6076 )
6177}
6278
79+ fn get_default_action ( vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
80+ vm. state
81+ . warnings
82+ . default_action
83+ . clone ( )
84+ . try_into ( )
85+ . map_err ( |_| {
86+ vm. new_value_error ( format ! (
87+ "_warnings.defaultaction must be a string, not '{}'" ,
88+ vm. state. warnings. default_action
89+ ) )
90+ } )
91+ }
92+
6393fn get_filter (
64- _category : PyObjectRef ,
65- _text : PyObjectRef ,
66- _lineno : usize ,
67- _module : PyObjectRef ,
94+ category : PyObjectRef ,
95+ text : PyObjectRef ,
96+ lineno : usize ,
97+ module : PyObjectRef ,
6898 mut _item : PyObjectRef ,
6999 vm : & VirtualMachine ,
70- ) -> PyResult < ( ) > {
100+ ) -> PyResult < PyObjectRef > {
71101 let filters = vm. state . warnings . filters . as_object ( ) . to_owned ( ) ;
72102
73103 let filters: PyListRef = filters
@@ -89,14 +119,50 @@ fn get_filter(
89119 } ?;
90120
91121 /* Python code: action, msg, cat, mod, ln = item */
92- let _action = tmp_item. get ( 0 ) ;
93- let _msg = tmp_item. get ( 1 ) ;
94- let _cat = tmp_item. get ( 2 ) ;
95- let _item_mod = tmp_item. get ( 3 ) ;
96- let _ln_obj = tmp_item. get ( 4 ) ;
122+ let action = tmp_item. get ( 0 ) ;
123+ let msg = tmp_item. get ( 1 ) ;
124+ let cat = tmp_item. get ( 2 ) ;
125+ let item_mod = tmp_item. get ( 3 ) ;
126+ let ln_obj = tmp_item. get ( 4 ) ;
127+
128+ let action = if let Some ( action) = action {
129+ action. str ( vm) . map ( |action| action. into_object ( ) )
130+ } else {
131+ Err ( vm. new_type_error ( "action must be a string" . to_string ( ) ) )
132+ } ;
133+
134+ let good_msg = if let Some ( msg) = msg {
135+ check_matched ( msg, & text, vm) ?
136+ } else {
137+ false
138+ } ;
139+
140+ let good_mod = if let Some ( item_mod) = item_mod {
141+ check_matched ( item_mod, & module, vm) ?
142+ } else {
143+ false
144+ } ;
145+
146+ let is_subclass = if let Some ( cat) = cat {
147+ category. fast_isinstance ( & cat. class ( ) )
148+ } else {
149+ false
150+ } ;
151+
152+ // I would like some help on how to deal with it
153+ let ln = if let Some ( ln_obj) = ln_obj {
154+ ln_obj. length ( vm) ?
155+ } else {
156+ 0
157+ } ;
158+
159+ if good_msg && good_mod && is_subclass && ( ln == 0 || lineno == ln) {
160+ _item = tmp_item. into_object ( ) ;
161+ return action;
162+ }
97163 }
98164
99- Ok ( ( ) )
165+ get_default_action ( vm )
100166}
101167
102168fn already_warned (
@@ -192,6 +258,7 @@ fn warn_explicit(
192258 ( message. class ( ) . into_owned ( ) , message. as_object ( ) . str ( vm) ?)
193259 } else {
194260 ( category, message)
261+ // (category, message.to_owned())
195262 } ;
196263
197264 // Create key.
@@ -221,6 +288,14 @@ fn warn_explicit(
221288 vm,
222289 ) ;
223290
291+ // if action.str(vm)?.as_str().eq("error") {
292+ // return Err(vm.new_type_error(message.to_string()));
293+ // }
294+
295+ // if action.str(vm)?.as_str().eq("ignore") {
296+ // return Ok(());
297+ // }
298+
224299 let stderr = crate :: stdlib:: sys:: PyStderr ( vm) ;
225300 writeln ! ( stderr, "{}: {}" , category. name( ) , text, ) ;
226301 Ok ( ( ) )
0 commit comments