Lines 38-51
Link Here
|
38 |
|
38 |
|
39 |
# The registrations are of the form: |
39 |
# The registrations are of the form: |
40 |
|
40 |
|
41 |
# {(subscription, with, name, specification) -> factories} |
41 |
# {(subscription, waswith, name, specification) -> factories} |
42 |
|
42 |
|
43 |
# where: |
43 |
# where: |
44 |
|
44 |
|
45 |
# 'subscription' is a flag indicating if this registration is for |
45 |
# 'subscription' is a flag indicating if this registration is for |
46 |
# subscription adapters. |
46 |
# subscription adapters. |
47 |
|
47 |
|
48 |
# 'with' is a tuple of specs that is non-empty only in the case |
48 |
# 'waswith' is a tuple of specs that is non-empty only in the case |
49 |
# of multi-adapters. |
49 |
# of multi-adapters. |
50 |
|
50 |
|
51 |
# 'name' is a unicode adapter name. Unnamed adapters have an empty |
51 |
# 'name' is a unicode adapter name. Unnamed adapters have an empty |
Lines 68-74
Link Here
|
68 |
|
68 |
|
69 |
# For multiple adapters: |
69 |
# For multiple adapters: |
70 |
# |
70 |
# |
71 |
# {(specification, order) -> {name -> {with -> object}}} |
71 |
# {(specification, order) -> {name -> {waswith -> object}}} |
72 |
|
72 |
|
73 |
# For single subscription adapters: |
73 |
# For single subscription adapters: |
74 |
# |
74 |
# |
Lines 76-82
Link Here
|
76 |
|
76 |
|
77 |
# For multiple-subscription adapters: |
77 |
# For multiple-subscription adapters: |
78 |
# |
78 |
# |
79 |
# {('s', specification, order) -> {with -> tuple([object])}} |
79 |
# {('s', specification, order) -> {waswith -> tuple([object])}} |
80 |
|
80 |
|
81 |
|
81 |
|
82 |
from __future__ import generators |
82 |
from __future__ import generators |
Lines 191-212
Link Here
|
191 |
if not oldwithobs: |
191 |
if not oldwithobs: |
192 |
oldwithobs = implied[key] = {} |
192 |
oldwithobs = implied[key] = {} |
193 |
|
193 |
|
194 |
# v is {with -> tuple([object])} |
194 |
# v is {waswith -> tuple([object])} |
195 |
for with, objects in v.iteritems(): |
195 |
for waswith, objects in v.iteritems(): |
196 |
oldwithobs[with] = oldwithobs.get(with, ()) + objects |
196 |
oldwithobs[waswith] = oldwithobs.get(waswith, ()) + objects |
197 |
|
197 |
|
198 |
else: |
198 |
else: |
199 |
oldbyname = implied.get(key) |
199 |
oldbyname = implied.get(key) |
200 |
if not oldbyname: |
200 |
if not oldbyname: |
201 |
implied[key] = oldbyname = {} |
201 |
implied[key] = oldbyname = {} |
202 |
|
202 |
|
203 |
# v is {name -> {with -> ?}} |
203 |
# v is {name -> {waswith -> ?}} |
204 |
for name, withobs in v.iteritems(): |
204 |
for name, withobs in v.iteritems(): |
205 |
oldwithobs = oldbyname.get(name) |
205 |
oldwithobs = oldbyname.get(name) |
206 |
if not oldwithobs: |
206 |
if not oldwithobs: |
207 |
oldwithobs = oldbyname[name] = {} |
207 |
oldwithobs = oldbyname[name] = {} |
208 |
|
208 |
|
209 |
# withobs is {with -> object} |
209 |
# withobs is {waswith -> object} |
210 |
oldwithobs.update(withobs) |
210 |
oldwithobs.update(withobs) |
211 |
|
211 |
|
212 |
# Now flatten with mappings to tuples |
212 |
# Now flatten with mappings to tuples |
Lines 219-226
Link Here
|
219 |
byname = v |
219 |
byname = v |
220 |
for name, value in byname.iteritems(): |
220 |
for name, value in byname.iteritems(): |
221 |
if isinstance(value, dict): |
221 |
if isinstance(value, dict): |
222 |
# We have {with -> value} |
222 |
# We have {waswith -> value} |
223 |
# convert it to sorted [(with, value] |
223 |
# convert it to sorted [(waswith, value] |
224 |
byname[name] = orderwith(value) |
224 |
byname[name] = orderwith(value) |
225 |
|
225 |
|
226 |
self.get = implied.get |
226 |
self.get = implied.get |
Lines 253-276
Link Here
|
253 |
def unsubscribe(self, dependent): |
253 |
def unsubscribe(self, dependent): |
254 |
del self.dependents[dependent] |
254 |
del self.dependents[dependent] |
255 |
|
255 |
|
256 |
def _adaptTo(self, specification, object, name='', with=()): |
256 |
def _adaptTo(self, specification, object, name='', waswith=()): |
257 |
if object is None: |
257 |
if object is None: |
258 |
try: |
258 |
try: |
259 |
del self.adapters[False, tuple(with), name, specification] |
259 |
del self.adapters[False, tuple(waswith), name, specification] |
260 |
except KeyError: |
260 |
except KeyError: |
261 |
pass |
261 |
pass |
262 |
else: |
262 |
else: |
263 |
self.adapters[False, tuple(with), name, specification |
263 |
self.adapters[False, tuple(waswith), name, specification |
264 |
] = object |
264 |
] = object |
265 |
|
265 |
|
266 |
self.dirty() |
266 |
self.dirty() |
267 |
|
267 |
|
268 |
def _subscriptionAdaptTo(self, specification, object, with=()): |
268 |
def _subscriptionAdaptTo(self, specification, object, waswith=()): |
269 |
if object is None: |
269 |
if object is None: |
270 |
raise TypeError, ("Unregistering subscription adapters" |
270 |
raise TypeError, ("Unregistering subscription adapters" |
271 |
" isn't implemented") |
271 |
" isn't implemented") |
272 |
|
272 |
|
273 |
key = (True, tuple(with), '', specification) |
273 |
key = (True, tuple(waswith), '', specification) |
274 |
self.adapters[key] = self.adapters.get(key, ()) + (object, ) |
274 |
self.adapters[key] = self.adapters.get(key, ()) + (object, ) |
275 |
self.dirty() |
275 |
self.dirty() |
276 |
|
276 |
|
Lines 282-299
Link Here
|
282 |
|
282 |
|
283 |
def orderwith(bywith): |
283 |
def orderwith(bywith): |
284 |
|
284 |
|
285 |
# Convert {with -> adapter} to withs, [(with, value)] |
285 |
# Convert {waswith -> adapter} to withs, [(waswith, value)] |
286 |
# such that there are no i, j, i < j, such that |
286 |
# such that there are no i, j, i < j, such that |
287 |
# withs[j][0] extends withs[i][0]. |
287 |
# withs[j][0] extends withs[i][0]. |
288 |
|
288 |
|
289 |
withs = [] |
289 |
withs = [] |
290 |
for with, value in bywith.iteritems(): |
290 |
for waswith, value in bywith.iteritems(): |
291 |
for i, (w, v) in enumerate(withs): |
291 |
for i, (w, v) in enumerate(withs): |
292 |
if withextends(with, w): |
292 |
if withextends(waswith, w): |
293 |
withs.insert(i, (with, value)) |
293 |
withs.insert(i, (waswith, value)) |
294 |
break |
294 |
break |
295 |
else: |
295 |
else: |
296 |
withs.append((with, value)) |
296 |
withs.append((waswith, value)) |
297 |
|
297 |
|
298 |
return withs |
298 |
return withs |
299 |
|
299 |
|
Lines 355-361
Link Here
|
355 |
|
355 |
|
356 |
# Multi adapter |
356 |
# Multi adapter |
357 |
|
357 |
|
358 |
with = required[1:] |
358 |
waswith = required[1:] |
359 |
key = provided, order |
359 |
key = provided, order |
360 |
|
360 |
|
361 |
for surrogate in self.get(required[0]), self._default: |
361 |
for surrogate in self.get(required[0]), self._default: |
Lines 377-383
Link Here
|
377 |
for rwith, value in bywith: |
377 |
for rwith, value in bywith: |
378 |
# the `rank` describes how well the found adapter matches. |
378 |
# the `rank` describes how well the found adapter matches. |
379 |
rank = [] |
379 |
rank = [] |
380 |
for rspec, spec in zip(rwith, with): |
380 |
for rspec, spec in zip(rwith, waswith): |
381 |
if not spec.isOrExtends(rspec): |
381 |
if not spec.isOrExtends(rspec): |
382 |
break # This one is no good |
382 |
break # This one is no good |
383 |
# Determine the rank of this particular specification. |
383 |
# Determine the rank of this particular specification. |
Lines 459-465
Link Here
|
459 |
|
459 |
|
460 |
# Multi |
460 |
# Multi |
461 |
key = 's', provided, order |
461 |
key = 's', provided, order |
462 |
with = required[1:] |
462 |
waswith = required[1:] |
463 |
result = [] |
463 |
result = [] |
464 |
|
464 |
|
465 |
for surrogate in self.get(required[0]), self._default: |
465 |
for surrogate in self.get(required[0]), self._default: |
Lines 468-474
Link Here
|
468 |
continue |
468 |
continue |
469 |
|
469 |
|
470 |
for rwith, values in bywith: |
470 |
for rwith, values in bywith: |
471 |
for rspec, spec in zip(rwith, with): |
471 |
for rspec, spec in zip(rwith, waswith): |
472 |
if not spec.isOrExtends(rspec): |
472 |
if not spec.isOrExtends(rspec): |
473 |
break # This one is no good |
473 |
break # This one is no good |
474 |
else: |
474 |
else: |
Lines 537-558
Link Here
|
537 |
|
537 |
|
538 |
def register(self, required, provided, name, value): |
538 |
def register(self, required, provided, name, value): |
539 |
if required: |
539 |
if required: |
540 |
with = [] |
540 |
waswith = [] |
541 |
for iface in required[1:]: |
541 |
for iface in required[1:]: |
542 |
if iface is None: |
542 |
if iface is None: |
543 |
iface = Interface |
543 |
iface = Interface |
544 |
with.append(iface) |
544 |
waswith.append(iface) |
545 |
with = tuple(with) |
545 |
waswith = tuple(waswith) |
546 |
required = self.get(required[0]) |
546 |
required = self.get(required[0]) |
547 |
else: |
547 |
else: |
548 |
with = () |
548 |
waswith = () |
549 |
required = self._null |
549 |
required = self._null |
550 |
|
550 |
|
551 |
if not isinstance(name, basestring): |
551 |
if not isinstance(name, basestring): |
552 |
raise TypeError("The name provided to provideAdapter " |
552 |
raise TypeError("The name provided to provideAdapter " |
553 |
"must be a string or unicode") |
553 |
"must be a string or unicode") |
554 |
|
554 |
|
555 |
required._adaptTo(provided, value, unicode(name), with) |
555 |
required._adaptTo(provided, value, unicode(name), waswith) |
556 |
|
556 |
|
557 |
def lookupAll(self, required, provided): |
557 |
def lookupAll(self, required, provided): |
558 |
order = len(required) |
558 |
order = len(required) |
Lines 585-591
Link Here
|
585 |
|
585 |
|
586 |
# Multi adapter |
586 |
# Multi adapter |
587 |
|
587 |
|
588 |
with = required[1:] |
588 |
waswith = required[1:] |
589 |
key = provided, order |
589 |
key = provided, order |
590 |
first = () |
590 |
first = () |
591 |
|
591 |
|
Lines 599-605
Link Here
|
599 |
continue |
599 |
continue |
600 |
|
600 |
|
601 |
for rwith, value in bywith: |
601 |
for rwith, value in bywith: |
602 |
for rspec, spec in zip(rwith, with): |
602 |
for rspec, spec in zip(rwith, waswith): |
603 |
if not spec.isOrExtends(rspec): |
603 |
if not spec.isOrExtends(rspec): |
604 |
break # This one is no good |
604 |
break # This one is no good |
605 |
else: |
605 |
else: |
Lines 611-629
Link Here
|
611 |
|
611 |
|
612 |
def subscribe(self, required, provided, value): |
612 |
def subscribe(self, required, provided, value): |
613 |
if required: |
613 |
if required: |
614 |
required, with = self.get(required[0]), tuple(required[1:]) |
614 |
required, waswith = self.get(required[0]), tuple(required[1:]) |
615 |
else: |
615 |
else: |
616 |
required = self._null |
616 |
required = self._null |
617 |
with = () |
617 |
waswith = () |
618 |
|
618 |
|
619 |
if provided is None: |
619 |
if provided is None: |
620 |
provided = Null |
620 |
provided = Null |
621 |
|
621 |
|
622 |
required._subscriptionAdaptTo(provided, value, with) |
622 |
required._subscriptionAdaptTo(provided, value, waswith) |
623 |
|
623 |
|
624 |
def mextends(with, rwith): |
624 |
def mextends(waswith, rwith): |
625 |
if len(with) == len(rwith): |
625 |
if len(waswith) == len(rwith): |
626 |
for w, r in zip(with, rwith): |
626 |
for w, r in zip(waswith, rwith): |
627 |
if not w.isOrExtends(r): |
627 |
if not w.isOrExtends(r): |
628 |
break |
628 |
break |
629 |
else: |
629 |
else: |
Lines 646-664
Link Here
|
646 |
# TODO: Backward compatability |
646 |
# TODO: Backward compatability |
647 |
# Don't need to handle 3-tuples some day |
647 |
# Don't need to handle 3-tuples some day |
648 |
try: |
648 |
try: |
649 |
(subscription, with, name, target) = key |
649 |
(subscription, waswith, name, target) = key |
650 |
except ValueError: |
650 |
except ValueError: |
651 |
(with, name, target) = key |
651 |
(waswith, name, target) = key |
652 |
subscription = False |
652 |
subscription = False |
653 |
|
653 |
|
654 |
if subscription: |
654 |
if subscription: |
655 |
if with: |
655 |
if waswith: |
656 |
_add_multi_sub_adapter(with, target, multi, value) |
656 |
_add_multi_sub_adapter(waswith, target, multi, value) |
657 |
else: |
657 |
else: |
658 |
_add_named_sub_adapter(target, implied, value) |
658 |
_add_named_sub_adapter(target, implied, value) |
659 |
else: |
659 |
else: |
660 |
if with: |
660 |
if waswith: |
661 |
_add_multi_adapter(with, name, target, target, multi, |
661 |
_add_multi_adapter(waswith, name, target, target, multi, |
662 |
registered, value) |
662 |
registered, value) |
663 |
else: |
663 |
else: |
664 |
_add_named_adapter(target, target, name, implied, |
664 |
_add_named_adapter(target, target, name, implied, |
Lines 688-697
Link Here
|
688 |
_add_named_adapter(b, provided, name, implied, |
688 |
_add_named_adapter(b, provided, name, implied, |
689 |
registered, value) |
689 |
registered, value) |
690 |
|
690 |
|
691 |
def _add_multi_adapter(with, name, target, provided, implied, |
691 |
def _add_multi_adapter(waswith, name, target, provided, implied, |
692 |
registered, object): |
692 |
registered, object): |
693 |
|
693 |
|
694 |
ikey = target, (len(with) + 1) |
694 |
ikey = target, (len(waswith) + 1) |
695 |
byname = implied.get(ikey) |
695 |
byname = implied.get(ikey) |
696 |
if not byname: |
696 |
if not byname: |
697 |
byname = implied[ikey] = {} |
697 |
byname = implied[ikey] = {} |
Lines 701-708
Link Here
|
701 |
bywith = byname[name] = {} |
701 |
bywith = byname[name] = {} |
702 |
|
702 |
|
703 |
|
703 |
|
704 |
rkey = ikey, name, with # The full key has all 4 |
704 |
rkey = ikey, name, waswith # The full key has all 4 |
705 |
if (with not in bywith |
705 |
if (waswith not in bywith |
706 |
or |
706 |
or |
707 |
(rkey not in registered or registered[rkey].extends(provided)) |
707 |
(rkey not in registered or registered[rkey].extends(provided)) |
708 |
): |
708 |
): |
Lines 710-719
Link Here
|
710 |
# general interface that is closer provided than what we had |
710 |
# general interface that is closer provided than what we had |
711 |
# before |
711 |
# before |
712 |
registered[rkey] = provided |
712 |
registered[rkey] = provided |
713 |
bywith[with] = object |
713 |
bywith[waswith] = object |
714 |
|
714 |
|
715 |
for b in target.__bases__: |
715 |
for b in target.__bases__: |
716 |
_add_multi_adapter(with, name, b, provided, implied, |
716 |
_add_multi_adapter(waswith, name, b, provided, implied, |
717 |
registered, object) |
717 |
registered, object) |
718 |
|
718 |
|
719 |
def _add_named_sub_adapter(target, implied, objects): |
719 |
def _add_named_sub_adapter(target, implied, objects): |
Lines 723-735
Link Here
|
723 |
for b in target.__bases__: |
723 |
for b in target.__bases__: |
724 |
_add_named_sub_adapter(b, implied, objects) |
724 |
_add_named_sub_adapter(b, implied, objects) |
725 |
|
725 |
|
726 |
def _add_multi_sub_adapter(with, target, implied, objects): |
726 |
def _add_multi_sub_adapter(waswith, target, implied, objects): |
727 |
key = 's', target, (len(with) + 1) |
727 |
key = 's', target, (len(waswith) + 1) |
728 |
bywith = implied.get(key) |
728 |
bywith = implied.get(key) |
729 |
if not bywith: |
729 |
if not bywith: |
730 |
bywith = implied[key] = {} |
730 |
bywith = implied[key] = {} |
731 |
|
731 |
|
732 |
bywith[with] = bywith.get(with, ()) + objects |
732 |
bywith[waswith] = bywith.get(waswith, ()) + objects |
733 |
|
733 |
|
734 |
for b in target.__bases__: |
734 |
for b in target.__bases__: |
735 |
_add_multi_sub_adapter(with, b, implied, objects) |
735 |
_add_multi_sub_adapter(waswith, b, implied, objects) |