My personal opinion is that the text doesn’t say. Given that the rule[1] is “when the regex and text disagree, the text takes precedence”, but there’s no disagreement here, the regex (as the only form which says anything) applies, and the search is therefore greedy.
In general, the text seems to me to either say what the regex says, or not say anything, so this approach works in general.
I’m disappointed that the text is ambiguous, because we’ve always had issues when specs are ambiguous. But at least the regex (by nature of it being executable) isn’t ambiguous. And I’m even less happy with the idea that approved PEPs can be changed without following our process. If people want to follow the process, we should get the spec on packaging.python.org, and then someone needs to propose a change, which will either be approved[2] as a text-only change, or be referred back to the PEP process for a new PEP to be created.
By the way - PEP 723 now needs to be converted into a specification on packaging.python.org. @ofek, I assume you will do this (once the current discussion has died down)?
I’m somewhat uncomfortable with that rule, as I said, but that’s not relevant here. ↩︎
As per the normal process, I’d be the PEP-delegate by default making the decision on this - it’s not part of the scope of Brett’s remit to make a decision on PEP 722 vs 723. ↩︎
I am happy to do whatever but I lack time this week. If you wouldn’t mind, can you please tell me precisely what to potentially change? Not ideas but literally what you see fit as removing ambiguity completely. I will then incorporate what you say on the PR and after merge then I will convert into a spec.
edit: after re-reading your comment it appears I have to do the spec first. okay I’ll work on that next
I’d personally be fine with the change I suggested above:
Beyond that, others want the text to be clearer, so they should suggest what they want. But to be a “textual clarification” as opposed to a spec change, any suggested change needs to state the same rules as the current regex implements - changing the regex, or having the regex and the text conflict, is (IMO) a change to the PEP and not just a clarification.
But I agree, the first priority should be to get the spec as given in the PEP published as a standard.
The problem with the text being ambiguous and relying on the regex is that the text both expresses intent and communicates to users how they need to write such a block. If something isn’t specified in the text but is expressed through the behaviour of the implementation it’s hard to know if it’s a bug or not.
Updating the text based on making it reflect what the regex actually does is working backwards to me - extracting intent from implementation - but I guess that’s the best answer without needing a follow-up PEP. However I do think it’s necessary to do so if only for people writing metadata blocks so it’s clearer what will/won’t work. This can wait until the spec is up though and done through the standard process.
This part is just a thought from my experience of this process:
I feel like it may be worth revisiting the process in the future in the case of competing PEPs of going from both proposed to simultaneously rejecting one while fully accepting the other. I think the competitive nature of trying to point out why one PEP is better than the other potentially gets in the way of trying to make sure that the ‘winning’ PEP is as good as it can be.
Does this change really require a follow-up PEP? I’m seriously asking–I thought it’d be covered by this section as mentioned above. It’s a minor clarification to avoid an ambiguous situation that currently has no purpose [1].
Right now the only pronouncement in this thread from @brettcannon is “conditionally accepted”. The PR changing said status has not even been merged. If such a trivial clarification cannot be fixed now without a new PEP, that seems like needlessly rigid procedure. Is the PEP delegate forbidden from changing their decision at this point? If not, I don’t see why this change is out of bounds.
The needed clarification (IMO) is: add ? to the final + in regex, and modify the text to say “…and ends with the next line matching # ///”.
I think spec → discuss the change (in this thread?) → update PEP is fine, but self-defeating if it adds any meaningful delay between acceptance and clarification, as the whole point is to avoid the ambiguity in different tools.
Overall I agree with this advice from earlier:
that is, there’s no reason to expect it in real code ↩︎
Originally, the regex was definitive. The current text, as @ofek pointed out, was changed because I objected to that - but my intent in objecting was that people shouldn’t have to reverse-engineer the regex to know the rules. So to that extent I agree with you. But the regex was precise and I think that was important - the fact that the text wasn’t updated to be equally precise (and to match the regex) was IMO an oversight, and as such doesn’t reflect an intention to have different rules.
I agree that the process wasn’t ideal here, but I think that’s not so much to do with the situation now, as with the whole process of having competing PEPs. Ideally, I’d be against ever having competing PEPs, requiring one PEP to be rejected before an alternative could be submitted - but I don’t see how that would work in practice.
The problem with making a decision of one over another, and then refining the chosen PEP, is that it’s then not clear what was accepted. Was PEP 723 accepted just because it’s TOML? Or just because it mirrors pyproject.toml? Or because it includes requires-python? Or because it allows for other block types in future? Possibly all of these, although PEP 722 also experimented with multiple blocks, and dropped the idea because of parsing complexities that are quite reminiscent of the issues being raised here. If PEP 723 changes, does the decision stand? Could I make PEP 722 more acceptable if I changed it? At what point are we just abandoning the decision in that case?
I won’t debate @brettcannon’s decision here. It’s an incredibly stressful job, making a decision between two competing PEPs, and no matter what you decide, you always feel that some group is annoyed at you. I really appreciate the fact that Brett was willing to act as PEP delegate, and put so much effort and expertise into making a decision that was bound to be controversial. I suffered a lot of criticism for the decision over editable installs, and I absolutely will not subject Brett to that sort of thing.
So with that said, we have an accepted PEP. It says what it says, and people had all the time they needed before the PEPs were submitted for approval to request changes. What we’ve ended up with may not be perfect, but we need, as a community, to stand by our processes and our decisions. If we can’t do that, we will never be able to make progress.
We have a process for changing accepted standards. If there’s evidence that we need to invoke that, then we can do so. But I think we should give it more than 3 days after acceptance before deciding we need to take that route.
Both @ofek and I (as the authors of the two competing PEPs) have stated that PEP 723 should be read as saying that the regex defines the behaviour in this case. That should be sufficient in the short term at least. Clarifying, but not changing, the specification can happen later, once the spec is online - as per our process, that would need agreement[1] that it is just a clarification, if it were to be done without a PEP.
From me, as interoperability spec PEP delegate. ↩︎
I went back to Brett’s description in his acceptance of the PEP and it looks like the description is of the behaviour I expected, and not the behaviour of the regex. So I don’t think it’s unfair to ask if this should be considered an implementation bug.
Perhaps not time, but before the PEPs were submitted both implementations seemed to have the potential to significantly change at any moment (I had at one point, implemented the ## metadata block format from one of the PEP-722 drafts before discovering you had reverted it shortly after). There was a lot of time spent trying to come up with some kind of compromise PEP before deciding that wasn’t going to happen. I can only speak for myself but by that point I didn’t have the energy left to do this kind of work for both PEPs.
Edit: That said I no longer wish to argue and have implementations of both behaviours in branches of my parser whichever way things fall.
Can you please explain this a bit further? I don’t quite understand what is incorrect in the current text:
If there are characters after the # then the first character MUST be a space. The embedded content is formed by taking away the first two characters of each line if the second character is a space, otherwise just the first character (which means the line consists of only a single # ).
If you mean that the regular expression is unable to extract the final content directly without postprocessing then that is true for sure but I don’t think that is possible nor desirable to have such a complex pattern even if it is possible.
That part’s not the issue. The issue is the second part of
…between the /// pyproject and /// markers.
The regex does not stop on encountering a # /// marker, if it encounters another # /// before finding a line that doesn’t start with # it will consume up to that marker instead of yielding the first ‘block’.
First off, sorry for the delay in my response; busy weekend for personal reasons.
Yes.
Great!
Totally fine, hence why I made acceptance conditional (which you could argue means it hasn’t been fully accepted yet, which plays into what’s discussed below).
I think the question then is who is going to write that PEP? @ofek ? Me? Both of us? Someone else?
I agree it should be an error.
I think nested blocks are illegal with the statement above saying that lacking a closing # /// is illegal. Basically you would end up with the intermediate blocks being viewed as part of the outer block and probably causing a TOML syntax error.
As would I. If a substantive change was made I would have to go back to reconsidering the PEPs as it isn’t the same PEP anymore.
Yes, yes, no, and not specifically (hence why I’m not too bothered by tightening this part of the PEP up).
In this instance, none of these details change my decision regardless of what gets chosen. I personally view this as tightening the spec based on lessons being learned very quickly after the PEP was conditionally accepted (which is way sooner than we typically find out about gaps in our specs!). Nested blocks and such were never a concern of mine, so I’m fine with whichever direction we go (as I said above, though, if we require a closing # /// like the PEP says then nested blocks simply aren’t a thing as you flat-out can’t nest; you just have a random thing in the middle of your TOML which will likely break it; you find the opening marker and then start looking for the closing marker).
Or put another way, as the PEP delegate I am not bothered by us tightening our parsing rules without changing the markers (that would make it a new PEP). It’s still early, I didn’t accept PEP 723 over 722 due to nesting or anything and so it doesn’t change my reasoning for acceptance, and the acceptance is still conditional on [run] somehow making it into pyproject.toml so you can argue it’s a bit more malleable from a spec perspective.
I agree with this and maybe it’s worth starting a separate thread to discuss this. But I’ll put this here for now and maybe some of this will get split at some point. . .
Well, I think a big question here is at what point it becomes important to make a firm decision. As you mentioned, we don’t want to be in a position of making a decision and then immediately reversing it. But it seems to me that in many cases we can just take our time about making that firm decision in the first place.
In the discussion for both these PEPs there were various revisions and accommodations, which seems like a sign of a healthy process. The part whose healthiness I’m a bit less clear on is the later stage of finalizing the idea as a PEP, submitting it, and then getting an up-or-down decision which immediately is regarded as final and unrevisable. I guess maybe there is a desire to have closure and move on, but I feel like in many if not most cases it would be beneficial for acceptance to be provisional or for there to be some kind of “line item veto” that makes clear what would need to change for the PEP to be accepted. I keep thinking of the academic world, in which “revise and resubmit” or “accepted with revisions” are common “decisions” on a submitted paper, which just formally starts a new round of narrowing down what needs to be changed.
For instance, in this case one clear aspect of the decision was the finding from the user study that “TOML isn’t that big of a burden”. I think that is great info and hugely beneficial to the process of making these decisions. It would seem fine to me if the “result” was that a decision were made, on that basis, just on that aspect of the choice between the two PEPs, while still allowing for future refinement within that. In other words we could say “we’ve officially decided to use TOML, but we can take some more time to decide if PEP 723’s precise form is the best way to do that”. That would amount to rejecting PEP 722 while “remanding for potential revision” PEP 723. The current process doesn’t seem to allow for that exactly, although it can be implicit in the earlier discussion stages.
The other big, big, thing that I keep thinking is that it would really be great to have that kind of user perspective at earlier stages of the process, whether that’s in the form of focus-group type studies like we had here, or surveys, or whatever . I realize there are practical difficulties (like it takes person-hours and hence often money to do those studies), but in the long run I think Python would benefit if such user feedback could play a more explicit role in formulating proposals, rather than just deciding whether to approve a proposal whose form is already regarded as final. I’m sure a lot of the debate about the syntax differences between the two PEPs would have been quite different if we knew beforehand that users wouldn’t find it that big a deal to learn TOML!
I think the first step should be to open a discussion (or re-start the previous one) and get community consensus on what [run] in pyproject.toml would mean. The previous discussion did not leave me with a good sense that there’s community consensus, even on the idea of having [run] in pyproject.toml, much less what its semantics should be, or how it should interact with the [project] section (the data in the two sections has considerable overlap).
I don’t think there should even be any assumption here that it’s a given that [run] will someday be in pyproject.toml. PEP 723 can’t guarantee that (and indeed, it doesn’t - it merely says that if we ever get a [run] section in pyproject.toml, it must contain the two fields defined here). And IMO, there’s some semantics to be dealt with as well - PEP 723 says “The fields defined by this PEP are equally as applicable to full-fledged projects as they are to single-file scripts”, but I don’t believe that’s true - you don’t run a “full-fledged project” in Python, you run a file. So you can’t realistically add [run] to pyproject.toml until you have established what it means to “run a project” in the first place…
Anyway, all of this can be debated in the discussion thread for “[run] in pyproject.toml”, not here.
OK, so are you saying that the regex (and therefore the reference implication in the PEP) is wrong? And if so, do you agree with me that they need to be fixed to match the above ruling, along with any text changes to clarify the intent? I really don’t like the idea of including a regex in the PEP that doesn’t implement the correct rules - that’s just crying out for people to copy the regex and not be aware that they now have a buggy implementation.
Cool. So let’s do that, then.
Um. Now that you put it like this, are you saying that if I were to reject a PEP to add [run] to pyproject.toml, then PEP 723 would be withdrawn at that point? Would PEP 722 be reconsidered in that case? Because I’m not at all happy that I could be put in a position where I have to decide on a PEP to add [run] for pyproject.toml but my judgement on that matter could be called into question because PEP 722 got rejected
You seem to be assuming that adding [run] to pyproject.toml would be non-controversial. On the other hand, the reason I want it as a separate PEP is precisely because I think it will be controversial.
In particular, I think that your proposal for a run table would have problems because it doesn’t tie the requirements into “being used to run the project” (which is what PEP 723 requires). So ironically, I’d reject your proposal at least in part because of PEP 723, unless you could somehow define what “running a project” meant in terms of your proposal. And I’d be looking particularly hard at the use case of viewing a directory full of Python scripts with different requirements as a project…
At some stage, the PEP author needs the option to say “I’m done, let’s just make a decision”. A PEP is one author’s proposal, describing that author’s vision - the community can contribute ideas, but ultimately the PEP author has final say.
Equally, the PEP author has a right to get an unequivocal decision on their proposal. Is it accepted (in which case the author can migrate it to the packaging specs document, and the community can get on with using it) or not (in which case mark it as rejected and move on)?
And of course, we make mistakes and proposals have issues. We have a process for that - ask for approval to make a clarifying textual edit, or write a follow-up PEP to fix the issue. You may not like the process, and it’s certainly a bit heavyweight in some cases, but we have a process for changing the process too - by all means use it.
And finally, because the PEP delegate has relatively broad authority over what changes can be made as textual edits, we have flexibility on a case by case basis. The only issue here is that Brett was PEP delegate for this PEP, and this discussion came up very soon after acceptance, so there’s a bit of uncertainty as to whether changes come under his remit or mine. But that’s largely something we can agree between ourselves (and we basically have, in a few lines of comments earlier in this thread). So I don’t think things are as unhealthy as you suggest in that regard.
The unhealthy thing here seems to me to be that our processes are sometimes too laborious, but people prefer to complain and try to bypass those processes rather than using them (one last time!) to improve them.
Sure. “Revise and resubmit” in PEP terms would be “Rejected, but the PEP-delegate gives guidance on what a new/updated PEP that would be accepted could look like”. And “accepted with revisions” is “PEP-delegate speaks to the author asking for changes before approval, and once those are made, approves”.
Our process is perfectly capable of handling those ideas. And I’ve used both, myself, in the past.
We could. “PEP 722 is rejected, and PEP 723 is deferred - any successful PEP should follow PEP 723 and use TOML, but PEP 723 failed to make a good enough case for the specific syntax used to embed the TOML In a script”. That’s a valid PEP-delegate response, but it’s not what @brettcannon said in this case. As PEP delegate, I’m sure he spent plenty of time thinking about what his best response could be.
Absolutely. As a PEP author, if I had access to some means of asking for a study on some question relating to my PEP, I’d happily use it. Who’s going to set up such a service, though? It would have to be free - we don’t want PEP quality to become a “pay to play” exercise.
And as a PEP delegate, I’d also love to have access to a service like this. Community consensus is a poor substitute for a well-focused survey, and has additional downsides (people are led to think that consensus is the only criterion needed, and PEPs degenerate into popularity contests). But no-one’s offering me that service in my PEP delegate role, either.
That’s just not true, you have to “run” every Python application in existence. For example, I would assume the code for PyPI itself will use such a table.
This is actually quite odd to me because my interpretation of all the other threads is that this would not at all be controversial and has been requested frequently because we have no (standard) story at all about helping developers of applications.
OK let’s leave this for the other PEP discussion. I need to review the previous discussion and make sure I’ve got my personal views and my “PEP delegate viewpoint” sorted out rather than making more semi-informed comments