This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author taleinat
Recipients kbk, taleinat
Date 2007-10-28.00:28:30
SpamBayes Score 0.008437683
Marked as misclassified No
Message-id <1193531312.6.0.353927917933.issue1252@psf.upfronthosting.co.za>
In-reply-to
Content
It seems we're looking at Delegators and Percolators from increasingly
different points of view. Let's back up a little.


I see a Delegator object as a transparent proxy to its "delegate". This
means that attribute access is automatically delegated to the delegate,
unless it is explicitly overridden by the Delegator. That's it.

Some use cases for such a transparent proxy are:
* override only specific attributes/methods of an object
* allow replacement of an object which is referenced in several places
without having to update every reference

(Caching is just an implementation detail, whose only purpose is to
facilitate changing a Delegator's delegate.)


As for Percolator, it really "is a" delegator -- it delegates attribute
access to the bottom of the chain, unless it is explicitly overridden.
True, in a "normal" Delegator this overriding can only be done in one
place, and in a Percolator it can also happen in any of the chain's
links. But the concept is identical -- it is a transparent proxy for an
underlying object.

IMO chaining Percolators makes just as much sense as chaining Delegators
-- you're just chaining proxies. How each proxy works internally doesn't
really matter (as long as they work :).


Now, it seems to me that you aren't looking at Delegators and
Peroclators as transparent proxies at all. Specifically, what you wrote
implies that in order to proxy a callable, one should explicitly define
an __call__ method in their Delegator class/instance. But this is
exactly the opposite of the behavior with any other method/attribute,
where I can implicitly have the underlying attribute used by not
defining it in the Delegator. This is Delegator is for!


I'm attaching a Python file which will hopefully show how __call__ is
out of sync with the rest of Delegator's behavior. In its context,
"forwarded" means explicitly defined by a Delegator. "intercepted" means
that except for the interceptor and catcher, the method is not defined
(i.e. by the passers). Please take a moment to run it.


I should note that the situation is similar with other "magic" methods,
e.g. len(). This seems to make Python a bit less dynamic that I would
expect. Aside from implementation considerations such as speed, I'm not
sure I see why this is the way it is, e.g. why dynamically giving a
__call__ attribute to an instance shouldn't make it callable. I'll do
some more searching and reading on this.

Even though, I still think being able to delegate/percolate callables is
important enough to warrant such a change. After all, at the bottom
line, if the underlying object is callable then it will be called, and
if not then an appropriate exception will be raised. Isn't that the
Right Thing?
Files
File name Uploaded
Delegators3.py taleinat, 2007-10-28.00:28:30
History
Date User Action Args
2007-10-28 00:28:33taleinatsetspambayes_score: 0.00843768 -> 0.008437683
recipients: + taleinat, kbk
2007-10-28 00:28:32taleinatsetspambayes_score: 0.00843768 -> 0.00843768
messageid: <1193531312.6.0.353927917933.issue1252@psf.upfronthosting.co.za>
2007-10-28 00:28:32taleinatlinkissue1252 messages
2007-10-28 00:28:30taleinatcreate