4 ms·
My question is: what is your alternative to exceptions, and how would they would have made the error easier to spot? Its not obvious that the error would have b
by winstonewert 7y ago
My question is: what is your alternative to exceptions, and how would they would have made the error easier to spot? Its not obvious that the error would have been easier to spot if it had been written using Go's `!= nil` pattern or Rust's `?` pattern.
My experience is that while its true that its easy to have bugs in implicit exception handling logic, its just as easy, maybe easier, to have bugs in the explicit boilerplate its replacing.
- imron 7y ago> Its not obvious that the error would have been easier to spot if it had been written using Go's `!= nil` pattern or Rust's `?` pattern. I like Rust's `?` operator (and Swift's `guard` statement also), but it's worth noting that the bug wouldn't have existed in Rust in the first place because the file object wouldn't have outlived the scope it was defined in.
- masklinn 7y agoAlso and really because it’s quite hard to go and replace implementation details with code which behaves completely differently and implements an unrelated contract entirely.
- Dylan16807 7y ago> how would they would have made the error easier to spot? There was a try block with two function calls, and it seems like the author assumed only the first function call could throw. With return-based errors, the error handling wouldn't implicitly be shared between the two functions. The author would write the handling for the first function, and then they would notice the second function could return an error state too. Then they might write a correct handler, or at least we should expect them to say "this can't happen, so panic". This bug would have been trivial to fix if it panicked instead of corrupting fds.
- winstonewert 7y agoWhat makes you think that "the author assumed only the first function call could throw?" Programmers in exception languages never think (or at least should never think) "X cannot throw" because it is never true. Any function has the potential of throwing an exception. This is even more true in Python than in other exception throwing languages. No, the problem here is that the author has realized that they need special cleanup logic in the case that a file fails to be opened, but they applied that logic too broadly.
- deleted 7y ago[deleted]
- Dylan16807 7y agoSo for reference the second line is: return _TemporaryFileWrapper(file, name, delete) > What makes you think that "the author assumed only the first function call could throw?" Because it's almost true, and the code cleanup is clearly designed around just the first function. _TemporaryFileWrapper does nothing in its __init__ except copy the four parameters into the object. There's no reason to anticipate a problem. But thinking about it more precisely, there's an even worse issue. Even if neither function has an error, if you get a KeyboardInterrupt between the object creation and the actual return, everything gets corrupted. People aware of the bug, trying to fix this code, suggested a nested try/catch, and I think that would still explode if the timing was exactly wrong. Because really, who thinks about a return statement throwing? It's an unintuitive problem that can only happen with this style of exceptions. It's probably even worse than that. If an exception can hit right after the file object is made then you get a similar problem... Is there anything in Python that restricts the timing of KeyboardException or is this entire adventure on extremely treacherous territory?
- winstonewert 7y agoThat's precisely the point I was making: there is no python code which is guaranteed not to throw. If the original author thought that the line of code in question wouldn't throw, they were were wrong and fundamentally misunderstood Python.