-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
Original report was
# Original saves are [0, 1, 2, 3, 4]
# This version results in obj.SaveGames of [4, 3, 3, 4, 0]
obj.SaveGames = sorted(obj.SaveGames,
key=lambda x: x.LastSaveDate,
reverse=True)Slightly more insidiously, this is also equivalent to obj.SaveGames.sort(key=lambda x: x.LastSaveDate, reverse=True), which you might expect to work better.
The root cause is structs being reference types, so when we update the first value in the array we're changing the value of whatever index it got sorted to. This is very unintuitive.
As a workaround, you can make a copy of each struct before assigning them:
obj.SaveGames = sorted((copy.copy(x) for x in obj.SaveGames),
key=lambda x: x.LastSaveDate,
reverse=True)
obj.SaveGames = copy.deepcopy(sorted(obj.SaveGames,
key=lambda x: x.LastSaveDate,
reverse=True))This is a broader problem than just sorting though, any slice assignment might run into it
>>> arr = [1, 2, 3, 4, 5] # really a wrappedarray of structs
>>> arr[2:4] = (arr[3], arr[4], arr[3], 6)
>>> arr # should be
[1, 2, 4, 5, 4, 6, 5]And then more generally, 2d arrays or arrays of multicast delegates, currently the other two reference types, would also be vulnerable.
Metadata
Metadata
Assignees
Labels
No labels