Soni L. writes:

 > the fact that exception handlers aren't reusable and composable is 
 > really bothering me so I would like to propose something to make them 
 > reusable and composable.
 > 
 > for example, if I have this mess:

Looks nice and flat and orderly to me; the semantics are messy, so I
don't see how you can hide them.  The method as written makes sense to
me.  It specializes in keeping all the exception handling in one
place, while the "real work" is done elsewhere (factory(), self._obj,
.get_supported_properties()).

You can only disperse those semantics into functions, making it harder
to read.  "Hard to read" is especially true when you use a real-world
example, full of identifiers with unknown semantics.  It probably
makes more sense in context of the application, and again in that
context it might be a lot more persuasive that you want "reusable
handlers" vs. a function that specializes in "collecting handling".

 >      def get_property_values(self, prop):
 >          try:
 >              factory = self.get_supported_properties()[prop]
 >          except KeyError as exc:
 >              raise PropertyError from exc
 >          iterator = factory(self._obj)
 >          try:
 >              first = next(iterator)
 >          except StopIteration:
 >              return (x for x in ())
 >          except abdl.exceptions.ValidationError as exc:
 >              raise LookupError from exc
 >          return itertools.chain([first], iterator)
 > 
 > I get to refactor it into:
 > 
 >      def keyerror_handler(exc):
 >          raise PropertyError from exc
 > 
 >      def other_handler(exc):
 >          if isinstance(exc, StopIteration):
 >              return (x for x in ())
 >          raise LookupError from exc
 > 
 >      def get_property_values(self, prop):
 >          try:
 >              factory = self.get_supported_properties()[prop]
 >          except KeyError with keyerror_handler:
 >              pass
 >          iterator = factory(self._obj)
 >          try:
 >              first = next(iterator)
 >          except (StopIteration, abdl.exceptions.ValidationError) with 
 > other_handler as result:
 >              return result
 >          return itertools.chain([first], iterator)

I don't understand the semantics of "with".  Do you mean

    def get_property_values(self, prop):
        try:
            factory = self.get_supported_properties()[prop]
        except KeyError as exc:
            keyerror_handler(exc)
        iterator = factory(self._obj)
        try:
            first = next(iterator)
        except (StopIteration, abdl.exceptions.ValidationError) as result:
            other_handler(result)
            return result
        return itertools.chain([first], iterator)

If so, who needs "with"?  

 > another idea would be to use semicolons:

There's no need for semicolons (or keyword abuse, for that matter).
Also, they may not be grammatically ambiguous here, but Python already
has semicolons for dividing a physical line into logical lines,
whereas here it's an abbreviation for "apply the preceding function to
the current exception and return the result from the enclosing
function," which is pretty powerful semantics for five pixels on my
screen.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/DW2WVFHN2DL5XVQHFHIYNUXDWAWLQ5HV/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to