[Python-ideas] Improving Catching Exceptions

Jan Kaliszewski zuo at chopin.edu.pl
Fri Jul 7 20:57:02 EDT 2017


2017-06-25 Greg Ewing <greg.ewing at canterbury.ac.nz> dixit:

> > (2) There's a *specific* problem with property where a bug in your 
> > getter or setter that raises AttributeError will be masked,
> > appearing as if the property itself doesn't exist.
[...]
> Case 2 needs to be addressed within the method concerned on a
> case-by-case basis. If there's a general principle there, it's
> something like this: If you're writing a method that uses
> an exception as part of it's protocol, you should catch any
> incidental occurrences of the same exception and reraise it
> as a different exception.
> 
> I don't think there's anything more the Python language could do
> to help with either of those.

In "case 2", maybe some auto-zeroing flag (or even a decrementing
counter?) could be useful?  Please, consider the following draft:

    class ExtAttributeError(AttributeError):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self._propagate_beyond = True

    # of course this should be a class and it should support not only
    # getters but also setters and deleters -- but you get the idea...
    def new_property(func):
        def wrapper(self):
            try:
                return func(self)
            except AttributeError as exc:
                if getattr(exc, '_propagate_beyond', False):
                    exc._propagate_beyond = False
                    raise
                raise RuntimeError(
                    f'Unexpected {exc.__class__.__name__}') from exc 
        return wrapper

Then we could have:

    class Spam:
        @new_property
        def target(self):
            if len(self.targgets) == 1:
                return self.targets[0]
            raise ExtAttributeError(
                'only exists when this has exactly one target')

Cheers.
*j


More information about the Python-ideas mailing list