3 ms·
Let's say you write a module httpclient doing this: from ssl import sslsocket import httplib as hlib You can think of the code above as remapping and/
by user5994461 6y ago
Let's say you write a module httpclient doing this:
from ssl import sslsocket
import httplib as hlib
You can think of the code above as remapping and/or duplicating the whole library it's importing. Python imports involve complex local and global states (I don't pretend to understand most of it).
One direct effect on usage is that users of the library can call "httpclient.sslsocket" and "httpclient.hlib" as if they were provided by the library (the author certainly didn't mean to). This creates problem down the line when the author try to change the internal dependency, and this extends to other code also doing "import httpclient.sslsocket as sslsocket", creating problematic hidden dependencies.
More generally, this affects all import dependent features, like reload(module), mock, sys content, etc... imports are looked up and tracked by full path which doesn't always work as expected when paths are hot patched as above.
I used to work in a python shop (millions of line in total across the organization). Regularly had the problem with interns and new graduates abusing imports as above (sometimes even trying to change the existing imports because they though this was the better syntax). Then they couldn't pass their own tests (every new module must have a test) and asked for help after few hours of trying. Changing to a normal "import xxx" solved the problem. It's not always clear what was the exact issue, except side effects due to imports.
- codethief 6y agoLet me take the opposite standpoint here and play the devil's advocate. > users of the library can call "httpclient.sslsocket" and "httpclient.hlib" as if they were provided by the library Well, they obviously shouldn't. And maybe they also shouldn't write Python code to begin with because, clearly, they're not able to adhere to Python conventions. Besides, why do you as the library developer care so much about what the users of the library do? If they don't follow your API specifications (proper API documentation should tell the users what they should and shouldn't do), it's their fault. I mean, people can and will shoot themselves in the foot all the time and in various ways. There's is nothing you can do about it. > which doesn't always work as expected when paths are hot patched as above. There is a reason why hot patching (and, by implication, mocking) needs to be done with care and only if you fully understand the consequences. Regarding issues with mocking specifically, I suppose you're referring to nasty questions like https://stackoverflow.com/questions/14341689/how-to-mock-using-patch-relative-paths/ https://stackoverflow.com/questions/14341689/how-to-mock-usi... ? Again, these things need to be done with care. (And of course the code also needs to be written in a testable way – no surprise here – and mocking should be done only if you've exhausted all other options.) > It's not always clear what was the exact issue, except side effects due to imports. Like you I am a Pythonista but I have honestly never run into any problems with selective imports (`from X import Y`) or import renaming (`import X as Y`) and much less even know what problems you're talking about. Overall, I find Python's way of importing modules rather straight-forward. (That is, as long as PYTHONPATH and __name__ are set correctly. From my POV, this is the only seriously annoying caveat.) Anyway, I'm very open to changing my opinion but I'm afraid you'll have to be more specific about the issues you're encountering so often. (If you really did encounter them so often, I would think you would have noticed a pattern by now? No offense.)