
On Fri, Oct 1, 2021 at 6:12 AM Soni L. <fakedme+py@gmail.com> wrote:
Congratulations, you showed me some extremely complicated code, and then got miffed when I messed up something in trying to simplify it. Well done, you successfully tripped me up in my attempt to make code better.
Fair enough, we went too far there, sorry.
Apology accepted.
Can we stick to the point, please? You still haven't shown why (a) a context manager, nor (b) a custom exception, cannot solve this problem far better than this extremely magical syntax.
This syntax is far from magical. We're not sure how the context manager would work here, but, a custom exception doesn't work, because you still have the... whatever you'd call this issue: https://mail.python.org/pipermail/python-ideas/2017-June/046109.html (one of Steven's links also linked to this and it's fairly relevant.)
I don't think ImportError is actually a problem; if you're catching ImportError to cope with the fact that some module can't be loaded, wouldn't it be *correct* to catch the fact that a dependency of it failed to load? The exception states the exact failing module, so if you need to distinguish, you can. As mentioned, PEP 479 isn't really about "nested StopIteration", it's about the interaction between generator functions and iterators. They're using different protocols that happen to collide on an implementation detail. The trouble with the "nested AttributeError" problem is that it's indistinguishable from a genuinely refactored example. So that kinda is what you're talking about, and I'll focus on this one from here.
The imports issue sadly wouldn't be solved with this feature, but attributes would:
def __getattr__(self, name) with AttributeError: stuff and things if the thing: return some thing raise AttributeError
This also applies anywhere else you'd have something wrapping another thing and they happen to use the same exceptions in slightly distinct ways.
Right. And this IS a reasonable consideration. But most getattr methods are pretty simple, and would be best solved by something like: def __getattr__(self, name): with dontraise(AttributeError): stuff and things if the thing: return some thing raise AttributeError
Yes, it's most noticeable with StopIteration (which got tweaked with the change to generators), imports (because the modules you depend on generally also depend on other modules), and attributes (because you might do a foo.typo in your __getattr__ and it's not particularly uncommon to dynamically probe attributes). But it does happen in other cases too. (KeyError is an interesting one, especially when making a wrapper over a dict/subclassing dict/etc.)
In one of the examples, we showed this function: https://github.com/ganarchy/GAnarchy/blob/993a8ca85db1564e64550276d61d972342...
In reality, we really should also be catching any PropertyError in the unpacking, just in case someone happened to implement get_property_values incorrectly and it waited until iteration to raise, because that's a case where a bug would be swallowed. And the only reason we didn't bother to guard against ValueError during iteration is simply this: property kinds have arity, some are 1-ary and some are n-ary. it's a programming bug to call get_property_value on an n-ary property, so we decided to assume nobody's gonna actually catch those ValueError. This is, in practice, an extremely dangerous assumption, especially in the wider ecosystem, because, as it's a documented part of the API, ppl do assume the implementation is strictly correct about it. But it would also be wrong to not make it a documented part of the API.
I still think that your use of LookupError is confusing the issue somewhat, partly because it's a base class rather than something that's ever raised per se. If you were using a custom exception type, how likely is it that that exception would be raised during the unpacking? Under what situations would this happen, and might it actually be an intended way for that property value to say "actually, heh... I don't exist"? Because the logical way to spell that would be "raise PropertyNotFoundError" (or whatever you use instead of LookupError). IOW, bubbling is exactly correct. You still haven't explained how that isn't the case. ChrisA