La fausse bonne idée du "Grep Test"
Je ne connaissais pas le Grep Test avant de le voir mentionné sur LinkedIn. Je ne sais pas à quel point l'idée est répandue mais elle est très simpliste : tous les appels de fonction doivent être explicites au point d'être trouvables via la commande grep.
The Grep Test: If any code declares or makes use of a function, class, module, or variable that cannot be located by grepping for its full identifying token, it fails the Grep Test.
By “full identifying token”, I mean that if I search for
inverseTransform, I expect to find every declaration or invocation of any method namedinverseTransform.
Cette règle parait être un règle de bon sens. C'est vrai tant que le code considéré reste basique. Mais il y existe des cas où cette règle n'est plus valide.
Considérons le code suivant.
1from functools import partial
2
3def multiply(x, y):
4 return x * y
5
6double = partial(multiply, y=2)
7print(double(5))
C'est un cas simple d'inversion de contrôle. Notre code dépend du module functools et celui-ci n'a aucune connaissance de notre existence.
A la ligne 6, on informe functools de l'existence de notre fonction multiply.
A la ligne 7, on invoque un objet issu de functools qui, à son tour, va invoquer notre fonction multiply.
Ces 2 lignes pourraient être séparées de dizaines d'autres ou même être dans des fichiers différents.
Le "Grep Test" va donc échouer : à la ligne 7, le code de functools utilise notre fonction multiply sans qu'un grep ne permette de localiser cet appel.
Si on lit attentivement l'article qui décrit le "Grep Test", il met l'accent sur tout autre chose : les noms de fonctions construits dynamiquement qui rendent difficile la recherche par nom de ces fonctions et les remaniements de code. Et quand les définitions et les appels sont tous dynamiques, aucun grep ne pourra rien y faire.
1name1 = "my_" + "function"
2exec(f"""
3def {name1}():
4 print("Hello World!")
5""", globals())
6
7name2 = "my" + "_function"
8globals()[name2]()
Au final, l'utilisation du grep n'est qu'une distraction qui s'écarte du sujet mais parler de "grep test", ça claque évidemment beaucoup plus qu'une explication barbante sur les noms de fonctions dynamiques.