@@ -447,8 +447,6 @@ fn builtin_map(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
447447}
448448
449449fn builtin_max ( vm : & mut VirtualMachine , args : PyFuncArgs ) ->PyResult {
450- // arg_check!(vm, args, required = [(x, None), (y, None)]);
451-
452450let candidates =if args. args . len ( ) >1 {
453451 args. args . clone ( )
454452} else if args. args . len ( ) ==1 {
@@ -502,19 +500,53 @@ fn builtin_max(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
502500// builtin_memoryview
503501
504502fn 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+ } ;
510511
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+ }
512520
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) ?
515530} else {
516- Ok ( x. clone ( ) )
531+ x. clone ( )
532+ } ;
533+
534+ for yin 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+ }
517547}
548+
549+ Ok ( x)
518550}
519551
520552fn builtin_next ( vm : & mut VirtualMachine , args : PyFuncArgs ) ->PyResult {