Repeated indexes into a collection yield different objects each time

Bug #551704 reported by Martin Pitt
8
This bug affects 1 person
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.transitionTo{Target,Status} worked just fine in "beta", the equivalent operations in 1.0 (assign to target_link and status, and lp_save()) are just ignored.

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/changestatus.py
[<bug_task at https://api.staging.launchpad.net/1.0/coreutils/+bug/549305>, <bug_task at https://api.staging.launchpad.net/1.0/ubuntu/+bug/549305>, <bug_task at https://api.staging.launchpad.net/1.0/ubuntu/+source/pmount/+bug/549305>]
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".

Revision history for this message
Martin Pitt (pitti) wrote :
summary: - [1.0 API] assignment to status and target_link is ignored
+ Repeated indexes into a collection yield different objects each time
Revision history for this message
Leonard Richardson (leonardr) wrote :

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.

affects: launchpadlib → lazr.restfulclient
Gary Poster (gary)
Changed in launchpad-foundations:
status: New → Triaged
importance: Undecided → Low
Changed in lazr.restfulclient:
status: New → Triaged
importance: Undecided → Low
Revision history for this message
Gary Poster (gary) wrote :

I think I'd like to have this addressed with a weakref value dictionary as a cache in the Launchpad instance. That would mean a mapping from objects' self_link values to weakrefs of the objects. If the weakref exists, it should be verified to still exist, updated, and returned, so that existence checks like this one work as expected.

no longer affects: launchpad
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.