Merge lp:~allenap/launchpad/cache-experiment-roll-out into lp:launchpad

Proposed by Gavin Panella
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 11495
Proposed branch: lp:~allenap/launchpad/cache-experiment-roll-out
Merge into: lp:launchpad
Prerequisite: lp:~allenap/launchpad/cache-experiment
Diff against target: 2880 lines (+248/-457)
114 files modified
.ctags (+3/-0)
lib/canonical/cachedproperty.py (+0/-229)
lib/canonical/database/sqlbase.py (+0/-6)
lib/canonical/launchpad/browser/launchpad.py (+1/-1)
lib/canonical/launchpad/utilities/geoip.py (+1/-1)
lib/canonical/launchpad/webapp/error.py (+1/-1)
lib/canonical/launchpad/webapp/login.py (+1/-1)
lib/canonical/launchpad/webapp/servers.py (+1/-1)
lib/canonical/lazr/feed/feed.py (+17/-8)
lib/canonical/tests/test_cachedproperty.py (+0/-15)
lib/canonical/widgets/popup.py (+8/-7)
lib/lp/answers/browser/faqcollection.py (+1/-1)
lib/lp/answers/browser/question.py (+1/-1)
lib/lp/answers/browser/questiontarget.py (+3/-3)
lib/lp/answers/notification.py (+1/-1)
lib/lp/app/browser/root.py (+1/-1)
lib/lp/archivepublisher/diskpool.py (+1/-1)
lib/lp/blueprints/browser/specification.py (+1/-1)
lib/lp/blueprints/browser/specificationgoal.py (+1/-1)
lib/lp/blueprints/browser/specificationtarget.py (+1/-1)
lib/lp/blueprints/browser/sprint.py (+1/-1)
lib/lp/bugs/browser/bug.py (+1/-1)
lib/lp/bugs/browser/bugalsoaffects.py (+1/-1)
lib/lp/bugs/browser/bugbranch.py (+1/-1)
lib/lp/bugs/browser/bugtarget.py (+1/-1)
lib/lp/bugs/browser/bugtask.py (+1/-1)
lib/lp/bugs/browser/bugtracker.py (+1/-1)
lib/lp/bugs/browser/cvereport.py (+1/-1)
lib/lp/bugs/browser/distribution_upstream_bug_report.py (+1/-1)
lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt (+3/-1)
lib/lp/bugs/externalbugtracker/mantis.py (+1/-1)
lib/lp/bugs/externalbugtracker/rt.py (+1/-1)
lib/lp/bugs/model/bug.py (+13/-12)
lib/lp/bugs/model/bugattachment.py (+3/-3)
lib/lp/bugs/model/bugtask.py (+2/-2)
lib/lp/bugs/tests/externalbugtracker.py (+0/-8)
lib/lp/buildmaster/model/builder.py (+1/-1)
lib/lp/code/browser/bazaar.py (+1/-1)
lib/lp/code/browser/branch.py (+1/-1)
lib/lp/code/browser/branchlisting.py (+1/-1)
lib/lp/code/browser/branchmergeproposal.py (+1/-1)
lib/lp/code/browser/branchmergeproposallisting.py (+1/-1)
lib/lp/code/browser/branchvisibilitypolicy.py (+1/-1)
lib/lp/code/browser/codeimport.py (+1/-1)
lib/lp/code/browser/codeimportmachine.py (+1/-1)
lib/lp/code/browser/codereviewcomment.py (+1/-1)
lib/lp/code/browser/decorations.py (+1/-1)
lib/lp/code/browser/summary.py (+1/-1)
lib/lp/code/feed/branch.py (+1/-1)
lib/lp/code/model/branchvisibilitypolicy.py (+1/-1)
lib/lp/codehosting/codeimport/worker.py (+1/-1)
lib/lp/codehosting/puller/scheduler.py (+1/-1)
lib/lp/hardwaredb/scripts/hwdbsubmissions.py (+1/-1)
lib/lp/registry/browser/__init__.py (+1/-1)
lib/lp/registry/browser/announcement.py (+1/-1)
lib/lp/registry/browser/distribution.py (+2/-4)
lib/lp/registry/browser/distributionmirror.py (+1/-1)
lib/lp/registry/browser/distributionsourcepackage.py (+4/-3)
lib/lp/registry/browser/distroseries.py (+1/-1)
lib/lp/registry/browser/karma.py (+1/-1)
lib/lp/registry/browser/mailinglists.py (+1/-1)
lib/lp/registry/browser/milestone.py (+1/-1)
lib/lp/registry/browser/person.py (+6/-6)
lib/lp/registry/browser/pillar.py (+1/-1)
lib/lp/registry/browser/product.py (+3/-3)
lib/lp/registry/browser/productseries.py (+1/-1)
lib/lp/registry/browser/project.py (+1/-1)
lib/lp/registry/browser/structuralsubscription.py (+1/-1)
lib/lp/registry/browser/team.py (+1/-1)
lib/lp/registry/model/distribution.py (+5/-8)
lib/lp/registry/model/distroseries.py (+3/-5)
lib/lp/registry/model/mailinglist.py (+1/-1)
lib/lp/registry/model/person.py (+4/-22)
lib/lp/registry/model/product.py (+6/-3)
lib/lp/registry/vocabularies.py (+1/-1)
lib/lp/services/mailman/doc/staging.txt (+2/-1)
lib/lp/services/openid/browser/openiddiscovery.py (+1/-1)
lib/lp/services/propertycache.py (+41/-0)
lib/lp/services/salesforce/proxy.py (+1/-1)
lib/lp/services/tests/test_doc.py (+4/-2)
lib/lp/shipit.py (+4/-0)
lib/lp/soyuz/browser/archive.py (+2/-4)
lib/lp/soyuz/browser/archivesubscription.py (+1/-1)
lib/lp/soyuz/browser/build.py (+2/-2)
lib/lp/soyuz/browser/builder.py (+1/-1)
lib/lp/soyuz/browser/distributionsourcepackagerelease.py (+2/-2)
lib/lp/soyuz/browser/packagesearch.py (+1/-1)
lib/lp/soyuz/browser/publishing.py (+1/-1)
lib/lp/soyuz/model/archive.py (+1/-3)
lib/lp/soyuz/model/distroarchseriesbinarypackage.py (+2/-2)
lib/lp/soyuz/model/distroseriesbinarypackage.py (+6/-3)
lib/lp/soyuz/model/queue.py (+1/-1)
lib/lp/soyuz/model/sourcepackagerelease.py (+2/-4)
lib/lp/soyuz/scripts/ppareport.py (+1/-1)
lib/lp/soyuz/scripts/queue.py (+1/-1)
lib/lp/testing/__init__.py (+7/-2)
lib/lp/testopenid/browser/server.py (+7/-3)
lib/lp/translations/browser/distribution.py (+1/-1)
lib/lp/translations/browser/distroseries.py (+1/-1)
lib/lp/translations/browser/hastranslationimports.py (+1/-1)
lib/lp/translations/browser/language.py (+1/-1)
lib/lp/translations/browser/person.py (+1/-1)
lib/lp/translations/browser/poexportrequest.py (+1/-1)
lib/lp/translations/browser/pofile.py (+1/-1)
lib/lp/translations/browser/product.py (+1/-1)
lib/lp/translations/browser/productseries.py (+1/-1)
lib/lp/translations/browser/serieslanguage.py (+1/-1)
lib/lp/translations/browser/translationmessage.py (+1/-1)
lib/lp/translations/browser/translations.py (+1/-1)
lib/lp/translations/model/pofile.py (+1/-1)
lib/lp/translations/model/potemplate.py (+1/-1)
lib/lp/translations/model/translationmessage.py (+1/-1)
lib/lp/translations/utilities/translation_import.py (+1/-1)
utilities/sourcedeps.conf (+1/-1)
To merge this branch: bzr merge lp:~allenap/launchpad/cache-experiment-roll-out
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Robert Collins (community) Approve
Review via email: mp+33542@code.launchpad.net

Commit message

Roll out the propertycache API everywhere, remove canonical.cachedproperty, and provide bits of the API for shipit to import.

Description of the change

This rolls out the propertycache API - see lp:~allenap/launchpad/cache-experiment - everywhere and removes canonical.cachedproperty.

It also provides hooks for shipit to import the propertycache bits it needs. See lp:~allenap/shipit/shipit-use-propertycache for the other side of that deal. Once the shipit branch has landed, utilities/sourcedeps.conf will be updated to point to the relevant revision.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

While this branch appears very long, the majority of it is mechanical
changes. I've attached a diff of the non-mechanical parts.

1=== removed file 'lib/canonical/cachedproperty.py'
2--- lib/canonical/cachedproperty.py 2010-08-17 07:03:25 +0000
3+++ lib/canonical/cachedproperty.py 1970-01-01 00:00:00 +0000
4@@ -1,229 +0,0 @@
5-# Copyright 2009 Canonical Ltd. This software is licensed under the
6-# GNU Affero General Public License version 3 (see the file LICENSE).
7-
8-"""Cached properties for situations where a property is computed once and
9-then returned each time it is asked for.
10-
11-The clear_cachedproperties function can be used to wipe the cache of properties
12-from an instance.
13-"""
14-
15-__metaclass__ = type
16-
17-__all__ = [
18- 'cache_property',
19- 'cachedproperty',
20- 'clear_cachedproperties',
21- 'clear_property',
22- ]
23-
24-from zope.security.proxy import removeSecurityProxy
25-
26-from canonical.lazr.utils import safe_hasattr
27-
28-# XXX: JonathanLange 2010-01-11 bug=505731: Move this to lp.services.
29-
30-def cachedproperty(attrname_or_fn):
31- """A decorator for methods that makes them properties with their return
32- value cached.
33-
34- The value is cached on the instance, using the attribute name provided.
35-
36- If you don't provide a name, the mangled name of the property is used.
37-
38- cachedproperty is not threadsafe - it should not be used on objects which
39- are shared across threads / external locking should be used on those
40- objects.
41-
42- >>> class CachedPropertyTest(object):
43- ...
44- ... @cachedproperty('_foo_cache')
45- ... def foo(self):
46- ... print 'foo computed'
47- ... return 23
48- ...
49- ... @cachedproperty
50- ... def bar(self):
51- ... print 'bar computed'
52- ... return 69
53-
54- >>> cpt = CachedPropertyTest()
55- >>> getattr(cpt, '_foo_cache', None) is None
56- True
57- >>> cpt.foo
58- foo computed
59- 23
60- >>> cpt.foo
61- 23
62- >>> cpt._foo_cache
63- 23
64- >>> cpt.bar
65- bar computed
66- 69
67- >>> cpt._bar_cached_value
68- 69
69-
70- Cached properties are listed on instances.
71- >>> sorted(cpt._cached_properties)
72- ['_bar_cached_value', '_foo_cache']
73-
74- """
75- if isinstance(attrname_or_fn, basestring):
76- attrname = attrname_or_fn
77- return CachedPropertyForAttr(attrname)
78- else:
79- fn = attrname_or_fn
80- attrname = '_%s_cached_value' % fn.__name__
81- return CachedProperty(attrname, fn)
82-
83-def cache_property(instance, attrname, value):
84- """Cache value on instance as attrname.
85-
86- instance._cached_properties is updated with attrname.
87-
88- >>> class CachedPropertyTest(object):
89- ...
90- ... @cachedproperty('_foo_cache')
91- ... def foo(self):
92- ... return 23
93- ...
94- >>> instance = CachedPropertyTest()
95- >>> cache_property(instance, '_foo_cache', 42)
96- >>> instance.foo
97- 42
98- >>> instance._cached_properties
99- ['_foo_cache']
100-
101- Caching a new value does not duplicate the cache keys.
102-
103- >>> cache_property(instance, '_foo_cache', 84)
104- >>> instance._cached_properties
105- ['_foo_cache']
106-
107- And does update the cached value.
108-
109- >>> instance.foo
110- 84
111- """
112- naked_instance = removeSecurityProxy(instance)
113- clear_property(naked_instance, attrname)
114- setattr(naked_instance, attrname, value)
115- cached_properties = getattr(naked_instance, '_cached_properties', [])
116- cached_properties.append(attrname)
117- naked_instance._cached_properties = cached_properties
118-
119-
120-def clear_property(instance, attrname):
121- """Remove a cached attribute from instance.
122-
123- The attribute name is removed from instance._cached_properties.
124-
125- If the property is not cached, nothing happens.
126-
127- :seealso clear_cachedproperties: For clearing all cached items at once.
128-
129- >>> class CachedPropertyTest(object):
130- ...
131- ... @cachedproperty('_foo_cache')
132- ... def foo(self):
133- ... return 23
134- ...
135- >>> instance = CachedPropertyTest()
136- >>> instance.foo
137- 23
138- >>> clear_property(instance, '_foo_cache')
139- >>> instance._cached_properties
140- []
141- >>> is_cached(instance, '_foo_cache')
142- False
143- >>> clear_property(instance, '_foo_cache')
144- """
145- naked_instance = removeSecurityProxy(instance)
146- if not is_cached(naked_instance, attrname):
147- return
148- delattr(naked_instance, attrname)
149- naked_instance._cached_properties.remove(attrname)
150-
151-
152-def clear_cachedproperties(instance):
153- """Clear cached properties from an object.
154-
155- >>> class CachedPropertyTest(object):
156- ...
157- ... @cachedproperty('_foo_cache')
158- ... def foo(self):
159- ... return 23
160- ...
161- >>> instance = CachedPropertyTest()
162- >>> instance.foo
163- 23
164- >>> instance._cached_properties
165- ['_foo_cache']
166- >>> clear_cachedproperties(instance)
167- >>> instance._cached_properties
168- []
169- >>> hasattr(instance, '_foo_cache')
170- False
171- """
172- naked_instance = removeSecurityProxy(instance)
173- cached_properties = getattr(naked_instance, '_cached_properties', [])
174- for property_name in cached_properties:
175- delattr(naked_instance, property_name)
176- naked_instance._cached_properties = []
177-
178-
179-def is_cached(instance, attrname):
180- """Return True if attrname is cached on instance.
181-
182- >>> class CachedPropertyTest(object):
183- ...
184- ... @cachedproperty('_foo_cache')
185- ... def foo(self):
186- ... return 23
187- ...
188- >>> instance = CachedPropertyTest()
189- >>> instance.foo
190- 23
191- >>> is_cached(instance, '_foo_cache')
192- True
193- >>> is_cached(instance, '_var_cache')
194- False
195- """
196- naked_instance = removeSecurityProxy(instance)
197- return safe_hasattr(naked_instance, attrname)
198-
199-
200-class CachedPropertyForAttr:
201- """Curry a decorator to provide arguments to the CachedProperty."""
202-
203- def __init__(self, attrname):
204- self.attrname = attrname
205-
206- def __call__(self, fn):
207- return CachedProperty(self.attrname, fn)
208-
209-
210-class CachedProperty:
211-
212- # Used to detect not-yet-cached properties.
213- sentinel = object()
214-
215- def __init__(self, attrname, fn):
216- self.fn = fn
217- self.attrname = attrname
218-
219- def __get__(self, inst, cls=None):
220- if inst is None:
221- return self
222- cachedresult = getattr(inst, self.attrname, CachedProperty.sentinel)
223- if cachedresult is CachedProperty.sentinel:
224- result = self.fn(inst)
225- cache_property(inst, self.attrname, result)
226- return result
227- else:
228- return cachedresult
229-
230-
231-if __name__ == '__main__':
232- import doctest
233- doctest.testmod()
234
235=== modified file 'lib/canonical/database/sqlbase.py'
236--- lib/canonical/database/sqlbase.py 2010-08-23 10:57:10 +0000
237+++ lib/canonical/database/sqlbase.py 2010-08-24 10:29:11 +0000
238@@ -65,7 +65,6 @@
239 from zope.interface import implements
240 from zope.security.proxy import removeSecurityProxy
241
242-from canonical.cachedproperty import clear_cachedproperties
243 from canonical.config import (
244 config,
245 dbconfig,
246@@ -271,10 +270,6 @@
247 # XXX: RobertCollins 2010-08-16 bug=622648: Note this is not directly
248 # tested, but the entire test suite blows up awesomely if it's broken.
249 # It's entirely unclear where tests for this should be.
250-
251- # While canonical.cachedproperty and lp.services.propertycache are
252- # both in use, we must clear the caches for both.
253- clear_cachedproperties(self)
254 IPropertyCacheManager(self).clear()
255
256
257
258=== removed file 'lib/canonical/tests/test_cachedproperty.py'
259--- lib/canonical/tests/test_cachedproperty.py 2010-07-14 14:11:15 +0000
260+++ lib/canonical/tests/test_cachedproperty.py 1970-01-01 00:00:00 +0000
261@@ -1,15 +0,0 @@
262-# Copyright 2009 Canonical Ltd. This software is licensed under the
263-# GNU Affero General Public License version 3 (see the file LICENSE).
264-
265-from doctest import DocTestSuite, ELLIPSIS
266-import unittest
267-
268-import canonical.cachedproperty
269-
270-def test_suite():
271- suite = DocTestSuite(canonical.cachedproperty, optionflags=ELLIPSIS)
272- return suite
273-
274-
275-if __name__ == '__main__':
276- unittest.main(defaultTest='test_suite')
277
278=== modified file 'lib/lp/bugs/model/bug.py'
279--- lib/lp/bugs/model/bug.py 2010-08-22 18:31:30 +0000
280+++ lib/lp/bugs/model/bug.py 2010-08-24 10:12:39 +0000
281@@ -70,9 +70,9 @@
282 providedBy,
283 )
284
285-from canonical.cachedproperty import (
286+from lp.services.propertycache import (
287 cachedproperty,
288- clear_property,
289+ IPropertyCache,
290 )
291 from canonical.config import config
292 from canonical.database.constants import UTC_NOW
293@@ -633,7 +633,7 @@
294 # disabled see the change.
295 store.flush()
296 self.updateHeat()
297- clear_property(self, '_cached_viewers')
298+ del IPropertyCache(self)._known_viewers
299 return
300
301 def unsubscribeFromDupes(self, person, unsubscribed_by):
302@@ -1626,7 +1626,7 @@
303 self, self.messages[comment_number])
304 bug_message.visible = visible
305
306- @cachedproperty('_cached_viewers')
307+ @cachedproperty
308 def _known_viewers(self):
309 """A dict of of known persons able to view this bug."""
310 return set()
311
312=== modified file 'lib/lp/bugs/model/bugtask.py'
313--- lib/lp/bugs/model/bugtask.py 2010-08-22 18:31:30 +0000
314+++ lib/lp/bugs/model/bugtask.py 2010-08-24 10:32:39 +0000
315@@ -59,7 +59,6 @@
316 removeSecurityProxy,
317 )
318
319-from canonical.cachedproperty import cache_property
320 from canonical.config import config
321 from canonical.database.constants import UTC_NOW
322 from canonical.database.datetimecol import UtcDateTimeCol
323@@ -156,6 +155,9 @@
324 from lp.soyuz.interfaces.publishing import PackagePublishingStatus
325 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
326 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
327+from lp.services.propertycache import (
328+ IPropertyCache,
329+ )
330
331
332 debbugsseveritymap = {None: BugTaskImportance.UNDECIDED,
333@@ -1324,7 +1326,7 @@
334 """
335 userid = user.id
336 def cache_user_can_view_bug(bugtask):
337- cache_property(bugtask.bug, '_cached_viewers', set([userid]))
338+ IPropertyCache(bugtask.bug)._known_viewers = set([userid])
339 return bugtask
340 return cache_user_can_view_bug
341
342
343=== modified file 'lib/lp/registry/browser/person.py'
344--- lib/lp/registry/browser/person.py 2010-08-23 03:25:20 +0000
345+++ lib/lp/registry/browser/person.py 2010-08-24 10:19:26 +0000
346@@ -141,7 +141,10 @@
347 from zope.security.interfaces import Unauthorized
348 from zope.security.proxy import removeSecurityProxy
349
350-from canonical.cachedproperty import cachedproperty
351+from lp.services.propertycache import (
352+ cachedproperty,
353+ IPropertyCache,
354+ )
355 from canonical.config import config
356 from canonical.database.sqlbase import flush_database_updates
357 from canonical.launchpad import (
358@@ -5693,10 +5696,7 @@
359 def _reset_state(self):
360 """Reset the cache because the recipients changed."""
361 self._count_recipients = None
362- if safe_hasattr(self, '_all_recipients_cached'):
363- # The clear the cache of _all_recipients. The caching will fail
364- # if this method creates the attribute before _all_recipients.
365- del self._all_recipients_cached
366+ del IPropertyCache(self)._all_recipients
367
368 def _getPrimaryReason(self, person_or_team):
369 """Return the primary reason enumeration.
370@@ -5804,7 +5804,7 @@
371 'You are contacting %s of the %s (%s) team directly.'
372 % (text, person_or_team.displayname, person_or_team.name))
373
374- @cachedproperty('_all_recipients_cached')
375+ @cachedproperty
376 def _all_recipients(self):
377 """Set the cache of all recipients."""
378 all_recipients = {}
379
380=== modified file 'lib/lp/registry/model/distroseries.py'
381--- lib/lp/registry/model/distroseries.py 2010-08-22 18:31:30 +0000
382+++ lib/lp/registry/model/distroseries.py 2010-08-24 10:20:53 +0000
383@@ -547,7 +547,7 @@
384 orderBy=["Language.englishname"])
385 return result
386
387- @cachedproperty('_previous_series_cached')
388+ @cachedproperty
389 def previous_series(self):
390 """See `IDistroSeries`."""
391 # This property is cached because it is used intensely inside
392
393=== modified file 'lib/lp/registry/model/product.py'
394--- lib/lp/registry/model/product.py 2010-08-22 19:26:46 +0000
395+++ lib/lp/registry/model/product.py 2010-08-24 10:23:04 +0000
396@@ -38,7 +38,10 @@
397 from zope.interface import implements
398 from zope.security.proxy import removeSecurityProxy
399
400-from canonical.cachedproperty import cachedproperty
401+from lp.services.propertycache import (
402+ cachedproperty,
403+ IPropertyCache,
404+ )
405 from canonical.database.constants import UTC_NOW
406 from canonical.database.datetimecol import UtcDateTimeCol
407 from canonical.database.enumcol import EnumCol
408@@ -428,7 +431,7 @@
409 notNull=True, default=False,
410 storm_validator=_validate_license_approved)
411
412- @cachedproperty('_commercial_subscription_cached')
413+ @cachedproperty
414 def commercial_subscription(self):
415 return CommercialSubscription.selectOneBy(product=self)
416
417@@ -475,7 +478,7 @@
418 purchaser=purchaser,
419 sales_system_id=voucher,
420 whiteboard=whiteboard)
421- self._commercial_subscription_cached = subscription
422+ IPropertyCache(self).commercial_subscription = subscription
423 else:
424 if current_datetime <= self.commercial_subscription.date_expires:
425 # Extend current subscription.
426
427=== modified file 'lib/lp/soyuz/model/distroseriesbinarypackage.py'
428--- lib/lp/soyuz/model/distroseriesbinarypackage.py 2010-08-20 20:31:18 +0000
429+++ lib/lp/soyuz/model/distroseriesbinarypackage.py 2010-08-24 10:25:36 +0000
430@@ -12,7 +12,10 @@
431 from storm.store import Store
432 from zope.interface import implements
433
434-from canonical.cachedproperty import cachedproperty
435+from lp.services.propertycache import (
436+ cachedproperty,
437+ IPropertyCache,
438+ )
439 from canonical.database.sqlbase import sqlvalues
440 from lp.soyuz.interfaces.distroseriesbinarypackage import (
441 IDistroSeriesBinaryPackage,
442@@ -40,7 +43,7 @@
443 self.distroseries = distroseries
444 self.binarypackagename = binarypackagename
445 if cache is not None:
446- self._cache = cache
447+ IPropertyCache(self).cache = cache
448
449 @property
450 def name(self):
451@@ -58,7 +61,7 @@
452 """See IDistroSeriesBinaryPackage."""
453 return self.distroseries.distribution
454
455- @cachedproperty('_cache')
456+ @cachedproperty
457 def cache(self):
458 """See IDistroSeriesBinaryPackage."""
459 store = Store.of(self.distroseries)
460
461=== modified file 'lib/lp/testopenid/browser/server.py'
462--- lib/lp/testopenid/browser/server.py 2010-08-20 20:31:18 +0000
463+++ lib/lp/testopenid/browser/server.py 2010-08-24 10:27:59 +0000
464@@ -32,7 +32,10 @@
465 from zope.security.proxy import isinstance as zisinstance
466 from zope.session.interfaces import ISession
467
468-from canonical.cachedproperty import cachedproperty
469+from lp.services.propertycache import (
470+ cachedproperty,
471+ IPropertyCache,
472+ )
473 from canonical.launchpad import _
474 from canonical.launchpad.interfaces.account import (
475 AccountStatus,
476@@ -142,7 +145,7 @@
477 return (self.openid_request.idSelect() or
478 self.openid_request.identity == self.user_identity_url)
479
480- @cachedproperty('_openid_parameters')
481+ @cachedproperty
482 def openid_parameters(self):
483 """A dictionary of OpenID query parameters from request."""
484 query = {}
485@@ -165,8 +168,9 @@
486 def restoreRequestFromSession(self):
487 """Get the OpenIDRequest from our session."""
488 session = self.getSession()
489+ cache = IPropertyCache(self)
490 try:
491- self._openid_parameters = session[OPENID_REQUEST_SESSION_KEY]
492+ cache.openid_parameters = session[OPENID_REQUEST_SESSION_KEY]
493 except KeyError:
494 raise UnexpectedFormData("No OpenID request in session")
495
496
497=== modified file 'lib/lp/shipit.py'
498--- lib/lp/shipit.py 2010-08-20 20:31:18 +0000
499+++ lib/lp/shipit.py 2010-08-24 15:27:46 +0000
500@@ -106,6 +106,10 @@
501 from lp.registry.model.person import Person
502 from lp.services.mail import stub
503 from lp.services.mail.sendmail import simple_sendmail
504+from lp.services.propertycache import (
505+ cachedproperty,
506+ IPropertyCache,
507+ )
508 from lp.services.scripts.base import (
509 LaunchpadCronScript,
510 LaunchpadScript,
Revision history for this message
Robert Collins (lifeless) wrote :

\o/

review: Approve
Revision history for this message
Graham Binns (gmb) wrote :

r=me on the changes made here: http://paste.ubuntu.com/486317/

review: Approve (code)
Revision history for this message
Gavin Panella (allenap) wrote :

Hi Rob,

If you get a chance, please could you review my workaround for bug
628762
(diff attached). It passes the full test suite, hurrah :)

Thanks, Gavin.

1=== modified file 'lib/lp/services/propertycache.py'
2--- lib/lp/services/propertycache.py 2010-08-31 11:03:41 +0000
3+++ lib/lp/services/propertycache.py 2010-09-02 12:52:40 +0000
4@@ -184,3 +184,32 @@
5 name = name_or_function.__name__
6 populate = name_or_function
7 return CachedProperty(name=name, populate=populate)
8+
9+
10+# XXX: GavinPanella 2010-09-02 bug=628762: There are some weird adaption
11+# failures when running the full test suite. All that follows is a temporary,
12+# mostly non-Zope, workaround.
13+
14+_IPropertyCache = IPropertyCache
15+_IPropertyCacheManager = IPropertyCacheManager
16+
17+def IPropertyCache(target):
18+ """Return the `IPropertyCache` for `target`.
19+
20+ Note: this is a workaround; see bug 628762.
21+ """
22+ if _IPropertyCache.providedBy(target):
23+ return target
24+ else:
25+ return get_default_cache(target)
26+
27+def IPropertyCacheManager(target):
28+ """Return the `IPropertyCacheManager` for `target`.
29+
30+ Note: this is a workaround; see bug 628762.
31+ """
32+ cache = IPropertyCache(target)
33+ if isinstance(cache, DefaultPropertyCache):
34+ return DefaultPropertyCacheManager(cache)
35+ else:
36+ return PropertyCacheManager(cache)
Revision history for this message
Robert Collins (lifeless) wrote :

looks ok to me

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.ctags'
2--- .ctags 2010-01-06 20:06:23 +0000
3+++ .ctags 2010-09-02 12:57:56 +0000
4@@ -1,1 +1,4 @@
5 --python-kinds=-iv
6+--exclude=*-min.js
7+--exclude=*-debug.js
8+--extra=+f
9
10=== removed file 'lib/canonical/cachedproperty.py'
11--- lib/canonical/cachedproperty.py 2010-08-17 07:03:25 +0000
12+++ lib/canonical/cachedproperty.py 1970-01-01 00:00:00 +0000
13@@ -1,229 +0,0 @@
14-# Copyright 2009 Canonical Ltd. This software is licensed under the
15-# GNU Affero General Public License version 3 (see the file LICENSE).
16-
17-"""Cached properties for situations where a property is computed once and
18-then returned each time it is asked for.
19-
20-The clear_cachedproperties function can be used to wipe the cache of properties
21-from an instance.
22-"""
23-
24-__metaclass__ = type
25-
26-__all__ = [
27- 'cache_property',
28- 'cachedproperty',
29- 'clear_cachedproperties',
30- 'clear_property',
31- ]
32-
33-from zope.security.proxy import removeSecurityProxy
34-
35-from canonical.lazr.utils import safe_hasattr
36-
37-# XXX: JonathanLange 2010-01-11 bug=505731: Move this to lp.services.
38-
39-def cachedproperty(attrname_or_fn):
40- """A decorator for methods that makes them properties with their return
41- value cached.
42-
43- The value is cached on the instance, using the attribute name provided.
44-
45- If you don't provide a name, the mangled name of the property is used.
46-
47- cachedproperty is not threadsafe - it should not be used on objects which
48- are shared across threads / external locking should be used on those
49- objects.
50-
51- >>> class CachedPropertyTest(object):
52- ...
53- ... @cachedproperty('_foo_cache')
54- ... def foo(self):
55- ... print 'foo computed'
56- ... return 23
57- ...
58- ... @cachedproperty
59- ... def bar(self):
60- ... print 'bar computed'
61- ... return 69
62-
63- >>> cpt = CachedPropertyTest()
64- >>> getattr(cpt, '_foo_cache', None) is None
65- True
66- >>> cpt.foo
67- foo computed
68- 23
69- >>> cpt.foo
70- 23
71- >>> cpt._foo_cache
72- 23
73- >>> cpt.bar
74- bar computed
75- 69
76- >>> cpt._bar_cached_value
77- 69
78-
79- Cached properties are listed on instances.
80- >>> sorted(cpt._cached_properties)
81- ['_bar_cached_value', '_foo_cache']
82-
83- """
84- if isinstance(attrname_or_fn, basestring):
85- attrname = attrname_or_fn
86- return CachedPropertyForAttr(attrname)
87- else:
88- fn = attrname_or_fn
89- attrname = '_%s_cached_value' % fn.__name__
90- return CachedProperty(attrname, fn)
91-
92-def cache_property(instance, attrname, value):
93- """Cache value on instance as attrname.
94-
95- instance._cached_properties is updated with attrname.
96-
97- >>> class CachedPropertyTest(object):
98- ...
99- ... @cachedproperty('_foo_cache')
100- ... def foo(self):
101- ... return 23
102- ...
103- >>> instance = CachedPropertyTest()
104- >>> cache_property(instance, '_foo_cache', 42)
105- >>> instance.foo
106- 42
107- >>> instance._cached_properties
108- ['_foo_cache']
109-
110- Caching a new value does not duplicate the cache keys.
111-
112- >>> cache_property(instance, '_foo_cache', 84)
113- >>> instance._cached_properties
114- ['_foo_cache']
115-
116- And does update the cached value.
117-
118- >>> instance.foo
119- 84
120- """
121- naked_instance = removeSecurityProxy(instance)
122- clear_property(naked_instance, attrname)
123- setattr(naked_instance, attrname, value)
124- cached_properties = getattr(naked_instance, '_cached_properties', [])
125- cached_properties.append(attrname)
126- naked_instance._cached_properties = cached_properties
127-
128-
129-def clear_property(instance, attrname):
130- """Remove a cached attribute from instance.
131-
132- The attribute name is removed from instance._cached_properties.
133-
134- If the property is not cached, nothing happens.
135-
136- :seealso clear_cachedproperties: For clearing all cached items at once.
137-
138- >>> class CachedPropertyTest(object):
139- ...
140- ... @cachedproperty('_foo_cache')
141- ... def foo(self):
142- ... return 23
143- ...
144- >>> instance = CachedPropertyTest()
145- >>> instance.foo
146- 23
147- >>> clear_property(instance, '_foo_cache')
148- >>> instance._cached_properties
149- []
150- >>> is_cached(instance, '_foo_cache')
151- False
152- >>> clear_property(instance, '_foo_cache')
153- """
154- naked_instance = removeSecurityProxy(instance)
155- if not is_cached(naked_instance, attrname):
156- return
157- delattr(naked_instance, attrname)
158- naked_instance._cached_properties.remove(attrname)
159-
160-
161-def clear_cachedproperties(instance):
162- """Clear cached properties from an object.
163-
164- >>> class CachedPropertyTest(object):
165- ...
166- ... @cachedproperty('_foo_cache')
167- ... def foo(self):
168- ... return 23
169- ...
170- >>> instance = CachedPropertyTest()
171- >>> instance.foo
172- 23
173- >>> instance._cached_properties
174- ['_foo_cache']
175- >>> clear_cachedproperties(instance)
176- >>> instance._cached_properties
177- []
178- >>> hasattr(instance, '_foo_cache')
179- False
180- """
181- naked_instance = removeSecurityProxy(instance)
182- cached_properties = getattr(naked_instance, '_cached_properties', [])
183- for property_name in cached_properties:
184- delattr(naked_instance, property_name)
185- naked_instance._cached_properties = []
186-
187-
188-def is_cached(instance, attrname):
189- """Return True if attrname is cached on instance.
190-
191- >>> class CachedPropertyTest(object):
192- ...
193- ... @cachedproperty('_foo_cache')
194- ... def foo(self):
195- ... return 23
196- ...
197- >>> instance = CachedPropertyTest()
198- >>> instance.foo
199- 23
200- >>> is_cached(instance, '_foo_cache')
201- True
202- >>> is_cached(instance, '_var_cache')
203- False
204- """
205- naked_instance = removeSecurityProxy(instance)
206- return safe_hasattr(naked_instance, attrname)
207-
208-
209-class CachedPropertyForAttr:
210- """Curry a decorator to provide arguments to the CachedProperty."""
211-
212- def __init__(self, attrname):
213- self.attrname = attrname
214-
215- def __call__(self, fn):
216- return CachedProperty(self.attrname, fn)
217-
218-
219-class CachedProperty:
220-
221- # Used to detect not-yet-cached properties.
222- sentinel = object()
223-
224- def __init__(self, attrname, fn):
225- self.fn = fn
226- self.attrname = attrname
227-
228- def __get__(self, inst, cls=None):
229- if inst is None:
230- return self
231- cachedresult = getattr(inst, self.attrname, CachedProperty.sentinel)
232- if cachedresult is CachedProperty.sentinel:
233- result = self.fn(inst)
234- cache_property(inst, self.attrname, result)
235- return result
236- else:
237- return cachedresult
238-
239-
240-if __name__ == '__main__':
241- import doctest
242- doctest.testmod()
243
244=== modified file 'lib/canonical/database/sqlbase.py'
245--- lib/canonical/database/sqlbase.py 2010-09-02 12:57:52 +0000
246+++ lib/canonical/database/sqlbase.py 2010-09-02 12:57:56 +0000
247@@ -65,7 +65,6 @@
248 from zope.interface import implements
249 from zope.security.proxy import removeSecurityProxy
250
251-from canonical.cachedproperty import clear_cachedproperties
252 from canonical.config import (
253 config,
254 dbconfig,
255@@ -73,7 +72,6 @@
256 from canonical.database.interfaces import ISQLBase
257 from lp.services.propertycache import IPropertyCacheManager
258
259-
260 # Default we want for scripts, and the PostgreSQL default. Note psycopg1 will
261 # use SERIALIZABLE unless we override, but psycopg2 will not.
262 ISOLATION_LEVEL_DEFAULT = ISOLATION_LEVEL_READ_COMMITTED
263@@ -271,10 +269,6 @@
264 # XXX: RobertCollins 2010-08-16 bug=622648: Note this is not directly
265 # tested, but the entire test suite blows up awesomely if it's broken.
266 # It's entirely unclear where tests for this should be.
267-
268- # While canonical.cachedproperty and lp.services.propertycache are
269- # both in use, we must clear the caches for both.
270- clear_cachedproperties(self)
271 IPropertyCacheManager(self).clear()
272
273
274
275=== modified file 'lib/canonical/launchpad/browser/launchpad.py'
276--- lib/canonical/launchpad/browser/launchpad.py 2010-08-20 20:31:18 +0000
277+++ lib/canonical/launchpad/browser/launchpad.py 2010-09-02 12:57:56 +0000
278@@ -53,7 +53,6 @@
279 from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
280 from zope.security.interfaces import Unauthorized
281
282-from canonical.cachedproperty import cachedproperty
283 from canonical.config import config
284 from canonical.launchpad.helpers import intOrZero
285 from canonical.launchpad.interfaces.account import AccountStatus
286@@ -142,6 +141,7 @@
287 )
288 from lp.registry.interfaces.projectgroup import IProjectGroupSet
289 from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
290+from lp.services.propertycache import cachedproperty
291 from lp.services.worlddata.interfaces.country import ICountrySet
292 from lp.services.worlddata.interfaces.language import ILanguageSet
293 from lp.soyuz.interfaces.binarypackagename import IBinaryPackageNameSet
294
295=== modified file 'lib/canonical/launchpad/utilities/geoip.py'
296--- lib/canonical/launchpad/utilities/geoip.py 2010-08-20 20:31:18 +0000
297+++ lib/canonical/launchpad/utilities/geoip.py 2010-09-02 12:57:56 +0000
298@@ -15,7 +15,6 @@
299 from zope.i18n.interfaces import IUserPreferredLanguages
300 from zope.interface import implements
301
302-from canonical.cachedproperty import cachedproperty
303 from canonical.config import config
304 from canonical.launchpad.components.request_country import (
305 ipaddress_from_request,
306@@ -26,6 +25,7 @@
307 IRequestLocalLanguages,
308 IRequestPreferredLanguages,
309 )
310+from lp.services.propertycache import cachedproperty
311 from lp.services.worlddata.interfaces.country import ICountrySet
312 from lp.services.worlddata.interfaces.language import ILanguageSet
313
314
315=== modified file 'lib/canonical/launchpad/webapp/error.py'
316--- lib/canonical/launchpad/webapp/error.py 2010-08-23 21:58:28 +0000
317+++ lib/canonical/launchpad/webapp/error.py 2010-09-02 12:57:56 +0000
318@@ -22,7 +22,6 @@
319 from zope.exceptions.exceptionformatter import format_exception
320 from zope.interface import implements
321
322-from canonical.cachedproperty import cachedproperty
323 from canonical.config import config
324 import canonical.launchpad.layers
325 from canonical.launchpad.webapp.adapter import (
326@@ -31,6 +30,7 @@
327 )
328 from canonical.launchpad.webapp.interfaces import ILaunchBag
329 from canonical.launchpad.webapp.publisher import LaunchpadView
330+from lp.services.propertycache import cachedproperty
331
332
333 class SystemErrorView(LaunchpadView):
334
335=== modified file 'lib/canonical/launchpad/webapp/login.py'
336--- lib/canonical/launchpad/webapp/login.py 2010-08-20 20:31:18 +0000
337+++ lib/canonical/launchpad/webapp/login.py 2010-09-02 12:57:56 +0000
338@@ -42,7 +42,6 @@
339 ISession,
340 )
341
342-from canonical.cachedproperty import cachedproperty
343 from canonical.config import config
344 from canonical.launchpad import _
345 from canonical.launchpad.interfaces.account import AccountSuspendedError
346@@ -65,6 +64,7 @@
347 IPersonSet,
348 PersonCreationRationale,
349 )
350+from lp.services.propertycache import cachedproperty
351
352
353 class UnauthorizedView(SystemErrorView):
354
355=== modified file 'lib/canonical/launchpad/webapp/servers.py'
356--- lib/canonical/launchpad/webapp/servers.py 2010-08-27 16:01:05 +0000
357+++ lib/canonical/launchpad/webapp/servers.py 2010-09-02 12:57:56 +0000
358@@ -62,7 +62,6 @@
359 from zope.server.http.wsgihttpserver import PMDBWSGIHTTPServer
360 from zope.session.interfaces import ISession
361
362-from canonical.cachedproperty import cachedproperty
363 from canonical.config import config
364 from canonical.launchpad.interfaces.launchpad import (
365 IFeedsApplication,
366@@ -117,6 +116,7 @@
367 from canonical.lazr.timeout import set_default_timeout_function
368 from lp.app.errors import UnexpectedFormData
369 from lp.services.features.flags import NullFeatureController
370+from lp.services.propertycache import cachedproperty
371 from lp.testopenid.interfaces.server import ITestOpenIDApplication
372
373
374
375=== modified file 'lib/canonical/lazr/feed/feed.py'
376--- lib/canonical/lazr/feed/feed.py 2009-06-25 05:30:52 +0000
377+++ lib/canonical/lazr/feed/feed.py 2010-09-02 12:57:56 +0000
378@@ -17,32 +17,41 @@
379 'MINUTES',
380 ]
381
382-from BeautifulSoup import BeautifulSoup
383 from datetime import datetime
384-import pytz
385 import operator
386 import os
387 import time
388 from urlparse import urljoin
389 from xml.sax.saxutils import escape as xml_escape
390
391+from BeautifulSoup import BeautifulSoup
392+import pytz
393+from z3c.ptcompat import ViewPageTemplateFile
394+from zope.component import getUtility
395 from zope.datetime import rfc1123_date
396-from zope.component import getUtility
397 from zope.interface import implements
398
399-from z3c.ptcompat import ViewPageTemplateFile
400-
401-from canonical.cachedproperty import cachedproperty
402 from canonical.config import config
403 # XXX: bac 2007-09-20 bug=153795: modules in canonical.lazr should not import
404 # from canonical.launchpad, but we're doing it here as an expediency to get a
405 # working prototype.
406 from canonical.launchpad.interfaces import ILaunchpadRoot
407 from canonical.launchpad.webapp import (
408- LaunchpadView, canonical_url, urlappend, urlparse)
409+ canonical_url,
410+ LaunchpadView,
411+ urlappend,
412+ urlparse,
413+ )
414 from canonical.launchpad.webapp.vhosts import allvhosts
415 from canonical.lazr.interfaces import (
416- IFeed, IFeedEntry, IFeedPerson, IFeedTypedData, UnsupportedFeedFormat)
417+ IFeed,
418+ IFeedEntry,
419+ IFeedPerson,
420+ IFeedTypedData,
421+ UnsupportedFeedFormat,
422+ )
423+from lp.services.propertycache import cachedproperty
424+
425
426 SUPPORTED_FEEDS = ('.atom', '.html')
427 MINUTES = 60 # Seconds in a minute.
428
429=== removed file 'lib/canonical/tests/test_cachedproperty.py'
430--- lib/canonical/tests/test_cachedproperty.py 2010-07-14 14:11:15 +0000
431+++ lib/canonical/tests/test_cachedproperty.py 1970-01-01 00:00:00 +0000
432@@ -1,15 +0,0 @@
433-# Copyright 2009 Canonical Ltd. This software is licensed under the
434-# GNU Affero General Public License version 3 (see the file LICENSE).
435-
436-from doctest import DocTestSuite, ELLIPSIS
437-import unittest
438-
439-import canonical.cachedproperty
440-
441-def test_suite():
442- suite = DocTestSuite(canonical.cachedproperty, optionflags=ELLIPSIS)
443- return suite
444-
445-
446-if __name__ == '__main__':
447- unittest.main(defaultTest='test_suite')
448
449=== modified file 'lib/canonical/widgets/popup.py'
450--- lib/canonical/widgets/popup.py 2010-06-21 18:51:07 +0000
451+++ lib/canonical/widgets/popup.py 2010-09-02 12:57:56 +0000
452@@ -7,18 +7,19 @@
453
454 __metaclass__ = type
455
456+import cgi
457 import os
458-import cgi
459+
460 import simplejson
461-
462+from z3c.ptcompat import ViewPageTemplateFile
463+from zope.app.form.browser.itemswidgets import (
464+ ItemsWidgetBase,
465+ SingleDataHelper,
466+ )
467 from zope.schema.interfaces import IChoice
468-from zope.app.form.browser.itemswidgets import (
469- ItemsWidgetBase, SingleDataHelper)
470-
471-from z3c.ptcompat import ViewPageTemplateFile
472
473 from canonical.launchpad.webapp import canonical_url
474-from canonical.cachedproperty import cachedproperty
475+from lp.services.propertycache import cachedproperty
476
477
478 class VocabularyPickerWidget(SingleDataHelper, ItemsWidgetBase):
479
480=== modified file 'lib/lp/answers/browser/faqcollection.py'
481--- lib/lp/answers/browser/faqcollection.py 2010-08-20 20:31:18 +0000
482+++ lib/lp/answers/browser/faqcollection.py 2010-09-02 12:57:56 +0000
483@@ -12,7 +12,6 @@
484
485 from urllib import urlencode
486
487-from canonical.cachedproperty import cachedproperty
488 from canonical.launchpad import _
489 from canonical.launchpad.webapp import (
490 action,
491@@ -34,6 +33,7 @@
492 )
493 from lp.answers.interfaces.questionenums import QuestionSort
494 from lp.registry.interfaces.projectgroup import IProjectGroup
495+from lp.services.propertycache import cachedproperty
496
497
498 class FAQCollectionMenu(NavigationMenu):
499
500=== modified file 'lib/lp/answers/browser/question.py'
501--- lib/lp/answers/browser/question.py 2010-08-20 20:31:18 +0000
502+++ lib/lp/answers/browser/question.py 2010-09-02 12:57:56 +0000
503@@ -55,7 +55,6 @@
504 )
505 import zope.security
506
507-from canonical.cachedproperty import cachedproperty
508 from canonical.launchpad import _
509 from canonical.launchpad.helpers import (
510 is_english_variant,
511@@ -116,6 +115,7 @@
512 UnexpectedFormData,
513 )
514 from lp.registry.interfaces.projectgroup import IProjectGroup
515+from lp.services.propertycache import cachedproperty
516
517
518 class QuestionLinksMixin:
519
520=== modified file 'lib/lp/answers/browser/questiontarget.py'
521--- lib/lp/answers/browser/questiontarget.py 2010-08-26 17:45:46 +0000
522+++ lib/lp/answers/browser/questiontarget.py 2010-09-02 12:57:56 +0000
523@@ -28,8 +28,8 @@
524 from z3c.ptcompat import ViewPageTemplateFile
525 from zope.app.form.browser import DropdownWidget
526 from zope.component import (
527+ getMultiAdapter,
528 getUtility,
529- getMultiAdapter,
530 queryMultiAdapter,
531 )
532 from zope.formlib import form
533@@ -43,7 +43,6 @@
534 SimpleVocabulary,
535 )
536
537-from canonical.cachedproperty import cachedproperty
538 from canonical.launchpad import _
539 from canonical.launchpad.helpers import (
540 browserLanguages,
541@@ -67,7 +66,6 @@
542 from canonical.launchpad.webapp.breadcrumb import Breadcrumb
543 from canonical.launchpad.webapp.menu import structured
544 from canonical.widgets import LabeledMultiCheckBoxWidget
545-from lp.app.errors import NotFoundError
546 from lp.answers.browser.faqcollection import FAQCollectionMenu
547 from lp.answers.interfaces.faqcollection import IFAQCollection
548 from lp.answers.interfaces.questioncollection import (
549@@ -80,10 +78,12 @@
550 IQuestionTarget,
551 ISearchQuestionsForm,
552 )
553+from lp.app.errors import NotFoundError
554 from lp.registry.interfaces.distribution import IDistribution
555 from lp.registry.interfaces.product import IProduct
556 from lp.registry.interfaces.projectgroup import IProjectGroup
557 from lp.services.fields import PublicPersonChoice
558+from lp.services.propertycache import cachedproperty
559 from lp.services.worlddata.interfaces.language import ILanguageSet
560
561
562
563=== modified file 'lib/lp/answers/notification.py'
564--- lib/lp/answers/notification.py 2010-08-20 20:31:18 +0000
565+++ lib/lp/answers/notification.py 2010-09-02 12:57:56 +0000
566@@ -10,7 +10,6 @@
567
568 import os
569
570-from canonical.cachedproperty import cachedproperty
571 from canonical.config import config
572 from canonical.launchpad.mail import (
573 format_address,
574@@ -21,6 +20,7 @@
575 from lp.registry.interfaces.person import IPerson
576 from lp.services.mail.mailwrapper import MailWrapper
577 from lp.services.mail.notificationrecipientset import NotificationRecipientSet
578+from lp.services.propertycache import cachedproperty
579
580
581 def get_email_template(filename):
582
583=== modified file 'lib/lp/app/browser/root.py'
584--- lib/lp/app/browser/root.py 2010-08-20 20:31:18 +0000
585+++ lib/lp/app/browser/root.py 2010-09-02 12:57:56 +0000
586@@ -20,7 +20,6 @@
587 from zope.schema.interfaces import TooLong
588 from zope.schema.vocabulary import getVocabularyRegistry
589
590-from canonical.cachedproperty import cachedproperty
591 from canonical.config import config
592 from canonical.launchpad.interfaces.launchpad import (
593 ILaunchpadCelebrities,
594@@ -54,6 +53,7 @@
595 from lp.registry.interfaces.person import IPersonSet
596 from lp.registry.interfaces.pillar import IPillarNameSet
597 from lp.registry.interfaces.product import IProductSet
598+from lp.services.propertycache import cachedproperty
599
600
601 shipit_faq_url = 'http://www.ubuntu.com/getubuntu/shipit-faq'
602
603=== modified file 'lib/lp/archivepublisher/diskpool.py'
604--- lib/lp/archivepublisher/diskpool.py 2010-08-20 20:31:18 +0000
605+++ lib/lp/archivepublisher/diskpool.py 2010-09-02 12:57:56 +0000
606@@ -6,12 +6,12 @@
607 import os
608 import tempfile
609
610-from canonical.cachedproperty import cachedproperty
611 from canonical.librarian.utils import (
612 copy_and_close,
613 sha1_from_path,
614 )
615 from lp.archivepublisher import HARDCODED_COMPONENT_ORDER
616+from lp.services.propertycache import cachedproperty
617 from lp.soyuz.interfaces.publishing import (
618 MissingSymlinkInPool,
619 NotInPool,
620
621=== modified file 'lib/lp/blueprints/browser/specification.py'
622--- lib/lp/blueprints/browser/specification.py 2010-08-20 20:31:18 +0000
623+++ lib/lp/blueprints/browser/specification.py 2010-09-02 12:57:56 +0000
624@@ -61,7 +61,6 @@
625 SimpleVocabulary,
626 )
627
628-from canonical.cachedproperty import cachedproperty
629 from canonical.config import config
630 from canonical.launchpad import _
631 from canonical.launchpad.browser.launchpad import AppFrontPageSearchView
632@@ -100,6 +99,7 @@
633 from lp.code.interfaces.branchnamespace import IBranchNamespaceSet
634 from lp.registry.interfaces.distribution import IDistribution
635 from lp.registry.interfaces.product import IProduct
636+from lp.services.propertycache import cachedproperty
637
638
639 class NewSpecificationView(LaunchpadFormView):
640
641=== modified file 'lib/lp/blueprints/browser/specificationgoal.py'
642--- lib/lp/blueprints/browser/specificationgoal.py 2010-08-20 20:31:18 +0000
643+++ lib/lp/blueprints/browser/specificationgoal.py 2010-09-02 12:57:56 +0000
644@@ -12,7 +12,6 @@
645
646 from zope.component import getUtility
647
648-from canonical.cachedproperty import cachedproperty
649 from canonical.launchpad.webapp import (
650 canonical_url,
651 LaunchpadView,
652@@ -20,6 +19,7 @@
653 from canonical.launchpad.webapp.interfaces import ILaunchBag
654 from lp.blueprints.browser.specificationtarget import HasSpecificationsView
655 from lp.blueprints.interfaces.specification import SpecificationFilter
656+from lp.services.propertycache import cachedproperty
657
658
659 class GoalDecideView(HasSpecificationsView, LaunchpadView):
660
661=== modified file 'lib/lp/blueprints/browser/specificationtarget.py'
662--- lib/lp/blueprints/browser/specificationtarget.py 2010-08-20 20:31:18 +0000
663+++ lib/lp/blueprints/browser/specificationtarget.py 2010-09-02 12:57:56 +0000
664@@ -17,7 +17,6 @@
665
666 from zope.component import queryMultiAdapter
667
668-from canonical.cachedproperty import cachedproperty
669 from canonical.config import config
670 from canonical.launchpad import _
671 from canonical.launchpad.helpers import shortlist
672@@ -48,6 +47,7 @@
673 IProjectGroup,
674 IProjectGroupSeries,
675 )
676+from lp.services.propertycache import cachedproperty
677
678
679 class HasSpecificationsMenuMixin:
680
681=== modified file 'lib/lp/blueprints/browser/sprint.py'
682--- lib/lp/blueprints/browser/sprint.py 2010-08-20 20:31:18 +0000
683+++ lib/lp/blueprints/browser/sprint.py 2010-09-02 12:57:56 +0000
684@@ -30,7 +30,6 @@
685 from zope.component import getUtility
686 from zope.interface import implements
687
688-from canonical.cachedproperty import cachedproperty
689 from canonical.launchpad import _
690 from canonical.launchpad.helpers import shortlist
691 from canonical.launchpad.webapp import (
692@@ -71,6 +70,7 @@
693 IRegistryCollectionNavigationMenu,
694 RegistryCollectionActionMenuBase,
695 )
696+from lp.services.propertycache import cachedproperty
697
698
699 class SprintFacets(StandardLaunchpadFacets):
700
701=== modified file 'lib/lp/bugs/browser/bug.py'
702--- lib/lp/bugs/browser/bug.py 2010-08-27 05:34:32 +0000
703+++ lib/lp/bugs/browser/bug.py 2010-09-02 12:57:56 +0000
704@@ -63,7 +63,6 @@
705 from zope.schema.interfaces import IText
706 from zope.security.interfaces import Unauthorized
707
708-from canonical.cachedproperty import cachedproperty
709 from canonical.launchpad import _
710 from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
711 from canonical.launchpad.mailnotification import MailWrapper
712@@ -115,6 +114,7 @@
713 from lp.bugs.interfaces.cve import ICveSet
714 from lp.bugs.mail.bugnotificationbuilder import format_rfc2822_date
715 from lp.services.fields import DuplicateBug
716+from lp.services.propertycache import cachedproperty
717
718
719 class BugNavigation(Navigation):
720
721=== modified file 'lib/lp/bugs/browser/bugalsoaffects.py'
722--- lib/lp/bugs/browser/bugalsoaffects.py 2010-08-20 20:31:18 +0000
723+++ lib/lp/bugs/browser/bugalsoaffects.py 2010-09-02 12:57:56 +0000
724@@ -29,7 +29,6 @@
725 SimpleVocabulary,
726 )
727
728-from canonical.cachedproperty import cachedproperty
729 from canonical.launchpad import _
730 from canonical.launchpad.browser.multistep import (
731 MultiStepView,
732@@ -85,6 +84,7 @@
733 License,
734 )
735 from lp.services.fields import StrippedTextLine
736+from lp.services.propertycache import cachedproperty
737
738
739 class BugAlsoAffectsProductMetaView(MultiStepView):
740
741=== modified file 'lib/lp/bugs/browser/bugbranch.py'
742--- lib/lp/bugs/browser/bugbranch.py 2010-08-20 20:31:18 +0000
743+++ lib/lp/bugs/browser/bugbranch.py 2010-09-02 12:57:56 +0000
744@@ -22,7 +22,6 @@
745 Interface,
746 )
747
748-from canonical.cachedproperty import cachedproperty
749 from canonical.launchpad import _
750 from canonical.launchpad.webapp import (
751 action,
752@@ -38,6 +37,7 @@
753 latest_proposals_for_each_branch,
754 )
755 from lp.code.enums import BranchLifecycleStatus
756+from lp.services.propertycache import cachedproperty
757
758
759 class BugBranchPrimaryContext:
760
761=== modified file 'lib/lp/bugs/browser/bugtarget.py'
762--- lib/lp/bugs/browser/bugtarget.py 2010-08-22 18:31:30 +0000
763+++ lib/lp/bugs/browser/bugtarget.py 2010-09-02 12:57:56 +0000
764@@ -50,7 +50,6 @@
765 from zope.schema.vocabulary import SimpleVocabulary
766 from zope.security.proxy import removeSecurityProxy
767
768-from canonical.cachedproperty import cachedproperty
769 from canonical.config import config
770 from canonical.launchpad import _
771 from canonical.launchpad.browser.feeds import (
772@@ -137,6 +136,7 @@
773 from lp.registry.interfaces.sourcepackage import ISourcePackage
774 from lp.registry.vocabularies import ValidPersonOrTeamVocabulary
775 from lp.services.job.interfaces.job import JobStatus
776+from lp.services.propertycache import cachedproperty
777
778 # A simple vocabulary for the subscribe_to_existing_bug form field.
779 SUBSCRIBE_TO_BUG_VOCABULARY = SimpleVocabulary.fromItems(
780
781=== modified file 'lib/lp/bugs/browser/bugtask.py'
782--- lib/lp/bugs/browser/bugtask.py 2010-08-31 18:15:15 +0000
783+++ lib/lp/bugs/browser/bugtask.py 2010-09-02 12:57:56 +0000
784@@ -125,7 +125,6 @@
785 )
786 from zope.traversing.interfaces import IPathAdapter
787
788-from canonical.cachedproperty import cachedproperty
789 from canonical.config import config
790 from canonical.database.sqlbase import cursor
791 from canonical.launchpad import (
792@@ -260,6 +259,7 @@
793 from lp.registry.interfaces.sourcepackage import ISourcePackage
794 from lp.registry.vocabularies import MilestoneVocabulary
795 from lp.services.fields import PersonChoice
796+from lp.services.propertycache import cachedproperty
797
798
799 @component.adapter(IBugTask, IReferenceChoice, IWebServiceClientRequest)
800
801=== modified file 'lib/lp/bugs/browser/bugtracker.py'
802--- lib/lp/bugs/browser/bugtracker.py 2010-08-26 12:33:03 +0000
803+++ lib/lp/bugs/browser/bugtracker.py 2010-09-02 12:57:56 +0000
804@@ -29,7 +29,6 @@
805 from zope.schema.vocabulary import SimpleVocabulary
806 from zope.security.interfaces import Unauthorized
807
808-from canonical.cachedproperty import cachedproperty
809 from canonical.database.sqlbase import flush_database_updates
810 from canonical.launchpad import _
811 from canonical.launchpad.helpers import (
812@@ -69,6 +68,7 @@
813 IBugTrackerSet,
814 IRemoteBug,
815 )
816+from lp.services.propertycache import cachedproperty
817
818 # A set of bug tracker types for which there can only ever be one bug
819 # tracker.
820
821=== modified file 'lib/lp/bugs/browser/cvereport.py'
822--- lib/lp/bugs/browser/cvereport.py 2010-08-20 20:31:18 +0000
823+++ lib/lp/bugs/browser/cvereport.py 2010-09-02 12:57:56 +0000
824@@ -11,7 +11,6 @@
825
826 from zope.component import getUtility
827
828-from canonical.cachedproperty import cachedproperty
829 from canonical.launchpad.helpers import shortlist
830 from canonical.launchpad.searchbuilder import any
831 from canonical.launchpad.webapp import LaunchpadView
832@@ -23,6 +22,7 @@
833 UNRESOLVED_BUGTASK_STATUSES,
834 )
835 from lp.bugs.interfaces.cve import ICveSet
836+from lp.services.propertycache import cachedproperty
837
838
839 class BugTaskCve:
840
841=== modified file 'lib/lp/bugs/browser/distribution_upstream_bug_report.py'
842--- lib/lp/bugs/browser/distribution_upstream_bug_report.py 2010-08-20 20:31:18 +0000
843+++ lib/lp/bugs/browser/distribution_upstream_bug_report.py 2010-09-02 12:57:56 +0000
844@@ -11,13 +11,13 @@
845
846 from operator import attrgetter
847
848-from canonical.cachedproperty import cachedproperty
849 from canonical.launchpad.webapp.publisher import (
850 canonical_url,
851 LaunchpadView,
852 )
853 from canonical.launchpad.webapp.url import urlappend
854 from lp.bugs.browser.bugtask import get_buglisting_search_filter_url
855+from lp.services.propertycache import cachedproperty
856
857 # TODO: fix column sorting to work for the different colspans, or
858 # alternatively implement a sort option box.
859
860=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt'
861--- lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-04-21 10:30:24 +0000
862+++ lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-09-02 12:57:56 +0000
863@@ -121,8 +121,10 @@
864 Instead of issuing one request per bug watch, like was done before,
865 updateBugWatches() issues only one request to update all watches:
866
867+ >>> from lp.services.propertycache import IPropertyCache
868+ >>> del IPropertyCache(example_ext_bug_tracker).csv_data
869+
870 >>> example_ext_bug_tracker.trace_calls = True
871- >>> example_ext_bug_tracker.cleanCache()
872 >>> bug_watch_updater.updateBugWatches(
873 ... example_ext_bug_tracker, example_bug_tracker.watches)
874 INFO:...:Updating 6 watches for 6 bugs on http://bugs.some.where
875
876=== modified file 'lib/lp/bugs/externalbugtracker/mantis.py'
877--- lib/lp/bugs/externalbugtracker/mantis.py 2010-08-20 20:31:18 +0000
878+++ lib/lp/bugs/externalbugtracker/mantis.py 2010-09-02 12:57:56 +0000
879@@ -18,7 +18,6 @@
880 SoupStrainer,
881 )
882
883-from canonical.cachedproperty import cachedproperty
884 from canonical.launchpad.webapp.url import urlparse
885 from lp.bugs.externalbugtracker import (
886 BugNotFound,
887@@ -37,6 +36,7 @@
888 BugTaskStatus,
889 )
890 from lp.bugs.interfaces.externalbugtracker import UNKNOWN_REMOTE_IMPORTANCE
891+from lp.services.propertycache import cachedproperty
892
893
894 class MantisLoginHandler(urllib2.HTTPRedirectHandler):
895
896=== modified file 'lib/lp/bugs/externalbugtracker/rt.py'
897--- lib/lp/bugs/externalbugtracker/rt.py 2010-08-20 20:31:18 +0000
898+++ lib/lp/bugs/externalbugtracker/rt.py 2010-09-02 12:57:56 +0000
899@@ -10,7 +10,6 @@
900 import urllib
901 import urllib2
902
903-from canonical.cachedproperty import cachedproperty
904 from canonical.config import config
905 from canonical.launchpad.webapp.url import urlparse
906 from lp.bugs.externalbugtracker import (
907@@ -24,6 +23,7 @@
908 from lp.bugs.externalbugtracker.isolation import ensure_no_transaction
909 from lp.bugs.interfaces.bugtask import BugTaskStatus
910 from lp.bugs.interfaces.externalbugtracker import UNKNOWN_REMOTE_IMPORTANCE
911+from lp.services.propertycache import cachedproperty
912
913
914 class RequestTracker(ExternalBugTracker):
915
916=== modified file 'lib/lp/bugs/model/bug.py'
917--- lib/lp/bugs/model/bug.py 2010-08-31 23:22:19 +0000
918+++ lib/lp/bugs/model/bug.py 2010-09-02 12:57:56 +0000
919@@ -70,11 +70,6 @@
920 providedBy,
921 )
922
923-from canonical.cachedproperty import (
924- cachedproperty,
925- cache_property,
926- clear_property,
927- )
928 from canonical.config import config
929 from canonical.database.constants import UTC_NOW
930 from canonical.database.datetimecol import UtcDateTimeCol
931@@ -83,7 +78,9 @@
932 SQLBase,
933 sqlvalues,
934 )
935-from canonical.launchpad.components.decoratedresultset import DecoratedResultSet
936+from canonical.launchpad.components.decoratedresultset import (
937+ DecoratedResultSet,
938+ )
939 from canonical.launchpad.database.librarian import LibraryFileAlias
940 from canonical.launchpad.database.message import (
941 Message,
942@@ -189,6 +186,10 @@
943 from lp.registry.model.pillar import pillar_sort_key
944 from lp.registry.model.teammembership import TeamParticipation
945 from lp.services.fields import DuplicateBug
946+from lp.services.propertycache import (
947+ cachedproperty,
948+ IPropertyCache,
949+ )
950
951
952 _bug_tag_query_template = """
953@@ -636,7 +637,7 @@
954 # disabled see the change.
955 store.flush()
956 self.updateHeat()
957- clear_property(self, '_cached_viewers')
958+ del IPropertyCache(self)._known_viewers
959 return
960
961 def unsubscribeFromDupes(self, person, unsubscribed_by):
962@@ -1658,7 +1659,7 @@
963 self, self.messages[comment_number])
964 bug_message.visible = visible
965
966- @cachedproperty('_cached_viewers')
967+ @cachedproperty
968 def _known_viewers(self):
969 """A dict of of known persons able to view this bug."""
970 return set()
971@@ -1775,7 +1776,7 @@
972 @property
973 def attachments(self):
974 """See `IBug`.
975-
976+
977 This property does eager loading of the index_messages so that the API
978 which wants the message_link for the attachment can answer that without
979 O(N^2) overhead. As such it is moderately expensive to call (it
980@@ -1791,7 +1792,7 @@
981 # will be found without a query when dereferenced.
982 indexed_message = message_to_indexed.get(attachment._messageID)
983 if indexed_message is not None:
984- cache_property(attachment, '_message_cached', indexed_message)
985+ IPropertyCache(attachment).message = indexed_message
986 return attachment
987 rawresults = self._attachments_query()
988 return DecoratedResultSet(rawresults, set_indexed_message)
989@@ -1799,9 +1800,9 @@
990 @property
991 def attachments_unpopulated(self):
992 """See `IBug`.
993-
994+
995 This version does not pre-lookup messages and LibraryFileAliases.
996-
997+
998 The regular 'attachments' property does prepopulation because it is
999 exposed in the API.
1000 """
1001
1002=== modified file 'lib/lp/bugs/model/bugattachment.py'
1003--- lib/lp/bugs/model/bugattachment.py 2010-08-29 22:26:36 +0000
1004+++ lib/lp/bugs/model/bugattachment.py 2010-09-02 12:57:56 +0000
1005@@ -19,7 +19,6 @@
1006 from zope.event import notify
1007 from zope.interface import implements
1008
1009-from canonical.cachedproperty import cachedproperty
1010 from canonical.database.enumcol import EnumCol
1011 from canonical.database.sqlbase import SQLBase
1012 from lp.app.errors import NotFoundError
1013@@ -28,6 +27,7 @@
1014 IBugAttachment,
1015 IBugAttachmentSet,
1016 )
1017+from lp.services.propertycache import cachedproperty
1018
1019
1020 class BugAttachment(SQLBase):
1021@@ -50,10 +50,10 @@
1022 _message = ForeignKey(
1023 foreignKey='Message', dbName='message', notNull=True)
1024
1025- @cachedproperty('_message_cached')
1026+ @cachedproperty
1027 def message(self):
1028 """This is a cachedproperty to allow message to be an IIndexedMessage.
1029-
1030+
1031 This is needed for the bug/attachments API call which needs to index
1032 an IIndexedMessage rather than a simple DB model IMessage. See
1033 Bug.attachments where the injection occurs.
1034
1035=== modified file 'lib/lp/bugs/model/bugtask.py'
1036--- lib/lp/bugs/model/bugtask.py 2010-08-30 19:30:45 +0000
1037+++ lib/lp/bugs/model/bugtask.py 2010-09-02 12:57:56 +0000
1038@@ -58,7 +58,6 @@
1039 removeSecurityProxy,
1040 )
1041
1042-from canonical.cachedproperty import cache_property
1043 from canonical.config import config
1044 from canonical.database.constants import UTC_NOW
1045 from canonical.database.datetimecol import UtcDateTimeCol
1046@@ -153,6 +152,7 @@
1047 from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
1048 from lp.registry.model.pillar import pillar_sort_key
1049 from lp.registry.model.sourcepackagename import SourcePackageName
1050+from lp.services.propertycache import IPropertyCache
1051 from lp.soyuz.enums import PackagePublishingStatus
1052 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
1053 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
1054@@ -1338,7 +1338,7 @@
1055 """
1056 userid = user.id
1057 def cache_user_can_view_bug(bugtask):
1058- cache_property(bugtask.bug, '_cached_viewers', set([userid]))
1059+ IPropertyCache(bugtask.bug)._known_viewers = set([userid])
1060 return bugtask
1061 return cache_user_can_view_bug
1062
1063
1064=== modified file 'lib/lp/bugs/tests/externalbugtracker.py'
1065--- lib/lp/bugs/tests/externalbugtracker.py 2010-08-21 07:31:45 +0000
1066+++ lib/lp/bugs/tests/externalbugtracker.py 2010-09-02 12:57:56 +0000
1067@@ -1102,14 +1102,6 @@
1068 print "CALLED _postPage(%r, ...)" % (page)
1069 return ''
1070
1071- def cleanCache(self):
1072- """Clean the csv_data cache."""
1073- # Remove the self._csv_data_cached_value if it exists.
1074- try:
1075- del self._csv_data_cached_value
1076- except AttributeError:
1077- pass
1078-
1079
1080 class TestTrac(Trac):
1081 """Trac ExternalBugTracker for testing purposes.
1082
1083=== modified file 'lib/lp/buildmaster/model/builder.py'
1084--- lib/lp/buildmaster/model/builder.py 2010-08-23 10:38:44 +0000
1085+++ lib/lp/buildmaster/model/builder.py 2010-09-02 12:57:56 +0000
1086@@ -38,7 +38,6 @@
1087 from zope.interface import implements
1088
1089 from canonical.buildd.slave import BuilderStatus
1090-from canonical.cachedproperty import cachedproperty
1091 from canonical.config import config
1092 from canonical.database.sqlbase import (
1093 SQLBase,
1094@@ -80,6 +79,7 @@
1095 from lp.services.job.interfaces.job import JobStatus
1096 from lp.services.job.model.job import Job
1097 from lp.services.osutils import until_no_eintr
1098+from lp.services.propertycache import cachedproperty
1099 # XXX Michael Nelson 2010-01-13 bug=491330
1100 # These dependencies on soyuz will be removed when getBuildRecords()
1101 # is moved.
1102
1103=== modified file 'lib/lp/code/browser/bazaar.py'
1104--- lib/lp/code/browser/bazaar.py 2010-08-31 01:11:34 +0000
1105+++ lib/lp/code/browser/bazaar.py 2010-09-02 12:57:56 +0000
1106@@ -15,7 +15,6 @@
1107 import bzrlib
1108 from zope.component import getUtility
1109
1110-from canonical.cachedproperty import cachedproperty
1111 from canonical.config import config
1112 from canonical.launchpad.webapp import (
1113 canonical_url,
1114@@ -32,6 +31,7 @@
1115 from lp.code.interfaces.branchcollection import IAllBranches
1116 from lp.code.interfaces.codeimport import ICodeImportSet
1117 from lp.registry.interfaces.product import IProductSet
1118+from lp.services.propertycache import cachedproperty
1119
1120
1121 class BazaarApplicationView(LaunchpadView):
1122
1123=== modified file 'lib/lp/code/browser/branch.py'
1124--- lib/lp/code/browser/branch.py 2010-08-20 20:31:18 +0000
1125+++ lib/lp/code/browser/branch.py 2010-09-02 12:57:56 +0000
1126@@ -72,7 +72,6 @@
1127 )
1128 from zope.traversing.interfaces import IPathAdapter
1129
1130-from canonical.cachedproperty import cachedproperty
1131 from canonical.config import config
1132 from canonical.database.constants import UTC_NOW
1133 from canonical.launchpad import _
1134@@ -145,6 +144,7 @@
1135 )
1136 from lp.registry.interfaces.productseries import IProductSeries
1137 from lp.registry.vocabularies import UserTeamsParticipationPlusSelfVocabulary
1138+from lp.services.propertycache import cachedproperty
1139
1140
1141 def quote(text):
1142
1143=== modified file 'lib/lp/code/browser/branchlisting.py'
1144--- lib/lp/code/browser/branchlisting.py 2010-08-23 04:48:17 +0000
1145+++ lib/lp/code/browser/branchlisting.py 2010-09-02 12:57:56 +0000
1146@@ -52,7 +52,6 @@
1147 )
1148 from zope.schema import Choice
1149
1150-from canonical.cachedproperty import cachedproperty
1151 from canonical.config import config
1152 from canonical.launchpad import _
1153 from canonical.launchpad.browser.feeds import (
1154@@ -131,6 +130,7 @@
1155 from lp.registry.interfaces.sourcepackage import ISourcePackageFactory
1156 from lp.registry.model.sourcepackage import SourcePackage
1157 from lp.services.browser_helpers import get_plural_text
1158+from lp.services.propertycache import cachedproperty
1159
1160
1161 class CodeVHostBreadcrumb(Breadcrumb):
1162
1163=== modified file 'lib/lp/code/browser/branchmergeproposal.py'
1164--- lib/lp/code/browser/branchmergeproposal.py 2010-08-20 20:31:18 +0000
1165+++ lib/lp/code/browser/branchmergeproposal.py 2010-09-02 12:57:56 +0000
1166@@ -68,7 +68,6 @@
1167 SimpleVocabulary,
1168 )
1169
1170-from canonical.cachedproperty import cachedproperty
1171 from canonical.config import config
1172 from canonical.launchpad import _
1173 from canonical.launchpad.interfaces.message import IMessageSet
1174@@ -122,6 +121,7 @@
1175 Summary,
1176 Whiteboard,
1177 )
1178+from lp.services.propertycache import cachedproperty
1179
1180
1181 def latest_proposals_for_each_branch(proposals):
1182
1183=== modified file 'lib/lp/code/browser/branchmergeproposallisting.py'
1184--- lib/lp/code/browser/branchmergeproposallisting.py 2010-08-20 20:31:18 +0000
1185+++ lib/lp/code/browser/branchmergeproposallisting.py 2010-09-02 12:57:56 +0000
1186@@ -29,7 +29,6 @@
1187 )
1188 from zope.schema import Choice
1189
1190-from canonical.cachedproperty import cachedproperty
1191 from canonical.config import config
1192 from canonical.launchpad import _
1193 from canonical.launchpad.webapp import (
1194@@ -53,6 +52,7 @@
1195 IBranchMergeProposalListingBatchNavigator,
1196 )
1197 from lp.code.interfaces.hasbranches import IHasMergeProposals
1198+from lp.services.propertycache import cachedproperty
1199
1200
1201 class BranchMergeProposalListingItem:
1202
1203=== modified file 'lib/lp/code/browser/branchvisibilitypolicy.py'
1204--- lib/lp/code/browser/branchvisibilitypolicy.py 2010-08-23 03:30:54 +0000
1205+++ lib/lp/code/browser/branchvisibilitypolicy.py 2010-09-02 12:57:56 +0000
1206@@ -22,7 +22,6 @@
1207 SimpleVocabulary,
1208 )
1209
1210-from canonical.cachedproperty import cachedproperty
1211 from canonical.launchpad import _
1212 from canonical.launchpad.webapp import (
1213 action,
1214@@ -42,6 +41,7 @@
1215 from lp.code.interfaces.branchvisibilitypolicy import (
1216 IBranchVisibilityTeamPolicy,
1217 )
1218+from lp.services.propertycache import cachedproperty
1219
1220
1221 class BaseBranchVisibilityTeamPolicyView(LaunchpadFormView):
1222
1223=== modified file 'lib/lp/code/browser/codeimport.py'
1224--- lib/lp/code/browser/codeimport.py 2010-08-20 20:31:18 +0000
1225+++ lib/lp/code/browser/codeimport.py 2010-09-02 12:57:56 +0000
1226@@ -29,7 +29,6 @@
1227 from zope.interface import Interface
1228 from zope.schema import Choice
1229
1230-from canonical.cachedproperty import cachedproperty
1231 from canonical.launchpad import _
1232 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
1233 from canonical.launchpad.webapp import (
1234@@ -75,6 +74,7 @@
1235 from lp.code.interfaces.codeimportmachine import ICodeImportMachineSet
1236 from lp.registry.interfaces.product import IProduct
1237 from lp.services.fields import URIField
1238+from lp.services.propertycache import cachedproperty
1239
1240
1241 class CodeImportSetNavigation(Navigation):
1242
1243=== modified file 'lib/lp/code/browser/codeimportmachine.py'
1244--- lib/lp/code/browser/codeimportmachine.py 2010-08-20 20:31:18 +0000
1245+++ lib/lp/code/browser/codeimportmachine.py 2010-09-02 12:57:56 +0000
1246@@ -19,7 +19,6 @@
1247 from zope.interface import Interface
1248 from zope.schema import TextLine
1249
1250-from canonical.cachedproperty import cachedproperty
1251 from canonical.launchpad import _
1252 from canonical.launchpad.webapp import (
1253 action,
1254@@ -35,6 +34,7 @@
1255 )
1256 from lp.code.interfaces.codeimportevent import ICodeImportEvent
1257 from lp.code.interfaces.codeimportmachine import ICodeImportMachineSet
1258+from lp.services.propertycache import cachedproperty
1259
1260
1261 class CodeImportMachineBreadcrumb(Breadcrumb):
1262
1263=== modified file 'lib/lp/code/browser/codereviewcomment.py'
1264--- lib/lp/code/browser/codereviewcomment.py 2010-08-20 20:31:18 +0000
1265+++ lib/lp/code/browser/codereviewcomment.py 2010-09-02 12:57:56 +0000
1266@@ -24,7 +24,6 @@
1267 )
1268 from zope.schema import Text
1269
1270-from canonical.cachedproperty import cachedproperty
1271 from canonical.config import config
1272 from canonical.launchpad import _
1273 from canonical.launchpad.interfaces import ILibraryFileAlias
1274@@ -41,6 +40,7 @@
1275 from lp.code.interfaces.codereviewcomment import ICodeReviewComment
1276 from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference
1277 from lp.services.comments.interfaces.conversation import IComment
1278+from lp.services.propertycache import cachedproperty
1279
1280
1281 class CodeReviewDisplayComment:
1282
1283=== modified file 'lib/lp/code/browser/decorations.py'
1284--- lib/lp/code/browser/decorations.py 2010-08-20 20:31:18 +0000
1285+++ lib/lp/code/browser/decorations.py 2010-09-02 12:57:56 +0000
1286@@ -14,13 +14,13 @@
1287
1288 from lazr.delegates import delegates
1289
1290-from canonical.cachedproperty import cachedproperty
1291 from canonical.launchpad.webapp.authorization import check_permission
1292 from lp.bugs.interfaces.bug import IBug
1293 from lp.code.interfaces.branch import (
1294 BzrIdentityMixin,
1295 IBranch,
1296 )
1297+from lp.services.propertycache import cachedproperty
1298
1299
1300 class DecoratedBug:
1301
1302=== modified file 'lib/lp/code/browser/summary.py'
1303--- lib/lp/code/browser/summary.py 2010-08-20 20:31:18 +0000
1304+++ lib/lp/code/browser/summary.py 2010-09-02 12:57:56 +0000
1305@@ -9,13 +9,13 @@
1306 ]
1307
1308
1309-from canonical.cachedproperty import cachedproperty
1310 from canonical.launchpad import _
1311 from canonical.launchpad.webapp.publisher import LaunchpadView
1312 from lp.code.interfaces.branch import DEFAULT_BRANCH_STATUS_IN_LISTING
1313 from lp.code.interfaces.branchcollection import IBranchCollection
1314 from lp.code.interfaces.revisioncache import IRevisionCache
1315 from lp.services.browser_helpers import get_plural_text
1316+from lp.services.propertycache import cachedproperty
1317
1318
1319 class BranchCountSummaryView(LaunchpadView):
1320
1321=== modified file 'lib/lp/code/feed/branch.py'
1322--- lib/lp/code/feed/branch.py 2010-08-20 20:31:18 +0000
1323+++ lib/lp/code/feed/branch.py 2010-09-02 12:57:56 +0000
1324@@ -24,7 +24,6 @@
1325 from zope.interface import implements
1326 from zope.security.interfaces import Unauthorized
1327
1328-from canonical.cachedproperty import cachedproperty
1329 from canonical.config import config
1330 from canonical.launchpad.webapp import (
1331 canonical_url,
1332@@ -49,6 +48,7 @@
1333 from lp.registry.interfaces.person import IPerson
1334 from lp.registry.interfaces.product import IProduct
1335 from lp.registry.interfaces.projectgroup import IProjectGroup
1336+from lp.services.propertycache import cachedproperty
1337
1338
1339 def revision_feed_id(revision):
1340
1341=== modified file 'lib/lp/code/model/branchvisibilitypolicy.py'
1342--- lib/lp/code/model/branchvisibilitypolicy.py 2010-08-20 20:31:18 +0000
1343+++ lib/lp/code/model/branchvisibilitypolicy.py 2010-09-02 12:57:56 +0000
1344@@ -15,7 +15,6 @@
1345 from sqlobject import ForeignKey
1346 from zope.interface import implements
1347
1348-from canonical.cachedproperty import cachedproperty
1349 from canonical.database.enumcol import EnumCol
1350 from canonical.database.sqlbase import SQLBase
1351 from canonical.launchpad.helpers import shortlist
1352@@ -27,6 +26,7 @@
1353 from lp.registry.interfaces.person import validate_person
1354 from lp.registry.interfaces.product import IProduct
1355 from lp.registry.interfaces.projectgroup import IProjectGroup
1356+from lp.services.propertycache import cachedproperty
1357
1358
1359 class BranchVisibilityTeamPolicy(SQLBase):
1360
1361=== modified file 'lib/lp/codehosting/codeimport/worker.py'
1362--- lib/lp/codehosting/codeimport/worker.py 2010-08-20 20:31:18 +0000
1363+++ lib/lp/codehosting/codeimport/worker.py 2010-09-02 12:57:56 +0000
1364@@ -45,7 +45,6 @@
1365 import CVS
1366 import SCM
1367
1368-from canonical.cachedproperty import cachedproperty
1369 from canonical.config import config
1370 from lp.code.enums import RevisionControlSystems
1371 from lp.codehosting.codeimport.foreigntree import (
1372@@ -57,6 +56,7 @@
1373 extract_tarball,
1374 )
1375 from lp.codehosting.codeimport.uifactory import LoggingUIFactory
1376+from lp.services.propertycache import cachedproperty
1377
1378
1379 class CodeImportWorkerExitCode:
1380
1381=== modified file 'lib/lp/codehosting/puller/scheduler.py'
1382--- lib/lp/codehosting/puller/scheduler.py 2010-08-20 20:31:18 +0000
1383+++ lib/lp/codehosting/puller/scheduler.py 2010-09-02 12:57:56 +0000
1384@@ -34,12 +34,12 @@
1385 log,
1386 )
1387
1388-from canonical.cachedproperty import cachedproperty
1389 from canonical.config import config
1390 from canonical.launchpad.webapp import errorlog
1391 from lp.code.interfaces.codehosting import LAUNCHPAD_SERVICES
1392 from lp.codehosting.puller import get_lock_id_for_branch_id
1393 from lp.codehosting.puller.worker import get_canonical_url_for_branch_name
1394+from lp.services.propertycache import cachedproperty
1395 from lp.services.twistedsupport.processmonitor import (
1396 ProcessMonitorProtocolWithTimeout,
1397 )
1398
1399=== modified file 'lib/lp/hardwaredb/scripts/hwdbsubmissions.py'
1400--- lib/lp/hardwaredb/scripts/hwdbsubmissions.py 2010-08-20 20:31:18 +0000
1401+++ lib/lp/hardwaredb/scripts/hwdbsubmissions.py 2010-09-02 12:57:56 +0000
1402@@ -35,7 +35,7 @@
1403
1404 from canonical.lazr.xml import RelaxNGValidator
1405
1406-from canonical.cachedproperty import cachedproperty
1407+from lp.services.propertycache import cachedproperty
1408 from canonical.config import config
1409 from canonical.librarian.interfaces import LibrarianServerError
1410 from lp.hardwaredb.interfaces.hwdb import (
1411
1412=== modified file 'lib/lp/registry/browser/__init__.py'
1413--- lib/lp/registry/browser/__init__.py 2010-08-27 22:33:36 +0000
1414+++ lib/lp/registry/browser/__init__.py 2010-09-02 12:57:56 +0000
1415@@ -20,7 +20,6 @@
1416 from storm.store import Store
1417 from zope.component import getUtility
1418
1419-from canonical.cachedproperty import cachedproperty
1420 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
1421 from canonical.launchpad.webapp.launchpadform import (
1422 action,
1423@@ -33,6 +32,7 @@
1424 )
1425 from lp.registry.interfaces.productseries import IProductSeries
1426 from lp.registry.interfaces.series import SeriesStatus
1427+from lp.services.propertycache import cachedproperty
1428
1429
1430 class StatusCount:
1431
1432=== modified file 'lib/lp/registry/browser/announcement.py'
1433--- lib/lp/registry/browser/announcement.py 2010-08-20 20:31:18 +0000
1434+++ lib/lp/registry/browser/announcement.py 2010-09-02 12:57:56 +0000
1435@@ -26,7 +26,6 @@
1436 TextLine,
1437 )
1438
1439-from canonical.cachedproperty import cachedproperty
1440 from canonical.config import config
1441 from canonical.launchpad import _
1442 from canonical.launchpad.browser.feeds import (
1443@@ -58,6 +57,7 @@
1444 Summary,
1445 Title,
1446 )
1447+from lp.services.propertycache import cachedproperty
1448
1449
1450 class AnnouncementMenuMixin:
1451
1452=== modified file 'lib/lp/registry/browser/distribution.py'
1453--- lib/lp/registry/browser/distribution.py 2010-08-27 19:19:27 +0000
1454+++ lib/lp/registry/browser/distribution.py 2010-09-02 12:57:56 +0000
1455@@ -44,7 +44,6 @@
1456 from zope.lifecycleevent import ObjectCreatedEvent
1457 from zope.security.interfaces import Unauthorized
1458
1459-from canonical.cachedproperty import cachedproperty
1460 from canonical.launchpad.browser.feeds import FeedsMixin
1461 from canonical.launchpad.components.decoratedresultset import (
1462 DecoratedResultSet,
1463@@ -109,11 +108,10 @@
1464 )
1465 from lp.registry.interfaces.product import IProduct
1466 from lp.registry.interfaces.series import SeriesStatus
1467+from lp.services.propertycache import cachedproperty
1468 from lp.soyuz.browser.packagesearch import PackageSearchViewBase
1469 from lp.soyuz.enums import ArchivePurpose
1470-from lp.soyuz.interfaces.archive import (
1471- IArchiveSet,
1472- )
1473+from lp.soyuz.interfaces.archive import IArchiveSet
1474
1475
1476 class UsesLaunchpadMixin:
1477
1478=== modified file 'lib/lp/registry/browser/distributionmirror.py'
1479--- lib/lp/registry/browser/distributionmirror.py 2010-08-20 20:31:18 +0000
1480+++ lib/lp/registry/browser/distributionmirror.py 2010-09-02 12:57:56 +0000
1481@@ -22,7 +22,6 @@
1482 from zope.interface import implements
1483 from zope.lifecycleevent import ObjectCreatedEvent
1484
1485-from canonical.cachedproperty import cachedproperty
1486 from canonical.launchpad import _
1487 from canonical.launchpad.webapp import (
1488 action,
1489@@ -40,6 +39,7 @@
1490 from lp.registry.browser.objectreassignment import ObjectReassignmentView
1491 from lp.registry.interfaces.distribution import IDistributionMirrorMenuMarker
1492 from lp.registry.interfaces.distributionmirror import IDistributionMirror
1493+from lp.services.propertycache import cachedproperty
1494 from lp.soyuz.browser.sourceslist import (
1495 SourcesListEntries,
1496 SourcesListEntriesView,
1497
1498=== modified file 'lib/lp/registry/browser/distributionsourcepackage.py'
1499--- lib/lp/registry/browser/distributionsourcepackage.py 2010-08-26 13:42:56 +0000
1500+++ lib/lp/registry/browser/distributionsourcepackage.py 2010-09-02 12:57:56 +0000
1501@@ -26,7 +26,7 @@
1502 Interface,
1503 )
1504
1505-from canonical.cachedproperty import cachedproperty
1506+from canonical.launchpad.helpers import shortlist
1507 from canonical.launchpad.webapp import (
1508 action,
1509 canonical_url,
1510@@ -36,7 +36,6 @@
1511 redirection,
1512 StandardLaunchpadFacets,
1513 )
1514-from canonical.launchpad.helpers import shortlist
1515 from canonical.launchpad.webapp.breadcrumb import Breadcrumb
1516 from canonical.launchpad.webapp.menu import (
1517 ApplicationMenu,
1518@@ -62,6 +61,7 @@
1519 IDistributionSourcePackage,
1520 )
1521 from lp.registry.interfaces.pocket import pocketsuffix
1522+from lp.services.propertycache import cachedproperty
1523 from lp.soyuz.browser.sourcepackagerelease import (
1524 extract_bug_numbers,
1525 extract_email_addresses,
1526@@ -73,7 +73,8 @@
1527 )
1528 from lp.soyuz.interfaces.packagediff import IPackageDiffSet
1529 from lp.translations.browser.customlanguagecode import (
1530- HasCustomLanguageCodesTraversalMixin)
1531+ HasCustomLanguageCodesTraversalMixin,
1532+ )
1533
1534
1535 class DistributionSourcePackageFormatterAPI(CustomizableFormatter):
1536
1537=== modified file 'lib/lp/registry/browser/distroseries.py'
1538--- lib/lp/registry/browser/distroseries.py 2010-08-20 20:31:18 +0000
1539+++ lib/lp/registry/browser/distroseries.py 2010-09-02 12:57:56 +0000
1540@@ -27,7 +27,6 @@
1541 SimpleVocabulary,
1542 )
1543
1544-from canonical.cachedproperty import cachedproperty
1545 from canonical.database.constants import UTC_NOW
1546 from canonical.launchpad import (
1547 _,
1548@@ -72,6 +71,7 @@
1549 )
1550 from lp.registry.interfaces.distroseries import IDistroSeries
1551 from lp.registry.interfaces.series import SeriesStatus
1552+from lp.services.propertycache import cachedproperty
1553 from lp.services.worlddata.interfaces.country import ICountry
1554 from lp.services.worlddata.interfaces.language import ILanguageSet
1555 from lp.soyuz.browser.packagesearch import PackageSearchViewBase
1556
1557=== modified file 'lib/lp/registry/browser/karma.py'
1558--- lib/lp/registry/browser/karma.py 2010-08-20 20:31:18 +0000
1559+++ lib/lp/registry/browser/karma.py 2010-09-02 12:57:56 +0000
1560@@ -13,7 +13,6 @@
1561
1562 from zope.component import getUtility
1563
1564-from canonical.cachedproperty import cachedproperty
1565 from canonical.launchpad import _
1566 from canonical.launchpad.webapp import (
1567 action,
1568@@ -29,6 +28,7 @@
1569 )
1570 from lp.registry.interfaces.product import IProduct
1571 from lp.registry.interfaces.projectgroup import IProjectGroup
1572+from lp.services.propertycache import cachedproperty
1573
1574
1575 TOP_CONTRIBUTORS_LIMIT = 20
1576
1577=== modified file 'lib/lp/registry/browser/mailinglists.py'
1578--- lib/lp/registry/browser/mailinglists.py 2010-08-20 20:31:18 +0000
1579+++ lib/lp/registry/browser/mailinglists.py 2010-09-02 12:57:56 +0000
1580@@ -20,7 +20,6 @@
1581 from zope.interface import Interface
1582 from zope.security.proxy import removeSecurityProxy
1583
1584-from canonical.cachedproperty import cachedproperty
1585 from canonical.launchpad import _
1586 from canonical.launchpad.webapp import (
1587 action,
1588@@ -37,6 +36,7 @@
1589 MailingListStatus,
1590 )
1591 from lp.registry.interfaces.person import ITeam
1592+from lp.services.propertycache import cachedproperty
1593
1594
1595 class ReviewForm(Interface):
1596
1597=== modified file 'lib/lp/registry/browser/milestone.py'
1598--- lib/lp/registry/browser/milestone.py 2010-08-20 20:31:18 +0000
1599+++ lib/lp/registry/browser/milestone.py 2010-09-02 12:57:56 +0000
1600@@ -29,7 +29,6 @@
1601 )
1602 from zope.schema import Choice
1603
1604-from canonical.cachedproperty import cachedproperty
1605 from canonical.launchpad import _
1606 from canonical.launchpad.webapp import (
1607 action,
1608@@ -75,6 +74,7 @@
1609 IProjectGroupMilestone,
1610 )
1611 from lp.registry.interfaces.product import IProduct
1612+from lp.services.propertycache import cachedproperty
1613
1614
1615 class MilestoneSetNavigation(GetitemNavigation):
1616
1617=== modified file 'lib/lp/registry/browser/person.py'
1618--- lib/lp/registry/browser/person.py 2010-08-31 14:00:54 +0000
1619+++ lib/lp/registry/browser/person.py 2010-09-02 12:57:56 +0000
1620@@ -141,7 +141,6 @@
1621 from zope.security.interfaces import Unauthorized
1622 from zope.security.proxy import removeSecurityProxy
1623
1624-from canonical.cachedproperty import cachedproperty
1625 from canonical.config import config
1626 from canonical.database.sqlbase import flush_database_updates
1627 from canonical.launchpad import (
1628@@ -309,6 +308,10 @@
1629 )
1630 from lp.services.openid.interfaces.openid import IOpenIDPersistentIdentity
1631 from lp.services.openid.interfaces.openidrpsummary import IOpenIDRPSummarySet
1632+from lp.services.propertycache import (
1633+ cachedproperty,
1634+ IPropertyCache,
1635+ )
1636 from lp.services.salesforce.interfaces import (
1637 ISalesforceVoucherProxy,
1638 SalesforceVoucherProxyException,
1639@@ -5743,10 +5746,7 @@
1640 def _reset_state(self):
1641 """Reset the cache because the recipients changed."""
1642 self._count_recipients = None
1643- if safe_hasattr(self, '_all_recipients_cached'):
1644- # The clear the cache of _all_recipients. The caching will fail
1645- # if this method creates the attribute before _all_recipients.
1646- del self._all_recipients_cached
1647+ del IPropertyCache(self)._all_recipients
1648
1649 def _getPrimaryReason(self, person_or_team):
1650 """Return the primary reason enumeration.
1651@@ -5854,7 +5854,7 @@
1652 'You are contacting %s of the %s (%s) team directly.'
1653 % (text, person_or_team.displayname, person_or_team.name))
1654
1655- @cachedproperty('_all_recipients_cached')
1656+ @cachedproperty
1657 def _all_recipients(self):
1658 """Set the cache of all recipients."""
1659 all_recipients = {}
1660
1661=== modified file 'lib/lp/registry/browser/pillar.py'
1662--- lib/lp/registry/browser/pillar.py 2010-08-31 14:45:20 +0000
1663+++ lib/lp/registry/browser/pillar.py 2010-09-02 12:57:56 +0000
1664@@ -19,7 +19,6 @@
1665 Interface,
1666 )
1667
1668-from canonical.cachedproperty import cachedproperty
1669 from canonical.launchpad.webapp.menu import (
1670 ApplicationMenu,
1671 enabled_with_permission,
1672@@ -42,6 +41,7 @@
1673 from lp.registry.interfaces.distroseries import IDistroSeries
1674 from lp.registry.interfaces.pillar import IPillar
1675 from lp.registry.interfaces.projectgroup import IProjectGroup
1676+from lp.services.propertycache import cachedproperty
1677
1678
1679 class IInvolved(Interface):
1680
1681=== modified file 'lib/lp/registry/browser/product.py'
1682--- lib/lp/registry/browser/product.py 2010-08-25 23:43:13 +0000
1683+++ lib/lp/registry/browser/product.py 2010-09-02 12:57:56 +0000
1684@@ -50,6 +50,8 @@
1685 )
1686 from operator import attrgetter
1687
1688+from lazr.delegates import delegates
1689+from lazr.restful.interface import copy_field
1690 import pytz
1691 from z3c.ptcompat import ViewPageTemplateFile
1692 from zope.app.form import CustomWidgetFactory
1693@@ -76,10 +78,7 @@
1694 )
1695 from zope.security.proxy import removeSecurityProxy
1696
1697-from canonical.cachedproperty import cachedproperty
1698 from canonical.config import config
1699-from lazr.delegates import delegates
1700-from lazr.restful.interface import copy_field
1701 from canonical.launchpad import (
1702 _,
1703 helpers,
1704@@ -191,6 +190,7 @@
1705 PillarAliases,
1706 PublicPersonChoice,
1707 )
1708+from lp.services.propertycache import cachedproperty
1709 from lp.services.worlddata.interfaces.country import ICountry
1710 from lp.translations.browser.customlanguagecode import (
1711 HasCustomLanguageCodesTraversalMixin,
1712
1713=== modified file 'lib/lp/registry/browser/productseries.py'
1714--- lib/lp/registry/browser/productseries.py 2010-08-27 19:19:27 +0000
1715+++ lib/lp/registry/browser/productseries.py 2010-09-02 12:57:56 +0000
1716@@ -54,7 +54,6 @@
1717 SimpleVocabulary,
1718 )
1719
1720-from canonical.cachedproperty import cachedproperty
1721 from canonical.launchpad import _
1722 from canonical.launchpad.helpers import browserLanguages
1723 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
1724@@ -137,6 +136,7 @@
1725 from lp.registry.interfaces.productseries import IProductSeries
1726 from lp.registry.interfaces.series import SeriesStatus
1727 from lp.services.fields import URIField
1728+from lp.services.propertycache import cachedproperty
1729 from lp.services.worlddata.interfaces.country import ICountry
1730 from lp.services.worlddata.interfaces.language import ILanguageSet
1731 from lp.translations.interfaces.potemplate import IPOTemplateSet
1732
1733=== modified file 'lib/lp/registry/browser/project.py'
1734--- lib/lp/registry/browser/project.py 2010-08-21 18:41:57 +0000
1735+++ lib/lp/registry/browser/project.py 2010-09-02 12:57:56 +0000
1736@@ -42,7 +42,6 @@
1737 from zope.lifecycleevent import ObjectCreatedEvent
1738 from zope.schema import Choice
1739
1740-from canonical.cachedproperty import cachedproperty
1741 from canonical.launchpad import _
1742 from canonical.launchpad.browser.feeds import FeedsMixin
1743 from canonical.launchpad.webapp import (
1744@@ -98,6 +97,7 @@
1745 PillarAliases,
1746 PublicPersonChoice,
1747 )
1748+from lp.services.propertycache import cachedproperty
1749
1750
1751 class ProjectNavigation(Navigation,
1752
1753=== modified file 'lib/lp/registry/browser/structuralsubscription.py'
1754--- lib/lp/registry/browser/structuralsubscription.py 2010-08-20 20:31:18 +0000
1755+++ lib/lp/registry/browser/structuralsubscription.py 2010-09-02 12:57:56 +0000
1756@@ -22,7 +22,6 @@
1757 SimpleVocabulary,
1758 )
1759
1760-from canonical.cachedproperty import cachedproperty
1761 from canonical.launchpad.webapp import (
1762 action,
1763 canonical_url,
1764@@ -43,6 +42,7 @@
1765 IStructuralSubscriptionForm,
1766 IStructuralSubscriptionTarget,
1767 )
1768+from lp.services.propertycache import cachedproperty
1769
1770
1771 class StructuralSubscriptionView(LaunchpadFormView):
1772
1773=== modified file 'lib/lp/registry/browser/team.py'
1774--- lib/lp/registry/browser/team.py 2010-08-27 22:33:36 +0000
1775+++ lib/lp/registry/browser/team.py 2010-09-02 12:57:56 +0000
1776@@ -41,7 +41,6 @@
1777 SimpleVocabulary,
1778 )
1779
1780-from canonical.cachedproperty import cachedproperty
1781 from canonical.launchpad import _
1782 from canonical.launchpad.interfaces.authtoken import LoginTokenType
1783 from canonical.launchpad.interfaces.emailaddress import IEmailAddressSet
1784@@ -92,6 +91,7 @@
1785 )
1786 from lp.registry.interfaces.teammembership import TeamMembershipStatus
1787 from lp.services.fields import PublicPersonChoice
1788+from lp.services.propertycache import cachedproperty
1789
1790
1791 class TeamPrivacyAdapter:
1792
1793=== modified file 'lib/lp/registry/model/distribution.py'
1794--- lib/lp/registry/model/distribution.py 2010-09-02 12:57:52 +0000
1795+++ lib/lp/registry/model/distribution.py 2010-09-02 12:57:56 +0000
1796@@ -149,15 +149,11 @@
1797 from lp.registry.model.structuralsubscription import (
1798 StructuralSubscriptionTargetMixin,
1799 )
1800-<<<<<<< TREE
1801-from lp.soyuz.enums import (
1802-=======
1803 from lp.services.propertycache import (
1804 cachedproperty,
1805 IPropertyCache,
1806 )
1807-from lp.soyuz.interfaces.archive import (
1808->>>>>>> MERGE-SOURCE
1809+from lp.soyuz.enums import (
1810 ArchivePurpose,
1811 ArchiveStatus,
1812 PackagePublishingStatus,
1813@@ -170,10 +166,11 @@
1814 from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
1815 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
1816 from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
1817-from lp.soyuz.interfaces.publishing import (
1818- active_publishing_status,
1819- )
1820+from lp.soyuz.interfaces.publishing import active_publishing_status
1821+from lp.soyuz.model.archive import Archive
1822 from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
1823+from lp.soyuz.model.binarypackagename import BinaryPackageName
1824+from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
1825 from lp.soyuz.model.distributionsourcepackagecache import (
1826 DistributionSourcePackageCache,
1827 )
1828
1829=== modified file 'lib/lp/registry/model/distroseries.py'
1830--- lib/lp/registry/model/distroseries.py 2010-08-26 08:02:08 +0000
1831+++ lib/lp/registry/model/distroseries.py 2010-09-02 12:57:56 +0000
1832@@ -36,7 +36,6 @@
1833 from zope.component import getUtility
1834 from zope.interface import implements
1835
1836-from canonical.cachedproperty import cachedproperty
1837 from canonical.database.constants import (
1838 DEFAULT,
1839 UTC_NOW,
1840@@ -114,15 +113,14 @@
1841 from lp.registry.model.structuralsubscription import (
1842 StructuralSubscriptionTargetMixin,
1843 )
1844+from lp.services.propertycache import cachedproperty
1845 from lp.services.worlddata.model.language import Language
1846 from lp.soyuz.enums import (
1847 ArchivePurpose,
1848 PackagePublishingStatus,
1849 PackageUploadStatus,
1850 )
1851-from lp.soyuz.interfaces.archive import (
1852- ALLOW_RELEASE_BUILDS,
1853- )
1854+from lp.soyuz.interfaces.archive import ALLOW_RELEASE_BUILDS
1855 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
1856 from lp.soyuz.interfaces.binarypackagename import IBinaryPackageName
1857 from lp.soyuz.interfaces.buildrecords import IHasBuildRecords
1858@@ -551,7 +549,7 @@
1859 orderBy=["Language.englishname"])
1860 return result
1861
1862- @cachedproperty('_previous_series_cached')
1863+ @cachedproperty
1864 def previous_series(self):
1865 """See `IDistroSeries`."""
1866 # This property is cached because it is used intensely inside
1867
1868=== modified file 'lib/lp/registry/model/mailinglist.py'
1869--- lib/lp/registry/model/mailinglist.py 2010-08-22 19:14:23 +0000
1870+++ lib/lp/registry/model/mailinglist.py 2010-09-02 12:57:56 +0000
1871@@ -51,7 +51,6 @@
1872 )
1873 from zope.security.proxy import removeSecurityProxy
1874
1875-from canonical.cachedproperty import cachedproperty
1876 from canonical.config import config
1877 from canonical.database.constants import (
1878 DEFAULT,
1879@@ -95,6 +94,7 @@
1880 from lp.registry.interfaces.person import validate_public_person
1881 from lp.registry.model.person import Person
1882 from lp.registry.model.teammembership import TeamParticipation
1883+from lp.services.propertycache import cachedproperty
1884
1885
1886 EMAIL_ADDRESS_STATUSES = (
1887
1888=== modified file 'lib/lp/registry/model/person.py'
1889--- lib/lp/registry/model/person.py 2010-09-02 12:57:52 +0000
1890+++ lib/lp/registry/model/person.py 2010-09-02 12:57:56 +0000
1891@@ -272,9 +272,7 @@
1892 )
1893 from lp.services.worlddata.model.language import Language
1894 from lp.soyuz.enums import ArchivePurpose
1895-from lp.soyuz.interfaces.archive import (
1896- IArchiveSet,
1897- )
1898+from lp.soyuz.interfaces.archive import IArchiveSet
1899 from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
1900 from lp.soyuz.interfaces.archivesubscriber import IArchiveSubscriberSet
1901 from lp.soyuz.model.archive import Archive
1902@@ -1620,7 +1618,7 @@
1903 if not person:
1904 return
1905 email = column
1906- cache_property(person, '_preferredemail_cached', email)
1907+ IPropertyCache(person).preferredemail = email
1908 decorators.append(handleemail)
1909 def handleaccount(person, column):
1910 #-- validity caching
1911@@ -1632,7 +1630,7 @@
1912 column is not None
1913 # -- preferred email found
1914 and person.preferredemail is not None)
1915- cache_property(person, '_is_valid_person_cached', valid)
1916+ IPropertyCache(person).is_valid_person = valid
1917 decorators.append(handleaccount)
1918 return dict(
1919 joins=origins,
1920@@ -1752,27 +1750,11 @@
1921 if need_preferred_email and not need_validity:
1922 email = row[index]
1923 index += 1
1924-<<<<<<< TREE
1925- cache_property(result, '_preferredemail_cached', email)
1926+ cache.preferredemail = email
1927 for decorator in decorators:
1928 column = row[index]
1929-=======
1930- cache.preferredemail = email
1931- #-- validity caching
1932- if need_validity:
1933- # valid if:
1934- valid = (
1935- # -- valid account found
1936- row[index] is not None
1937- # -- preferred email found
1938- and result.preferredemail is not None)
1939->>>>>>> MERGE-SOURCE
1940 index += 1
1941-<<<<<<< TREE
1942 decorator(result, column)
1943-=======
1944- cache.is_valid_person = valid
1945->>>>>>> MERGE-SOURCE
1946 return result
1947 return DecoratedResultSet(raw_result,
1948 result_decorator=prepopulate_person)
1949
1950=== modified file 'lib/lp/registry/model/product.py'
1951--- lib/lp/registry/model/product.py 2010-08-31 05:58:45 +0000
1952+++ lib/lp/registry/model/product.py 2010-09-02 12:57:56 +0000
1953@@ -38,7 +38,6 @@
1954 from zope.interface import implements
1955 from zope.security.proxy import removeSecurityProxy
1956
1957-from canonical.cachedproperty import cachedproperty
1958 from canonical.database.constants import UTC_NOW
1959 from canonical.database.datetimecol import UtcDateTimeCol
1960 from canonical.database.enumcol import EnumCol
1961@@ -150,6 +149,10 @@
1962 StructuralSubscriptionTargetMixin,
1963 )
1964 from lp.services.database.prejoin import prejoin
1965+from lp.services.propertycache import (
1966+ cachedproperty,
1967+ IPropertyCache,
1968+ )
1969 from lp.translations.interfaces.customlanguagecode import (
1970 IHasCustomLanguageCodes,
1971 )
1972@@ -428,7 +431,7 @@
1973 notNull=True, default=False,
1974 storm_validator=_validate_license_approved)
1975
1976- @cachedproperty('_commercial_subscription_cached')
1977+ @cachedproperty
1978 def commercial_subscription(self):
1979 return CommercialSubscription.selectOneBy(product=self)
1980
1981@@ -475,7 +478,7 @@
1982 purchaser=purchaser,
1983 sales_system_id=voucher,
1984 whiteboard=whiteboard)
1985- self._commercial_subscription_cached = subscription
1986+ IPropertyCache(self).commercial_subscription = subscription
1987 else:
1988 if current_datetime <= self.commercial_subscription.date_expires:
1989 # Extend current subscription.
1990
1991=== modified file 'lib/lp/registry/vocabularies.py'
1992--- lib/lp/registry/vocabularies.py 2010-08-24 07:51:22 +0000
1993+++ lib/lp/registry/vocabularies.py 2010-09-02 12:57:56 +0000
1994@@ -88,7 +88,6 @@
1995 removeSecurityProxy,
1996 )
1997
1998-from canonical.cachedproperty import cachedproperty
1999 from canonical.database.sqlbase import (
2000 quote,
2001 quote_like,
2002@@ -169,6 +168,7 @@
2003 from lp.registry.model.projectgroup import ProjectGroup
2004 from lp.registry.model.sourcepackagename import SourcePackageName
2005 from lp.registry.model.teammembership import TeamParticipation
2006+from lp.services.propertycache import cachedproperty
2007
2008
2009 class BasePersonVocabulary:
2010
2011=== modified file 'lib/lp/services/mailman/doc/staging.txt'
2012--- lib/lp/services/mailman/doc/staging.txt 2010-06-09 03:38:46 +0000
2013+++ lib/lp/services/mailman/doc/staging.txt 2010-09-02 12:57:56 +0000
2014@@ -30,8 +30,9 @@
2015 >>> logout()
2016
2017 >>> from canonical.launchpad.testing.pages import setupBrowser
2018+ >>> from lp.services.propertycache import IPropertyCache
2019 >>> browser = setupBrowser('Basic %s:%s' %
2020- ... (owner._preferredemail_cached.email,
2021+ ... (IPropertyCache(owner).preferredemail.email,
2022 ... owner._password_cleartext_cached))
2023
2024 >>> from lp.services.mailman.testing import helpers
2025
2026=== modified file 'lib/lp/services/openid/browser/openiddiscovery.py'
2027--- lib/lp/services/openid/browser/openiddiscovery.py 2010-08-20 20:31:18 +0000
2028+++ lib/lp/services/openid/browser/openiddiscovery.py 2010-09-02 12:57:56 +0000
2029@@ -14,9 +14,9 @@
2030 YADIS_HEADER_NAME,
2031 )
2032
2033-from canonical.cachedproperty import cachedproperty
2034 from canonical.launchpad.webapp import canonical_url
2035 from lp.services.openid.adapters.openid import CurrentOpenIDEndPoint
2036+from lp.services.propertycache import cachedproperty
2037
2038
2039 class XRDSContentNegotiationMixin:
2040
2041=== modified file 'lib/lp/services/propertycache.py'
2042--- lib/lp/services/propertycache.py 2010-09-02 12:57:52 +0000
2043+++ lib/lp/services/propertycache.py 2010-09-02 12:57:56 +0000
2044@@ -20,6 +20,7 @@
2045 from zope.component import (
2046 adapter,
2047 adapts,
2048+ getGlobalSiteManager,
2049 )
2050 from zope.interface import (
2051 implementer,
2052@@ -62,6 +63,11 @@
2053 """Empty the cache."""
2054
2055
2056+# Register adapters with the global site manager so that they work even when
2057+# ZCML has not been executed.
2058+registerAdapter = getGlobalSiteManager().registerAdapter
2059+
2060+
2061 class DefaultPropertyCache:
2062 """A simple cache."""
2063
2064@@ -94,6 +100,8 @@
2065 naked_target._property_cache = DefaultPropertyCache()
2066 return naked_target._property_cache
2067
2068+registerAdapter(get_default_cache)
2069+
2070
2071 class PropertyCacheManager:
2072 """A simple `IPropertyCacheManager`.
2073@@ -112,6 +120,8 @@
2074 for name in list(self.cache):
2075 delattr(self.cache, name)
2076
2077+registerAdapter(PropertyCacheManager)
2078+
2079
2080 class DefaultPropertyCacheManager:
2081 """A `IPropertyCacheManager` specifically for `DefaultPropertyCache`.
2082@@ -128,6 +138,8 @@
2083 def clear(self):
2084 self.cache.__dict__.clear()
2085
2086+registerAdapter(DefaultPropertyCacheManager)
2087+
2088
2089 class CachedProperty:
2090 """Cached property descriptor.
2091@@ -172,3 +184,32 @@
2092 name = name_or_function.__name__
2093 populate = name_or_function
2094 return CachedProperty(name=name, populate=populate)
2095+
2096+
2097+# XXX: GavinPanella 2010-09-02 bug=628762: There are some weird adaption
2098+# failures when running the full test suite. All that follows is a temporary,
2099+# mostly non-Zope, workaround.
2100+
2101+_IPropertyCache = IPropertyCache
2102+_IPropertyCacheManager = IPropertyCacheManager
2103+
2104+def IPropertyCache(target):
2105+ """Return the `IPropertyCache` for `target`.
2106+
2107+ Note: this is a workaround; see bug 628762.
2108+ """
2109+ if _IPropertyCache.providedBy(target):
2110+ return target
2111+ else:
2112+ return get_default_cache(target)
2113+
2114+def IPropertyCacheManager(target):
2115+ """Return the `IPropertyCacheManager` for `target`.
2116+
2117+ Note: this is a workaround; see bug 628762.
2118+ """
2119+ cache = IPropertyCache(target)
2120+ if isinstance(cache, DefaultPropertyCache):
2121+ return DefaultPropertyCacheManager(cache)
2122+ else:
2123+ return PropertyCacheManager(cache)
2124
2125=== modified file 'lib/lp/services/salesforce/proxy.py'
2126--- lib/lp/services/salesforce/proxy.py 2010-08-20 20:31:18 +0000
2127+++ lib/lp/services/salesforce/proxy.py 2010-09-02 12:57:56 +0000
2128@@ -20,10 +20,10 @@
2129 from zope.component import getUtility
2130 from zope.interface import implements
2131
2132-from canonical.cachedproperty import cachedproperty
2133 from canonical.config import config
2134 from canonical.lazr.timeout import SafeTransportWithTimeout
2135 from lp.registry.interfaces.product import IProductSet
2136+from lp.services.propertycache import cachedproperty
2137 from lp.services.salesforce.interfaces import (
2138 ISalesforceVoucher,
2139 ISalesforceVoucherProxy,
2140
2141=== modified file 'lib/lp/services/tests/test_doc.py'
2142--- lib/lp/services/tests/test_doc.py 2010-09-02 12:57:52 +0000
2143+++ lib/lp/services/tests/test_doc.py 2010-09-02 12:57:56 +0000
2144@@ -8,8 +8,10 @@
2145 import os
2146
2147 from canonical.launchpad.testing.systemdocs import LayeredDocFileSuite
2148-from canonical.testing import BaseLayer
2149-from canonical.testing import LaunchpadZopelessLayer
2150+from canonical.testing import (
2151+ BaseLayer,
2152+ LaunchpadZopelessLayer,
2153+ )
2154 from lp.services.testing import build_test_suite
2155
2156
2157
2158=== modified file 'lib/lp/shipit.py'
2159--- lib/lp/shipit.py 2010-08-20 20:31:18 +0000
2160+++ lib/lp/shipit.py 2010-09-02 12:57:56 +0000
2161@@ -106,6 +106,10 @@
2162 from lp.registry.model.person import Person
2163 from lp.services.mail import stub
2164 from lp.services.mail.sendmail import simple_sendmail
2165+from lp.services.propertycache import (
2166+ cachedproperty,
2167+ IPropertyCache,
2168+ )
2169 from lp.services.scripts.base import (
2170 LaunchpadCronScript,
2171 LaunchpadScript,
2172
2173=== modified file 'lib/lp/soyuz/browser/archive.py'
2174--- lib/lp/soyuz/browser/archive.py 2010-08-27 11:19:54 +0000
2175+++ lib/lp/soyuz/browser/archive.py 2010-09-02 12:57:56 +0000
2176@@ -56,7 +56,6 @@
2177 from zope.security.interfaces import Unauthorized
2178 from zope.security.proxy import removeSecurityProxy
2179
2180-from canonical.cachedproperty import cachedproperty
2181 from canonical.launchpad import _
2182 from canonical.launchpad.browser.librarian import FileNavigationMixin
2183 from canonical.launchpad.components.tokens import create_token
2184@@ -107,6 +106,7 @@
2185 from lp.registry.interfaces.series import SeriesStatus
2186 from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
2187 from lp.services.browser_helpers import get_user_agent_distroseries
2188+from lp.services.propertycache import cachedproperty
2189 from lp.services.worlddata.interfaces.country import ICountrySet
2190 from lp.soyuz.adapters.archivedependencies import (
2191 default_component_dependency_name,
2192@@ -134,9 +134,7 @@
2193 IPPAActivateForm,
2194 NoSuchPPA,
2195 )
2196-from lp.soyuz.interfaces.archivepermission import (
2197- IArchivePermissionSet,
2198- )
2199+from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
2200 from lp.soyuz.interfaces.archivesubscriber import IArchiveSubscriberSet
2201 from lp.soyuz.interfaces.binarypackagebuild import (
2202 BuildSetStatus,
2203
2204=== modified file 'lib/lp/soyuz/browser/archivesubscription.py'
2205--- lib/lp/soyuz/browser/archivesubscription.py 2010-08-20 20:31:18 +0000
2206+++ lib/lp/soyuz/browser/archivesubscription.py 2010-09-02 12:57:56 +0000
2207@@ -30,7 +30,6 @@
2208 Text,
2209 )
2210
2211-from canonical.cachedproperty import cachedproperty
2212 from canonical.launchpad import _
2213 from canonical.launchpad.webapp.launchpadform import (
2214 action,
2215@@ -45,6 +44,7 @@
2216 from canonical.widgets import DateWidget
2217 from canonical.widgets.popup import PersonPickerWidget
2218 from lp.services.fields import PersonChoice
2219+from lp.services.propertycache import cachedproperty
2220 from lp.soyuz.browser.sourceslist import (
2221 SourcesListEntries,
2222 SourcesListEntriesView,
2223
2224=== modified file 'lib/lp/soyuz/browser/build.py'
2225--- lib/lp/soyuz/browser/build.py 2010-08-27 11:19:54 +0000
2226+++ lib/lp/soyuz/browser/build.py 2010-09-02 12:57:56 +0000
2227@@ -19,7 +19,6 @@
2228 from zope.component import getUtility
2229 from zope.interface import implements
2230
2231-from canonical.cachedproperty import cachedproperty
2232 from canonical.launchpad import _
2233 from canonical.launchpad.browser.librarian import (
2234 FileNavigationMixin,
2235@@ -44,12 +43,13 @@
2236 from lp.app.errors import UnexpectedFormData
2237 from lp.buildmaster.enums import BuildStatus
2238 from lp.services.job.interfaces.job import JobStatus
2239+from lp.services.propertycache import cachedproperty
2240+from lp.soyuz.enums import PackageUploadStatus
2241 from lp.soyuz.interfaces.binarypackagebuild import (
2242 IBinaryPackageBuild,
2243 IBinaryPackageBuildSet,
2244 IBuildRescoreForm,
2245 )
2246-from lp.soyuz.enums import PackageUploadStatus
2247
2248
2249 class BuildUrl:
2250
2251=== modified file 'lib/lp/soyuz/browser/builder.py'
2252--- lib/lp/soyuz/browser/builder.py 2010-08-20 20:31:18 +0000
2253+++ lib/lp/soyuz/browser/builder.py 2010-09-02 12:57:56 +0000
2254@@ -28,7 +28,6 @@
2255 from zope.event import notify
2256 from zope.lifecycleevent import ObjectCreatedEvent
2257
2258-from canonical.cachedproperty import cachedproperty
2259 from canonical.launchpad import _
2260 from canonical.launchpad.webapp import (
2261 action,
2262@@ -53,6 +52,7 @@
2263 IBuilder,
2264 IBuilderSet,
2265 )
2266+from lp.services.propertycache import cachedproperty
2267 from lp.soyuz.browser.build import BuildRecordsView
2268 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
2269
2270
2271=== modified file 'lib/lp/soyuz/browser/distributionsourcepackagerelease.py'
2272--- lib/lp/soyuz/browser/distributionsourcepackagerelease.py 2010-08-24 15:29:01 +0000
2273+++ lib/lp/soyuz/browser/distributionsourcepackagerelease.py 2010-09-02 12:57:56 +0000
2274@@ -14,7 +14,6 @@
2275
2276 from zope.component import getUtility
2277
2278-from canonical.cachedproperty import cachedproperty
2279 from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
2280 from canonical.launchpad.webapp import (
2281 LaunchpadView,
2282@@ -25,11 +24,12 @@
2283 from canonical.lazr.utils import smartquote
2284 from lp.app.errors import NotFoundError
2285 from lp.archivepublisher.debversion import Version
2286+from lp.services.propertycache import cachedproperty
2287+from lp.soyuz.enums import PackagePublishingStatus
2288 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
2289 from lp.soyuz.interfaces.distributionsourcepackagerelease import (
2290 IDistributionSourcePackageRelease,
2291 )
2292-from lp.soyuz.enums import PackagePublishingStatus
2293
2294
2295 class DistributionSourcePackageReleaseBreadcrumb(Breadcrumb):
2296
2297=== modified file 'lib/lp/soyuz/browser/packagesearch.py'
2298--- lib/lp/soyuz/browser/packagesearch.py 2010-03-04 22:11:34 +0000
2299+++ lib/lp/soyuz/browser/packagesearch.py 2010-09-02 12:57:56 +0000
2300@@ -7,9 +7,9 @@
2301 'PackageSearchViewBase'
2302 ]
2303
2304-from canonical.cachedproperty import cachedproperty
2305 from canonical.launchpad.webapp.batching import BatchNavigator
2306 from canonical.launchpad.webapp.publisher import LaunchpadView
2307+from lp.services.propertycache import cachedproperty
2308
2309
2310 class PackageSearchViewBase(LaunchpadView):
2311
2312=== modified file 'lib/lp/soyuz/browser/publishing.py'
2313--- lib/lp/soyuz/browser/publishing.py 2010-08-24 15:29:01 +0000
2314+++ lib/lp/soyuz/browser/publishing.py 2010-09-02 12:57:56 +0000
2315@@ -17,11 +17,11 @@
2316 from lazr.delegates import delegates
2317 from zope.interface import implements
2318
2319-from canonical.cachedproperty import cachedproperty
2320 from canonical.launchpad.browser.librarian import ProxiedLibraryFileAlias
2321 from canonical.launchpad.webapp.authorization import check_permission
2322 from canonical.launchpad.webapp.interfaces import ICanonicalUrlData
2323 from canonical.launchpad.webapp.publisher import LaunchpadView
2324+from lp.services.propertycache import cachedproperty
2325 from lp.soyuz.enums import PackagePublishingStatus
2326 from lp.soyuz.interfaces.binarypackagebuild import BuildSetStatus
2327 from lp.soyuz.interfaces.packagediff import IPackageDiff
2328
2329=== modified file 'lib/lp/soyuz/model/archive.py'
2330--- lib/lp/soyuz/model/archive.py 2010-09-02 12:57:52 +0000
2331+++ lib/lp/soyuz/model/archive.py 2010-09-02 12:57:56 +0000
2332@@ -129,9 +129,7 @@
2333 )
2334 from lp.soyuz.interfaces.archivearch import IArchiveArchSet
2335 from lp.soyuz.interfaces.archiveauthtoken import IArchiveAuthTokenSet
2336-from lp.soyuz.interfaces.archivepermission import (
2337- IArchivePermissionSet,
2338- )
2339+from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
2340 from lp.soyuz.interfaces.archivesubscriber import (
2341 ArchiveSubscriptionError,
2342 IArchiveSubscriberSet,
2343
2344=== modified file 'lib/lp/soyuz/model/distroarchseriesbinarypackage.py'
2345--- lib/lp/soyuz/model/distroarchseriesbinarypackage.py 2010-08-24 15:29:01 +0000
2346+++ lib/lp/soyuz/model/distroarchseriesbinarypackage.py 2010-09-02 12:57:56 +0000
2347@@ -17,14 +17,14 @@
2348 )
2349 from zope.interface import implements
2350
2351-from canonical.cachedproperty import cachedproperty
2352 from canonical.database.sqlbase import sqlvalues
2353 from canonical.launchpad.interfaces import IStore
2354 from lp.app.errors import NotFoundError
2355+from lp.services.propertycache import cachedproperty
2356+from lp.soyuz.enums import PackagePublishingStatus
2357 from lp.soyuz.interfaces.distroarchseriesbinarypackage import (
2358 IDistroArchSeriesBinaryPackage,
2359 )
2360-from lp.soyuz.enums import PackagePublishingStatus
2361 from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
2362 from lp.soyuz.model.distroarchseriesbinarypackagerelease import (
2363 DistroArchSeriesBinaryPackageRelease,
2364
2365=== modified file 'lib/lp/soyuz/model/distroseriesbinarypackage.py'
2366--- lib/lp/soyuz/model/distroseriesbinarypackage.py 2010-08-20 20:31:18 +0000
2367+++ lib/lp/soyuz/model/distroseriesbinarypackage.py 2010-09-02 12:57:56 +0000
2368@@ -12,8 +12,11 @@
2369 from storm.store import Store
2370 from zope.interface import implements
2371
2372-from canonical.cachedproperty import cachedproperty
2373 from canonical.database.sqlbase import sqlvalues
2374+from lp.services.propertycache import (
2375+ cachedproperty,
2376+ IPropertyCache,
2377+ )
2378 from lp.soyuz.interfaces.distroseriesbinarypackage import (
2379 IDistroSeriesBinaryPackage,
2380 )
2381@@ -40,7 +43,7 @@
2382 self.distroseries = distroseries
2383 self.binarypackagename = binarypackagename
2384 if cache is not None:
2385- self._cache = cache
2386+ IPropertyCache(self).cache = cache
2387
2388 @property
2389 def name(self):
2390@@ -58,7 +61,7 @@
2391 """See IDistroSeriesBinaryPackage."""
2392 return self.distroseries.distribution
2393
2394- @cachedproperty('_cache')
2395+ @cachedproperty
2396 def cache(self):
2397 """See IDistroSeriesBinaryPackage."""
2398 store = Store.of(self.distroseries)
2399
2400=== modified file 'lib/lp/soyuz/model/queue.py'
2401--- lib/lp/soyuz/model/queue.py 2010-08-24 12:25:48 +0000
2402+++ lib/lp/soyuz/model/queue.py 2010-09-02 12:57:56 +0000
2403@@ -33,7 +33,6 @@
2404 from zope.component import getUtility
2405 from zope.interface import implements
2406
2407-from canonical.cachedproperty import cachedproperty
2408 from canonical.config import config
2409 from canonical.database.constants import UTC_NOW
2410 from canonical.database.datetimecol import UtcDateTimeCol
2411@@ -72,6 +71,7 @@
2412 PackagePublishingPocket,
2413 pocketsuffix,
2414 )
2415+from lp.services.propertycache import cachedproperty
2416 from lp.soyuz.enums import (
2417 BinaryPackageFormat,
2418 PackageUploadCustomFormat,
2419
2420=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
2421--- lib/lp/soyuz/model/sourcepackagerelease.py 2010-08-27 11:19:54 +0000
2422+++ lib/lp/soyuz/model/sourcepackagerelease.py 2010-09-02 12:57:56 +0000
2423@@ -30,7 +30,6 @@
2424 from zope.component import getUtility
2425 from zope.interface import implements
2426
2427-from canonical.cachedproperty import cachedproperty
2428 from canonical.database.constants import (
2429 DEFAULT,
2430 UTC_NOW,
2431@@ -59,6 +58,7 @@
2432 SourcePackageType,
2433 SourcePackageUrgency,
2434 )
2435+from lp.services.propertycache import cachedproperty
2436 from lp.soyuz.enums import (
2437 PackageDiffStatus,
2438 PackagePublishingStatus,
2439@@ -68,9 +68,7 @@
2440 MAIN_ARCHIVE_PURPOSES,
2441 )
2442 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet
2443-from lp.soyuz.interfaces.packagediff import (
2444- PackageDiffAlreadyRequested,
2445- )
2446+from lp.soyuz.interfaces.packagediff import PackageDiffAlreadyRequested
2447 from lp.soyuz.interfaces.sourcepackagerelease import ISourcePackageRelease
2448 from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
2449 from lp.soyuz.model.files import SourcePackageReleaseFile
2450
2451=== modified file 'lib/lp/soyuz/scripts/ppareport.py'
2452--- lib/lp/soyuz/scripts/ppareport.py 2010-08-23 16:51:11 +0000
2453+++ lib/lp/soyuz/scripts/ppareport.py 2010-09-02 12:57:56 +0000
2454@@ -19,11 +19,11 @@
2455 from storm.store import Store
2456 from zope.component import getUtility
2457
2458-from canonical.cachedproperty import cachedproperty
2459 from canonical.config import config
2460 from canonical.launchpad.helpers import emailPeople
2461 from canonical.launchpad.webapp import canonical_url
2462 from lp.registry.interfaces.distribution import IDistributionSet
2463+from lp.services.propertycache import cachedproperty
2464 from lp.services.scripts.base import (
2465 LaunchpadScript,
2466 LaunchpadScriptFailure,
2467
2468=== modified file 'lib/lp/soyuz/scripts/queue.py'
2469--- lib/lp/soyuz/scripts/queue.py 2010-08-24 12:25:48 +0000
2470+++ lib/lp/soyuz/scripts/queue.py 2010-09-02 12:57:56 +0000
2471@@ -24,11 +24,11 @@
2472 import pytz
2473 from zope.component import getUtility
2474
2475-from canonical.cachedproperty import cachedproperty
2476 from canonical.config import config
2477 from canonical.launchpad.webapp.tales import DurationFormatterAPI
2478 from canonical.librarian.utils import filechunks
2479 from lp.app.errors import NotFoundError
2480+from lp.services.propertycache import cachedproperty
2481 from lp.soyuz.enums import PackageUploadStatus
2482 from lp.soyuz.interfaces.component import IComponentSet
2483 from lp.soyuz.interfaces.queue import (
2484
2485=== modified file 'lib/lp/testing/__init__.py'
2486--- lib/lp/testing/__init__.py 2010-08-30 21:10:54 +0000
2487+++ lib/lp/testing/__init__.py 2010-09-02 12:57:56 +0000
2488@@ -56,7 +56,6 @@
2489 )
2490 from inspect import (
2491 getargspec,
2492- getmembers,
2493 getmro,
2494 isclass,
2495 ismethod,
2496@@ -1023,7 +1022,13 @@
2497 assert isclass(mock_class), (
2498 "validate_mock_class() must be called for a class")
2499 base_classes = getmro(mock_class)
2500- for name, obj in getmembers(mock_class):
2501+ # Don't use inspect.getmembers() here because it fails on __provides__, a
2502+ # descriptor added by zope.interface as part of its caching strategy. See
2503+ # http://comments.gmane.org/gmane.comp.python.zope.interface/241.
2504+ for name in dir(mock_class):
2505+ if name == '__provides__':
2506+ continue
2507+ obj = getattr(mock_class, name)
2508 if ismethod(obj):
2509 for base_class in base_classes[1:]:
2510 if name in base_class.__dict__:
2511
2512=== modified file 'lib/lp/testopenid/browser/server.py'
2513--- lib/lp/testopenid/browser/server.py 2010-08-20 20:31:18 +0000
2514+++ lib/lp/testopenid/browser/server.py 2010-09-02 12:57:56 +0000
2515@@ -32,7 +32,6 @@
2516 from zope.security.proxy import isinstance as zisinstance
2517 from zope.session.interfaces import ISession
2518
2519-from canonical.cachedproperty import cachedproperty
2520 from canonical.launchpad import _
2521 from canonical.launchpad.interfaces.account import (
2522 AccountStatus,
2523@@ -61,6 +60,10 @@
2524 from lp.services.openid.browser.openiddiscovery import (
2525 XRDSContentNegotiationMixin,
2526 )
2527+from lp.services.propertycache import (
2528+ cachedproperty,
2529+ IPropertyCache,
2530+ )
2531 from lp.testopenid.interfaces.server import (
2532 get_server_url,
2533 ITestOpenIDApplication,
2534@@ -142,7 +145,7 @@
2535 return (self.openid_request.idSelect() or
2536 self.openid_request.identity == self.user_identity_url)
2537
2538- @cachedproperty('_openid_parameters')
2539+ @cachedproperty
2540 def openid_parameters(self):
2541 """A dictionary of OpenID query parameters from request."""
2542 query = {}
2543@@ -165,8 +168,9 @@
2544 def restoreRequestFromSession(self):
2545 """Get the OpenIDRequest from our session."""
2546 session = self.getSession()
2547+ cache = IPropertyCache(self)
2548 try:
2549- self._openid_parameters = session[OPENID_REQUEST_SESSION_KEY]
2550+ cache.openid_parameters = session[OPENID_REQUEST_SESSION_KEY]
2551 except KeyError:
2552 raise UnexpectedFormData("No OpenID request in session")
2553
2554
2555=== modified file 'lib/lp/translations/browser/distribution.py'
2556--- lib/lp/translations/browser/distribution.py 2010-08-20 20:31:18 +0000
2557+++ lib/lp/translations/browser/distribution.py 2010-09-02 12:57:56 +0000
2558@@ -13,7 +13,6 @@
2559
2560 import operator
2561
2562-from canonical.cachedproperty import cachedproperty
2563 from canonical.launchpad.webapp import (
2564 action,
2565 canonical_url,
2566@@ -26,6 +25,7 @@
2567 from lp.registry.browser.distribution import DistributionEditView
2568 from lp.registry.interfaces.distribution import IDistribution
2569 from lp.registry.interfaces.series import SeriesStatus
2570+from lp.services.propertycache import cachedproperty
2571 from lp.translations.browser.translations import TranslationsMixin
2572
2573
2574
2575=== modified file 'lib/lp/translations/browser/distroseries.py'
2576--- lib/lp/translations/browser/distroseries.py 2010-08-20 20:31:18 +0000
2577+++ lib/lp/translations/browser/distroseries.py 2010-09-02 12:57:56 +0000
2578@@ -16,7 +16,6 @@
2579
2580 from zope.component import getUtility
2581
2582-from canonical.cachedproperty import cachedproperty
2583 from canonical.launchpad import helpers
2584 from canonical.launchpad.webapp import action
2585 from canonical.launchpad.webapp.authorization import check_permission
2586@@ -33,6 +32,7 @@
2587 from lp.app.errors import TranslationUnavailable
2588 from lp.registry.interfaces.distroseries import IDistroSeries
2589 from lp.registry.interfaces.series import SeriesStatus
2590+from lp.services.propertycache import cachedproperty
2591 from lp.translations.browser.potemplate import BaseSeriesTemplatesView
2592 from lp.translations.browser.translations import TranslationsMixin
2593 from lp.translations.interfaces.distroserieslanguage import (
2594
2595=== modified file 'lib/lp/translations/browser/hastranslationimports.py'
2596--- lib/lp/translations/browser/hastranslationimports.py 2010-08-20 20:31:18 +0000
2597+++ lib/lp/translations/browser/hastranslationimports.py 2010-09-02 12:57:56 +0000
2598@@ -25,7 +25,6 @@
2599 SimpleVocabulary,
2600 )
2601
2602-from canonical.cachedproperty import cachedproperty
2603 from canonical.launchpad import _
2604 from canonical.launchpad.webapp import (
2605 action,
2606@@ -40,6 +39,7 @@
2607 from lp.app.errors import UnexpectedFormData
2608 from lp.registry.interfaces.distribution import IDistribution
2609 from lp.registry.interfaces.pillar import IPillarNameSet
2610+from lp.services.propertycache import cachedproperty
2611 from lp.translations.interfaces.translationimportqueue import (
2612 IHasTranslationImports,
2613 ITranslationImportQueue,
2614
2615=== modified file 'lib/lp/translations/browser/language.py'
2616--- lib/lp/translations/browser/language.py 2010-08-20 20:31:18 +0000
2617+++ lib/lp/translations/browser/language.py 2010-09-02 12:57:56 +0000
2618@@ -21,7 +21,6 @@
2619 from zope.lifecycleevent import ObjectCreatedEvent
2620 from zope.schema import TextLine
2621
2622-from canonical.cachedproperty import cachedproperty
2623 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
2624 from canonical.launchpad.webapp import (
2625 action,
2626@@ -39,6 +38,7 @@
2627 from canonical.launchpad.webapp.breadcrumb import Breadcrumb
2628 from canonical.launchpad.webapp.tales import LanguageFormatterAPI
2629 from canonical.widgets import LabeledMultiCheckBoxWidget
2630+from lp.services.propertycache import cachedproperty
2631 from lp.services.worlddata.interfaces.language import (
2632 ILanguage,
2633 ILanguageSet,
2634
2635=== modified file 'lib/lp/translations/browser/person.py'
2636--- lib/lp/translations/browser/person.py 2010-08-20 20:31:18 +0000
2637+++ lib/lp/translations/browser/person.py 2010-09-02 12:57:56 +0000
2638@@ -25,7 +25,6 @@
2639 Interface,
2640 )
2641
2642-from canonical.cachedproperty import cachedproperty
2643 from canonical.launchpad import _
2644 from canonical.launchpad.webapp import (
2645 action,
2646@@ -40,6 +39,7 @@
2647 from canonical.launchpad.webapp.publisher import LaunchpadView
2648 from canonical.widgets import LaunchpadRadioWidget
2649 from lp.registry.interfaces.sourcepackage import ISourcePackage
2650+from lp.services.propertycache import cachedproperty
2651 from lp.translations.browser.translationlinksaggregator import (
2652 TranslationLinksAggregator,
2653 )
2654
2655=== modified file 'lib/lp/translations/browser/poexportrequest.py'
2656--- lib/lp/translations/browser/poexportrequest.py 2010-08-20 20:31:18 +0000
2657+++ lib/lp/translations/browser/poexportrequest.py 2010-09-02 12:57:56 +0000
2658@@ -11,13 +11,13 @@
2659
2660 from zope.component import getUtility
2661
2662-from canonical.cachedproperty import cachedproperty
2663 from canonical.launchpad import _
2664 from canonical.launchpad.webapp import (
2665 canonical_url,
2666 LaunchpadView,
2667 )
2668 from canonical.launchpad.webapp.tales import DurationFormatterAPI
2669+from lp.services.propertycache import cachedproperty
2670 from lp.translations.interfaces.poexportrequest import IPOExportRequestSet
2671 from lp.translations.interfaces.potemplate import IHasTranslationTemplates
2672 from lp.translations.interfaces.translationexporter import (
2673
2674=== modified file 'lib/lp/translations/browser/pofile.py'
2675--- lib/lp/translations/browser/pofile.py 2010-08-27 10:53:40 +0000
2676+++ lib/lp/translations/browser/pofile.py 2010-09-02 12:57:56 +0000
2677@@ -24,7 +24,6 @@
2678 from zope.component import getUtility
2679 from zope.publisher.browser import FileUpload
2680
2681-from canonical.cachedproperty import cachedproperty
2682 from canonical.config import config
2683 from canonical.launchpad import _
2684 from canonical.launchpad.interfaces import ILaunchBag
2685@@ -44,6 +43,7 @@
2686 UnexpectedFormData,
2687 )
2688 from lp.registry.interfaces.person import IPersonSet
2689+from lp.services.propertycache import cachedproperty
2690 from lp.translations.browser.poexportrequest import BaseExportView
2691 from lp.translations.browser.potemplate import POTemplateFacets
2692 from lp.translations.browser.translationmessage import (
2693
2694=== modified file 'lib/lp/translations/browser/product.py'
2695--- lib/lp/translations/browser/product.py 2010-08-20 20:31:18 +0000
2696+++ lib/lp/translations/browser/product.py 2010-09-02 12:57:56 +0000
2697@@ -11,7 +11,6 @@
2698 'ProductView',
2699 ]
2700
2701-from canonical.cachedproperty import cachedproperty
2702 from canonical.launchpad.webapp import (
2703 canonical_url,
2704 enabled_with_permission,
2705@@ -24,6 +23,7 @@
2706 from lp.registry.interfaces.product import IProduct
2707 from lp.registry.interfaces.productseries import IProductSeries
2708 from lp.registry.interfaces.series import SeriesStatus
2709+from lp.services.propertycache import cachedproperty
2710 from lp.translations.browser.translations import TranslationsMixin
2711
2712
2713
2714=== modified file 'lib/lp/translations/browser/productseries.py'
2715--- lib/lp/translations/browser/productseries.py 2010-08-20 20:31:18 +0000
2716+++ lib/lp/translations/browser/productseries.py 2010-09-02 12:57:56 +0000
2717@@ -24,7 +24,6 @@
2718 from zope.component import getUtility
2719 from zope.publisher.browser import FileUpload
2720
2721-from canonical.cachedproperty import cachedproperty
2722 from canonical.launchpad import _
2723 from canonical.launchpad.helpers import is_tar_filename
2724 from canonical.launchpad.webapp import (
2725@@ -42,6 +41,7 @@
2726 from canonical.widgets.itemswidgets import LaunchpadRadioWidgetWithDescription
2727 from lp.code.interfaces.branchjob import IRosettaUploadJobSource
2728 from lp.registry.interfaces.productseries import IProductSeries
2729+from lp.services.propertycache import cachedproperty
2730 from lp.translations.browser.poexportrequest import BaseExportView
2731 from lp.translations.browser.potemplate import BaseSeriesTemplatesView
2732 from lp.translations.browser.translations import TranslationsMixin
2733
2734=== modified file 'lib/lp/translations/browser/serieslanguage.py'
2735--- lib/lp/translations/browser/serieslanguage.py 2010-08-20 20:31:18 +0000
2736+++ lib/lp/translations/browser/serieslanguage.py 2010-09-02 12:57:56 +0000
2737@@ -12,12 +12,12 @@
2738 'ProductSeriesLanguageView',
2739 ]
2740
2741-from canonical.cachedproperty import cachedproperty
2742 from canonical.launchpad.readonly import is_read_only
2743 from canonical.launchpad.webapp import LaunchpadView
2744 from canonical.launchpad.webapp.batching import BatchNavigator
2745 from canonical.launchpad.webapp.publisher import Navigation
2746 from canonical.launchpad.webapp.tales import PersonFormatterAPI
2747+from lp.services.propertycache import cachedproperty
2748 from lp.translations.interfaces.distroserieslanguage import (
2749 IDistroSeriesLanguage,
2750 )
2751
2752=== modified file 'lib/lp/translations/browser/translationmessage.py'
2753--- lib/lp/translations/browser/translationmessage.py 2010-08-20 20:31:18 +0000
2754+++ lib/lp/translations/browser/translationmessage.py 2010-09-02 12:57:56 +0000
2755@@ -37,7 +37,6 @@
2756 from zope.interface import implements
2757 from zope.schema.vocabulary import getVocabularyRegistry
2758
2759-from canonical.cachedproperty import cachedproperty
2760 from canonical.launchpad.webapp import (
2761 ApplicationMenu,
2762 canonical_url,
2763@@ -50,6 +49,7 @@
2764 from canonical.launchpad.webapp.interfaces import ILaunchBag
2765 from canonical.launchpad.webapp.menu import structured
2766 from lp.app.errors import UnexpectedFormData
2767+from lp.services.propertycache import cachedproperty
2768 from lp.translations.browser.browser_helpers import (
2769 contract_rosetta_escapes,
2770 convert_newlines_to_web_form,
2771
2772=== modified file 'lib/lp/translations/browser/translations.py'
2773--- lib/lp/translations/browser/translations.py 2010-08-20 20:31:18 +0000
2774+++ lib/lp/translations/browser/translations.py 2010-09-02 12:57:56 +0000
2775@@ -17,7 +17,6 @@
2776
2777 from zope.component import getUtility
2778
2779-from canonical.cachedproperty import cachedproperty
2780 from canonical.config import config
2781 from canonical.launchpad import helpers
2782 from canonical.launchpad.interfaces.geoip import IRequestPreferredLanguages
2783@@ -36,6 +35,7 @@
2784 from canonical.launchpad.webapp.interfaces import ILaunchpadRoot
2785 from lp.registry.interfaces.person import IPersonSet
2786 from lp.registry.interfaces.product import IProductSet
2787+from lp.services.propertycache import cachedproperty
2788 from lp.services.worlddata.interfaces.country import ICountry
2789 from lp.translations.publisher import TranslationsLayer
2790
2791
2792=== modified file 'lib/lp/translations/model/pofile.py'
2793--- lib/lp/translations/model/pofile.py 2010-08-20 20:31:18 +0000
2794+++ lib/lp/translations/model/pofile.py 2010-09-02 12:57:56 +0000
2795@@ -44,7 +44,6 @@
2796 from zope.interface import implements
2797 from zope.security.proxy import removeSecurityProxy
2798
2799-from canonical.cachedproperty import cachedproperty
2800 from canonical.database.constants import UTC_NOW
2801 from canonical.database.datetimecol import UtcDateTimeCol
2802 from canonical.database.sqlbase import (
2803@@ -66,6 +65,7 @@
2804 from canonical.launchpad.webapp.publisher import canonical_url
2805 from lp.registry.interfaces.person import validate_public_person
2806 from lp.registry.model.person import Person
2807+from lp.services.propertycache import cachedproperty
2808 from lp.translations.interfaces.pofile import (
2809 IPOFile,
2810 IPOFileSet,
2811
2812=== modified file 'lib/lp/translations/model/potemplate.py'
2813--- lib/lp/translations/model/potemplate.py 2010-08-24 21:02:12 +0000
2814+++ lib/lp/translations/model/potemplate.py 2010-09-02 12:57:56 +0000
2815@@ -48,7 +48,6 @@
2816 from zope.interface import implements
2817 from zope.security.proxy import removeSecurityProxy
2818
2819-from canonical.cachedproperty import cachedproperty
2820 from canonical.database.constants import DEFAULT
2821 from canonical.database.datetimecol import UtcDateTimeCol
2822 from canonical.database.enumcol import EnumCol
2823@@ -70,6 +69,7 @@
2824 from lp.registry.model.sourcepackagename import SourcePackageName
2825 from lp.services.database.collection import Collection
2826 from lp.services.database.prejoin import prejoin
2827+from lp.services.propertycache import cachedproperty
2828 from lp.services.worlddata.model.language import Language
2829 from lp.translations.interfaces.pofile import IPOFileSet
2830 from lp.translations.interfaces.potemplate import (
2831
2832=== modified file 'lib/lp/translations/model/translationmessage.py'
2833--- lib/lp/translations/model/translationmessage.py 2010-08-20 20:31:18 +0000
2834+++ lib/lp/translations/model/translationmessage.py 2010-09-02 12:57:56 +0000
2835@@ -24,7 +24,6 @@
2836 from storm.store import Store
2837 from zope.interface import implements
2838
2839-from canonical.cachedproperty import cachedproperty
2840 from canonical.database.constants import (
2841 DEFAULT,
2842 UTC_NOW,
2843@@ -37,6 +36,7 @@
2844 sqlvalues,
2845 )
2846 from lp.registry.interfaces.person import validate_public_person
2847+from lp.services.propertycache import cachedproperty
2848 from lp.translations.interfaces.translationmessage import (
2849 ITranslationMessage,
2850 ITranslationMessageSet,
2851
2852=== modified file 'lib/lp/translations/utilities/translation_import.py'
2853--- lib/lp/translations/utilities/translation_import.py 2010-08-20 20:31:18 +0000
2854+++ lib/lp/translations/utilities/translation_import.py 2010-09-02 12:57:56 +0000
2855@@ -21,7 +21,6 @@
2856 from zope.component import getUtility
2857 from zope.interface import implements
2858
2859-from canonical.cachedproperty import cachedproperty
2860 from canonical.config import config
2861 from canonical.database.sqlbase import (
2862 cursor,
2863@@ -33,6 +32,7 @@
2864 IPersonSet,
2865 PersonCreationRationale,
2866 )
2867+from lp.services.propertycache import cachedproperty
2868 from lp.translations.interfaces.translationexporter import (
2869 ITranslationExporter,
2870 )
2871
2872=== modified file 'utilities/sourcedeps.conf'
2873--- utilities/sourcedeps.conf 2010-08-30 00:51:55 +0000
2874+++ utilities/sourcedeps.conf 2010-09-02 12:57:56 +0000
2875@@ -14,4 +14,4 @@
2876 subvertpy lp:~launchpad-pqm/subvertpy/trunk;revno=2042
2877 python-debian lp:~launchpad-pqm/python-debian/devel;revno=185
2878 testresources lp:~launchpad-pqm/testresources/dev;revno=16
2879-shipit lp:~launchpad-pqm/shipit/trunk;revno=8910 optional
2880+shipit lp:~launchpad-pqm/shipit/trunk;revno=8911 optional