"pegen.py python" should validate the output file.
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 36k
- Métriques de merge des PR
- Métriques de PR en attente
Description
I ran pegen python -o grammar_parser.py after making an incorrect change to metagrammar.gram. This was invoked by make regen-pegen-metaparser, or build.bat --regen on Windows.
The resulting output file was syntactically correct, but it could not correctly parse the metagrammar file. So when I ran the make again later, it failed. The call to GeneratedParser.start() raised an exception.
The previous (correctly working) version of grammar_parser.py is now lost, unless I could get it back from Git.
Desired behavior
pegen must be sure that the newly generated output file will work correctly, before writing it out to the filesystem.
Generation of the output file begins in pegen/build.py,
def build_python_generator(
grammar: Grammar,
grammar_file: str,
output_file: str,
skip_actions: bool = False,
) -> ParserGenerator:
with open(output_file, "w") as file:
gen: ParserGenerator = PythonParserGenerator(grammar, file) # TODO: skip_actions
gen.generate(grammar_file)
return gen
This creates a new output file. Even if the body of the with raises an exception, the output file is closed and remains in the filesystem, overwriting the previous version.
Instead,
- Use a
StringIOas the file, instead of a realopen()file. Call itresult. - Generate the file, which fills in
result. - Validate
result(see more below). - If validation succeeds, then write the
resultto a newopen(output_file, "w"). - Otherwise, do nothing more. The file designated by
output_filewill still be intact.
Validating the output file
To validate the output file result, go through the entire process of generating result, except using
result instead of the grammar_parser module. This process is the entire code of build_python_parser_and_generator, not just the build_python_generator function.
grammar_parser is used to import the class GeneratedParser. For validation purposes, exec(result) with an empty globals/locals dict, then use the ['GeneratedParser'] item. Note, in build.py, this class is imported as the name GrammarParser.
This process should generate a new_result StringIO, and it should be identical to result. Perhaps there may be some insignificant differences between the two, and if so, they shouldn't be compared.
If the generation of new_result raises an exception, then the validation has failed.
Linked PRs
- gh-101937
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par pegen/build.py, en particulier build_python_generator et build_python_parser_and_generator. Suivez la manière dont la sortie du parser généré est produite et validée, puis préservez le fichier de sortie existant lorsque la validation échoue et vérifiez que la sortie valide n’est écrite qu’après la réussite de la validation. Consultez le PR lié gh-101937 pour voir le travail déjà en cours.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- build-system, compilers
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 32/100