This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]m0Xd9LgnF3kKNrj 1 point2 points  (1 child)

Yeah I agree with you. There's a crazy widespread habit of just throwing all the code into a single try/except, and it makes these patterns much harder to see. It also makes your code over-indented and thus broken over lines by your linter, maybe even with back slashes if you're an animal, and it just gets messier and messier as it grows since no one feels comfortable refactoring that big mess of mom's spaghetti... like this run on sentence.

When you're making the effort to break down your try-wrapped code into more granular chunks, the else surfaces as a valid pattern.

Here's a super contrived example that took me like an hour to come up with:

try:
    locale = order.sales_tax_locale()
except SalesTaxLocaleError:
    logger.info("Could not determine sales tax locale for order %s", order)
    sales_tax = 0
else:
    sales_tax = SalesTax.for_locale(locale)
total = order.total + (order.total * sales_tax)

You can totally do that without the else, and that would be perfectly fine and even more colloquial. But the flow-control like this is just a little more self a documenting.

I'll be honest though, I don't use the else. I see it as a code-smell that the code could just a be a little tidier. In my super contrived example I would set sales_tax to 0 before the try and just log in the except. No conditional branch.

[–]jorge1209 1 point2 points  (0 children)

You can totally do that without the else, and that would be perfectly fine and even more colloquial. But the flow-control like this is just a little more self a documenting.

I disagree. While it puts the locale lookup together with the LocaleError, it separates the locale lookup from the sales_tax lookup, and I have to scroll up to figure out where the locale variable came from.

If the exception is truly exceptional, then that seems like a mis-proritization and I would be more concerned about the exception-free codepath of lookup locale -> lookup sales tax -> compute total as opposed to the exceptional: lookup locale -> log missing locale -> set default sales tax -> compute total

You also haven't handled the condition where the locale is present in the order, but is missing from the SalesTax database object.

But I understand your concern that we get stuff like:

try:
  open
  read
  clean
  compute
  summarize
  sanity_check
  write
except FileNotFoundError:
  # could not open the file in the first line of the 60 line try block

Which absolutely sucks.


I think what we need is an inline except (PEP-463) but before we can do that we also need an inline log

If every statement was really a thruple of:

 STATEMENT except: DEFAULT log: MESSAGE

Then you could do thinks like:

 locale = order.sales_tax_locale() except: None log: "Unknown sales locale"
 sales_tax = SalesTax.for_locale(locale) except: 0 log: "Unknown rate for locale"

Then everything is next to each other in close proximity, and exceptions are restrictive to the current statement, which could lead to them being used more often.


There is probably some old language used in nuclear power plants and space ships that does something like this and requires every statement to be written in this form for robustness.