On Wed, Feb 1, 2012 at 10:48 AM, Ethan Furman <et...@stoneleaf.us> wrote: > Guido van Rossum wrote: >> >> Hm... Reading this draft, I like the idea of using "raise X from >> None", but I still have one quibble. It seems the from clause sets >> __cause__, and __cause__ can indicate three things: (1) print >> __cause__ (explicitly set), (2) print __context__ (default), (3) print >> neither (raise X from None). For (1), __cause__ must of course be a >> traceback object. > > > Actually, for (1) __cause__ is an exception object, not a traceback.
Ah, sorry. I'm not as detail-oriented as I was. :-) >> The PEP currently proposes to use two special >> values: False for (2), None for (3). To me, this has a pretty strong >> code smell, and I don't want this pattern to be enshrined in a PEP as >> an example for all to follow. (And I also don't like "do as I say, >> don't do as I do." :-) > > > My apologies for my ignorance, but is the code smell because both False and > None evaluate to bool(False)? That's part of it, but the other part is that the type of __context__ is now truly dynamic. I often *think* of variables as having some static type, e.g. "integer" or "Foo instance", and for most Foo instances I consider None an acceptable value (since that's how pointer types work in most static languages). But the type of __context__ you're proposing is now a union of exception and bool, except that the bool can only be False. > I suppose we could use True for (2) to > indicate that __context__ should be printed, leaving None for (3)... but > having __context__ at None and __cause__ at True could certainly be > confusing (the default case when no chaining is in effect). It seems you really need a marker object. I'd be fine with using some other opaque marker -- IMO that's much better than using False but disallowing True. >> Can we think of a different special value to distinguish between (2) >> and (3)? Ideally one that doesn't change the nice "from None" idiom, >> which I actually like as a way to spell this. > > > How about this: > > > Exception Life Cycle > ==================== > > > Stage 1 - brand new exception > ----------------------------- > > raise ValueError() > > * __context__ is None > * __cause__ is None > > > Stage 2 - exception caught, exception raised > -------------------------------------------- > > try: > raise ValueError() > except Exception: > raise CustomError() > > * __context__ is previous exception > * __cause__ is True > > > Stage 3 - exception raised from [exception | None] > -------------------------------------------------- > > try: > raise ValueError() > except Exception: > raise CustomError() from [OtherException | None] > > * __context__ is previous exception > * __cause__ is [OtherException | None] No, this has the same code smell for me. See above. >> Sorry that life isn't easier, > > > Where would be the fun without the challenge? +1 :-) -- --Guido van Rossum (python.org/~guido) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com