File tree Expand file tree Collapse file tree 3 files changed +35
-5
lines changed Expand file tree Collapse file tree 3 files changed +35
-5
lines changed Original file line number Diff line number Diff line change @@ -166,3 +166,11 @@ def __eq__(self, other):
166
166
167
167
y .update (y )
168
168
assert y == {'a' : 2 , 'b' : 12 , 'c' : 19 , 'd' : - 1 } # hasn't changed
169
+
170
+ x = {1 : 'a' , '1' : None }
171
+ assert x .pop (1 ) == 'a'
172
+ assert x .pop ('1' ) is None
173
+ assert x == {}
174
+
175
+ with assertRaises (KeyError ):
176
+ x .pop ("not here" )
Original file line number Diff line number Diff line change @@ -87,14 +87,18 @@ impl<T: Clone> Dict<T> {
87
87
}
88
88
}
89
89
90
+ fn unchecked_get ( & self , index : usize ) -> T {
91
+ if let Some ( entry) = & self . entries [ index] {
92
+ entry. value . clone ( )
93
+ } else {
94
+ panic ! ( "Lookup returned invalid index into entries!" ) ;
95
+ }
96
+ }
97
+
90
98
/// Retrieve a key
91
99
pub fn get ( & self , vm : & VirtualMachine , key : & PyObjectRef ) -> PyResult < Option < T > > {
92
100
if let LookupResult :: Existing ( index) = self . lookup ( vm, key) ? {
93
- if let Some ( entry) = & self . entries [ index] {
94
- Ok ( Some ( entry. value . clone ( ) ) )
95
- } else {
96
- panic ! ( "Lookup returned invalid index into entries!" ) ;
97
- }
101
+ Ok ( Some ( self . unchecked_get ( index) ) )
98
102
} else {
99
103
Ok ( None )
100
104
}
@@ -190,6 +194,19 @@ impl<T: Clone> Dict<T> {
190
194
// warn!("Perturb value: {}", i);
191
195
}
192
196
}
197
+
198
+ /// Retrieve and delete a key
199
+ pub fn pop ( & mut self , vm : & VirtualMachine , key : & PyObjectRef ) -> PyResult < T > {
200
+ if let LookupResult :: Existing ( index) = self . lookup ( vm, key) ? {
201
+ let value = self . unchecked_get ( index) ;
202
+ self . entries [ index] = None ;
203
+ self . size -= 1 ;
204
+ Ok ( value)
205
+ } else {
206
+ let key_repr = vm. to_pystr ( key) ?;
207
+ Err ( vm. new_key_error ( format ! ( "Key not found: {}" , key_repr) ) )
208
+ }
209
+ }
193
210
}
194
211
195
212
enum LookupResult {
Original file line number Diff line number Diff line change @@ -228,6 +228,10 @@ impl PyDictRef {
228
228
PyDictRef :: merge ( & self . entries , dict_obj, kwargs, vm)
229
229
}
230
230
231
+ fn pop ( self , key : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
232
+ self . entries . borrow_mut ( ) . pop ( vm, & key)
233
+ }
234
+
231
235
/// Take a python dictionary and convert it to attributes.
232
236
pub fn to_attributes ( self ) -> PyAttributes {
233
237
let mut attrs = PyAttributes :: new ( ) ;
@@ -458,6 +462,7 @@ pub fn init(context: &PyContext) {
458
462
"get" => context. new_rustfunc( PyDictRef :: get) ,
459
463
"copy" => context. new_rustfunc( PyDictRef :: copy) ,
460
464
"update" => context. new_rustfunc( PyDictRef :: update) ,
465
+ "pop" => context. new_rustfunc( PyDictRef :: pop) ,
461
466
} ) ;
462
467
463
468
PyDictKeys :: extend_class ( context, & context. dictkeys_type ) ;
You can’t perform that action at this time.
0 commit comments