4 ms·
Not sure I agree that this is magic. Syntactic sugar? Definitely. But it doesn't obscure any of the underlying logic.
by okal 14y ago
Not sure I agree that this is magic. Syntactic sugar? Definitely. But it doesn't obscure any of the underlying logic.
- lmm 14y agoIt causes "import" to behave in ways you wouldn't expect.
- im3w1l 14y agoCould you elaborate on this point? What happens and what would you expect?
- apl 14y agoThis tool hijacks the import mechanism by directly writing to Python's look-up tables. After all, when you do from sh import git there's no module 'sh' invoked in the normal sense. Instead, the library generates a wrapper for the shell command 'git' on the fly. While that kind of monkey patching may be neat, it's also a bit brittle and a potential security issue.
- emidln 14y agoDoubtful that this is more damaging than: import os os.system('insert local exploit here') It's true that it is another place that you can get a python script to execute code outside of its environment, but you get a ton of those for free with the stdlib.
- jerf 14y agoPython has a lot of built-in support for overriding how imports work, and modules have always been just namespaces. As hacks go, this isn't very hacky in Python, and it isn't particularly brittle, as it's just implementing existing interfaces. It is also not "monkeypatching", which ought to be reserved for things that involve reaching into an existing class and modifying things. This on-demand loading, which doesn't have anywhere near the same evil factor, but is rather more like dynamic programming languages working-as-designed. You may find this distasteful. I do, actually, though I'm not 100% sure why. But it's not because it's some sort of abuse of Python. Python is very nearly designed to do this, and the last little bit that it isn't designed for isn't that big a deal, especially compared to something like the "import python modules through zipfiles" functionality, which now ships with the core.
- SilasX 14y agoYou must consider Ruby on Rails to be pure hellspawn then. (I agree, but for different reasons ...)
- MBlume 14y agoWell, the Python and Ruby communities have different engineering cultures and this is part of that. "Explicit is better than implicit" is one of the mantras on the Python side. http://www.python.org/dev/peps/pep-0020/ http://www.python.org/dev/peps/pep-0020/
- timtadh 14y agoYou expect import imports names which have actually been declared somewhere. Names which you can find and look at the definition. This library essentially hijacks the import process to allow you to import any name, each name is then actually a wrapper on a system to run shell commands. Definitely a hack, but a cool and useful looking hack.
- esrauch 14y agoThat is a reasonable assumption in the common case, but it's reasonable to not always assume that. The same is true if you have obj.v(), you would normally expect there to be some v property defined on the object but really it might be coming dynamically from __getattr__(). This is something that python specifically has language level support for, I wouldn't say it's a hack just because its using a feature that isn't taught in Python 101.
- lmm 14y agoRightly or wrongly I expect import to be simple, fail only when packages haven't been installed properly, and more generally depend only on PYTHONPATH. When I'm debugging I don't normally even look at the import statements. Other replies have described what this does; I think I'd rather offer such functionality as something that looks like a method call that might fail (something like git = sh.getProxyForShellCommand("git") - probably not that verbose, my head's in java-land at the moment, but you get the idea)
- daenz 14y agoimport sh git = sh.Command("/usr/bin/git") the Command object takes a full path, but you can use it together with sh's "which": import sh git = sh.Command(sh.which("git"))