@@ -39,22 +39,13 @@ func init() {
39
39
}, 0 , "extend([item])" )
40
40
41
41
ListType .Dict ["sort" ] = MustNewMethod ("sort" , func (self Object , args Tuple , kwargs StringDict ) (Object , error ) {
42
-
43
- if len (args ) != 0 {
44
- return nil , ExceptionNewf (TypeError , "sort() takes no positional arguments" )
45
- }
46
-
47
- var keyFunc Object = None
48
- var reverse Object = False
49
-
50
- err := ParseTupleAndKeywords (nil , kwargs , "|Op:sort" , []string {"key" , "reverse" }, & keyFunc , & reverse )
42
+ const funcName = "sort"
43
+ err := UnpackTuple (args , nil , funcName , 0 , 0 )
51
44
if err != nil {
52
45
return nil , err
53
46
}
54
-
55
47
listSelf := self .(* List )
56
-
57
- err = SortInPlace (listSelf , keyFunc , reverse )
48
+ err = SortInPlace (listSelf , kwargs , funcName )
58
49
if err != nil {
59
50
return nil , err
60
51
}
@@ -375,27 +366,27 @@ func (s ptrSortable) Len() int {
375
366
}
376
367
377
368
func (s ptrSortable ) Swap (i , j int ) {
378
- elemI , err := s .s .l .M__getitem__ (Int (i ))
369
+ itemI , err := s .s .l .M__getitem__ (Int (i ))
379
370
if err != nil {
380
371
if s .s .firstErr == nil {
381
372
s .s .firstErr = err
382
373
}
383
374
return
384
375
}
385
- elemJ , err := s .s .l .M__getitem__ (Int (j ))
376
+ itemJ , err := s .s .l .M__getitem__ (Int (j ))
386
377
if err != nil {
387
378
if s .s .firstErr == nil {
388
379
s .s .firstErr = err
389
380
}
390
381
return
391
382
}
392
- _ , err = s .s .l .M__setitem__ (Int (i ), elemJ )
383
+ _ , err = s .s .l .M__setitem__ (Int (i ), itemJ )
393
384
if err != nil {
394
385
if s .s .firstErr == nil {
395
386
s .s .firstErr = err
396
387
}
397
388
}
398
- _ , err = s .s .l .M__setitem__ (Int (j ), elemI )
389
+ _ , err = s .s .l .M__setitem__ (Int (j ), itemI )
399
390
if err != nil {
400
391
if s .s .firstErr == nil {
401
392
s .s .firstErr = err
@@ -404,14 +395,14 @@ func (s ptrSortable) Swap(i, j int) {
404
395
}
405
396
406
397
func (s ptrSortable ) Less (i , j int ) bool {
407
- elemI , err := s .s .l .M__getitem__ (Int (i ))
398
+ itemI , err := s .s .l .M__getitem__ (Int (i ))
408
399
if err != nil {
409
400
if s .s .firstErr == nil {
410
401
s .s .firstErr = err
411
402
}
412
403
return false
413
404
}
414
- elemJ , err := s .s .l .M__getitem__ (Int (j ))
405
+ itemJ , err := s .s .l .M__getitem__ (Int (j ))
415
406
if err != nil {
416
407
if s .s .firstErr == nil {
417
408
s .s .firstErr = err
@@ -420,31 +411,34 @@ func (s ptrSortable) Less(i, j int) bool {
420
411
}
421
412
422
413
if s .s .keyFunc != None {
423
- elemI , err = Call (s .s .keyFunc , Tuple {elemI }, nil )
414
+ itemI , err = Call (s .s .keyFunc , Tuple {itemI }, nil )
424
415
if err != nil {
425
416
if s .s .firstErr == nil {
426
417
s .s .firstErr = err
427
418
}
419
+ return false
428
420
}
429
- elemJ , err = Call (s .s .keyFunc , Tuple {elemJ }, nil )
421
+ itemJ , err = Call (s .s .keyFunc , Tuple {itemJ }, nil )
430
422
if err != nil {
431
423
if s .s .firstErr == nil {
432
424
s .s .firstErr = err
433
425
}
426
+ return false
434
427
}
435
428
}
436
429
437
430
var cmpResult Object
438
431
if s .s .reverse {
439
- cmpResult , err = Lt (elemJ , elemI )
432
+ cmpResult , err = Lt (itemJ , itemI )
440
433
} else {
441
- cmpResult , err = Lt (elemI , elemJ )
434
+ cmpResult , err = Lt (itemI , itemJ )
442
435
}
443
436
444
437
if err != nil {
445
438
if s .s .firstErr == nil {
446
439
s .s .firstErr = err
447
440
}
441
+ return false
448
442
}
449
443
450
444
if boolResult , ok := cmpResult .(Bool ); ok {
@@ -454,12 +448,22 @@ func (s ptrSortable) Less(i, j int) bool {
454
448
return false
455
449
}
456
450
457
- func SortInPlace (l * List , keyFunc Object , reverse Object ) error {
458
- switch keyFunc .(type ) {
459
- case NoneType , I__call__ :
460
- default :
461
- return ExceptionNewf (TypeError , "'%s' object is not callable" , keyFunc .Type ().Name )
451
+ // SortInPlace sorts the given List in place using a stable sort.
452
+ // kwargs can have the keys "key" and "reverse".
453
+ func SortInPlace (l * List , kwargs StringDict , funcName string ) error {
454
+ var keyFunc Object
455
+ var reverse Object
456
+ err := ParseTupleAndKeywords (nil , kwargs , "|$OO:" + funcName , []string {"key" , "reverse" }, & keyFunc , & reverse )
457
+ if err != nil {
458
+ return err
459
+ }
460
+ if keyFunc == nil {
461
+ keyFunc = None
462
+ }
463
+ if reverse == nil {
464
+ reverse = False
462
465
}
466
+ // FIXME: requires the same bool-check like CPython (or better "|$Op" that doesn't panic on nil).
463
467
s := ptrSortable {& sortable {l , keyFunc , ObjectIsTrue (reverse ), nil }}
464
468
sort .Stable (s )
465
469
return s .s .firstErr
0 commit comments