Repeated indexes into a collection yield different objects each time
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
lazr.restfulclient |
Triaged
|
Low
|
Unassigned |
Bug Description
I'm trying to convert Apport from the beta to the 1.0 API, and I noticed a regression. While bug_task.
I noticed that assignment to target_link and status does not mark those attributes as dirty, so lp_save() doesn't write back anything.
I attach a reproducing script which tries to set the "pmount" package task to "invalid:
$ python /tmp/changestat
[<bug_task at https:/
d-a task: {}
d-a bug: {}
New
the 2nd and 3rd line show the dirty attributes of teh task and the entire bug, and shouldn't be empty (but are). The last line is the new status of the task, which should be "Invalid".
summary: |
- [1.0 API] assignment to status and target_link is ignored + Repeated indexes into a collection yield different objects each time |
Changed in launchpad-foundations: | |
status: | New → Triaged |
importance: | Undecided → Low |
Changed in lazr.restfulclient: | |
status: | New → Triaged |
importance: | Undecided → Low |
no longer affects: | launchpad |
This is the problem:
>>> b.bug_tasks[2] is b.bug_tasks[2]
False
A lazr.restfulclient scoped collection object is a lazy collection. If you ask for element 2, it will make an HTTP request to /bugs/549305/ bug_tasks? ws.start= 2, grab element #2, and wrap it in a Python object. If you ask for element 2 again, it will make another HTTP request and wrap the result in another Python object. If you set bug_tasks[ 2].status, the field will be set, but you'll never see that object again, because you didn't hold a reference to it.
Semi-obvious solutions include caching individual elements of scoped collections in the scoped-collection object (a solution distinct from caching HTTP requests for scoped collection pages, and probably easier to implement).
The workaround is to assign an object to a variable if you're going to use it more than once.