-
- Notifications
You must be signed in to change notification settings - Fork 604
Make exceptions picklable on Python 2.X #179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make exceptions picklable on Python 2.X #179
Conversation
| Hey! I don't particularly want to support pickle as a use case going forward, but I think adding a call to If you'd be interested in changing to do that that'd be great! Thanks either way for the report. |
| Not invoking parent constructor breaks class inheritance and should be considered bad programming. There is no reason to doubt the necessity for this PR, or require a test-case for the obvious. |
| I've just said that I will accept a patch that calls the parent's init? Everything must have tests though. I just don't want a test ensuring that things are picklable when I don't intend to put in work to make that be true going forward. |
| re: re: don't support pickling: I agree, it's not common to transfer exceptions over the wire in general but offloading validation is probably not that exotic: I myself discovered this when I moved validation into a subprocess to avoid blocking the event loop. |
| That sounds potentially reasonable (although things like |
| In non-twisted world it's a common recommendation to use multiprocessing to side-step GIL in CPU-intensive tasks and that involves pickling and unpickling the results (or errors). |
| In twisted world fork-noexec is frowned upon, so I don't advertise a hack I've written that implements |
7e80f7b to 4525543 Compare | Ah I see, yeah I don't care for the multiprocessing module either, but even if you use it, you don't need pickle to send things back and forth, the normal serialization and deserialization procedures should work fine in whatever format you chose for that. |
What do you mean? import multiprocessing class AErr(Exception): def __reduce__(self): return raise_valueerror, () def raise_valueerror(): raise ValueError("hello, world") def a(x): raise AErr("hello, world") if __name__ == '__main__': p = multiprocessing.Pool() p.map(a, [1, 2, 3]) |
| What I mean is that your example and your presumable actual code either send exceptions back across processes or otherwise propagate them by allowing them to be raised, when you could be sending other things back and forth, like whatever you're actually interested in. A list of error messages or whatever. |
4525543 to 0a51b66 Compare | Ok, let me take out the tests so that the fix can be applied. We can talk about long-term support later, although, it seems we're close to agree to disagree here. I mean, I might be biased because I got bitten by this issue, but I just can't see how it is beneficial to recommend users to jump through hoops to avoid running into an issue with not-really-supported pickle serialization despite its ubiquity throughout the ecosystem. |
| OK, sounds good, definitely would take that patch and appreciate the time. I don't think pickle is ubiquitous by any means, but even if it were, I'd love to do my part to make it not so. It's bad software. So is multiprocessing. IMHO there's never a good reason to use either. But if you are going to use either, it's not jumping through hoops to send data back and forth, that's how you transfer things between processes, not by serializing random objects. |
| Please, see the patch. Jumping through hoops is writing your own serialization, deserialization and communication code when sticking to pickle and multiprocessing would require you to write none. The good thing about pickle and multiprocessing is that they just work, most of the time. I mean, yes, pickle is as dangerous as eval, but bad... Why? |
| Merged and added the test. Thanks. |
| Awesome, thanks. |
It turns out exceptions raised by jsonschema weren't picklable in python 2.7 because
Exception.__reduce__returned emptyException.argstuple and ValidationError afterwards wasn't happy with being constructed without any arguments: