I don't normally use Python. When I see something that I'd like to install, and the docs say "written in Python", my heart sinks. I know I'll have to find out how to install multiple dependencies in various packaging systems, all of which will be incompatible (but surely much better) than my system package manager.
I find all of this ironic given that the main gripe people used to have against Common Lisp was "but how do I make a self-contained binary?". Somehow this was never required of Python.
This means the users don't have to know it's made with Python or install anything, and it just works.
However, Python is not like Go or Rust, and providing such an installer requires more work, so a huge part of the user base (which have a lot of non professional coders) don't have the skill, time or resources to do it.
And few people make the promotion of it.
I should write an article on that because really, nobody wants to setup python just to use a tool.
Do check out nuitka though, it's has great support for QT, numpy, advanced Python constructs and has a permissive learning curve. You may even get a up to a X4 perf boot.
>That's more of cultural problem in the Python community.
The Python community also loves making minor breaking changes. Like the language itself, with the changes from Python2 to Python3, then later on the changes to e.g. introduce "async" as a keyword and break all existing code that had a variable of the same name. Some dynamic languages, like Clojure, take the approach that it's not okay to collectively waste tens to hundreds of thousands of hours of users' collective time just to satisfy the library developer's aesthetic urges, and packages very rarely make breaking changes. Personally I'd much prefer a language/library with some deprecated cruft than one that wastes days of my time updating my code every time some developer finds a new way to make their API "cleaner".
> The Python community also loves making minor breaking changes.
This is almost entirely untrue. Python 3 was a huge deal because the community held off for so long on making breaking changes. The async thing was probably a misstep. That happens.
That's actually very true, the author just didn't choose a very good example.
The reality of Python is this: there's no standard and no obligation to keep any Python code working. The matrix of supported environments is huge. So, to even build and test packages for more than 4 minor language versions is prohibitively expensive.
The 4 here is a very important number. Python's own release cycle is intended in such a way that they don't care about more minor versions backwards: and typically, you can no longer build Python of that version on a modern OS with a modern compiler.
Another consequence of this is that if you need to install an older package, even if in principle it should work with current Python, you'll discover that Python packages will have a lot of very particular and very convoluted dependency relationships. These typically work if you can allow yourself to be within last 4 versions of Python, but if you fall behind -- all bets are off. You start to discover that you can no longer install things due to botched dependency specification, you start installing things manually, repackaging while fixing dependency definitions and so on.
Some of these problems can be blamed / explained in terms of others. Eg. interface of SSL library Python uses changed in incompatible ways not so long ago, which now prevents older codebase from building with new library and newer codeabse building with the old one. There's a similar story with C interface, TK bindings, and probably more that I didn't encounter personally.
> community held off for so long on making breaking changes.
That's bullshit. Community bravely moves fast and breaks things. Just not in the case of Python 2.X -> Python 3.X transition. But that's rather an odd exception to the rule.
Python was created 30 years ago, before Java, at the time the first game boy came around.
It accumulated a lot of things, and it’s a constant battle to balance what to change (to keep the project lean and modern) and what to keep (to maintain compat).
Whatever move you chose, someone in the community will say the core devs are doing it wrong.
I read as many posts saying python is moving too fast as ones saying it’s not adopting “feature x” fast enough. As many people saying we should get rid of the GIL than one saying they are deprecating too many API.
When you are as popular as Python, with a community as diverse, it’s very hard job.
Why is python so popular? It reminds me of a less flexible JavaScript, except a little cleaner feeling. However, the flexibility (functions are data, etc) is the main allure of JavaScript, besides it being required for web
What draws everyone to python? Why don’t people use c# or Java or c++ or some other language? What’s the killer benefit they get?
Numpy, scikit (learn/image), panda, and probably tensorflow (never used that one).
Tbf numpy+pandas is like using a mathlab that also have easy way to do http requests/web scraping, so there's that.
I didn't really do datascience in 6 years now (except that one time I demo'ed our jupyterlab+dask setup vs a classic Hadoop), but to me those are the clear reasons.
Also the first time I used python I was doing a CTF and had to add between 70 and 130 NOP (randomly) before the payload. I think I now could do that in perl and awk, but at the time it was a python one-liner and I do think python was the easiest to debug between the three, hence was the best solution.
Today, Python is popular because Python is popular.
It doesn't have any engineering merits of its own. But you also cannot compete against it on engineering merits. It doesn't matter if you do everything better in your language than how it's done in Python. Unless you find a way to make it popular, Python will stay popular and your language will fade into oblivion.
What was the initial seed that created this popularity? -- well, it seemed cool for nonsense reasons. The choice of Python was often reactionary, to spite those who chose Java. Python just happened to fill the niche of "what language should I write in if I think Java sucks?"
This had an appeal to better programmers of that time (early 2000s), and this made others believe that language was what made those better programmers better. The better programmers started to flee Python some 5-10 years later, but it had already enough momentum to attract lots of mediocre programmers, and before you knew it, Python started to be used everywhere, and while the quality of Python programmers consistently dropped, the popularity only grew.
So... if you are planning on a project for yourself, or for a group of skilled and motivated individuals -- there's no reason to choose Python, in fact, you'll come to regret it if you do. But, if your goal is to make a project in the context of an industry giant, then Python is a great pick -- you'll have an infinite stream of replaceable programmers, lots of 3rd-party libraries. You'll save a lot on developing the product. It won't be a high-quality one, but in this context nobody cares about quality anyways.
>Python was created 30 years ago, before Java, at the time the first game boy came around.
C++ was created even earlier, and it largely managed to maintain backwards compatibility; most code from back then will still compile, albeit with warnings.
Python was never lean nor modern. It was a still-born language, intended more like a toy / joke, if you want to give credit to its author.
It's very aspirational to claim that there's some process that involves intelligent thought that decides what features should be added or removed from the language. From where I stand, a petri dish has more intelligence than all Python core devs combined.
The reason to have an interpreter or any kind of separation of software into modules is that you can audit common pieces of software just once, that you don't waste space on users' computers to store it, that you don't require to build walls to protect separate environments with similar but not the same copies of the same piece of software.
Another benefit of an environment like Python is that you have source code available and you can fix problems before or instead of engaging the original developers.
I had a misfortune to work with the tools written by someone like you (a lot of Linux LDAP utilities are like this). It's a huge pain to deal with.
It's really not an awful idea in general, but might be for a user like you. I'm not sure if you read the article but it details the many various types of users and why they may use Python projects and libraries. Having an executable available will make installing the tool much much easier for some users. And you can still have the source code and regular packages available for those that know how to handle it.
OP mistakes the problems Python users have with the actual problems Python packaging system has.
The overwhelming majority of "pain" the author talks about is self-inflicted. The overwhelming majority of Python users are bottom-of-the-barrel worst programmers to walk the face of the Earth. Their problems come from just being really, really bad at what they are supposed to be good at.
So, one complaint you could make is that Python packaging isn't very friendly to incompetent users... well, that's true, but I wouldn't care about that. Quite the contrary: I wouldn't mind it if things were more complex, but worked well, once you mastered them.
Your idea of distributing a single binary is bad for all the reasons I described in the previous post. You just decided that it's not so bad because it helps users who suck to suck less... But I don't want a "solution" that would sacrifice many other desired properties to deal with my potential incompetence. I'd rather learn how to do things right than enjoy being stupid and have someone else cover for my stupidity.
that you can audit common pieces of software just once, that you don't waste space on users' computers
Python has completely given up on that idea years ago. Even when not packaging your python project into binaries, the official recommendation is that each application gets it own complete copy of all its dependencies and to never share library code between projects.
Why does it matter what Python has given up on? -- Python sucks, this is the central point of my argument. They've given up on doing the right thing? -- Is this news to anyone? This has been like that since as far back as I can remember... so, at least two decades now.
In other words, who cares what "recommendation" says (recommended by who? Same Python core devs? -- why should anyone take those clowns seriously)?
- you have to install pipx and they recommand to install it... with pip. Back to all the same problems.
- pipx implicitly use a python version underneath. For things like mypy or black, you get stuck to the syntax of this version, and you'll get errors a lot of users can't solve
- pipx is not stable enough, it just fails sometimes
- people have to know about a third party tool
- it adds to the paradox of choice
- pipx PATH injection is hit or miss
I should have listed pipx in the article, it's not a solution, it's a crutch.
This was the main reason I started writing my random tools and scripts in Go.
I can just write, cross-compile and deploy.
Trying to get a "simple" Python tool with library dependencies working on a random server is a huge pain in the keister I'd rather not deal with if I have the option.
This became even easier now that I can "simply" feed my old Python stuff to GPT4 and have it transform it to mostly-working Go code =)
My problem is the exact opposite. Every distribution under the sun comes with some form of Python but getting Go running can be a hassle (sometimes even impossible). For scripts, Python works great in my experience.
Every time I need to load some Go related project into my workflow I somehow end up at some open Github issue that says "we can't do X I go yet but we plan on implementing it in 2021 when <some compiler feature> is done".
It's not just Go, but its opinionated nature (solving difficult problems by picking one solution making it the default you can't change, and then assume nobody ever has a problem with it) and the fact it compiles to binaries makes it susceptible to "it always works except if your system does <something my system happens to do>". Things like "paths are always UTF-8" are great assumptions Go tools utterly fails to deal with.
> For scripts, Python works great in my experience
For scripts _with no external dependencies_ I do agree with you.
But as soon as you do something non-trivial then you have requests and boto in there and maybe a few smaller utility ones. And now you've got issues. You can't just install them globally, because that'll change it for ALL Python programs on the machine.
Not the original commenter, but Go programs are all statically-compiled, with everything needed at run time bundled into the executable. Go does use a runtime, but that's incorporated into the exe, so no external libraries required. As such, you can get a program written in Go running on a new machine just by downloading it :)
For machines where you may actually have a Go installation already, the majority of programs now can also be installed from source via Go's built-in package manager, which installs it to your home directory. A lot of dev utils, like go-imports, the language server, etc. are typically installed this way. It's usually just a single command (though the exact command can vary between projects, but is usually signposted fairly clearly).
For 99% of stuff I need to move either one statically compiled Go binary and maybe a configuration yaml. That's it.
With Python I need to have Python installed in there, and it has to be the correct version because of <reasons>. Then I need to figure out how I can install the dependencies for the program, with the correct version(s).
This usually would require me to figure out what's the current virtual env du jour and how do I get it working on a random *nix distro on the target computer.
Then I can install what's in requirements.txt or whatever the venv tool is using. And now I can maybe run it if all went well.
And when I need to update said program, with Go I can just scp/rsync a new binary on top of the old one at it'll Just Work.
With Python I need to move the Python source file(s) there, check for possible updates to libraries, update them using the venv tool and re-check that I have the correct Python version installed once more.
Now picture a situation where I need to do the process above for, let's say 12 different servers on different clients after every fortnight. All servers are Intel-based, but run a variety of Linux distros. I can use the exact same Go binary for every single one, the Python solution is a complete clusterf...
I do need to spend a bit more time when developing a Go solution compared to Python, but the ease of deployment is definitely worth it.
It seems too easy coming from python land where dependencies are handled so poorly, but for a lot of go programs (depends on how you're holding it), a simple scp program server: is enough.
Most programmers don't give a crap about the user. Python assumes that the user will be a Python programmer, and want to maintain a whole independent part of their system just to run a Python program.
> I don't normally use Python. When I see something that I'd like to install, and the docs say "written in Python", my heart sinks.
I do use python regularly, but still have this reaction. If I've set up a project that runs a CLI script, or Django web server etc, I can manage dependencies. If it's someone else's code, all hope is lost! It also makes me wonder why it's not wrapped into a binary using one of the various tools available.
Maybe you are doing something wrong? I have installed countless Python packages using "pip install --user pkg-name" If something fucks up i just rm -rf ~/.local/lib/python3.11/site-packages and reinstall the package. I've stuck to this workflow for over ten years and the only major issue I have had with it was with TensorFlow which didn't support the latest Python version.
Nowadays, I have to add the flag "--break-system-packages" but the workflow still works as well as it ever did.
Sample apps using PyTorch are best examples of an adventure, when ran on Windows. One needs to carefuly consider a WSL2 machine, full vm or Anaconda, because each comes with some caveats. WSL doesn't implement sound/microphone access, full vm's don't pass through the main display GPU, Anaconda based ones complain that the host system doesn't support hard symlinks (unless the Developer mode is turned on)
Why does it matter if a program is a self-contained binary? It seems like such an odd requirement. If you really want that it seems in principle easy to compile it all into one script with no imports and put a shebang at the top. What's the point, though?
Pyinstaller is pretty good for if you need a standalone installer.
> Why does it matter if a program is a self-contained binary?
Because simple is better than complex. I'd rather download a binary than download a binary + dependencies + set them up + bookkeep for when I want to delete all those files.
> Pyinstaller is pretty good for if you need a standalone installer.
PyInstaller doesn't work for many edge cases. If you're using a Python package that uses a compiled binary written in another language, good luck on your way down the rabbit hole of PyInstaller config. I personally could not succeed in packaging a uvicorn app, for example.
> Why does it matter if a program is a self-contained binary? It seems like such an odd requirement.
Because sometimes I just want to write `my_program | your_program` without learning how to install and set up a program in a language I don't personally use, particularly when that language has the worst packaging ecosystem of any mainstream language.
This doesn't match my experience at all. Can you give any concrete examples of packages that are difficult to install because they are written in Python?
"difficult" is in the eyes of the beholder. But one quite simple and well maintained package, which many have still have problems with is librosa. See for example Stack Overflow questions about it or the issue tracker. Some of the challenges come from having dependencies on native libraries (audio codecs), that need to be installed manually. Others come from using numba, which break on every new Python version.
librosa is a library. That means you need to learn to do Python development to be able to use it obviously.
This is the problem. People aren't even talking about the same thing. This thread started off as something about single file distributables and the only concrete example given is a library.
I assume the gold standard is just downloading a compiled binary and using that. Which is the norm for almost everyone ... except python projects.
When it comes to compiling/running from source, Python is in the middle of the pack. It's not as smooth as rust (install cargo from your package manager or from rustup, run "cargo build") but not as bad as C++ (run through the install section of the readme of each dependency, then debug whatever build system the project is using).
Perl, Ruby, JavaScript, PHP, Bash, Go, C, C++, Rust and even Java is easier to deal with than Python tools. Seeing that it is a Python tool usually make my heart drop a lot and makes me look for alternatives before attempting to get it running.
pip installing one thing is usually not a problem.
You can do the binary thing with Python for sure. Does Lisp really work much better?
Part of the issue with Python is versions of the language. So you really shouldn't be installing packages locally in most cases, but you should use one of these tools so you're running your dev environment isolated from other environments.
Most of the popular ones are a lot better than Python. Python might be comparable to CAD Lisp or that abomination embedded in GIMP (though I think they stopped supporting it) in terms of quality of design and execution.
> So you really shouldn't be installing packages locally in most cases
Where do you suggest I install them instead? On someone else's computer? What kind of advise is that?..
Many languages have much better tools that make it easy to compile/bundle an artefact that can be run without the end user having to build or install anything.
Surely "to run the program from source, you need to know how to build/run it" applies to every language.
But I'm more comfortable working through problems I might encounter in languages I've worked with, than in languages I'm not familiar with.
I'd say Python is notorious, since you're probably going to hear about at least six or seven ways people are able to run things; so if you're not familiar with it, you're likely to do something wrong. -- e.g. elsewhere in this thread, you've pointed out that stuff should be run from a venv; that's something you have to know.
It's true: some people like Docker for Python, some like venv, some like conda... some lose it entirely and install everything locally! (acting like I haven't done this at least once!)
Of course badly written code is buggy and will require bug fixing because it only works on the machine of the developer. I'm not sure this isn't true in other languages. I've seen go CLI utilities that were dynamically linking Gnome libraries and could not start without installing Gnome.
I find all of this ironic given that the main gripe people used to have against Common Lisp was "but how do I make a self-contained binary?". Somehow this was never required of Python.