Merge lp:~lvh/divmod.org/storeless-conform-1118498 into lp:divmod.org

Proposed by Laurens Van Houtven
Status: Merged
Approved by: Tristan Seligmann
Approved revision: 2705
Merged at revision: 2704
Proposed branch: lp:~lvh/divmod.org/storeless-conform-1118498
Merge into: lp:divmod.org
Diff against target: 93 lines (+34/-20)
2 files modified
Axiom/axiom/item.py (+16/-14)
Axiom/axiom/test/test_powerup.py (+18/-6)
To merge this branch: bzr merge lp:~lvh/divmod.org/storeless-conform-1118498
Reviewer Review Type Date Requested Status
Tristan Seligmann Approve
Review via email: mp+148490@code.launchpad.net

Description of the change

Adds a test case for __conform__ for unstored objects, and changes the implementation to pass that test.

This means that unstored objects with in-memory powerups can be adapted to their interfaces. Previously, in-memory powerups were useless for unstored objects.

To post a comment you must log in.
Revision history for this message
Tristan Seligmann (mithrandi) wrote :

This basically looks good, I only have two trivial things to comment on:

8 -
9 aggregateInterfaces = {
10 IService: serviceSpecialCase,
11 - IServiceCollection: serviceSpecialCase}
12 + IServiceCollection: serviceSpecialCase
13 + }

Instead of getting into a convoluted discussion about coding style, I'll just suggest that since you're not otherwise changing this code, the formatting should be left as-is.

36 + # adapt every popwerup to IPowerupIndirector, calling this method.

Typo: "popwerup" -> "powerup"

review: Needs Fixing
2704. By Laurens Van Houtven

Fix popwerup -> powerup typo

2705. By Laurens Van Houtven

Undo style change

Revision history for this message
Laurens Van Houtven (lvh) wrote :

Hey Tristan,

Thanks for your review, I've made the requested changes.

Revision history for this message
Tristan Seligmann (mithrandi) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Axiom/axiom/item.py'
2--- Axiom/axiom/item.py 2010-04-03 22:36:04 +0000
3+++ Axiom/axiom/item.py 2013-05-02 12:51:26 +0000
4@@ -193,7 +193,6 @@
5 return value is the powerup. These are used only by the callable
6 interface adaption API, not C{powerupsFor}.
7 """
8-
9 aggregateInterfaces = {
10 IService: serviceSpecialCase,
11 IServiceCollection: serviceSpecialCase}
12@@ -314,19 +313,22 @@
13 special rules. The full list of such interfaces is present in the
14 'aggregateInterfaces' class attribute.
15 """
16- if (self.store is None # Don't bother doing a *query* if we're not
17- # even stored in a store yet
18- or interface is IPowerupIndirector): # you can't do a query for
19- # IPowerupIndirector, that
20- # would just start an infinite
21- # loop.
22- return
23- pups = self.powerupsFor(interface)
24- agg = self.aggregateInterfaces
25- if interface in agg:
26- return agg[interface](self, pups)
27- for p in pups:
28- return p
29+ if interface is IPowerupIndirector:
30+ # This would cause an infinite loop, since powerupsFor will try to
31+ # adapt every powerup to IPowerupIndirector, calling this method.
32+ return
33+
34+ try:
35+ pups = self.powerupsFor(interface)
36+ except AttributeError: # self.store is None -> self.store.query...
37+ return
38+
39+ aggregator = self.aggregateInterfaces.get(interface, None)
40+ if aggregator is not None:
41+ return aggregator(self, pups)
42+
43+ for pup in pups:
44+ return pup # return first one, or None if no powerups
45
46
47 def powerupsFor(self, interface):
48
49=== modified file 'Axiom/axiom/test/test_powerup.py'
50--- Axiom/axiom/test/test_powerup.py 2008-10-09 13:17:41 +0000
51+++ Axiom/axiom/test/test_powerup.py 2013-05-02 12:51:26 +0000
52@@ -289,14 +289,19 @@
53 """
54 Tests for the behavior of powerups which are not database-resident.
55 """
56+ def _createEmpowered(self, withStore=True):
57+ powerup = object()
58+ item = SumContributor(store=Store() if withStore else None)
59+ item.inMemoryPowerUp(powerup, ISumProducer)
60+ return powerup, item
61+
62+
63 def test_powerupsFor(self):
64 """
65 L{Item.powerupsFor} returns a list the first element of which is the
66 object previously passed to L{Item.inMemoryPowerUp}.
67 """
68- powerup = object()
69- item = SumContributor(store=Store())
70- item.inMemoryPowerUp(powerup, ISumProducer)
71+ powerup, item = self._createEmpowered()
72 self.assertEqual(list(item.powerupsFor(ISumProducer)), [powerup])
73
74
75@@ -306,8 +311,15 @@
76 that item for that interface even if there are database-resident
77 powerups on that item for that interface.
78 """
79- powerup = object()
80- item = SumContributor(store=Store())
81- item.inMemoryPowerUp(powerup, ISumProducer)
82+ powerup, item = self._createEmpowered()
83 item.powerUp(item, ISumProducer)
84 self.assertIdentical(ISumProducer(item), powerup)
85+
86+
87+ def test_conformWithoutStore(self):
88+ """
89+ Adaptation (through L{Item.__conform__}) should be allowed even if the
90+ object is not stored, as long as it has an in-memory powerup.
91+ """
92+ powerup, item = self._createEmpowered(withStore=False)
93+ self.assertIdentical(ISumProducer(item), powerup)

Subscribers

People subscribed via source and target branches