Thanks for yours and @ofek responses.
So when we say commented TOML, it could look like(?):
# [run]
# dependencies = [
# "rich", # comment
# #comment
# "requests=1.0",
# ]
Thanks for yours and @ofek responses.
So when we say commented TOML, it could look like(?):
# [run]
# dependencies = [
# "rich", # comment
# #comment
# "requests=1.0",
# ]
Yup, that is completely valid TOML
Erm, Iām not sure I understand?
I donāt see beginners using this (or any) PEP in relation to Python version management. Beginners should basically never have more than one version of Python installed, so they have no need for such a thing.
And given that Iāve already said that I donāt like framing this as being about ābeginnersā, Iāll note that the same thing applies to anyone (beginner, expert, or anywhere in between) who uses Python for the ābetter batch fileā use case, or as a tool to enable them to do a job that isnāt āprogramming a Python applicationā.
Okay hereās an example: a user can only download a single tool because that is what they read online and is easy for them. By default, their system provides Python 3.10 and they want to use match statements from 3.11. What is best for them between a tool doing it for them and learning how to manage Python installations?
I think the PEP 722 extension of allowing X-User-Defined-Thing
might be the best solution for effectively punting on the version management issue?
There are lots of target users who are only vaguely aware that there are multiple versions of python. 2 and 3!
They get python via the installer or linux distro packaging, and they have no need for a python version specifier.
But Iād also like to embed some of those ābetter batch scriptsā in shared places for use by other members of my team. e.g. a scripts/
directory in the root of a common repo.
In that case, specifying a minimum python version might be important, even if it just results in an error for team members running old pythons. But the script author in this case is a well-versed python user who can lead off with a if sys.version_info
check in the worst case.
If use cases are so numerous that thereās quickly demand to expand PEP 72{2,3}
to support python_requires
, I donāt think that kind of additive change to the spec is a major issue.
I must say I do not understand the debate about supporting or not supporting python-requires
.
What does āsupportingā mean here? If itās, for pipx or pip-run, a matter of erroring out if the current Python version is incompatible with the python-requires
value⦠that should be ~5 lines of code? I canāt imagine that theyād be OK with implementing PEP 723 except requires-python
.
āSupportingā could also mean Python version management features (by which I mean auto-downloading and installing given Python versions), but I donāt really see pipx or pip-run doing that⦠and itās fine? I mean, as long as packaging is organized around several tools and PEPs do not have the power to dictate the behavior of those tools, is there a problem with a python-requires
metadata being used by certain tools to restrain scripts that can be run (hard error if Python doesnāt match), and some others to auto-manage Python versions (run the script with a compatible Python)?
Here Iām confused, because you said (IIUC) that you preferred no [tool]
table in this iteration of the proposal, but this sounds a lot like a different incarnation of it.
Itād be useful to have some actual input from pipx/pip-run maintainers. Unfortunately GitHub doesnāt list repository maintainers, but at least @bernatgabor is a maintainer of pipx on PyPI.
pip-run is maintained by @jaraco.
I donāt think that this is what these PEPs (primarily driven by package requirements) should be seeing as vital constraints. Leaving room in a specification so as not to preclude future metadata is fine, but Iāve commented before about a concern on scope-creep, which I do want to re-iterateāIām unsure why the run.dependencies
proposal needs to have anything to do with the interpreter.
A
We could require the below, but I fear that would limit what youāre looking for in terms of future expansion of the [run]
table.
run.dependencies = [
"...",
]
Perhaps # Script Metadata
as a marker ā I think # [run]
on its own is likely too generic, even if not currently used much.
A
P.S. @moderators would it be possible to split the recent discussion into a [dependencies.run]
thread please? (perhaps starting at PEP 723: Embedding pyproject.toml in single-file scripts - #123).
I only say this as it might be a helpful insight into someone ignorant of pyproject.toml: The specifiers threw me off. I was stumping after I first tried:
[run.dependencies]
package1=1.0
In a TOML linter. It was accepted as a key/value pair. So then I tried
package2 # without any specifier
And of course it balked at the missing ā=ā. And then I was getting very confused at how ā<ā, ā>ā, etc work! Of course now I understand we are assigning a list of strings to ādependenciesā.
I think your confusion (which I share) stems from āsupporting python-requiresā meaning either
If itās imprecise, one audience is unsatisfied because of the imprecision and potential for tools to diverge. If itās fully specified, another audience might be displeased because weāre trying to set behavior for tools without necessarily having full grasp of whatās needed.
I think itās unlikely that weāll find a version of the python_requires data which will satisfy everyone. Putting it in some kind of extension space spares us having to sort it out right now.
The extension space for the [run]
table is very different from [tool]
in that one is already in use by tools and one is not. So it dodges a lot of the issues about tool configs in different places unless tool authors want to explicitly go after those sorts of problems.
No problem! I had my team read through both PEPs this morning, but it was mostly to get them into the right head space, explain the background, to start thinking about how we could do a user study around this, etc.
Iām in no rush to make a final decision and we can tweak stuff along the way. It will take some time to line up a user study anyway, so while @courtneywebster thinks through how she wants to run one, we can iterate as needed. We can also make sure that any user study asks key high-level questions (e.g., formatting) that is going to come up regardless, as well as other questions such as would supporting a [tool]
table be too confusing, is TOML easy enough to learn regardless of what table(s) are supported, etc. Plenty to get beginner feedback on that isnāt inherently tied to any future change we make here.
They can error out if a version of Python thatās required isnāt installed in a much clearer way than some SyntaxError
or AttributeError
for something in the stdlib. And this is in the easy cases of something obviously missing compared to some subtle semantic change.
For example, a tool could say, āthe specified file requires Python >=3.8, but only Python 3.7 was found. Please install an appropriate version of Python.ā which is clearer than TypeError: 'type' object is not subscriptable
(which is something I ran into trying to backport some code in packaging
to Python 3.7).
It would be great if we could receive user feedback somehow like @brettcannon mentioned to find out what is preferable (for example I also dislike triple backticks).
And this is one of the key reasons we are going to do user studies as I think we need some independent feedback from beginners as to what format they find the least confusing.
For example, a tool could say, āthe specified file requires Python >=3.8, but only Python 3.7 was found. Please install an appropriate version of Python.ā which is clearer than
TypeError: 'type' object is not subscriptable
(which is something I ran into trying to backport some code inpackaging
to Python 3.7).
I think the whole requires-python
question comes down to whether we want to be writing down whatās required to make an single-file script/application run, or is this just a list of requirements that must somehow be installed? If itās the former than the version of Python that the code requires is part of the information to run the script (and I think the only thing necessary that I can think of beyond its dependencies). But if itās the latter case of just requirements then the Python version requirement is obviously superfluous. The importance of this probably plays into whether you think such scripts should be as shareable as possible across machines as thatās where specifying the required Python version plays into this.
Iām not personally interested in a PEP that wonāt be supported by pipx and pip-run. So yes, it is one of my criteria, even if itās not one of yours. Iām very much more interested in supporting interoperability for existing tools than in creating a standard that is simply a spec for a capability that hatch wants to implement.
Iām not sure I get you here. Why is it specifically important that two particular tools (pipx and pip-run) implement the behavior rather than some other particular tool (hatch)?
Conversely, not mandating support of
python-requires
doesnāt limit any tools. Hatch can implement such support for itself, as a non-standard extension.
I think thatās a good solution, as long as the spec is defined to be extensible in that manner. That is, if the spec says āthere is a requirements block, thatās itā, then that doesnāt leave scope for hatch to add Python-requirements. Of course, hatch can add that as a totally separate magic comment, but then weāll just be back in the same situation weāre in now, with some tools implementing behavior that hasnāt yet been standardized.
Beginners should basically never have more than one version of Python installed, so they have no need for such a thing.
And given that Iāve already said that I donāt like framing this as being about ābeginnersā, Iāll note that the same thing applies to anyone (beginner, expert, or anywhere in between) who uses Python for the ābetter batch fileā use case, or as a tool to enable them to do a job that isnāt āprogramming a Python applicationā.
In my experience that isnāt entirely true. Iām someone who often wants to use Python for the better batch file case, but even so, this sometimes does require thinking about different Python versions. Different ābetter batch fileā scripts may require different Python versions, and itās not always possible to just upgrade to the latest one and use that for all. For instance, you may have some of these batch files that need to be run with some installed Python that you donāt control (e.g., because theyāre doing system tasks), but at the same time may have other āpersonalā batch files you also want to run that require a newer version of Python, and for these ones you may be able to run them in an environment where you do control the Python version.
I continue to think it is best to simply think of the Python version as part and parcel of what is required to run a script.
We can also make sure that any user study asks key high-level questions (e.g., formatting) that is going to come up regardless, as well as other questions such as would supporting a
[tool]
table be too confusing, is TOML easy enough to learn regardless of what table(s) are supported, etc. Plenty to get beginner feedback on that isnāt inherently tied to any future change we make here.
That sounds wonderful. I do hope that we can remain open to the possibility that user feedback may lead us towards a solution which differs from all of the current proposals.
I think the whole
requires-python
question comes down to whether we want to be writing down whatās required to make an single-file script/application run, or is this just a list of requirements that must somehow be installed?
What distinction are you drawing between āwhatās requiredā and ārequirementsā?
Conversely, not mandating support of
python-requires
doesnāt limit any tools. Hatch can implement such support for itself, as a non-standard extension. If you want, we can state that top-level tables namedx-*
will never be defined by a standard, so hatch can usex-python-requires
without any fear of its implementation being broken by future standards.
There is definitely a use case for being able to define the Python version required, but at the same time, being able to support that is also significantly more complex. I agree here that at least for now it should be optional. PEP 722/723 already provide a lot of value as is. This part, while also providing value, should not hinder this PEP. Let it be up to the tools to decide how much they want to lock with the information that is given. Personally, I like to be able to use this dependency specification with locking data in the same file, but thatās clearly also another step further and out of scope here.
s
Exactly this. People have different requirements, and I think we can consider both use cases.
I suggest for this PEP we keep the requires-python
optional, as itās far easier to implement, and to get more support for the important part of this PEP: non-interpreter dependencies. At the same, it would be great if, while being optional, it is encouraged to record required-python
and considered during execution to improve the reproducibility when executing. And that tools executing the script are encouraged to warn about mismatching Python version so there is no surprise when features are used in the script that are not available with the running Python.
Then it is entirely up to whoever wrote the script to decide whether they care about that level of reproducibility or not and choose tooling for it accordingly.
Paul, I think (correct me if Iām wrong) youāre interpreting my advocacy of the Python requirement as being exclusively about my maintainership of Hatch and I feel (again, could be wrong) that you are finding that quite offputting.
While it is true that Hatch would be able to satisfy the Python constraints it is not true that that tool would be the sole beneficiary as other tools could also support that like the py
launcher. Furthermore, and most importantly, I think you should look at it more as not a feature per se but rather UX for ensuring proper run-time behavior. If pip
fails to install when the Python version is not met then certainly any runner should follow suit lest the user encounters random errors as Brett was saying.
As far as being (possibly) perturbed by my advocacy, I donāt really know how to fix that. Itās not as if Iāll be writing this feature just for fun like āoh wow if I write this and this here and there then cool stuff happens! progress bars so pretty!!ā. No, not at all. Development takes a significant time out of my personal life like the rest of us. Supporting Python management is a feature that will tremendously help users and has been requested outside of Hatch for over a decade. Users simply donāt want to deal with that, nor should they have to.
Pants has the notion of applying an interpreter constraint to every python file. I could see us scraping this new field to populate that metadata on behalf of the user.
That being said, my vote is still that this is given piecemeal. First we decide on a format (because we havenāt done that yet) in a way that most people are ok with (Ofek wants toml, Paulās OK with it but not pyproject.toml, Brettās working on user surveys, and then everyones comments on the 3 threads). Then we can decide what goes in. It seems this discussion is starting to mirror, somewhat, Projects that aren't meant to generate a wheel and `pyproject.toml` so perhaps thatās not a coincidence?
I think for this to be the smoothest sailing, we might want to try and tackle each sub problem, or else weāre stuck discussing how to format things, or decide on multiple fields on PEPs dedicated to getting single-file scripts runnable.
Paul, I think (correct me if Iām wrong) youāre interpreting my advocacy of the Python requirement as being exclusively about my maintainership of Hatch and I feel (again, could be wrong) that you are finding that quite offputting.
I hope Iām not, but I can see how it would look that way.
My real concern here is that my main motivation for writing PEP 722 at all was to standardise existing practice, in such a way that tools like VS Code could interoperate with that existing behaviour without having to rely on implementation-dependent information. Therefore, to me it is a key point that those existing tools will adopt the new standard - otherwise, in my view, weāve missed the whole point of standardisation.
With that in mind, whether tools that donāt currently implement a ārun script with dependenciesā feature (such as hatch) adopt this standard is largely irrelevant - if (for example) VS Code adds an āinsert runtime dependency dataā action that works with hatch, but doesnāt work with existing tools, we havenāt achieved any real form of interoperability, rather weāve created a new approach and applied the weight of standardisation to enforce a type of āimplement this or be left behindā pressure. I donāt believe thatās the right way to use the standards process.
As I say - all of this may be irrelevant. The existing tools may have no issue with adding support for a ārequires Python version Xā check. But thatās not (IMO) a foregone conclusion - pipx run --python /path/to/my/python somescript.py
doesnāt have access to the requested interpreter without an additional subprocess call, so checking the version is costly. As a result, I donāt know if I would agree to adding a Python version check - the benefit is (IMO) minimal and the cost is non-trivial.
All Iām really asking here is that we donāt add features to the standard that the existing tools providing solutions for this use case are unhappy with adopting. Iām really quite confused why thatās seen as such a big ask[1]. But maybe Iāve not explained myself well enough - with luck, this clarifies things.
Maybe because I didnāt make a big point of it with PEP 722? But as I said, that proposal was specifically designed to match the existing implementations, so I felt comfortable assuming it wouldnāt be an issue. ā©ļø
Would you be more comfortable if the error was SHOULD and satisfying the constraint is MAY?