Premiers pas avec Emacs et Python

De Ensiwiki
Révision de 22 juin 2016 à 16:09 par Moym (discussion | contributions) (Utilisation de Pylint)

Aller à : navigation, rechercher

Emacs ... un éditeur de texte

Emacs est un éditeur de texte, très puissant, extensible, même s'il n'est pas toujours très intuitif. Certains disent qu'il peut tout faire sauf le café, ils se trompent.

D'abord, qu'est-ce que ça veut dire, un « Éditeur de texte » ? Vous avez surement déjà utilisé un « Traitement de texte », qui permet de taper du texte, de le mettre en forme (gras, italique, taille et choix des polices, …). Un éditeur de texte édite du texte brut : pas de mise en forme, pas de dessins, juste du texte. Une suite de caractères, quoi. Mais en informatique, on trouve du texte brut partout : langage de programmation, fichiers de configuration de beaucoup de logiciels, …

On pourrait essayer d'éditer le texte d'un programme Python avec un traitement de texte classique, mais on aurait énormément de fonctionnalités inutiles, et par contre, il manquerait énormément de choses.

Ouvrir un fichier

Commencez par télécharger le fichier hello.py, et sauvegardez-le sur votre compte.

Un moyen simple d'ouvrir ce fichier dans Emacs est de lancer, en ligne de commande :

emacs hello.py

Un autre moyen, c'est de lancer Emacs, puis dans le menu File, choisir Open File…, et choisir le fichier à ouvrir.

Emacs-open-hello-py.png

Quand on a plusieurs fichiers sur lesquels on veut travailler en même temps, il faut ouvrir chaque fichier depuis une fenêtre Emacs déjà ouverte, sinon, on lance beaucoup de processus Emacs, c'est moins pratique, et ça consomme beaucoup plus de ressources de l'ordinateur.

En pratique, on va beaucoup plus vite en faisant la même chose au clavier, sans utiliser le menu. Depuis une fenêtre Emacs, faire C-x C-f, c'est à dire Control-x puis (sans relâcher la touche Control pour aller vite), Control-f. Une invite apparaît en bas de la fenêtre (ce qu'Emacs appelle le « minibuffer »). Entrez le nom du fichier (la touche tabulation permet de completer quand on a entré les premières lettres) et validez avec Entrée :

Emacs-control-x-control-f.png

Créer un fichier

Quand on lance la commande emacs sans argument, une fenêtre s'ouvre, mais elle ne correspond à aucun fichier. Si on veut travailler sur un nouveau fichier, il faut créer ce fichier avant d'entrer son contenu (ce qui permet à Emacs de savoir à quel langage de programmation il doit s'adapter) :

emacs

Emacs-visit-new-file.png

En fait, tout ce que nous venons de voir pour ouvrir un fichier existant s'applique aussi pour créer un nouveau fichier : il suffit de demander à ouvrir un fichier qui n'existe pas, et Emacs le créera pour vous. Par exemple depuis la ligne de commande :

emacs nouveau_fichier.py

(Attention, cette version ouvre une nouvelle instance d'Emacs, à éviter si vous avez déjà un Emacs lancé)

Le plus rapide si vous avez déjà un Emacs lancé : C-x C-f (comme ci-dessus), entrez le nom du fichier à créer puis validez avec Entree :

Emacs-control-x-control-f-new.png

Naviguer entre les fichiers ouverts

Si vous avez suivi les explications ci-dessus, vous avez maintenant deux fichiers ouverts dans Emacs : hello.py et nouveau_fichier.py. Dans la terminologie Emacs, un fichier ouvert s'appelle un buffer (c'est la copie du contenu du fichier dans la mémoire). On peut passer de l'un à l'autre avec le menu « Buffers » :

Emacs-buffers.png

Là aussi, on peut aller bien plus vite au clavier avec le raccourcis C-x b (Control-x, puis relâcher, puis touche b). Entrez le nom du buffer (ou laissez vide pour choisir le buffer suggéré par Emacs), puis validez avec Entrée :

Emacs-control-x-b.png

Emacs et le Python

Revenons à notre fichier hello.py. Vous avez maintenant une fenêtre Emacs ouverte, avec le contenu de ce fichier affiché.

Coloration syntaxique

Premier constat : les mots clés (def, print, …) sont en couleur. Ah, mais on avait pourtant dit qu'il n'y avait pas de mise en forme dans un fichier texte ?!? Et non, il n'y a pas de couleurs dans le fichier, mais Emacs nous l'affiche quand même avec des couleurs. Vérifiez si vous voulez en faisant « less hello.py » dans un terminal, il n'y a pas de couleur.

Emacs-coloring-hello-py.png

Indentation

L'indentation (espaces en début de ligne) est crucial en Python : c'est ce qui détermine où se trouve la fin d'un bloc de code. Sur notre exemple, la fonction dire_bonjour se termine à la fin du bloc indenté, elle contient les deux instructions print.

Emacs vous aide à indenter votre code correctement : un appui sur la touche tabulation (notée TAB dans la suite) vous permet de choisir entre plusieurs indentations pour la ligne courante. Essayez de placer votre curseur sur la ligne print("Et bienvenue à l'Ensimag !"), et appuyez sur la touche TAB plusieurs fois. Emacs vous propose une version où cette ligne est désindentée (donc à l'extérieur de la fonction) et la version d'origine.

Emacs-python-indent.png

Pour indenter/désindenter plusieurs lignes, Emacs vous aide aussi. Essayez par exemple de répéter 3 fois le contenu de la fonction en ajoutant for i in range(3): autour du corps de la fonction :

  • Ajoutez la ligne for i in range(3): en début de fonction
  • Sélectionnez les deux instructions print (à la souris)
  • Appuyez sur Control-C, relâchez, puis appuyez sur la touche > : les deux lignes sont décalées. On aurait pu le faire pour un morceau de code plus long en utilisant autant de touches.

Emacs-python-shift-region.png

On peut faire l'opération inverse avec Control-C puis < pour désindenter un morceau de code.

Exécution d'un programme Python

Emacs permet d'exécuter un programme Python sans quitter son éditeur, mais restons simple pour le moment : ouvrez un terminal et si besoin placez-vous (cd) dans le même répertoire que le fichier hello.py.

On peut exécuter le programme en entrant la commande python3 hello.py (attention, le 3 dans « python3 » est important) dans le terminal :

Emacs-term-python.png

Une autre possibilité est de spécifier à l'intérieur du fichier qu'il s'agit d'un programme Python 3 en ajoutant en première ligne de hello.py :

#! /usr/bin/env python3

Il faut maintenant rendre le fichier exécutable en exécutant cette commande dans un terminal :

chmod +x hello.py

On peut maintenant exécuter le programme avec ./hello.py :

Emacs-term-chmod+x.png

Vérifications à la volée

Un défaut potentiel du langage Python est que la plupart des erreurs de programmation ne sont levées que pendant l'exécution du programme. Pour gagner du temps et écrire du code le plus fiable possible, il existe cependant des outils qui permettent de trouver certaines erreurs avant d'exécuter, et éventuellement en cours de frappe.

Utilisation de Flycheck et Flake8

Nous allons commencer avec l'outil flake8, qui trouve à la fois de problèmes de formatage de code et des bugs potentiels comme des utilisations de variables ou fonctions indéfinis.

Essayons dans un premier temps depuis un terminal : lancez la commande

flake8 hello.py

En principe, la commande ne doit produire aucune sortie : flake8 n'a trouvé aucun problème avec notre programme. Modifiez maintenant le programme en remplaçant la définition de la fonction par def dire_bonjour(arg) (remplacer « nom » par « arg ») et recommencez. Vous devriez obtenir un avertissement :

Emacs-term-flake8.png

En effet, nous utilisons la variable nom qui est maintenant indéfinie : c'est un bug. Le « F821 » n'est pas important : c'est le numéro de l'erreur.

Emacs peut nous faciliter la vie en appelant les outils comme flake8 pour nous au fur et à mesure qu'on écrit le programme.

Dans la fenêtre Emacs, faites Alt-x (que l'on note M-x dans le jargon Emacs), puis entrez flycheck-mode, comme ceci :

Emacs-M-x-flycheck-mode.png

Validez en appuyant sur « Entrée ». Emacs devrait vous répondre « flycheck mode enabled » :

Emacs-flycheck-mode-enabled.png

Si ça ne marche pas, c'est que le mode flycheck n'est pas installé, [www.flycheck.org/ suivez les instructions sur le site de flycheck] pour l'installer (ce n'est pas nécessaire sur les machines de l'école).

La variable nom est maintenant soulignée en rouge. En passant la souris ou en passant le curseur sur l'erreur, on voit apparaître le message précis (undefined name 'nom'). Il n'y a plus qu'à corriger (par exemple en revenant au programme d'origine en changeant « arg » par « nom » dans la déclaration de la fonction).

Pour voir d'un coup d'œil s'il reste des erreurs, la barre en bas (appelée « modeline » dans Emacs) affiche FlyC quand tout va bien, et FlyC:N/M pour dire qu'il reste N erreurs et M avertissements.

Utilisation de Pylint

Flake8 est content de notre petit programme, mais nous sommes plus exigeants que cela. Nous allons maintenant dire à Emacs d'utiliser l'outil Pylint, bien plus pointilleux que flake8.

Ouvrez le fichier .emacs, et faites en sorte qu'il contienne ces lignes :

;; Vérifications en cours de frappe
(when (featurep 'flycheck)
  (global-flycheck-mode 1)
  (push 'python-pylint flycheck-checkers)
  )

Dans le .emacs fourni, ces lignes sont déjà présentes pour vous aider, mais sont commentées (le point-virgule est le caractère de début de commentaire dans le langage de configuration d'Emacs), il vous suffit donc de supprimer les point-virgules en tête de ligne.

Rechargez le fichier en faisant M-x eval-buffer RET (Alt-x, puis relacher, puis entrer « eval-buffer », puis validez avec Entrée). On peut aussi fermer Emacs et le relancer.

Ces quelques lignes font deux choses :

  • Activer le mode flycheck par défaut pour tous les fichiers.
  • Utiliser pylint pour les fichiers Python

Revenez maintenant au fichier hello.py et si besoin faites une modification triviale (ajouter un espace puis le supprimer par exemple) pour relancer l'analyse par flycheck. C'est maintenant Pylint qui vous donne les avertissement, et il en trouve trois nouveaux :

Emacs-flycheck-pylint.png

Nous pouvons corriger comme ceci :

"""Module Python pour tester Flycheck et Pylint."""

def dire_bonjour(nom):
    """Fonction qui dit bonjour à l'utilisateur."""
    for _ in range(3):
        print("Bonjour,", nom, "!")
        print("Et bienvenue à l'Ensimag !")

dire_bonjour("vous")

Les deux chaînes de caractères ajoutées sont des « docstrings », et permettent de documenter le module python (en haut du fichier) et la fonction (entre la ligne def et la première ligne de code de la fonction). Nous avons remplacé i par _ qui est la convention Python pour dire « une variable qui n'est jamais utilisée ».