@@ -447,8 +447,6 @@ fn builtin_map(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
447
447
}
448
448
449
449
fn builtin_max ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
450
- // arg_check!(vm, args, required = [(x, None), (y, None)]);
451
-
452
450
let candidates = if args. args . len ( ) > 1 {
453
451
args. args . clone ( )
454
452
} else if args. args . len ( ) == 1 {
@@ -502,19 +500,53 @@ fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
502
500
// builtin_memoryview
503
501
504
502
fn builtin_min ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
505
- arg_check ! (
506
- vm,
507
- args,
508
- required = [ ( x, Some ( vm. ctx. int_type( ) ) ) , ( y, Some ( vm. ctx. int_type( ) ) ) ]
509
- ) ;
503
+ let candidates = if args. args . len ( ) > 1 {
504
+ args. args . clone ( )
505
+ } else if args. args . len ( ) == 1 {
506
+ vm. extract_elements ( & args. args [ 0 ] ) ?
507
+ } else {
508
+ // zero arguments means type error:
509
+ return Err ( vm. new_type_error ( "Expected 1 or more arguments" . to_string ( ) ) ) ;
510
+ } ;
510
511
511
- let order = vm. call_method ( x, "__gt__" , vec ! [ y. clone( ) ] ) ?;
512
+ if candidates. len ( ) == 0 {
513
+ let default = args. get_optional_kwarg ( "default" ) ;
514
+ if default. is_none ( ) {
515
+ return Err ( vm. new_value_error ( "min() arg is an empty sequence" . to_string ( ) ) ) ;
516
+ } else {
517
+ return Ok ( default. unwrap ( ) ) ;
518
+ }
519
+ }
512
520
513
- if objbool:: get_value ( & order) {
514
- Ok ( y. clone ( ) )
521
+ let key_func = args. get_optional_kwarg ( "key" ) ;
522
+
523
+ let mut candidates_iter = candidates. into_iter ( ) ;
524
+ let mut x = candidates_iter. next ( ) . unwrap ( ) ;
525
+ // TODO: this key function looks pretty duplicate. Maybe we can create
526
+ // a local function?
527
+ let mut x_key = if let Some ( f) = & key_func {
528
+ let args = PyFuncArgs :: new ( vec ! [ x. clone( ) ] , vec ! [ ] ) ;
529
+ vm. invoke ( f. clone ( ) , args) ?
515
530
} else {
516
- Ok ( x. clone ( ) )
531
+ x. clone ( )
532
+ } ;
533
+
534
+ for y in candidates_iter {
535
+ let y_key = if let Some ( f) = & key_func {
536
+ let args = PyFuncArgs :: new ( vec ! [ y. clone( ) ] , vec ! [ ] ) ;
537
+ vm. invoke ( f. clone ( ) , args) ?
538
+ } else {
539
+ y. clone ( )
540
+ } ;
541
+ let order = vm. call_method ( & x_key, "__gt__" , vec ! [ y_key. clone( ) ] ) ?;
542
+
543
+ if objbool:: get_value ( & order) {
544
+ x = y. clone ( ) ;
545
+ x_key = y_key;
546
+ }
517
547
}
548
+
549
+ Ok ( x)
518
550
}
519
551
520
552
fn builtin_next ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
0 commit comments