> You have the option to create a virtualenv and install it with pip, or snap, or use a docker image.
You could jump through all those silly hoops (most of which will be completely alien to people who are not Python devs) in order to use the "official" dependency-heavy Python client.
Or you could just use a single pre-compiled Go binary, LEGO [1].
I have been increasingly favouring Go recently because the functions delivered to the end-user are dependency free, you can just ship simple single binaries instead of having to say "oh you need Python X with this that and whatever other Python library under the kitchen sink installed on your system".
And that's before we start talking about conflicts that can occur between Python libraries....which, let's face it will happen in an "average Joe" environment where Joe is just randomly using apt to install any Python dependencies.
Indeed, for example this snippet from the Saltstack docs:
>For historical reasons, Salt requires PyCrypto as a "lowest common denominator". However, PyCrypto is unmaintained and best practice is to manually upgrade to use a more maintained library such as PyCryptodome. See Issue #52674 and Issue #54115 for more info
We wouldn't even be having that conversation with Go.
There would be no weird "lowest common denominator" dependency. There would be no concerns about potential conflicts between other crypto libraries, and no choice to make about which "better" library you want to install. Plus of course the 10 other non-crypto dependencies that Salt needs.
All you'd need is a binary, config file(s) and an init script and you'd be good to go.
Sure, static linking and the like make the initial deployment much easier. On the other hand, it also means that any bugs in the dependencies are baked into each application, and fixing those bugs (which may be critical security issues) requires rebuilding all the downstream code. Provided, that is, you can rebuild the downstream code. Users of closed-source binaries are simply out of luck.
Mixing multiple versions of the same (or closely related) libraries in the same program remains an issue even with self-contained applications. It might work out if the users of each version are isolated from each other, at the cost of program size and attack surface, but say you're using PyCrypto in one module and PyCryptodome in another, and you want to pass configuration or key information between them—the types won't match up. You'll also have two different API styles to deal with for the same tasks, which is bad for maintainability, which is ultimately bad for the user because it create more opportunities for bugs and makes it harder to implement new features and enhancements.
> On the other hand, it also means that any bugs in the dependencies are baked into each application, and fixing those bugs (which may be critical security issues) requires rebuilding all the downstream code.
I'm afraid I don't buy that argument at all.
Because Python is either the same or worse.
You've got the potential bugs in the Python code itself, and then the potential bugs in the random Python dependencies. You've got a whole stack of potential bugs there.
P.S. What's that nonsense about "closed-source" Go binaries ? If its an open-source project then its open-source until its compiled ! If the code's on Github then you can clone it and do as you please if you're not happy with the author's Go code.
No, you update a python library and it works for everything importing it. The point is that you can fix vulnerabilities in unmaintained apps with a simple update if the vulnerabilities are just in dependencies.
> P.S. What's that nonsense about "closed-source" Go binaries ?
The discussion is about passing around binaries and nothing else.
In practice the apps that don’t publish updated dependency lists are also the ones that end up breaking by when you do update their dependencies. It only works in the simplest of patch versions.
> And that's before we start talking about conflicts that can occur between Python libraries....which, let's face it will happen in an "average Joe" environment where Joe is just randomly using apt to install any Python dependencies.
What kind of conflicts are you talking about? In both Debian and Ubuntu repos, all Python packages and their dependencies are nicely versioned and separated so there can't be any conflicts between Python versions. As for the handful of Python packages that are mutually exclusive (Pillow and PIL), either only one implementation is in the repos or you can install any one of them and have it work since they're drop-on replacements.
Now, if you start installing system-wide packages with sudo pip, you'll of course break things, but if you're installing things from the apt repos, there is no reason to ever do this (and pip will yell at you that you shouldn't do it).
> You could jump through all those silly hoops (most of which will be completely alien to people who are not Python devs) in order to use the "official" dependency-heavy Python client.
Why would snaps or docker be completely alien to people who aren't python devs?
Why would you deploy a snap or an entire docker container for a job a single shell script or binary can do? It's like using a bulldozer to move a pebble.
You could jump through all those silly hoops (most of which will be completely alien to people who are not Python devs) in order to use the "official" dependency-heavy Python client.
Or you could just use a single pre-compiled Go binary, LEGO [1].
I have been increasingly favouring Go recently because the functions delivered to the end-user are dependency free, you can just ship simple single binaries instead of having to say "oh you need Python X with this that and whatever other Python library under the kitchen sink installed on your system".
And that's before we start talking about conflicts that can occur between Python libraries....which, let's face it will happen in an "average Joe" environment where Joe is just randomly using apt to install any Python dependencies.
[1]https://github.com/go-acme/lego