1- use itertools:: Itertools ;
2-
31use crate :: {
42 builtins:: { PyDict , PyDictRef , PyListRef , PyStrRef , PyTuple , PyTupleRef , PyType , PyTypeRef } ,
5- convert:: TryFromObject ,
3+ convert:: { IntoObject , TryFromObject } ,
64 AsObject , Context , Py , PyObjectRef , PyResult , VirtualMachine ,
75} ;
86
@@ -104,42 +102,43 @@ fn get_filter(
104102fn already_warned (
105103 registry : PyObjectRef ,
106104 key : PyObjectRef ,
107- should_set : usize ,
105+ should_set : bool ,
108106 vm : & VirtualMachine ,
109- ) -> bool {
110- let version_obj = registry. get_item ( "version" , vm) . ok ( ) ;
111- let filters_version = vm
112- . ctx
113- . new_int ( vm. state . warnings . filters_version )
114- . as_object ( )
115- . to_owned ( ) ;
107+ ) -> PyResult < bool > {
108+ let version_obj = registry. get_item ( identifier ! ( & vm. ctx, version) , vm) . ok ( ) ;
109+ let filters_version = vm. ctx . new_int ( vm. state . warnings . filters_version ) . into ( ) ;
116110
117- if version_obj. is_none ( )
118- || version_obj. as_ref ( ) . unwrap ( ) . try_int ( vm) . is_err ( )
119- || !version_obj. unwrap ( ) . is ( & filters_version)
120- {
121- let registry = registry. dict ( ) ;
122- registry. as_ref ( ) . map ( |registry| {
123- registry. into_iter ( ) . collect_vec ( ) . clear ( ) ;
124- registry
125- } ) ;
111+ match version_obj {
112+ Some ( version_obj)
113+ if version_obj. try_int ( vm) . is_ok ( ) || version_obj. is ( & filters_version) =>
114+ {
115+ let already_warned = registry. get_item ( key. as_ref ( ) , vm) ?;
116+ if already_warned. is_true ( vm) ? {
117+ return Ok ( true ) ;
118+ }
119+ }
120+ _ => {
121+ let registry = registry. dict ( ) ;
122+ registry. as_ref ( ) . map ( |registry| {
123+ registry. clear ( ) ;
124+ registry
125+ } ) ;
126126
127- if let Some ( registry) = registry {
128- if registry. set_item ( "version" , filters_version, vm) . is_err ( ) {
129- return false ;
127+ if let Some ( registry) = registry {
128+ if registry. set_item ( "version" , filters_version, vm) . is_err ( ) {
129+ return Ok ( false ) ;
130+ }
130131 }
131132 }
132- } else {
133- let already_warned = registry. get_item ( key. as_ref ( ) , vm) ;
134- return already_warned. is_ok ( ) ;
135133 }
136134
137135 /* This warning wasn't found in the registry, set it. */
138- if should_set != 0 {
139- registry. set_item ( key. as_ref ( ) , vm. new_pyobj ( "" ) , vm) . ok ( ) ;
140- }
141-
142- false
136+ Ok ( if should_set {
137+ let item = vm. ctx . true_value . clone ( ) . into ( ) ;
138+ registry. set_item ( key. as_ref ( ) , item, vm) . map ( |_| true ) ?
139+ } else {
140+ false
141+ } )
143142}
144143
145144fn normalize_module ( filename : PyStrRef , vm : & VirtualMachine ) -> Option < PyObjectRef > {
@@ -148,7 +147,7 @@ fn normalize_module(filename: PyStrRef, vm: &VirtualMachine) -> Option<PyObjectR
148147 if len == 0 {
149148 Some ( vm. new_pyobj ( "<unknown>" ) )
150149 } else if len >= 3 && filename. as_str ( ) . contains ( ".py" ) {
151- Some ( vm. new_pyobj ( filename. as_str ( ) . replace ( ".py" , "" ) ) )
150+ Some ( vm. new_pyobj ( & filename. as_str ( ) [ ..len - 3 ] ) )
152151 } else {
153152 Some ( filename. as_object ( ) . to_owned ( ) )
154153 }
@@ -166,26 +165,16 @@ fn warn_explicit(
166165 _source : Option < PyObjectRef > ,
167166 vm : & VirtualMachine ,
168167) -> PyResult < ( ) > {
169- if registry. clone ( ) . is_true ( vm) ?
170- && !registry. class ( ) . is ( vm. ctx . types . dict_type )
171- && !registry. class ( ) . is ( vm. ctx . types . none_type )
172- {
173- return Err ( vm. new_type_error ( "'registry' must be a dict or None" . to_string ( ) ) ) ;
174- }
168+ let registry: PyObjectRef = registry
169+ . try_into_value ( vm)
170+ . map_err ( |_| vm. new_type_error ( "'registry' must be a dict or None" . to_owned ( ) ) ) ?;
175171
176172 // Normalize module.
177- let module = module. and ( normalize_module ( filename, vm) ) ;
178- let module = if let Some ( module) = module {
179- module
180- } else {
181- return Ok ( ( ) ) ;
173+ let module = match module. or_else ( || normalize_module ( filename, vm) ) {
174+ Some ( module) => module,
175+ None => return Ok ( ( ) ) ,
182176 } ;
183177
184- // Normalize message.
185- let text = message. as_str ( ) ;
186- if text. is_empty ( ) {
187- return Ok ( ( ) ) ;
188- }
189178 let category = if let Some ( category) = category {
190179 if !category. fast_issubclass ( vm. ctx . exceptions . warning ) {
191180 return Err ( vm. new_type_error ( format ! (
@@ -198,26 +187,34 @@ fn warn_explicit(
198187 vm. ctx . exceptions . user_warning . to_owned ( )
199188 } ;
200189
190+ // Normalize message.
191+ let ( category, text) = if message. fast_isinstance ( vm. ctx . exceptions . warning ) {
192+ ( message. class ( ) . into_owned ( ) , message. as_object ( ) . str ( vm) ?)
193+ } else {
194+ ( category, message)
195+ } ;
196+
201197 // Create key.
202198 let key = PyTuple :: new_ref (
203199 vec ! [
204200 vm. ctx. new_int( 3 ) . into( ) ,
205- vm. ctx. new_str( text) . into( ) ,
201+ vm. ctx. new_str( text. as_str ( ) ) . into( ) ,
206202 category. as_object( ) . to_owned( ) ,
207203 vm. ctx. new_int( lineno) . into( ) ,
208204 ] ,
209205 & vm. ctx ,
210206 ) ;
211207
212- if already_warned ( registry, key. as_object ( ) . to_owned ( ) , 0 , vm) {
208+ if !vm. is_none ( registry. as_object ( ) ) && already_warned ( registry, key. into_object ( ) , false , vm) ?
209+ {
213210 return Ok ( ( ) ) ;
214211 }
215212 // Else this warning hasn't been generated before.
216213
217214 let item = vm. ctx . new_tuple ( vec ! [ ] ) . into ( ) ;
218215 let _action = get_filter (
219216 category. as_object ( ) . to_owned ( ) ,
220- vm. ctx . new_str ( text) . into ( ) ,
217+ vm. ctx . new_str ( text. as_str ( ) ) . into ( ) ,
221218 lineno,
222219 module,
223220 item,
0 commit comments