Beyond what @pradyunsg already noted, I worked for many years in a large consultancy company, where we used many languages and scripting solutions. Python was just one option of many. Every Python user I knew in that environment would write single-file Python scripts, and would view Python as being similar to (but better than) shell scripts or batch files. They would never even conceive of giving a Python script its own directory, or of having to build the script in one location and then deploy it, and if they had been expected to do so, they would have considered Python unsuitable for many of tasks they used it for.
This is the experience I share, and as a user I was unable to find a really good way of handling 3rd party dependencies. Yes, I concede that I’m not an average user, but if I, with all my experience, can’t find a satisfactory approach, maybe that is stronger evidence that there’s an issue, not weaker?
This really has been discussed repeatedly already. I suggest that (if you haven’t already) you read the posts that have already been made here. Basically:
- There’s a real use case for single Python files living in a shared directory with other scripts (Python or otherwise).
- There’s no common idea of a unified “project” that encompasses all of the scripts in that directory.
- Building the code in a “project directory” and deploying it is not suitable for this use case.
Yes. Python doesn’t have a good approach for allowing those scripts to have dependencies. The common existing solution is creating (and managing) one or more virtual environments, containing a bunch of dependencies. This could be one “dump everything in here and hope there’s no conflicts” environment, or one environment per script, or something in between. But the environments need managing - for example, where do we store them? Do we back them up or have another script (which has its own dependency, virtualenv) to rebuild them on demand? All of this is extra admin work that (for example) shell scripts don’t need.
pip-run (and now pipx) offer an alternative approach. It’s not caught on widely yet, and it’s not necessarily the ultimate approach, but it’s an option. This PEP doesn’t change anything there, it simply acknowledges that there’s work going on to improve this area, and if we standardise the means of storing per-script dependencies, that means that users can store their dependencies without having to commit to a specific tool - which is good because I don’t think we have arrived at the ideal solution yet.
I’m really getting frustrated repeating this so much, but those “real solutions” are not solutions for this use case. They solve a different problem, but they violate a key requirement in this case, namely the “single file” requirement.
We’re not adding “yet another way”. We’re adding one way for a use case that isn’t addressed by existing solutions.
OK, that’s the problem. Your perception is wrong. This is not a matter of “turning one-off scripts into executables”. It’s about one-off scripts being a perfectly acceptable and valid use case in their own right, except for the fact that they have no means to declare dependencies on 3rd party libraries.
Nobody who’s interested in this solution wants to “turn” their scripts into anything else. They want to leave them exactly as they are. All they want is to enable tools to manage dependencies transparently.
You’re wrong. Would you be happy if I told you that all your shell scripts and batch files were no longer considered the “right way” to do things, and you had to create a project directory for each one and run a compiler on it to build an executable? Why do you think that it’s unacceptable to use Python in the same way as you use a batch file?
I’m sorry, but it really is. See my previous paragraph. In my ~/.local/scripts directory I have a script gh-event.py. You are explicitly saying that the problem is “to turn a script into an executable”. I don’t want to turn that script into an executable. I want to be able to run it as is without having to manually create or manage a virtualenv. That’s it. You’re telling me that what I’m explicitly saying I want, isn’t how I should work.
No, I can’t, because the current standards explicitly exclude this use case by requiring a project directory.
- No
- No (except by accident, it’s not an intended use case)
- No
Agreed. But adding a way to specify requirements for a use case that currently isn’t supported at all is progress, and will delight users who are frustrated that currently their requirements are being ignored.
I’ll take that on board. I’ll try to make it clearer in the PEP that “if you want to package your scripts for distribution, or for project management purposes, you should use the existing Python packaging workflows”. But the key is if you want to.
Apart from the fact that I resent being described as not a “real world user”, what do you think this thread (and the positive feedback from various real world users) is doing?
There’s not much I can link to. It’s more a case of linking to Nathaniel’s post (which I linked above, you should be able to find it by reading the thread) on multiple occasions, supporting tools like pip-run and pipx, my comments on the pip issue about adding a pip run command (again I’ve already linked this) and generally presenting my use cases as a user in various discussions. Mostly, I’ve just had my comments dismissed with the same “you can create a project” sort of arguments you’re repeating now. And I’ve tried - I am genuinely willing to follow the “official workflow” if it does the job - but not once have the results been as effective as simply writing a Python script and only using the stdlib (or hacky adhoc solutions for vendoring 3rd party dependencies).
Oh, and you’ll also see me regularly arguing against stripping down the stdlib, and quoting single-file scripts as one example of why “using 3rd party dependencies” isn’t as easy as people would have you believe. Again, I usually get shot down with “just use a virtualenv” (as if I wasn’t aware of that option…)
(BTW, sorry for the excess of emphasis and boldface. I’m getting really tired of repeating myself here.)