2 ms·
Python pretends to be a nice homogeneous "everything is at run time" language, but it is all a big lie and there aren't big flashing letters saying "you really
by tgbugs 7y ago
Python pretends to be a nice homogeneous "everything is at run time" language, but it is all a big lie and there aren't big flashing letters saying "you really probably shouldn't do this" when you start solving a problem in a certain way. For example, it is almost certainly best practice to _never_ call a function, class method, or static method inside a module that is going to be imported, and certainly never instantiate a class. However, there are certain patterns that almost necessitate it if you don't want to write loads of boiler plate or deal with the performance overhead of metaclasses. There are also a bunch of nice hacks like using `object()` at the top level as an instance distinct from everything else, but I'm sure there is a way that `MYTYPE = object()` will come back to absolutely ruin your day if you have to compare two `MYTYPE` instances in two different dicts derived from a parent process and a subprocess.
I have personally made this mistake on two or three occasions where I conflated file/module behavior with class behavior because I wanted a python file to act like it was a bit more declarative. Unfortunately this leads to a world of eternal pain. You can work around it, but you should have made everything a python class and pretended like the files/modules don't exist or at least have staggeringly different semantics hiding behind that innocent little `.` operator. Python simply cannot support the desire to solve a problem in a certain way because of the structure of the problem and forces you into using its happy path patterns if you want it to work in slightly different run time contexts.
Two relevant posts from instagram engineering on the subject which suggest that best practices for avoiding these kinds of issues are non-obvious and easy to miss.
https://news.ycombinator.com/item?id=20708889 https://news.ycombinator.com/item?id=20708889
https://news.ycombinator.com/item?id=21284669 https://news.ycombinator.com/item?id=21284669
- viraptor 7y ago> but I'm sure there is a way that `MYTYPE = object()` will come back to absolutely ruin your day if you have to compare two `MYTYPE` instances in two different dicts derived from a parent process and a subprocess. I don't see how this can be an issue with imports. You have two cases: you imported the module with MTYPE before or after fork. Before: they will compare fine. (unless IPC's involved) After: you transferred the dict with MTYPE through some kind of serialisation or shmem and you cannot compare identities - that's a property of IPC rather than something to do with python modules. Anyway, what I meant in previous comment was the risk matrix view. Sure, this can lead to bugs scoring various points in severity, but does it score high on likelihood?