Here's yet another alternative that may be easier to swallow:
Stick with the default traverser and provide your users with a base 
resource class for them to subclass.
The base class has some new method for your users to override (in the 
example below I named it "getitem") which takes a name and should return an 
object or None.  If getitem raises a KeyError, a RuntimeError is raised 
that includes the KeyError's stacktrace.


import traceback

class BaseResource(object):

    def getitem(self, name):
        """ Return resource for ``name``, or ``None``. """
        return None

    def __getitem__(self, name):
        try:
            item = self.getitem(name)
        except KeyError as e:
            tb = traceback.format_exc()
            raise RuntimeError("getitem(%r) raised: %r\n\n%s" % (name, e, 
tb))
        if item is None:
            raise KeyError
        return item



On Thursday, March 7, 2013 5:04:39 AM UTC-5, Peter Waller wrote:
>
> On 6 March 2013 16:48, Thomas G. Willis <[email protected] 
> <javascript:>>wrote:
>
>> this is just an idea, but you could catch KeyError s and log the 
>> stacktrace before re-raising, that might help.  
>>
>
> On 6 March 2013 16:51, Michael Merickel <[email protected] 
> <javascript:>>wrote:
>
>> Inside of your __getitem__ you have total control over what that method 
>> will return. You only want a KeyError to be raised if you are sure that the 
>> goal is to exit with no context. Thus, define what you mean by no context 
>> as "class NoContext(Exception): pass" .
>>
>> def __getitem__(self, key):
>>     try:
>>         # stuff to find context
>>         return context
>>     except NoContext:
>>         raise KeyError
>>     except KeyError:
>>         raise SomeOtherExceptionThatIsNotKeyError
>>
>
> The point I've been trying to make is that I also don't control the 
> `__getitem__` because I want other people to write them. These people may 
> never share their code with me. 
>
> In addition, IMO this isn't a pythonic solution. The try/except would have 
> to go in every resource written which is silly boilerplate. This is because 
> except for the most trivial implementations I can't guarantee that code 
> won't unintentionally cause a KeyError. Re-raising the true KeyError as a 
> different exception loses information about the nature (the key, the stack 
> trace) of the original exception. It makes KeyError special. It changes the 
> semantics that a KeyError is used to denote a non-existing resource. None 
> of the above is ideal, but maybe I should get over it.
>
> In my mind, the traversal *structure* is awesome for my use case and I 
> still love it. I'm beginning to think that in my replacement traverser I 
> should lose the idea that resources should pretend to be dictionaries and 
> instead use a different protocol. For example, instead of `__getitem__` I 
> could call it `child`, then I could have my own exception for resources 
> which don't exist, or a convention that it returns None.
>  

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pylons-discuss?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to