Skip to content

Commit 7cc1d0b

Browse files
committed
Unpacking of args works now for sorted and list.sort
1 parent ffb374f commit 7cc1d0b

File tree

2 files changed

+35
-31
lines changed

2 files changed

+35
-31
lines changed

builtin/builtin.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,24 +1076,24 @@ func builtin_sum(self py.Object, args py.Tuple) (py.Object, error) {
10761076
}
10771077

10781078
const sorted_doc = `sorted(iterable, key=None, reverse=False)
1079+
10791080
Return a new list containing all items from the iterable in ascending order.
10801081
10811082
A custom key function can be supplied to customize the sort order, and the
10821083
reverse flag can be set to request the result in descending order.`
10831084

10841085
func builtin_sorted(self py.Object, args py.Tuple, kwargs py.StringDict) (py.Object, error) {
1086+
const funcName = "sorted"
10851087
var iterable py.Object
1086-
var keyFunc py.Object = py.None
1087-
var reverse py.Object = py.False
1088-
err := py.ParseTupleAndKeywords(args, kwargs, "O|Op:sorted", []string{"iterable", "key", "reverse"}, &iterable, &keyFunc, &reverse)
1088+
err := py.UnpackTuple(args, nil, funcName, 1, 1, &iterable)
10891089
if err != nil {
10901090
return nil, err
10911091
}
10921092
l, err := py.SequenceList(iterable)
10931093
if err != nil {
10941094
return nil, err
10951095
}
1096-
err = py.SortInPlace(l, keyFunc, reverse)
1096+
err = py.SortInPlace(l, kwargs, funcName)
10971097
if err != nil {
10981098
return nil, err
10991099
}

py/list.go

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,13 @@ func init() {
3939
}, 0, "extend([item])")
4040

4141
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)
5144
if err != nil {
5245
return nil, err
5346
}
54-
5547
listSelf := self.(*List)
56-
57-
err = SortInPlace(listSelf, keyFunc, reverse)
48+
err = SortInPlace(listSelf, kwargs, funcName)
5849
if err != nil {
5950
return nil, err
6051
}
@@ -375,27 +366,27 @@ func (s ptrSortable) Len() int {
375366
}
376367

377368
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))
379370
if err != nil {
380371
if s.s.firstErr == nil {
381372
s.s.firstErr = err
382373
}
383374
return
384375
}
385-
elemJ, err := s.s.l.M__getitem__(Int(j))
376+
itemJ, err := s.s.l.M__getitem__(Int(j))
386377
if err != nil {
387378
if s.s.firstErr == nil {
388379
s.s.firstErr = err
389380
}
390381
return
391382
}
392-
_, err = s.s.l.M__setitem__(Int(i), elemJ)
383+
_, err = s.s.l.M__setitem__(Int(i), itemJ)
393384
if err != nil {
394385
if s.s.firstErr == nil {
395386
s.s.firstErr = err
396387
}
397388
}
398-
_, err = s.s.l.M__setitem__(Int(j), elemI)
389+
_, err = s.s.l.M__setitem__(Int(j), itemI)
399390
if err != nil {
400391
if s.s.firstErr == nil {
401392
s.s.firstErr = err
@@ -404,14 +395,14 @@ func (s ptrSortable) Swap(i, j int) {
404395
}
405396

406397
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))
408399
if err != nil {
409400
if s.s.firstErr == nil {
410401
s.s.firstErr = err
411402
}
412403
return false
413404
}
414-
elemJ, err := s.s.l.M__getitem__(Int(j))
405+
itemJ, err := s.s.l.M__getitem__(Int(j))
415406
if err != nil {
416407
if s.s.firstErr == nil {
417408
s.s.firstErr = err
@@ -420,31 +411,34 @@ func (s ptrSortable) Less(i, j int) bool {
420411
}
421412

422413
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)
424415
if err != nil {
425416
if s.s.firstErr == nil {
426417
s.s.firstErr = err
427418
}
419+
return false
428420
}
429-
elemJ, err = Call(s.s.keyFunc, Tuple{elemJ}, nil)
421+
itemJ, err = Call(s.s.keyFunc, Tuple{itemJ}, nil)
430422
if err != nil {
431423
if s.s.firstErr == nil {
432424
s.s.firstErr = err
433425
}
426+
return false
434427
}
435428
}
436429

437430
var cmpResult Object
438431
if s.s.reverse {
439-
cmpResult, err = Lt(elemJ, elemI)
432+
cmpResult, err = Lt(itemJ, itemI)
440433
} else {
441-
cmpResult, err = Lt(elemI, elemJ)
434+
cmpResult, err = Lt(itemI, itemJ)
442435
}
443436

444437
if err != nil {
445438
if s.s.firstErr == nil {
446439
s.s.firstErr = err
447440
}
441+
return false
448442
}
449443

450444
if boolResult, ok := cmpResult.(Bool); ok {
@@ -454,12 +448,22 @@ func (s ptrSortable) Less(i, j int) bool {
454448
return false
455449
}
456450

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
462465
}
466+
// FIXME: requires the same bool-check like CPython (or better "|$Op" that doesn't panic on nil).
463467
s := ptrSortable{&sortable{l, keyFunc, ObjectIsTrue(reverse), nil}}
464468
sort.Stable(s)
465469
return s.s.firstErr

0 commit comments

Comments
 (0)