@@ -6,7 +6,7 @@ use std::ops::Range;
6
6
use num_bigint:: { BigInt , ToBigInt } ;
7
7
use num_traits:: { One , Signed , ToPrimitive , Zero } ;
8
8
9
- use crate :: function:: { OptionalArg , PyFuncArgs } ;
9
+ use crate :: function:: OptionalArg ;
10
10
use crate :: pyobject:: {
11
11
IdProtocol , PyClassImpl , PyContext , PyIterable , PyObjectRef , PyRef , PyResult , PyValue ,
12
12
TryFromObject ,
@@ -17,8 +17,7 @@ use super::objbool;
17
17
//use super::objint;
18
18
use super :: objiter;
19
19
use super :: objsequence:: {
20
- get_elements_cell, get_elements_list, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt,
21
- seq_mul, SequenceIndex ,
20
+ get_elements_list, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul, SequenceIndex ,
22
21
} ;
23
22
use super :: objslice:: PySliceRef ;
24
23
use super :: objtype;
@@ -99,6 +98,14 @@ impl PyList {
99
98
}
100
99
}
101
100
101
+ #[ derive( FromArgs ) ]
102
+ struct SortOptions {
103
+ #[ pyarg( keyword_only, default = "None" ) ]
104
+ key : Option < PyObjectRef > ,
105
+ #[ pyarg( keyword_only, default = "false" ) ]
106
+ reverse : bool ,
107
+ }
108
+
102
109
pub type PyListRef = PyRef < PyList > ;
103
110
104
111
impl PyListRef {
@@ -687,6 +694,21 @@ impl PyListRef {
687
694
// then drain (the values to delete should now be contiguous at teh start of the range)
688
695
elements. drain ( range. start ..( range. start + deleted) ) ;
689
696
}
697
+
698
+ fn sort ( self , options : SortOptions , vm : & VirtualMachine ) -> PyResult < ( ) > {
699
+ // replace list contents with [] for duration of sort.
700
+ // this prevents keyfunc from messing with the list and makes it easy to
701
+ // check if it tries to append elements to it.
702
+ let mut elements = self . elements . replace ( vec ! [ ] ) ;
703
+ do_sort ( vm, & mut elements, options. key , options. reverse ) ?;
704
+ let temp_elements = self . elements . replace ( elements) ;
705
+
706
+ if !temp_elements. is_empty ( ) {
707
+ return Err ( vm. new_value_error ( "list modified during sort" . to_string ( ) ) ) ;
708
+ }
709
+
710
+ Ok ( ( ) )
711
+ }
690
712
}
691
713
692
714
fn list_new (
@@ -768,30 +790,6 @@ fn do_sort(
768
790
Ok ( ( ) )
769
791
}
770
792
771
- fn list_sort ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
772
- arg_check ! ( vm, args, required = [ ( list, Some ( vm. ctx. list_type( ) ) ) ] ) ;
773
- let key_func = args. get_optional_kwarg ( "key" ) ;
774
- let reverse = args. get_optional_kwarg ( "reverse" ) ;
775
- let reverse = match reverse {
776
- None => false ,
777
- Some ( val) => objbool:: boolval ( vm, val) ?,
778
- } ;
779
-
780
- let elements_cell = get_elements_cell ( list) ;
781
- // replace list contents with [] for duration of sort.
782
- // this prevents keyfunc from messing with the list and makes it easy to
783
- // check if it tries to append elements to it.
784
- let mut elements = elements_cell. replace ( vec ! [ ] ) ;
785
- do_sort ( vm, & mut elements, key_func, reverse) ?;
786
- let temp_elements = elements_cell. replace ( elements) ;
787
-
788
- if !temp_elements. is_empty ( ) {
789
- return Err ( vm. new_value_error ( "list modified during sort" . to_string ( ) ) ) ;
790
- }
791
-
792
- Ok ( vm. get_none ( ) )
793
- }
794
-
795
793
#[ pyclass]
796
794
#[ derive( Debug ) ]
797
795
pub struct PyListIterator {
@@ -896,7 +894,7 @@ pub fn init(context: &PyContext) {
896
894
"index" => context. new_rustfunc( PyListRef :: index) ,
897
895
"insert" => context. new_rustfunc( PyListRef :: insert) ,
898
896
"reverse" => context. new_rustfunc( PyListRef :: reverse) ,
899
- "sort" => context. new_rustfunc( list_sort ) ,
897
+ "sort" => context. new_rustfunc( PyListRef :: sort ) ,
900
898
"pop" => context. new_rustfunc( PyListRef :: pop) ,
901
899
"remove" => context. new_rustfunc( PyListRef :: remove)
902
900
} ) ;
0 commit comments