@@ -47,8 +47,8 @@ func init() {
4747 // py.MustNewMethod("iter", builtin_iter, 0, iter_doc),
4848 py .MustNewMethod ("len" , builtin_len , 0 , len_doc ),
4949 py .MustNewMethod ("locals" , py .InternalMethodLocals , 0 , locals_doc ),
50- // py.MustNewMethod("max", builtin_max, 0, max_doc),
51- // py.MustNewMethod("min", builtin_min, 0, min_doc),
50+ py .MustNewMethod ("max" , builtin_max , 0 , max_doc ),
51+ py .MustNewMethod ("min" , builtin_min , 0 , min_doc ),
5252 py .MustNewMethod ("next" , builtin_next , 0 , next_doc ),
5353 py .MustNewMethod ("open" , builtin_open , 0 , open_doc ),
5454 // py.MustNewMethod("oct", builtin_oct, 0, oct_doc),
@@ -772,6 +772,130 @@ func builtin_len(self, v py.Object) (py.Object, error) {
772772 return py .Len (v )
773773}
774774
775+ const max_doc = `
776+ max(iterable, *[, default=obj, key=func]) -> value
777+ max(arg1, arg2, *args, *[, key=func]) -> value
778+
779+ With a single iterable argument, return its biggest item. The
780+ default keyword-only argument specifies an object to return if
781+ the provided iterable is empty.
782+ With two or more arguments, return the largest argument.`
783+
784+ func builtin_max (self py.Object , args py.Tuple , kwargs py.StringDict ) (py.Object , error ) {
785+ return min_max (args , kwargs , "max" )
786+ }
787+
788+ const min_doc = `
789+ min(iterable, *[, default=obj, key=func]) -> value
790+ min(arg1, arg2, *args, *[, key=func]) -> value
791+
792+ With a single iterable argument, return its smallest item. The
793+ default keyword-only argument specifies an object to return if
794+ the provided iterable is empty.
795+ With two or more arguments, return the smallest argument.`
796+
797+ func builtin_min (self py.Object , args py.Tuple , kwargs py.StringDict ) (py.Object , error ) {
798+ return min_max (args , kwargs , "min" )
799+ }
800+
801+ func min_max (args py.Tuple , kwargs py.StringDict , name string ) (py.Object , error ) {
802+ kwlist := []string {"key" , "default" }
803+ positional := len (args )
804+ var format string
805+ var values py.Object
806+ var cmp func (a py.Object , b py.Object ) (py.Object , error )
807+ if name == "min" {
808+ format = "|$OO:min"
809+ cmp = py .Le
810+ } else if name == "max" {
811+ format = "|$OO:max"
812+ cmp = py .Ge
813+ }
814+ var defaultValue py.Object
815+ var keyFunc py.Object
816+ var maxVal , maxItem py.Object
817+ var kf * py.Function
818+
819+ if positional > 1 {
820+ values = args
821+ } else {
822+ err := py .UnpackTuple (args , nil , name , 1 , 1 , & values )
823+ if err != nil {
824+ return nil , err
825+ }
826+ }
827+ err := py .ParseTupleAndKeywords (nil , kwargs , format , kwlist , & keyFunc , & defaultValue )
828+ if err != nil {
829+ return nil , err
830+ }
831+ if keyFunc == py .None {
832+ keyFunc = nil
833+ }
834+ if keyFunc != nil {
835+ var ok bool
836+ kf , ok = keyFunc .(* py.Function )
837+ if ! ok {
838+ return nil , py .ExceptionNewf (py .TypeError , "'%s' object is not callable" , keyFunc .Type ())
839+ }
840+ }
841+ if defaultValue != nil {
842+ maxItem = defaultValue
843+ if keyFunc != nil {
844+ maxVal , err = py .Call (kf , py.Tuple {defaultValue }, nil )
845+ if err != nil {
846+ return nil , err
847+ }
848+ } else {
849+ maxVal = defaultValue
850+ }
851+ }
852+ iter , err := py .Iter (values )
853+ if err != nil {
854+ return nil , err
855+ }
856+
857+ for {
858+ item , err := py .Next (iter )
859+ if err != nil {
860+ if py .IsException (py .StopIteration , err ) {
861+ break
862+ }
863+ return nil , err
864+ }
865+ if maxVal == nil {
866+ if keyFunc != nil {
867+ maxVal , err = py .Call (kf , py.Tuple {item }, nil )
868+ if err != nil {
869+ return nil , err
870+ }
871+ } else {
872+ maxVal = item
873+ }
874+ maxItem = item
875+ } else {
876+ var compareVal py.Object
877+ if keyFunc != nil {
878+ compareVal , err = py .Call (kf , py.Tuple {item }, nil )
879+ if err != nil {
880+ return nil , err
881+ }
882+ } else {
883+ compareVal = item
884+ }
885+ changed , err := cmp (compareVal , maxVal )
886+ if err != nil {
887+ return nil , err
888+ }
889+ if changed == py .True {
890+ maxVal = compareVal
891+ maxItem = item
892+ }
893+ }
894+
895+ }
896+ return maxItem , nil
897+ }
898+
775899const chr_doc = `chr(i) -> Unicode character
776900
777901Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.`
0 commit comments