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.