Merge lp:~allenap/launchpad/remove-propertycache-adapters-bug-628762 into lp:launchpad

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 11793
Proposed branch: lp:~allenap/launchpad/remove-propertycache-adapters-bug-628762
Merge into: lp:launchpad
Diff against target: 874 lines (+114/-189)
22 files modified
lib/canonical/database/sqlbase.py (+2/-2)
lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt (+2/-2)
lib/lp/bugs/model/bug.py (+8/-8)
lib/lp/bugs/model/bugtask.py (+3/-3)
lib/lp/registry/browser/person.py (+6/-6)
lib/lp/registry/doc/personlocation.txt (+2/-2)
lib/lp/registry/doc/teammembership.txt (+2/-2)
lib/lp/registry/model/distribution.py (+2/-2)
lib/lp/registry/model/distroseriesdifference.py (+4/-3)
lib/lp/registry/model/person.py (+15/-15)
lib/lp/registry/model/product.py (+2/-3)
lib/lp/registry/tests/test_distribution.py (+2/-2)
lib/lp/registry/tests/test_distroseriesdifference.py (+2/-2)
lib/lp/services/configure.zcml (+0/-3)
lib/lp/services/doc/propertycache.txt (+32/-19)
lib/lp/services/propertycache.py (+19/-102)
lib/lp/shipit.py (+1/-3)
lib/lp/soyuz/model/archive.py (+2/-2)
lib/lp/soyuz/model/distroseriesbinarypackage.py (+2/-2)
lib/lp/testing/factory.py (+3/-3)
lib/lp/testopenid/browser/server.py (+2/-2)
utilities/sourcedeps.conf (+1/-1)
To merge this branch: bzr merge lp:~allenap/launchpad/remove-propertycache-adapters-bug-628762
Reviewer Review Type Date Requested Status
Henning Eggers (community) code Approve
Review via email: mp+39249@code.launchpad.net

Commit message

Ditch property cache adapters in favour of plain old Python. The IPropertyCache adapter is replaced by get_property_cache() and the IPropertyCacheManager adapter is replaced by clear_property_cache().

Description of the change

This removes the adapters from the propertycache module. They worked fine, but didn't work everywhere, so I'd had to work around them anyway. The IPropertyCache adapter is replaced with get_property_cache() and IPropertyCacheManager(thing).clear() is replaced by clear_property_cache().

At the bottom of shipit.py, IPropertyCache is created as an alias to get_property_cache. I have a related branch to update shipit so this will get removed as soon as that lands.

It passes in ec2.

To post a comment you must log in.
Revision history for this message
Henning Eggers (henninge) wrote :

Congratulations on this nice reduction of complexity and code lines. We discussed a little issue on the test narrative in IRC but other than that this branch is fine. Thanks for formatting the imports, too! ;-)

Cheers,
Henning

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/database/sqlbase.py'
2--- lib/canonical/database/sqlbase.py 2010-10-03 15:30:06 +0000
3+++ lib/canonical/database/sqlbase.py 2010-10-25 15:26:11 +0000
4@@ -71,7 +71,7 @@
5 dbconfig,
6 )
7 from canonical.database.interfaces import ISQLBase
8-from lp.services.propertycache import IPropertyCacheManager
9+from lp.services.propertycache import clear_property_cache
10
11 # Default we want for scripts, and the PostgreSQL default. Note psycopg1 will
12 # use SERIALIZABLE unless we override, but psycopg2 will not.
13@@ -270,7 +270,7 @@
14 # XXX: RobertCollins 2010-08-16 bug=622648: Note this is not directly
15 # tested, but the entire test suite blows up awesomely if it's broken.
16 # It's entirely unclear where tests for this should be.
17- IPropertyCacheManager(self).clear()
18+ clear_property_cache(self)
19
20
21 alreadyInstalledMsg = ("A ZopelessTransactionManager with these settings is "
22
23=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt'
24--- lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-10-18 22:24:59 +0000
25+++ lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-10-25 15:26:11 +0000
26@@ -122,8 +122,8 @@
27 Instead of issuing one request per bug watch, like was done before,
28 updateBugWatches() issues only one request to update all watches:
29
30- >>> from lp.services.propertycache import IPropertyCache
31- >>> del IPropertyCache(example_ext_bug_tracker).csv_data
32+ >>> from lp.services.propertycache import get_property_cache
33+ >>> del get_property_cache(example_ext_bug_tracker).csv_data
34
35 >>> example_ext_bug_tracker.trace_calls = True
36 >>> bug_watch_updater.updateBugWatches(
37
38=== modified file 'lib/lp/bugs/model/bug.py'
39--- lib/lp/bugs/model/bug.py 2010-10-19 21:30:53 +0000
40+++ lib/lp/bugs/model/bug.py 2010-10-25 15:26:11 +0000
41@@ -189,8 +189,8 @@
42 from lp.services.fields import DuplicateBug
43 from lp.services.propertycache import (
44 cachedproperty,
45- IPropertyCache,
46- IPropertyCacheManager,
47+ clear_property_cache,
48+ get_property_cache,
49 )
50
51
52@@ -483,7 +483,7 @@
53 for message in messages:
54 if message.id not in chunk_map:
55 continue
56- cache = IPropertyCache(message)
57+ cache = get_property_cache(message)
58 cache.text_contents = Message.chunks_text(
59 chunk_map[message.id])
60 def eager_load(rows, slice_info):
61@@ -741,7 +741,7 @@
62 def unsubscribe(self, person, unsubscribed_by):
63 """See `IBug`."""
64 # Drop cached subscription info.
65- IPropertyCacheManager(self).clear()
66+ clear_property_cache(self)
67 if person is None:
68 person = unsubscribed_by
69
70@@ -763,7 +763,7 @@
71 # disabled see the change.
72 store.flush()
73 self.updateHeat()
74- del IPropertyCache(self)._known_viewers
75+ del get_property_cache(self)._known_viewers
76 return
77
78 def unsubscribeFromDupes(self, person, unsubscribed_by):
79@@ -1426,7 +1426,7 @@
80 question_target = IQuestionTarget(bugtask.target)
81 question = question_target.createQuestionFromBug(self)
82 self.addChange(BugConvertedToQuestion(UTC_NOW, person, question))
83- IPropertyCache(self)._question_from_bug = question
84+ get_property_cache(self)._question_from_bug = question
85
86 notify(BugBecameQuestionEvent(self, question, person))
87 return question
88@@ -1761,7 +1761,7 @@
89 # and insert the new ones.
90 new_tags = set([tag.lower() for tag in tags])
91 old_tags = set(self.tags)
92- del IPropertyCache(self)._cached_tags
93+ del get_property_cache(self)._cached_tags
94 added_tags = new_tags.difference(old_tags)
95 removed_tags = old_tags.difference(new_tags)
96 for removed_tag in removed_tags:
97@@ -2012,7 +2012,7 @@
98 # will be found without a query when dereferenced.
99 indexed_message = message_to_indexed.get(attachment._messageID)
100 if indexed_message is not None:
101- IPropertyCache(attachment).message = indexed_message
102+ get_property_cache(attachment).message = indexed_message
103 return attachment
104 rawresults = self._attachments_query()
105 return DecoratedResultSet(rawresults, set_indexed_message)
106
107=== modified file 'lib/lp/bugs/model/bugtask.py'
108--- lib/lp/bugs/model/bugtask.py 2010-10-22 19:56:26 +0000
109+++ lib/lp/bugs/model/bugtask.py 2010-10-25 15:26:11 +0000
110@@ -157,7 +157,7 @@
111 from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
112 from lp.registry.model.pillar import pillar_sort_key
113 from lp.registry.model.sourcepackagename import SourcePackageName
114-from lp.services.propertycache import IPropertyCache
115+from lp.services.propertycache import get_property_cache
116 from lp.soyuz.enums import PackagePublishingStatus
117 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
118 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
119@@ -1347,7 +1347,7 @@
120 """
121 userid = user.id
122 def cache_user_can_view_bug(bugtask):
123- IPropertyCache(bugtask.bug)._known_viewers = set([userid])
124+ get_property_cache(bugtask.bug)._known_viewers = set([userid])
125 return bugtask
126 return cache_user_can_view_bug
127
128@@ -2377,7 +2377,7 @@
129 bugtask._syncFromConjoinedSlave()
130
131 bugtask.updateTargetNameCache()
132- del IPropertyCache(bug).bugtasks
133+ del get_property_cache(bug).bugtasks
134 # Because of block_implicit_flushes, it is possible for a new bugtask
135 # to be queued in appropriately, which leads to Bug.bugtasks not
136 # finding the bugtask.
137
138=== modified file 'lib/lp/registry/browser/person.py'
139--- lib/lp/registry/browser/person.py 2010-10-14 20:20:47 +0000
140+++ lib/lp/registry/browser/person.py 2010-10-25 15:26:11 +0000
141@@ -206,10 +206,6 @@
142 from canonical.launchpad.webapp.login import logoutPerson
143 from canonical.launchpad.webapp.menu import get_current_view
144 from canonical.launchpad.webapp.publisher import LaunchpadView
145-from lp.app.browser.tales import (
146- DateTimeFormatterAPI,
147- PersonFormatterAPI,
148- )
149 from canonical.lazr.utils import smartquote
150 from canonical.widgets import (
151 LaunchpadDropdownWidget,
152@@ -226,6 +222,10 @@
153 from lp.answers.interfaces.questionenums import QuestionParticipation
154 from lp.answers.interfaces.questionsperson import IQuestionsPerson
155 from lp.app.browser.stringformatter import FormattersAPI
156+from lp.app.browser.tales import (
157+ DateTimeFormatterAPI,
158+ PersonFormatterAPI,
159+ )
160 from lp.app.errors import (
161 NotFoundError,
162 UnexpectedFormData,
163@@ -311,7 +311,7 @@
164 from lp.services.openid.interfaces.openidrpsummary import IOpenIDRPSummarySet
165 from lp.services.propertycache import (
166 cachedproperty,
167- IPropertyCache,
168+ get_property_cache,
169 )
170 from lp.services.salesforce.interfaces import (
171 ISalesforceVoucherProxy,
172@@ -5736,7 +5736,7 @@
173 def _reset_state(self):
174 """Reset the cache because the recipients changed."""
175 self._count_recipients = None
176- del IPropertyCache(self)._all_recipients
177+ del get_property_cache(self)._all_recipients
178
179 def _getPrimaryReason(self, person_or_team):
180 """Return the primary reason enumeration.
181
182=== modified file 'lib/lp/registry/doc/personlocation.txt'
183--- lib/lp/registry/doc/personlocation.txt 2010-10-17 15:44:08 +0000
184+++ lib/lp/registry/doc/personlocation.txt 2010-10-25 15:26:11 +0000
185@@ -120,9 +120,9 @@
186 have been pre-cached so that we don't hit the database everytime we
187 access a person's .location property.
188
189- >>> from lp.services.propertycache import IPropertyCache
190+ >>> from lp.services.propertycache import get_property_cache
191 >>> for mapped in guadamen.getMappedParticipants():
192- ... cache = IPropertyCache(mapped)
193+ ... cache = get_property_cache(mapped)
194 ... if ("location" not in cache or
195 ... not verifyObject(IPersonLocation, cache.location)):
196 ... print 'No cached location on %s' % mapped.name
197
198=== modified file 'lib/lp/registry/doc/teammembership.txt'
199--- lib/lp/registry/doc/teammembership.txt 2010-10-19 18:44:31 +0000
200+++ lib/lp/registry/doc/teammembership.txt 2010-10-25 15:26:11 +0000
201@@ -983,8 +983,8 @@
202 >>> from canonical.launchpad.interfaces.lpstorm import IMasterObject
203 >>> IMasterObject(bad_user.account).status = AccountStatus.SUSPENDED
204 >>> IMasterObject(bad_user.preferredemail).status = EmailAddressStatus.OLD
205- >>> from lp.services.propertycache import IPropertyCache
206- >>> del IPropertyCache(removeSecurityProxy(bad_user)).preferredemail
207+ >>> from lp.services.propertycache import get_property_cache
208+ >>> del get_property_cache(removeSecurityProxy(bad_user)).preferredemail
209 >>> transaction.commit()
210
211 >>> [m.displayname for m in t3.allmembers]
212
213=== modified file 'lib/lp/registry/model/distribution.py'
214--- lib/lp/registry/model/distribution.py 2010-10-17 09:03:43 +0000
215+++ lib/lp/registry/model/distribution.py 2010-10-25 15:26:11 +0000
216@@ -151,7 +151,7 @@
217 )
218 from lp.services.propertycache import (
219 cachedproperty,
220- IPropertyCache,
221+ get_property_cache,
222 )
223 from lp.soyuz.enums import (
224 ArchivePurpose,
225@@ -1752,7 +1752,7 @@
226
227 # May wish to add this to the series rather than clearing the cache --
228 # RBC 20100816.
229- del IPropertyCache(self).series
230+ del get_property_cache(self).series
231
232 return series
233
234
235=== modified file 'lib/lp/registry/model/distroseriesdifference.py'
236--- lib/lp/registry/model/distroseriesdifference.py 2010-09-28 14:42:41 +0000
237+++ lib/lp/registry/model/distroseriesdifference.py 2010-10-25 15:26:11 +0000
238@@ -41,11 +41,12 @@
239 IDistroSeriesDifferenceCommentSource,
240 )
241 from lp.registry.model.distroseriesdifferencecomment import (
242- DistroSeriesDifferenceComment)
243+ DistroSeriesDifferenceComment,
244+ )
245 from lp.registry.model.sourcepackagename import SourcePackageName
246 from lp.services.propertycache import (
247 cachedproperty,
248- IPropertyCacheManager,
249+ clear_property_cache,
250 )
251
252
253@@ -189,7 +190,7 @@
254 # won't cause a hard-to find bug if a script ever creates a
255 # difference, copies/publishes a new version and then calls
256 # update() (like the tests for this method do).
257- IPropertyCacheManager(self).clear()
258+ clear_property_cache(self)
259 self._updateType()
260 updated = self._updateVersionsAndStatus()
261 return updated
262
263=== modified file 'lib/lp/registry/model/person.py'
264--- lib/lp/registry/model/person.py 2010-10-19 20:54:44 +0000
265+++ lib/lp/registry/model/person.py 2010-10-25 15:26:11 +0000
266@@ -264,7 +264,7 @@
267 from lp.services.openid.model.openididentifier import OpenIdIdentifier
268 from lp.services.propertycache import (
269 cachedproperty,
270- IPropertyCache,
271+ get_property_cache,
272 )
273 from lp.services.salesforce.interfaces import (
274 ISalesforceVoucherProxy,
275@@ -511,19 +511,19 @@
276
277 :raises AttributeError: If the cache doesn't exist.
278 """
279- return IPropertyCache(self).languages
280+ return get_property_cache(self).languages
281
282 def setLanguagesCache(self, languages):
283 """Set this person's cached languages.
284
285 Order them by name if necessary.
286 """
287- IPropertyCache(self).languages = sorted(
288+ get_property_cache(self).languages = sorted(
289 languages, key=attrgetter('englishname'))
290
291 def deleteLanguagesCache(self):
292 """Delete this person's cached languages, if it exists."""
293- del IPropertyCache(self).languages
294+ del get_property_cache(self).languages
295
296 def addLanguage(self, language):
297 """See `IPerson`."""
298@@ -626,7 +626,7 @@
299 """See `ISetLocation`."""
300 assert not self.is_team, 'Cannot edit team location.'
301 if self.location is None:
302- IPropertyCache(self).location = PersonLocation(
303+ get_property_cache(self).location = PersonLocation(
304 person=self, visible=visible)
305 else:
306 self.location.visible = visible
307@@ -645,7 +645,7 @@
308 self.location.last_modified_by = user
309 self.location.date_last_modified = UTC_NOW
310 else:
311- IPropertyCache(self).location = PersonLocation(
312+ get_property_cache(self).location = PersonLocation(
313 person=self, time_zone=time_zone, latitude=latitude,
314 longitude=longitude, last_modified_by=user)
315
316@@ -1633,7 +1633,7 @@
317 if not person:
318 return
319 email = column
320- IPropertyCache(person).preferredemail = email
321+ get_property_cache(person).preferredemail = email
322
323 decorators.append(handleemail)
324
325@@ -1647,7 +1647,7 @@
326 column is not None
327 # -- preferred email found
328 and person.preferredemail is not None)
329- IPropertyCache(person).is_valid_person = valid
330+ get_property_cache(person).is_valid_person = valid
331 decorators.append(handleaccount)
332 return dict(
333 joins=origins,
334@@ -1737,7 +1737,7 @@
335
336 def prepopulate_person(row):
337 result = row[0]
338- cache = IPropertyCache(result)
339+ cache = get_property_cache(result)
340 index = 1
341 #-- karma caching
342 if need_karma:
343@@ -1799,7 +1799,7 @@
344 result = self._getMembersWithPreferredEmails()
345 person_list = []
346 for person, email in result:
347- IPropertyCache(person).preferredemail = email
348+ get_property_cache(person).preferredemail = email
349 person_list.append(person)
350 return person_list
351
352@@ -1934,7 +1934,7 @@
353 # fetches the rows when they're needed.
354 locations = self._getMappedParticipantsLocations(limit=limit)
355 for location in locations:
356- IPropertyCache(location.person).location = location
357+ get_property_cache(location.person).location = location
358 participants = set(location.person for location in locations)
359 # Cache the ValidPersonCache query for all mapped participants.
360 if len(participants) > 0:
361@@ -2076,7 +2076,7 @@
362 self.account_status = AccountStatus.DEACTIVATED
363 self.account_status_comment = comment
364 IMasterObject(self.preferredemail).status = EmailAddressStatus.NEW
365- del IPropertyCache(self).preferredemail
366+ del get_property_cache(self).preferredemail
367 base_new_name = self.name + '-deactivatedaccount'
368 self.name = self._ensureNewName(base_new_name)
369
370@@ -2466,7 +2466,7 @@
371 if email_address is not None:
372 email_address.status = EmailAddressStatus.VALIDATED
373 email_address.syncUpdate()
374- del IPropertyCache(self).preferredemail
375+ del get_property_cache(self).preferredemail
376
377 def setPreferredEmail(self, email):
378 """See `IPerson`."""
379@@ -2503,7 +2503,7 @@
380 IMasterObject(email).syncUpdate()
381
382 # Now we update our cache of the preferredemail.
383- IPropertyCache(self).preferredemail = email
384+ get_property_cache(self).preferredemail = email
385
386 @cachedproperty
387 def preferredemail(self):
388@@ -3077,7 +3077,7 @@
389 # Populate the previously empty 'preferredemail' cached
390 # property, so the Person record is up-to-date.
391 if master_email.status == EmailAddressStatus.PREFERRED:
392- cache = IPropertyCache(account_person)
393+ cache = get_property_cache(account_person)
394 cache.preferredemail = master_email
395 return account_person
396 # There is no associated `Person` to the email `Account`.
397
398=== modified file 'lib/lp/registry/model/product.py'
399--- lib/lp/registry/model/product.py 2010-10-07 22:14:07 +0000
400+++ lib/lp/registry/model/product.py 2010-10-25 15:26:11 +0000
401@@ -71,7 +71,6 @@
402 MAIN_STORE,
403 )
404 from canonical.launchpad.webapp.sorting import sorted_version_numbers
405-
406 from lp.answers.interfaces.faqtarget import IFAQTarget
407 from lp.answers.interfaces.questioncollection import (
408 QUESTION_STATUS_DEFAULT_SEARCH,
409@@ -161,7 +160,7 @@
410 from lp.services.database.prejoin import prejoin
411 from lp.services.propertycache import (
412 cachedproperty,
413- IPropertyCache,
414+ get_property_cache,
415 )
416 from lp.translations.interfaces.customlanguagecode import (
417 IHasCustomLanguageCodes,
418@@ -538,7 +537,7 @@
419 purchaser=purchaser,
420 sales_system_id=voucher,
421 whiteboard=whiteboard)
422- IPropertyCache(self).commercial_subscription = subscription
423+ get_property_cache(self).commercial_subscription = subscription
424 else:
425 if current_datetime <= self.commercial_subscription.date_expires:
426 # Extend current subscription.
427
428=== modified file 'lib/lp/registry/tests/test_distribution.py'
429--- lib/lp/registry/tests/test_distribution.py 2010-09-29 14:16:22 +0000
430+++ lib/lp/registry/tests/test_distribution.py 2010-10-25 15:26:11 +0000
431@@ -18,7 +18,7 @@
432 from lp.registry.tests.test_distroseries import (
433 TestDistroSeriesCurrentSourceReleases,
434 )
435-from lp.services.propertycache import IPropertyCache
436+from lp.services.propertycache import get_property_cache
437 from lp.soyuz.interfaces.distributionsourcepackagerelease import (
438 IDistributionSourcePackageRelease,
439 )
440@@ -84,7 +84,7 @@
441 distribution = removeSecurityProxy(
442 self.factory.makeDistribution('foo'))
443
444- cache = IPropertyCache(distribution)
445+ cache = get_property_cache(distribution)
446
447 # Not yet cached.
448 self.assertNotIn("series", cache)
449
450=== modified file 'lib/lp/registry/tests/test_distroseriesdifference.py'
451--- lib/lp/registry/tests/test_distroseriesdifference.py 2010-10-06 18:53:53 +0000
452+++ lib/lp/registry/tests/test_distroseriesdifference.py 2010-10-25 15:26:11 +0000
453@@ -26,7 +26,7 @@
454 IDistroSeriesDifference,
455 IDistroSeriesDifferenceSource,
456 )
457-from lp.services.propertycache import IPropertyCacheManager
458+from lp.services.propertycache import get_property_cache
459 from lp.soyuz.interfaces.publishing import PackagePublishingStatus
460 from lp.testing import (
461 person_logged_in,
462@@ -419,7 +419,7 @@
463 ds_diff.source_pub
464 ds_diff.parent_source_pub
465
466- cache = IPropertyCacheManager(ds_diff).cache
467+ cache = get_property_cache(ds_diff)
468
469 self.assertContentEqual(
470 ['source_pub', 'parent_source_pub'], cache)
471
472=== modified file 'lib/lp/services/configure.zcml'
473--- lib/lp/services/configure.zcml 2010-09-12 15:15:16 +0000
474+++ lib/lp/services/configure.zcml 2010-10-25 15:26:11 +0000
475@@ -3,9 +3,6 @@
476 -->
477
478 <configure xmlns="http://namespaces.zope.org/zope">
479- <adapter factory=".propertycache.get_default_cache"/>
480- <adapter factory=".propertycache.PropertyCacheManager"/>
481- <adapter factory=".propertycache.DefaultPropertyCacheManager"/>
482 <include package=".comments" />
483 <include package=".database" />
484 <include package=".features" />
485
486=== modified file 'lib/lp/services/doc/propertycache.txt'
487--- lib/lp/services/doc/propertycache.txt 2010-09-06 09:11:43 +0000
488+++ lib/lp/services/doc/propertycache.txt 2010-10-25 15:26:11 +0000
489@@ -3,8 +3,9 @@
490
491 >>> from lp.services.propertycache import (
492 ... cachedproperty,
493+ ... clear_property_cache,
494+ ... get_property_cache,
495 ... IPropertyCache,
496- ... IPropertyCacheManager,
497 ... )
498
499 Cached properties are for situations where a property is computed once
500@@ -20,9 +21,19 @@
501
502 >>> foo = Foo()
503
504-The property cache can be obtained via adaption.
505-
506- >>> cache = IPropertyCache(foo)
507+The property cache can be obtained with `get_property_cache()`.
508+
509+ >>> cache = get_property_cache(foo)
510+
511+Calling `get_property_cache()` on a cache returns the cache:
512+
513+ >>> get_property_cache(cache) is cache
514+ True
515+
516+Caches provide the `IPropertyCache` interface.
517+
518+ >>> IPropertyCache.providedBy(cache)
519+ True
520
521 Initially it is empty. Caches can be iterated over to reveal the names
522 of the values cached within.
523@@ -82,25 +93,27 @@
524 >>> del cache.bar
525 >>> del cache.bar
526
527-A cache manager can be used to empty the cache.
528-
529- >>> manager = IPropertyCacheManager(cache)
530+The cache can be cleared with `clear_property_cache()`.
531
532 >>> cache.bar = 123
533 >>> cache.baz = 456
534 >>> sorted(cache)
535 ['bar', 'baz']
536
537- >>> manager.clear()
538- >>> list(cache)
539- []
540-
541-A cache manager can be obtained by adaption from non-cache objects
542-too.
543-
544- >>> manager = IPropertyCacheManager(foo)
545- >>> manager.cache is cache
546- True
547+ >>> clear_property_cache(cache)
548+ >>> list(cache)
549+ []
550+
551+For convenience, the property cache for an object can also be cleared
552+by passing the object itself into `clear_property_cache()`.
553+
554+ >>> cache.bar = 123
555+ >>> list(cache)
556+ ['bar']
557+
558+ >>> clear_property_cache(foo)
559+ >>> list(cache)
560+ []
561
562
563 The cachedproperty decorator
564@@ -134,7 +147,7 @@
565
566 >>> foo.a
567 1234
568- >>> IPropertyCache(foo).a_in_cache
569+ >>> get_property_cache(foo).a_in_cache
570 1234
571
572 `b` was defined without an explicit name so it is known as "b" in the
573@@ -149,5 +162,5 @@
574
575 >>> foo.b
576 5678
577- >>> IPropertyCache(foo).b
578+ >>> get_property_cache(foo).b
579 5678
580
581=== modified file 'lib/lp/services/propertycache.py'
582--- lib/lp/services/propertycache.py 2010-09-02 12:54:05 +0000
583+++ lib/lp/services/propertycache.py 2010-10-25 15:26:11 +0000
584@@ -10,24 +10,17 @@
585
586 __metaclass__ = type
587 __all__ = [
588- 'IPropertyCache',
589- 'IPropertyCacheManager',
590 'cachedproperty',
591+ 'clear_property_cache',
592+ 'get_property_cache',
593 ]
594
595 from functools import partial
596
597-from zope.component import (
598- adapter,
599- adapts,
600- getGlobalSiteManager,
601- )
602 from zope.interface import (
603- implementer,
604 implements,
605 Interface,
606 )
607-from zope.schema import Object
608 from zope.security.proxy import removeSecurityProxy
609
610
611@@ -55,19 +48,6 @@
612 """Iterate over the cached names."""
613
614
615-class IPropertyCacheManager(Interface):
616-
617- cache = Object(IPropertyCache)
618-
619- def clear():
620- """Empty the cache."""
621-
622-
623-# Register adapters with the global site manager so that they work even when
624-# ZCML has not been executed.
625-registerAdapter = getGlobalSiteManager().registerAdapter
626-
627-
628 class DefaultPropertyCache:
629 """A simple cache."""
630
631@@ -89,56 +69,22 @@
632 return iter(self.__dict__)
633
634
635-@adapter(Interface)
636-@implementer(IPropertyCache)
637-def get_default_cache(target):
638- """Adapter to obtain a `DefaultPropertyCache` for any object."""
639- naked_target = removeSecurityProxy(target)
640- try:
641- return naked_target._property_cache
642- except AttributeError:
643- naked_target._property_cache = DefaultPropertyCache()
644- return naked_target._property_cache
645-
646-registerAdapter(get_default_cache)
647-
648-
649-class PropertyCacheManager:
650- """A simple `IPropertyCacheManager`.
651-
652- Should work for any `IPropertyCache` instance.
653- """
654-
655- implements(IPropertyCacheManager)
656- adapts(Interface)
657-
658- def __init__(self, target):
659- self.cache = IPropertyCache(target)
660-
661- def clear(self):
662- """See `IPropertyCacheManager`."""
663- for name in list(self.cache):
664- delattr(self.cache, name)
665-
666-registerAdapter(PropertyCacheManager)
667-
668-
669-class DefaultPropertyCacheManager:
670- """A `IPropertyCacheManager` specifically for `DefaultPropertyCache`.
671-
672- The implementation of `clear` is more efficient.
673- """
674-
675- implements(IPropertyCacheManager)
676- adapts(DefaultPropertyCache)
677-
678- def __init__(self, cache):
679- self.cache = cache
680-
681- def clear(self):
682- self.cache.__dict__.clear()
683-
684-registerAdapter(DefaultPropertyCacheManager)
685+def get_property_cache(target):
686+ """Obtain a `DefaultPropertyCache` for any object."""
687+ if IPropertyCache.providedBy(target):
688+ return target
689+ else:
690+ naked_target = removeSecurityProxy(target)
691+ try:
692+ return naked_target._property_cache
693+ except AttributeError:
694+ naked_target._property_cache = DefaultPropertyCache()
695+ return naked_target._property_cache
696+
697+
698+def clear_property_cache(target):
699+ """Clear the property cache."""
700+ get_property_cache(target).__dict__.clear()
701
702
703 class CachedProperty:
704@@ -163,7 +109,7 @@
705 def __get__(self, instance, cls):
706 if instance is None:
707 return self
708- cache = IPropertyCache(instance)
709+ cache = get_property_cache(instance)
710 try:
711 return getattr(cache, self.name)
712 except AttributeError:
713@@ -184,32 +130,3 @@
714 name = name_or_function.__name__
715 populate = name_or_function
716 return CachedProperty(name=name, populate=populate)
717-
718-
719-# XXX: GavinPanella 2010-09-02 bug=628762: There are some weird adaption
720-# failures when running the full test suite. All that follows is a temporary,
721-# mostly non-Zope, workaround.
722-
723-_IPropertyCache = IPropertyCache
724-_IPropertyCacheManager = IPropertyCacheManager
725-
726-def IPropertyCache(target):
727- """Return the `IPropertyCache` for `target`.
728-
729- Note: this is a workaround; see bug 628762.
730- """
731- if _IPropertyCache.providedBy(target):
732- return target
733- else:
734- return get_default_cache(target)
735-
736-def IPropertyCacheManager(target):
737- """Return the `IPropertyCacheManager` for `target`.
738-
739- Note: this is a workaround; see bug 628762.
740- """
741- cache = IPropertyCache(target)
742- if isinstance(cache, DefaultPropertyCache):
743- return DefaultPropertyCacheManager(cache)
744- else:
745- return PropertyCacheManager(cache)
746
747=== modified file 'lib/lp/shipit.py'
748--- lib/lp/shipit.py 2010-08-24 15:28:02 +0000
749+++ lib/lp/shipit.py 2010-10-25 15:26:11 +0000
750@@ -108,7 +108,7 @@
751 from lp.services.mail.sendmail import simple_sendmail
752 from lp.services.propertycache import (
753 cachedproperty,
754- IPropertyCache,
755+ get_property_cache,
756 )
757 from lp.services.scripts.base import (
758 LaunchpadCronScript,
759@@ -126,5 +126,3 @@
760 )
761 from lp.testing.factory import LaunchpadObjectFactory
762 from lp.testing.publication import get_request_and_publication
763-
764-
765
766=== modified file 'lib/lp/soyuz/model/archive.py'
767--- lib/lp/soyuz/model/archive.py 2010-10-03 15:30:06 +0000
768+++ lib/lp/soyuz/model/archive.py 2010-10-25 15:26:11 +0000
769@@ -88,7 +88,7 @@
770 from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
771 from lp.registry.model.teammembership import TeamParticipation
772 from lp.services.job.interfaces.job import JobStatus
773-from lp.services.propertycache import IPropertyCache
774+from lp.services.propertycache import get_property_cache
775 from lp.soyuz.adapters.archivedependencies import expand_dependencies
776 from lp.soyuz.adapters.packagelocation import PackageLocation
777 from lp.soyuz.enums import (
778@@ -1839,7 +1839,7 @@
779 signing_key = owner.archive.signing_key
780 else:
781 # owner.archive is a cached property and we've just cached it.
782- del IPropertyCache(owner).archive
783+ del get_property_cache(owner).archive
784
785 new_archive = Archive(
786 owner=owner, distribution=distribution, name=name,
787
788=== modified file 'lib/lp/soyuz/model/distroseriesbinarypackage.py'
789--- lib/lp/soyuz/model/distroseriesbinarypackage.py 2010-08-24 10:45:57 +0000
790+++ lib/lp/soyuz/model/distroseriesbinarypackage.py 2010-10-25 15:26:11 +0000
791@@ -15,7 +15,7 @@
792 from canonical.database.sqlbase import sqlvalues
793 from lp.services.propertycache import (
794 cachedproperty,
795- IPropertyCache,
796+ get_property_cache,
797 )
798 from lp.soyuz.interfaces.distroseriesbinarypackage import (
799 IDistroSeriesBinaryPackage,
800@@ -43,7 +43,7 @@
801 self.distroseries = distroseries
802 self.binarypackagename = binarypackagename
803 if cache is not None:
804- IPropertyCache(self).cache = cache
805+ get_property_cache(self).cache = cache
806
807 @property
808 def name(self):
809
810=== modified file 'lib/lp/testing/factory.py'
811--- lib/lp/testing/factory.py 2010-10-22 21:04:06 +0000
812+++ lib/lp/testing/factory.py 2010-10-25 15:26:11 +0000
813@@ -82,10 +82,10 @@
814 EmailAddressStatus,
815 IEmailAddressSet,
816 )
817-from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
818 from canonical.launchpad.interfaces.gpghandler import IGPGHandler
819 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
820 from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
821+from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
822 from canonical.launchpad.interfaces.temporaryblobstorage import (
823 ITemporaryStorageManager,
824 )
825@@ -220,7 +220,7 @@
826 from lp.registry.model.suitesourcepackage import SuiteSourcePackage
827 from lp.services.mail.signedmessage import SignedMessage
828 from lp.services.openid.model.openididentifier import OpenIdIdentifier
829-from lp.services.propertycache import IPropertyCacheManager
830+from lp.services.propertycache import clear_property_cache
831 from lp.services.worlddata.interfaces.country import ICountrySet
832 from lp.services.worlddata.interfaces.language import ILanguageSet
833 from lp.soyuz.adapters.packagelocation import PackageLocation
834@@ -1947,7 +1947,7 @@
835
836 # We clear the cache on the diff, returning the object as if it
837 # was just loaded from the store.
838- IPropertyCacheManager(diff).clear()
839+ clear_property_cache(diff)
840 return diff
841
842 def makeDistroSeriesDifferenceComment(
843
844=== modified file 'lib/lp/testopenid/browser/server.py'
845--- lib/lp/testopenid/browser/server.py 2010-08-24 10:45:57 +0000
846+++ lib/lp/testopenid/browser/server.py 2010-10-25 15:26:11 +0000
847@@ -62,7 +62,7 @@
848 )
849 from lp.services.propertycache import (
850 cachedproperty,
851- IPropertyCache,
852+ get_property_cache,
853 )
854 from lp.testopenid.interfaces.server import (
855 get_server_url,
856@@ -168,7 +168,7 @@
857 def restoreRequestFromSession(self):
858 """Get the OpenIDRequest from our session."""
859 session = self.getSession()
860- cache = IPropertyCache(self)
861+ cache = get_property_cache(self)
862 try:
863 cache.openid_parameters = session[OPENID_REQUEST_SESSION_KEY]
864 except KeyError:
865
866=== modified file 'utilities/sourcedeps.conf'
867--- utilities/sourcedeps.conf 2010-10-06 11:46:51 +0000
868+++ utilities/sourcedeps.conf 2010-10-25 15:26:11 +0000
869@@ -14,4 +14,4 @@
870 subvertpy lp:~launchpad-pqm/subvertpy/trunk;revno=2042
871 python-debian lp:~launchpad-pqm/python-debian/devel;revno=185
872 testresources lp:~launchpad-pqm/testresources/dev;revno=16
873-shipit lp:~launchpad-pqm/shipit/trunk;revno=8919 optional
874+shipit lp:~launchpad-pqm/shipit/trunk;revno=8920 optional