Note greediness of PEP 723 reference parser

Ouverte Adaptée aux débutants
#1,960 4 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
68/100
Type d'issue
Documentation
Clarté
Plutôt claire
Activité
Calme
Stack technique
python
Domaine
documentation

Piste de recherche

Commencez par l’analyseur de référence de PEP 723 et la documentation de PyPA qui le répertorie, puis reproduisez le problème à l’aide des exemples REGEX et script_A/script_B du rapport. Mettez à jour la documentation concernée pour avertir de la concaténation gloutonne de blocs adjacents, et confirmez que l’avertissement décrit correctement le cas limite de TOML invalide qui en résulte.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Issue Description

While preparing a PR for PEP 723 support in pip, I noticed that the reference parser defined by the PEP and listed in the PyPA docs will collate multiple adjacent /// TYPE blocks as a single match, even when separated by a comment line (the spec refers to it as a "content line"). This greedy collation is surprising and makes distinguishing error cases a little complicated, so I think it merits a warning in the docs if it is not possible to update the specification itself.

I believe this quirk is caused by the last + in the reference regex being greedy and matching all the way to the trailing /// instead of to the first available one. In my limited experimentation, replacing this quantifier with +? resolves the issue, producing the expected number of matches.

This shouldn't slip through anybody's code unnoticed, as the collation will produce invalid TOML (the interior /// is invalid syntax), but it is a surprising enough edge case that I thought to report it here.

click for code
import re

script_A = """
# /// script
# data (1)
# ///
#
# /// script
# data (2)
# ///
"""

script_B = """
# /// script
# data (1)
# ///

# /// script
# data (2)
# ///
"""

# These lines adapted from PEP 723's reference parser:
# https://peps.python.org/pep-0723/#reference-implementation

REGEX = r"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$"
name = "script"
matches_A = list(
    filter(lambda m: m.group("type") == name, re.finditer(REGEX, script_A))
)
matches_B = list(
    filter(lambda m: m.group("type") == name, re.finditer(REGEX, script_B))
)

# output:
# 1
# 2
print(len(matches_A))
print(len(matches_B))
Code of Conduct
  • I am aware that participants in this repository must follow the PSF Code of Conduct.
Langage dominant
Python
Étoiles
1.7k
Forks
1.7k
Merge moyen
3 j 12 h
PR mergées (30 j)
4

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de pypa/packaging.python.org

Toutes les issues de pypa/packaging.python.org

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.