0
votes

Comment analyser les méthodes d'un code compilé Python

J'écris un Django Validator pour les fichiers téléchargés avec un forme. Ces fichiers sont des scripts Python qui peuvent être buggy et / ou dangereux, donc je ne dois donc pas les exécuter avant que les éléments soient complètement validés.

Un chèque est de s'assurer que les deux méthodes "exécuter" et "Rollback" sont présentes, encore une fois sans exécuter le code fort>. p>

Tous les scripts de python téléchargés ont la même structure: p> xxx pré>

J'ai trouvé la solution suivante à faire la solution suivante Ceci avec AST: P>

import ast
codetoanalyze=ast.parse(open("/path/to/script_to_analyse.py",'r').read())

if next((x for x in codetoanalyze.body[1].body if x.name == "run"), None) == None :
     raise ValidationError( _('Package error : module must contain a "run" method'), code='compilation_error', )

if next((x for x in codetoanalyze.body[1].body if x.name == "rollback"), None) == None :
     raise ValidationError( _('Package error : module must contain a "rollback" method'), code='compilation_error', )


7 commentaires

Vous pouvez simplement appeler les méthodes censées être là, piège tout attributeError qui résulte et se plaindre.


A quel point dans le processus avez-vous besoin de faire cela? Pourriez-vous utiliser un ABC ?


Vous pouvez faire comme "affirmation hasattr (action," gérer ") et hasattr (action, 'Rollback')" pour chaque classe


Merci pour vos réponses, ce contrôle fait partie d'un validateur Django. Je ne dois pas exécuter les scripts (chargez la classe) avant que cela n'a été validé. Actionglobal est une ABC mais l'action n'est pas. Dir () implique d'instancher un objet, je ne suis pas autorisé à cela à ce stade.


Pourriez-vous Modifier pour développer les raisons de vos besoins? "ne doit pas" , "pas autorisé à" - pourquoi, et par qui?


Oui, j'ai ajouté des détails.


pathlib.path ("/ chemin / à / script_to_analyse.py"). Read_text () est un peu meilleur, ferme automatiquement le fichier pour vous.


4 Réponses :


-1
votes

Je voudrais utiliser un visiteur comme un motif pour traverser l'arborescence


0 commentaires

1
votes

Vous devez utiliser dir () : xxx

sortie:

['__ classe__', '__delattr__', '__dic__', '__dir__', '__doc__', '__eq__', '__Format__', '__get__', '__gt__', '__gt__' , '__init__', '__init_subclass__', '__le__', '__lt__', '__Module__' ',' __Ne__ ',' __New__ '__New__', '__RECE_EX__', '__RePR__', '__SizeTtr__ "," __str__ ',' __subclasshook__ ',' __wakref __ ', ' méthodata ' , ' méthodétique> ]

ou, dans votre cas xxx

sortie:

true

fonctionne tous les deux dans python 2 et python 3


2 commentaires

Votre réponse est correcte Cependant, MyClass n'est pas importée dans mon processus. Je dois analyser le fichier sans l'exécuter.


@Julien j'ai compris votre problème. Si vous exécutez directement des fonctions et des méthodes dans votre module, AST est la meilleure solution; BTW L'approche idiomatique Python consiste à utiliser si __name__ == __Main __: : voir Qu'est-ce que si __name__ == __Main __ pour?



0
votes

Faire un ensemble de noms dans le code et la boucle sur tous les noms requis rendra votre code un peu moins de copie-pâte-y: xxx


0 commentaires

0
votes

Eh bien, il semble que Ast est une excellente solution pour mon besoin, alors j'ai créé un peu de poche l'expliquant ici

Pour ma question, voici la solution que j'ai implémentée: xxx

i J'attendra les autres postes et voter avant de sélectionner la réponse acceptée, si quelqu'un trouve un meilleur moyen d'y parvenir avec un autre module (peut-être avec le Parser ?).

Merci pour votre aide


0 commentaires