Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENHANCEMENT] PL Parser : parser les valeurs Python avec l'opérateur = #485

Open
ddoyen opened this issue Mar 24, 2022 · 0 comments
Open
Assignees
Labels
Enhancement New feature or request

Comments

@ddoyen
Copy link

ddoyen commented Mar 24, 2022

@nimdanor

Je reprends dans cette issue une proposition de modification du parser pl qui avait été discutée là (#380) et qui semblait avoir fait consensus.

Actuellement, le parser pl possède un opérateur = et un opérateur % pour affecter des valeurs aux clés. L'opérateur = lit la valeur comme une chaîne et l'opérateur % lit la valeur comme une valeur JSON.

On peut donc faire ce genre d'affectation.

# Affecte la chaîne "toto" dans mystr
mystr = toto

# Affecte le booléen true dans mybool
mybool % true

# Affecte la chaîne  "toto"  dans mystr2
mystr2 % "toto"

Mais la syntaxe des expressions JSON est légèrement différente des expressions Python correspondantes :

  • true/false vs True/False
  • null vs None
  • simple quotes non acceptées en JSON pour délimiter les chaînes

Et, en pratique, on est amené à jongler avec les deux syntaxes pour les clés (selon qu'on les définit dans le source PL ou dans un script Python), ce qui est perturbant, surtout pour les néophytes.

Nous proposions donc d'abandonner l'opérateur % et de modifier l'opérateur = de la façon suivante : le parser essaie d'interpréter ce qui est à droite de l'opérateur = comme une valeur Python et, s'il n'y arrive pas, il l'interprète comme une chaîne.

On pourrait donc écrire des affectations de ce genre.

mybool = False

mynull  = None

mystr1 = 'toto'

mystr2 = toto

En pratique, ça semble assez simple à faire. Il suffit de changer quelques lignes dans apps/loader/parsers/pl.py

Au lieu de...

if op == '=':
    self.dic_add_key(key, value)
elif op == '%':
    try:
        self.dic_add_key(key, json.loads(value))
    except json.decoder.JSONDecodeError:
        raise SyntaxErrorPL(join(self.directory.root, self.path),
                            line,
                            self.lineno,
                            message="Invalid JSON syntax starting ")

...il faudrait en gros faire ça

if op == '=':
    try:
        self.dic_add_key(key, ast.literal_eval(value))
    except:
        self.dic_add_key(key, value)

Questions en suspens.

  • Est-ce que c'est une bonne pratique de passer silencieusement vers une interprétation chaîne si on n'arrive pas à faire l'interprétation Python ? Ca masque d'éventuelles erreurs de syntaxe Python de la part de l'utilisateur. Je sais que Dominique aime bien ce mode où on écrit des chaînes sans quotes... :-) Perso, ça me dérange pas de mettre explicitement des quotes pour les chaînes. Sachant qu'on a déjà l'opérateur == ... == pour entrer du texte brut.

  • ast.literal_eval est capable de parser plus de types que les types JSON (tuples et sets notamment). Au moment où le dictionnaire Python de l'exercice va être converti en JSON, ça peut être problématique. Les tuples vont être convertis en array (comme les listes). Les sets vont peut-être déclencher des erreurs de conversion (à vérifier). Bref, il faudrait réfléchir à la façon de traiter ça de manière cohérente et robuste (soit au niveau du parsing, soit au niveau du dump Python->JSON).

@ddoyen ddoyen added the Enhancement New feature or request label Mar 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants