Introduction

Installation

Limitations du protocole "file"

Questions fréquemment posées

Syntaxe, mots-clés et fonctions intégrées

Distribution standard

Implémentation de import

Packages Brython

Interface avec le navigateur

Introduction - API DOM
Créer un document
Accéder aux éléments
Attributs, propriétés et méthodes

Evénements
Evénements souris
Evénements clavier
Evénements focus
Evénements pour glisser-déposer

Chaine de requête

Interactions avec Javascript

Modules intégrés propres à Brython

browser
browser.aio
browser.ajax
browser.html
browser.local_storage
browser.markdown
browser.object_storage
browser.session_storage
browser.svg
browser.template
browser.timer
browser.webcomponent
browser.websocket
browser.worker

Widgets
browser.widgets.dialog
browser.widgets.menu

interpreter
javascript

Travailler avec Brython

Options d'exécution
Test et débogage
Deployer une application

Recettes

Salut !
Insérer du contenu dans un élément
Mise en forme HTML (gras, italique...)
Table HTML
Attacher / détacher des événements
Gérer la sélection d'options dans un SELECT
Glisser-déposer
Obtenir le contenu d'un élément
Lire le contenu d'un fichier
Stocker des objets localement
Exemple de onmouseover
 

Questions fréquemment posées

Q : que signifie "Brython" ?

R : Browser Python (Python pour le navigateur). C'est aussi le mot gallois pour "Celte de langue brittonique".

Q : avec quels navigateurs peut-on utiliser Brython ?

R : sur tous les navigateurs modernes, y compris les smartphones. Le code Javascript généré évite intentionnellement de nouvelles syntaxes tant qu'elles ne sont pas supportées par la plupart des navigateurs.

Q : quelle est la performance de Brython par rapport à CPython ?

R : cette page compare le temps d'exécution d'un certain nombre d'opérations entre Brython et CPython sur Firefox. Les résultats sont variables selon les opérations, mais dans l'ensemble l'ordre de grandeur est le même.

Le repository Brython inclut un script, accessible à l'adresse localhost:8000/speed, qui compare la vitesse de Brython et de CPython sur la machine locale pour ces opérations élémentaires.

Q : quelle est la performance de Brython par rapport à Javascript ?

R : par rapport à Javascript, le rapport est naturellement très différent d'un programme à l'autre. Une console Javascript est fournie dans la distribution ou sur le site Brython, vous pouvez l'utiliser pour mesurer le temps d'exécution d'un script Javascript par rapport à son équivalent en Python dans l'éditeur (en décochant la case "debug").

La différence tient à deux facteurs :

  • le temps de traduction de Python en Javascript, réalisé à la volée dans le navigateur. Pour donner une idée, le module datetime (2130 lignes de code Python) est parsé et converti en code Javascript en environ 500 millisecondes sur un PC de puissance moyenne.
  • le code Javascript généré par Brython doit être conforme aux spécifications de Python, notamment au caractère dynamique de la recherche d'attributs, ce qui dans certains cas conduit à du code Javascript non optimisé.

Q : il y a des erreurs 404 dans la console du navigateur quand j'exécute des scripts Brython, pourquoi ?

R : c'est lié à la façon dont Brython gère les imports. Quand un script veut importer le module X, Brython recherche un fichier ou un paquetage dans différents répertoires : la bibliothèque standard (répertoire libs pour les modules en javascript, Lib pour les modules en Python), le répertoire Lib/site-packages, le répertoire de la page courante. Pour cela, il effectue des appels Ajax vers les url correspondantes ; si le fichier n'est pas trouvé, l'erreur 404 apparait dans la console, mais elle est capturée par Brython qui poursuit la recherche jusqu'à trouver le module, ou déclencher une ImportError si tous les chemins ont été essayés.

Q : pourquoi voit-on ce message dans la console du navigateur : "L’utilisation d’XMLHttpRequest de façon synchrone sur le fil d’exécution principal est obsolète à cause de son impact négatif sur la navigation de l’utilisateur final. Consulter http://xhr.spec.whatwg.org/ pour plus d’informations." ?

R : c'est aussi lié aux imports, ou à la lecture de fichiers. Pour réaliser ces opérations, Brython utilise des appels Ajax bloquants : il faut attendre qu'un module importé soit chargé pour pouvoir l'utiliser. Normalement les éditeurs de navigateurs ne devraient pas supprimer les appels bloquants avant longtemps.

Q : peut-on précompiler les scripts Brython pour réduire le temps d'exécution ?

R : Brython est conçu pour être aussi simple à utiliser que Javascript : on met du code Python dans une section <script> d'une page HTML, on charge la page, on édite le code, on recharge la page, etc. Ce n'est pas comme d'autres projets dans lesquels le code Python est transformé en Javascript par un programme en CPython, qu'il faut exécuter pour toute modification avant de recharger la page.

Une autre raison pour laquelle ce n'est pas une bonne idée de précompiler est que le code généré est typiquement 10 fois plus gros que le source Python de départ - c'est le prix à payer pour une compatibilité avec la spécification du langage. La page prendrait donc plus longtemps à se charger, et nous n'avons pas trouvé que cela ferait gagner du temps par rapport à une compilation à la volée.

En revanche, depuis la version 3.6.0, une version précompilée de scripts de la librairie standard est stockée dans une base de données indexedDB locale à chaque navigateur. La compilation se fait la première fois qu'un script est importé, ou si la version de Brython a changé depuis la précédente compilation. Cela permet d'améliorer sensiblement le temps de chargement des imports.

Q : j'essaie d'importer un module de la distribution standard Brython et j'ai un message d'erreur, pourquoi ?

R : la raison la plus probable est que le script brython_stdlib.js n'a pas été intégré dans la page.

Q : puis-je importer tous les modules / paquetages qui fonctionnent avec CPython ?

R : non, seulement ceux qui sont écrits entièrement en Python. Les programmes qui font appel à des extensions écrites en langage C ne sont pas supportés. Par exemple, Numpy, Matplotlib, Pandas ne peuvent pas fonctionner avec Brython.

De même pour les modules / paquetages qui font appel à des primitives du système d'exploitation qui ne sont pas disponibles dans le contexte du navigateur : par exemple requests, qui utilise les piles IP pour effectuer des requêtes HTTP vers des adresses arbitraires, alors qu'un navigateur ne peut qu'effectuer des appels Ajax dans le même domaine, ou vers les (rares) sites qui permettent les requêtes cross-origin.

Q : pourquoi utiliser l'opérateur <= pour construire l'arbre des éléments DOM ? Ce n'est pas pythonique !

R : Python ne possède pas de structure intégrée pour manipuler les arbres, c'est-à-dire pour ajouter des éléments "enfants" ou "frères" à un noeud de l'arbre. Pour ces opérations, on peut utiliser des fonctions ; la syntaxe favorisée par Brython est d'utiliser des opérateurs : c'est plus facile à saisir (pas de parenthèses) et plus lisible.

Pour ajouter un "frère" on utilise l'opérateur +.

Pour ajouter un descendant, l'opérateur <= a été choisi pour les raisons suivantes :

  • il a la forme d'une flèche, ce qui indique visuellement une affectation ; l'annotation de fonctions en Python utilise d'ailleurs un nouvel opérateur -> qui a été choisi pour sa forme de flèche
  • on ne peut pas confondre avec l'opérateur "inférieur ou égal" parce qu'une ligne comme "document <= elt" ne ferait rien s'il s'agissait de "inférieur ou égal" (qui est toujours utilisé dans une condition ou comme valeur de retour d'une fonction)
  • en Python, <= est utilisé comme opérateur pour les ensembles (classe set) avec une signification différente de "inférieur ou égal"
  • Python utilise le même opérateur % pour des opérations très différentes : modulo et formattage de chaines
  • le module pathlib de la bibliothèque standard utilise l'opérateur / pour construire des chemins dans le système de fichiers

De toutes façons, ceux qui sont allergiques à la surcharge d'opérateurs peuvent utiliser la méthode attach() des éléments DOM à la place.