[Zope3-dev] interface conventions: default=_RAISE_ERROR

Gary Poster garyposter@earthlink.net
Sun, 12 May 2002 19:28:35 -0400


On Sunday 12 May 2002 05:17 pm, Martijn Faassen wrote:
> Gary Poster wrote:
> > On Saturday 11 May 2002 04:04 pm, Martijn Faassen wrote:
> > > Gary Poster wrote:
> >
> > This convention, or something similar, goes back at least to Zope 2
> > development days, I think--long before my Zope interests.
>
> Could you give me an example of such in Zope2? I do not recall having
> run into this before.

search for default=_marker, for instance

> > In Zope 3, as you
> > said, a _RAISE_ERROR-type marker is used in Containers; I didn't notice
> > Traversal, but I believe it.
>
> It was just a grep for _RAISE_KEYERROR, to see how prevalent it was. :)
>
> [snip]
>
> > If you'd like to ponder and argue the issue a little more, I suggest
> > looking at the interfaces in the ComponentArchitecture package as a
> > conversation starter, remembering that every time you see "default=None"
> > it's a lie: we're using a marker convention.
>
> [snip]
>
> Okay, I took a look at that. It's just I myself generally dislike methods
> that behave differently dependent on the amount of arguments passed; in
> that case I am strongly inclined to pick two separate methods instead. I
> can't argue that very strongly, however.
>
> I am not well able to judge what the needs of ComponentArchitecture users
> are however, here -- I was speaking about what I see in Container and
> the like, where I think a strong case can be made to do away with
> _RAISE_KEYERROR and go to a more Pythonic pattern (after all Containers
> are very much like mappings of some sort).

I just dropped in on the tail end of the IRC on this, but I agree with you in 
the case of the IContainer, I think.  And I understand and appreciate your 
argument in general; but with modules like those in the ComponentArchitecture 
package, I find the brevity of the convention we are discussing to be useful.

> > I think raising an error is "correct," returning a default is a useful
> > shortcut, and combining the two on the basis of a marker is a reasonable
> > compromise that's easy to code.  Duplicating the pertinent methods to
> > parallel __getitem__ and get seems unnecessary and I don't care for it. 
> > But again, I'm happy to accomodate a community or ZC decision.
>
> For methods that do not parallel existing Python (folk) interfaces so
> much my objections are less strong. 

Great.

> A question though; how do you
> implement Guido's suggestion of explicitly passing an exception to
> signal you want it raised? Perhaps a premature optimization question,
> but aren't we going from a cheap 'is None' check to a 'is one of my
> base classes Exception' check, or isn't it like that? Are we checking
> whether a *particular* exception is passed instead, so
> 'is ComponentLookupError'?

In my opinion, the latter: a particular exception, as defined by the argument 
signature, using identity.  It's quick to excecute, easy to code, and 
*relatively* clear in the argument signature (something like 
"default=ComponentLookupError") as to what's going to happen.  The fact that 
this "default" keyword can either raise or return is a bit murky, which I 
perceive to be the heart of your point, but...it's a compromise.

Thanks

Gary