@@ -4,7 +4,7 @@ use std::fmt;
44
55use crate :: function:: { KwArgs , OptionalArg } ;
66use crate :: pyobject:: {
7- DictProtocol , PyAttributes , PyContext , PyObjectRef , PyRef , PyResult , PyValue ,
7+ DictProtocol , IntoPyObject , PyAttributes , PyContext , PyObjectRef , PyRef , PyResult , PyValue ,
88} ;
99use crate :: vm:: { ReprGuard , VirtualMachine } ;
1010
@@ -58,7 +58,7 @@ impl PyDictRef {
5858 if let OptionalArg :: Present ( dict_obj) = dict_obj {
5959 if objtype:: isinstance ( & dict_obj, & vm. ctx . dict_type ( ) ) {
6060 for ( needle, value) in get_key_value_pairs ( & dict_obj) {
61- dict. set_item ( & vm . ctx , & objstr :: get_value ( & needle) , value) ;
61+ dict. set_item ( needle, value, vm ) ;
6262 }
6363 } else {
6464 let iter = objiter:: get_iter ( vm, & dict_obj) ?;
@@ -77,13 +77,12 @@ impl PyDictRef {
7777 if objiter:: get_next_object ( vm, & elem_iter) ?. is_some ( ) {
7878 return Err ( err ( vm) ) ;
7979 }
80- dict. set_item ( & vm . ctx , & objstr :: get_value ( & needle) , value) ;
80+ dict. set_item ( needle, value, vm ) ;
8181 }
8282 }
8383 }
8484 for ( needle, value) in kwargs. into_iter ( ) {
85- let py_needle = vm. new_str ( needle) ;
86- dict. set_item ( & vm. ctx , & objstr:: get_value ( & py_needle) , value) ;
85+ dict. set_item ( vm. new_str ( needle) , value, vm) ;
8786 }
8887 Ok ( dict)
8988 }
@@ -181,7 +180,7 @@ impl PyDictRef {
181180 }
182181
183182 fn setitem ( self , needle : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) {
184- self . set_item ( & vm . ctx , & objstr :: get_value ( & needle) , value)
183+ self . set_item ( needle, value, vm )
185184 }
186185
187186 fn getitem ( self , key : PyStringRef , vm : & VirtualMachine ) -> PyResult {
@@ -216,6 +215,23 @@ impl PyDictRef {
216215 }
217216 }
218217
218+ // Used during module initialisation when vm isn't available.
219+ pub fn from_attributes ( ctx : & PyContext , attributes : PyAttributes ) -> PyDictRef {
220+ let dict = ctx. new_dict ( ) ;
221+ for ( key_str, value) in attributes. into_iter ( ) {
222+ dict. unsafe_str_insert ( & key_str, value, ctx) ;
223+ }
224+ dict
225+ }
226+
227+ // Pub needed for some nasty edge cases.
228+ // It will be unsafe if there are entries in the dictionary that compare equal.
229+ pub fn unsafe_str_insert ( & self , key : & str , value : PyObjectRef , ctx : & PyContext ) {
230+ self . entries
231+ . borrow_mut ( )
232+ . insert ( key. to_string ( ) , ( ctx. new_str ( key. to_string ( ) ) , value) ) ;
233+ }
234+
219235 /// Take a python dictionary and convert it to attributes.
220236 pub fn to_attributes ( self ) -> PyAttributes {
221237 let mut attrs = PyAttributes :: new ( ) ;
@@ -228,12 +244,14 @@ impl PyDictRef {
228244}
229245
230246impl DictProtocol for PyDictRef {
231- fn contains_key ( & self , k : & str ) -> bool {
232- self . entries . borrow ( ) . get ( k) . is_some ( )
247+ fn contains_key < T : IntoPyObject > ( & self , key : T , vm : & VirtualMachine ) -> bool {
248+ let key_str = & objstr:: get_value ( & key. into_pyobject ( vm) . unwrap ( ) ) ;
249+ self . entries . borrow ( ) . get ( key_str) . is_some ( )
233250 }
234251
235- fn get_item ( & self , k : & str ) -> Option < PyObjectRef > {
236- match self . entries . borrow ( ) . get ( k) {
252+ fn get_item < T : IntoPyObject > ( & self , key : T , vm : & VirtualMachine ) -> Option < PyObjectRef > {
253+ let key_str = & objstr:: get_value ( & key. into_pyobject ( vm) . unwrap ( ) ) ;
254+ match self . entries . borrow ( ) . get ( key_str) {
237255 Some ( v) => Some ( v. 1 . clone ( ) ) ,
238256 None => None ,
239257 }
@@ -244,10 +262,11 @@ impl DictProtocol for PyDictRef {
244262 }
245263
246264 // Item set/get:
247- fn set_item ( & self , ctx : & PyContext , key_str : & str , v : PyObjectRef ) {
248- let key = ctx. new_str ( key_str. to_string ( ) ) ;
265+ fn set_item < T : IntoPyObject > ( & self , key : T , value : PyObjectRef , vm : & VirtualMachine ) {
266+ let key = key. into_pyobject ( vm) . unwrap ( ) ;
267+ let key_str = & objstr:: get_value ( & key) ;
249268 let elements = & mut self . entries . borrow_mut ( ) ;
250- elements. insert ( key_str. to_string ( ) , ( key. clone ( ) , v . clone ( ) ) ) ;
269+ elements. insert ( key_str. to_string ( ) , ( key. clone ( ) , value ) ) ;
251270 }
252271
253272 fn del_item ( & self , key : & str ) {
0 commit comments