Macros/Conception et Développement d'Applications Python

    From The Document Foundation Wiki
    This page is a translated version of the page Macros/Python Design Guide and the translation is 97% complete.
    Outdated translations are marked like this.

    Introduction

    Cette page est destinée aux programmeurs de macros Python qui désirent concevoir des projets LibreOffice complexes et/ou collaboratifs. Elle concerne les utilisateurs débutants ou bien expérimentés. Une initiation à la programmation Python sous LibreOffice permet la découverte rapide du Python au sein de LibreOffice.

    Les volontaires au projet LibreOffice peuvent se reporter à ce Wiki.

    Une exposition raisonnable au langage Python ainsi qu'une certaine familiarité avec la suite LibreOfice sont bienvenues avant de poursuivre la lecture. Les exemples Python figurant ici sont incomplets et les usages de LibreOffice brièvement décrits.

    Documentation

    Cours en ligne

    Bibliographie

    Modélisation UML

    De nombreuses solutions de modélisation existent. Voici une liste arbitraire des outils gratuits, libres, multi-plate-formes ou multi-lingues.

    • ArgoUML : ArgoUML Développé en Java, il est disponible en dix langues (anglais, français, allemand, italien, portugais, espagnol, russe, norvégien et chinois).
    • StarUML : StarUML est proposé pour macOS 10.6+, Windows XP+ et Ubuntu (64/32-bit). StarUML compte de nombreuses fonctions mais exige la maîtrise de l'anglais.
    • Umbrello : Umbrello est multi-lingue et accompagne les distributions GNU/Linux, Windows (64 or 32-bit) et macOS.

    Une liste exhaustive d'outils pour Unified Modeling Language (UML) est disponible depuis Wikipedia.

    StarOffice Programmer's Tutorial décrit en anglais les documents LibreOffice à l'aide de diagrammes UML.

    Une description des Patrons de Conception est disponible sur Wikipedia, illustrée parfois d'exemples Python.

    Préambule

    Windows - Bibliothèques de scripts Python

    L'environnement de développement intégré (EDI), présent dans LibreOffice, permet l'écriture, la mise au point et la gestion des macros en langage Basic seulement. L'usage d'un EDI pour le développement de macros Python requiert un effort de configuration. En retour le développeur dispose d'un outil de développement à sa mesure ou adapté à ses besoins. Les recommandations ci-après s'adressent aux débutants comme aux utilisateurs expérimentés.

    La gestion de bibliothèques et de macros disponible pour le Basic, n'existe pas pour le Python. Cependant gérer les modules et fonctions du langage Python est tout à fait possible. Les packages Python ne correspondent pas exactement aux extensions LibreOffice ou aux packages UNO. Cette page utilise indifféremment le terme module pour bibliothèque et fonctions pour macros. La terminologie Python peut y être privilégiée pour accoutumer les familiers au Python.

    Il existe trois types de scripts Python, ceux propres à l'utilisateur, ceux qui sont partagés par tous ou bien ceux contenus dans les documents. Il sont présents en divers endroits selon leur type et selon la plate-forme utilisée.

    Pour gérer les scripts il est possible de recourir aux bibliothèques de Windows ou bien aux raccourcis sous Gnu/Linux. Cela permet de les organiser par simple glisser-lâcher. La définition de ces bibliothèques ou de ces raccourcis se fait en consultant Débuter avec OpenOffice ou LibreOffice.

    Outils - Macros - Gérer les scripts python

    Les projets Python peuvent se grouper par EDI au sein d'une bibliothèque comme illustré.

    Menu de l'extension APSO

    Une extension intitulée Alternative Python Script Organizer apporte une remarquable assistance à la gestion des scripts. Une fois installée et LibreOffice redémarré, apparaît un menu Outils - Macros - Gérer les scripts python.

    Les dépôts "Mes macros", "Macros LibreOffice" et "Nom du Document" distinguent les types de script.

    De multiples actions facilitent la gestion des scripts Python. Le bouton Exécuter lance la macro sélectionnée. Les actions du bouton Menu dépendent de l'élément actif :

    Gestion des scripts Python
    • Nouvelle macro ou bibliothèque en sélectionnant les dépôts "Mes macros" ou "Macros LibreOffice"
    • Modifier, Renommer ou Supprimer une macro ou bibliothèque
    • Copier une macro vers un document depuis les dépôts "Mes macros" ou "Macros LibreOffice"
    • Remplacer une bibliothèque d'un document par un module Python
    • Exporter une bibliothèque d'un document vers un module Python
    • Déboguer la macro sélectionnée
    • Lancer la console interactive de Python également appelée Python shell.

    Le chapitre "Mise au Point" détaille d'autres aspects liés à l'organisation des modules et des packages Python.

    La page Script LibreOffice détaille comment assigner des scripts personnalisés (ou macros) à des entrées de menu, des icônes, des contrôles de boîte de dialogue et des événements dans LibreOffice.

    Développement

    De nombreux logiciels ont recours au Python soit nativement soit spécifiquement. LibreOffice incorpore son propre interpréteur Python, lequel permet l'usage des API au travers d'Universal Network Objects (UNO). Le langage Python propose nativement un interpréteur utilisable parallèlement à celui de LibreOffice. Tous deux partagent une base commune et sont extensibles, ainsi certaines de leurs fonctions se recoupent, mais pas toutes. Le Python natif n'inclut pas l'interface UNO à l'API de LibreOffice et il n'offre pas la possibilité de les reconnaître. Réciproquement l'interpréteur de LibreOffice ne se comporte pas totalement comme le Python natif, ainsi n'étend il pas ses fonctionnalités de la même façon. Cependant ni LibreOffice ni le Python natif ne facilitent le développement d'applications en Python pour Writer, Calc, Impress, Draw, Base ou Math.

    LibreOffice est disponible en versions 32bits ou 64bits. L'environnement de développement intégré (EDI) qui peut lui être associé s'exécute dans le même contexte que la suite bureautique, soit tous deux en 32bits soit tous deux en 64bits. Il existe de nombreux EDIs pour Python, des plus basiques (quoique) comme IDLE aux plus élaborés comme PyCharm ou Pydev pour Eclipse. La liste qui suit est arbitraire, elle se focalise sur quelques outils libres gratuits, inter-opérables et si possible multi-lingues. La rubrique mise au point (débogage) est détaillée ci-après avec Pyzo et PyCharm à titre d'exemple. Le site Python.org répertorie une liste, en anglais, d'EDIs pour le langage Python. Un comparatif (en anglais) des Environnements de Développement Intégrés (EDI) par langage de programmation existe sur Wikipedia.

    • Integrated Development and Learning Environment (IDLE) supporte 32bits ou 64bits, est disponible sur un grand nombre de plate-formes, ne parle qu'anglais. C'est l'outil de référence pour s'initier au langage Python.
    • Geany fonctionne en 32bits et parle 43 langues différentes. Il tourne sur GNU/Linux, *BSD, macOS, AIX v5.3, Solaris Express et Windows. Geany est léger, convient aux petits projets, et peut lancer l'interpréteur Python de LibreOffice.
    • Liclipse
    • Aptana semble supporter le débogage, cf. ce sujet (en anglais).
    • PyCharm (dans sa version gratuite) supporte les plates-formes Gnu/Linux, macOS et Windows. Disponible en 32bits, il semble s'accommoder du 64bits également. PyCharm intègre un puissant débogueur compatible avec LibreOffice, de nombreuses autres fonctionnalités accompagnent la mise au point avec cet outil, cependant il exige de maîtriser l'anglais.
    • Pyzo fonctionne avec Linux, OS X et Windows dans 10 langues différentes. De nombreux interpréteurs Python sont configurables soit en 32bits soit en 64bits. Pyzo permet le débogage des modules ou routines Python.

    Voici une liste incomplète de possibilités offertes par ces EDIs, parfois sans équivalent dans l'EDI Basic propre à LibreOffice.

    Explorateur de Classe, Coloration Syntaxique

    IDLE, Geany et PyCharm facilitent l'édition de scripts Python à l'aide de la navigation dans le code et de la coloration syntaxique. Geany et PyCharm supportent aussi pliage et dépliage de code. Le navigateur de scripts d'IDLE ne supporte pas les classes internes ou imbriquées.

    Complétion de Code

    IDLE, comme Geany et PyCharm proposent une assistante à l'écriture de script appelée complétion de code.

    Débogage

    Déboguer un script Python fait l'objet d'un chapitre complet intitulé Mise au Point.

    Conventions de Codage (PEP)

    L'EDI Pycharm vérifie le respect des normes PEP de programmation Python (Python Enhancement Proposals).

    PyCharm Assistant des PEPs Python

    Les recommendations de codage Python (PEP) s'affiche sur la droite de l'EDI PyCharm. Pour le bonheur des programmeurs Python débutants.

    Développement Orienté Test (TDD) - ébauche

    Tests unitaires

    Gestion des Versions

    PyCharm dispose d'un historique local des modifications de code source comme dans cet exemple :

    Historique des modifications de code source

    Le programme Python apso.py y est affiché dans deux versions, labellisées v0.8.3 et v0.8.7. Un affichage différencié des copies identifie précisément les corrections apportées.

    Pycharm permet l'intégration d'autres solutions de gestion des versions telles que Git, GitHub, Mercurial, Perforce ou Subversion.

    Mise au Point

    Depuis LibreOffice

    Xray - Méthodes d'un objet texte Writer
    MRI - Propriétés, méthodes, service et interface d'un document Writer
    Object Inspector - Propriétés, méthodes, services supportés et interfaces exportées de 'StarDesktop'

    L'édition et la mise au point de macros en Python est possible directement depuis LibreOffice à l'aide de l'extension Alternative Python Script Organizer. Celle-ci permet de gérer bibliothèques et modules, de travailler avec l'éditeur de son choix, et d'exécuter les macros sans quitter LibreOffice.

    Travailler hors LibreOffice est également possible, le débogage devient alors réalisable. Développer hors LibreOffice à l'aide d'un environnement de développement intégré (EDI) offre bien d'autres avantages détaillés ci-après.

    Il existe trois extensions pour développeur, vite nécessaires sinon incontournables dans ces deux contextes. Elles sont utilisables que l'on code en LibreOffice Basic, en Python, en JavaScript ou en BeanShell. Toutes trois s'appuient sur la faculté d'introspection des API de la suite LibreOffice.

    Extensions utiles

    Identifier les services supportés par un objet au moment de la conception est délicat. Il existe des extensions qui aident le développeur à inspecter les objets UNO. Elles sont absentes du catalogue des extensions, à l'exception de MRI, elles reposent sur la réflexion qui est intrinsèque aux API de LibreOffice.

    • X-Ray inspecte les objets API de LibreOffice. X-Ray affiche les propriétés, les méthodes, les services et les interfaces supportés par un objet. Il est disponible en français, allemand, anglais, espagnol, polonais, russe et tchèque. X-Ray est écrit en Basic.
    • MRI (My Reflection and Introspection) est un outil d'introspection pour objets UNO, écrit en Python. Ces fonctions sont similaires à celles d'X-Ray. Il est disponible en anglais. La version MRI au sein du catalogue des extensions de LibreOffice est périmée.
    • Object Inspector L'extension Object Inspector affiche les caractéristiques des objets telles que les services supportés, les interfaces exportées, ainsi que les méthodes et les propriétés sous la forme d'une arborescence. Object Inspector est écrit en Java et est disponible en anglais seulement.
    • Le débogueur de l'extension APSO incorpore l'inspection des objets UNO. Elle utilise indifféremment x-Ray ou bien MRI.

    Usage des macros Python

    Avec LibreOffice les macros Python peuvent être présentes en de nombreux endroits et sous de nombreuses formes comme l'explique Python comme langage de macro. Les scripts sont soit personnels, soit partagés, soit présents dans une extension, soit intégrés dans un package (ou paquetage en français), soit intégrés dans un document. De chacun de ces dépôts découlent différents usages ou contraintes.

    • Dans un document chaque module Python est autonome, pas d'import entre modules.
    L'aide en ligne propose un contournement dans Import de module Python
    • Un module Python peut appeler depuis un document une extension en Basic ou en Python.
    • Les modules Python de <utilisateur>\python\pythonpath sont importables depuis un document ou depuis <utilisateur>\python
    • Le Basic n'est pas supporté depuis un EDI: Pas de X-Ray (sic).
    Cela dépend du type de passerelle entre l'EDI et LibreOffice
    • Python et Java fonctionnent depuis un EDI: MRI, Object Inspector sont utilisables.

    Voici comment utiliser Mri dans une macro Python:

    import uno
    def mri(target):
        ctx = uno.getComponentContext()
        mri = ctx.ServiceManager.createInstanceWithContext(
            "mytools.Mri",ctx)
        mri.inspect(target)
        
    if __name__ == '__main__':
        def Mri_test():
            document = XSCRIPTCONTEXT.getDocument()
            mri(document)
     
        Mri_test()

    Stopper l'exécution d'une macro avec X-Ray :

    import uno
    from com.sun.star.uno import RuntimeException as _rtex
    
    def xray(myObject):
      try:
        sm = uno.getComponentContext().ServiceManager
        mspf = sm.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", uno.getComponentContext())
        scriptPro = mspf.createScriptProvider("")
        xScript = scriptPro.getScript("vnd.sun.star.script:XrayTool._Main.Xray?language=Basic&location=application")
        xScript.invoke((myObject,), (), ())
        return
      except:
         raise _rtex("\nL'extension Xray est absente ou inactive", uno.getComponentContext())
    
    # ___________  Illustration d'usage  _______________ 
    
    def demoXray(): 
      """ Exemple: Utilisation d'xRay dans un document Writer """ 
      
      xTextDoc = XSCRIPTCONTEXT.getDocument() 
      xText = xTextDoc.Text 
      xray(xText)
      xray("Fin de la démo.") 
    
    g_exportedScripts = demoXray,

    Affichage de l'arborescence d'objets UNO avec Object Inspector :

    import uno
    def inspectObject( obj, title="Inspecteur d'object" ):
    	ctx = uno.getComponentContext()
    	oi = ctx.ServiceManager.createInstanceWithContext("org.openoffice.InstanceInspector", ctx)
    	if oi is None:  # i.e. ObjectInspector n'est pas installé ou est désactivé
    		return  # arrêt silencieux
    	oi.inspect( obj, title )
    def exObjInspector():
    	doc = XSCRIPTCONTEXT.getDocument()
    	dsk = XSCRIPTCONTEXT.getDesktop()
    	inspectObject(doc)
    	inspectObject(dsk, title="StarDesktop")

    Depuis un EDI via l'interpréteur Python de LibreOffice

    Développer des macros en Python depuis un EDI est possible en utilisant l'interpréteur de LibreOffice. IDLE qui accompagne le Python natif exécute son propre interpréteur, qui n'est pas compatible avec LibreOffice. Le recours à un EDI ouvre toute une gamme de nouvelles possibilités au développeur telles que la navigation dans le source, la coloration syntaxique, la complétion de code, le respect des conventions de codage, le développement orienté tests, le débogage, la gestion de version, et bien plus encore.

    Voici une présentation de l'IDE Geany, avec Python ou pas.

    A titre d'exemple uniquement, Python IDE Basics montre comment indiquer l'interpréteur Python de LibreOffice au sein de Geany, PyCharm ou de Pyzo.

    Une communication doit être établie entre l'EDI et LibreOffice afin d'exécuter un script depuis <utilisateur>\python ou <utilisateur>\python\pythonpath. Sans une passerelle les objets UNO sont inaccessibles. Une fois la communication activée, EDI et LibreOffice opèrent ensemble. Les liens qui suivent documentent ce processus :

    Le module IDE_utils facilite le développement de macros Python au sein d'EDIs, en s'inspirant notamment de ces liens.

    Usage des Scripts Python

    • ...appel de packages Python...

    Exécution externe avec Geany

    Une fenêtre s'affiche dans LibreOffice depuis Geany dans la figure ci-dessous. L'EDI Geany lance la fonction info() laquelle utilise l'API .awt.createMessageBox() du SDK. Le script utilisateur s'appelle SysInfo.py.

    Geany lance la fonction info() qui utilise l'API ..awt.createMessageBox() du SDK - Script <user>\SysInfo.py

    Débogage avec Pyzo

    PyUNO Workspace est une extension de l'EDI Pyzo pour PyUNO et les API de LibreOffice :

    Pyzo exécute <user>\..\IDE_utils.py en marquant un point d'arrêt
    Pyzo exécute <Utilisateur>\..\IDE_utils.py en marquant un point d'arrêt.

    Débogage avec PyCharm

    Voici le débogueur de PyCharm affichant le contenu d'objets UNO, de classes et objets Python :

    Débogage d'objets UNO, de classes et variable Python

    Débogage avec APSO

    L'exécution étape par étape, l'affichage de la pile d'appels et l'examen des objets UNO ou variables Python est disponible avec l'extension Alternative Python Script Organizer.

    Fenêtre de débogage d'APSO

    Sorties sur la console

    Les scripts Python sont prototypables dans la console de l'interpréteur, ainsi qu'à l'aide d'APSO (Alternative Python Script Organizer).

    Console d'APSO

    Interpréteur Python

    La console interactive de Python, appelée également interpréteur Python ou terminal Python, permet aux programmeurs l'évaluation des instructions sans fichier source. L'introspection des objets UNO ou des modules Python y est possible. L'aide de LibreOffice indique comment lancer la console.

    Terminal Python

    Console de Windows

    L'environnement Windows ne propose pas de console en standard. L'instruction print() ne s'affiche nulle part. Suivez les étapes suivantes pour créer une sortie sur console :

    • Lancer LibreOffice avec soffice.com au lieu de soffice.exe :

    Les instructions print() de Python apparaissent dans la console durant toute la session LibreOffice. Lorsque la console est absente les instructions print() sont sans effet.

    source: Proper console mode for LibreOffice on Windows

    La console est utilisable depuis la version 6.3. Pour les versions antérieures suivez les instructions suivantes :

    1. Fermer LibreOffice
    2. Télécharger Visual Studio Express 2010++ - il est possible qu'une version différente fonctionne aussi - et l'installer
    3. Ouvrir la console de Visual Studio
    4. Saisir:

    editbin.exe /subsystem:console "C:\Program Files\LibreOffice 5\program\soffice.exe"
    editbin.exe /subsystem:console "C:\Program Files\LibreOffice 5\program\soffice.bin"

    cf. EditBin reference sur TechNet

    Cela permettra le lancement de la console à l'ouverture de LibreOffice, l'affichage par print(), ainsi que l'obtention des exceptions Python au travers de traceback.

    import traceback
    […]
    try:
        […]
        except:
            traceback.print_exc()

    Les erreurs de syntaxe n'apparaissent pas au terminal.

    source: [Python] Errors report - Debugging configuration (en anglais)

    Gestion des Exceptions ( ébauche )

    Utilisation des Dialogues ( ébauche )

    cf. UNODiT UNO Dialog Tools Voici un liste de qq. références pour démarrer :

    Conception de Dialogues

    Programmation évènementielle

    Intercepter évènement menu Event Model, Environnement applicatif

    Internationalisation

    Les Commandes du 'Dispatcher'

    Interface-oriented programming in *Office, Christopher Bourez (2015) en anglais

    Création d'Extensions ( ébauche )

    Voici un liste de qq. références pour démarrer :

    Extensions_development

    UNO component packaging - Python component testing

    Construire un service

    Construire un Add-In pour Calc

    Construire un Add-In

    Miscellanées (ébauche)

    Importer le module d'un document

    cf. Importer des modules Python de l'aide en ligne

    Paquétage Python vs. Extension LibreOffice

    Il est courant en Python de définir des modules, ou packages, comme suit :

    • __init__.py expose les classes A, B et D héritées en dir1/, dir2/ et dans le module d.py.
    • dir1/
      • __init__.py
      • a'.py expose la classe A'
      • a".py expose la classe A" dérivée de A'
    • dir2/
      • __init__.py
      • b1.py expose la classe B1
      • b2.py expose la classe B2
      • b3.py expose la classe B3
    • c.py utilise A
    • d.py expose la classe D

    Un telle organisation n'est pas supportée dns une extension LibreOffice. Elle doit être réorganisée, aux dépens d'une maintenance aisée du code, comme suit :

    • (a'+a"+b).py

    En effet límport relatif n'est pas supporté dans les extensions Python:

    • from .a' import A' ne fonctionne pas
    • from . import A ne fonctionne pas

    Propriétés et méthodes statiques

    Quid de l'attribut global de Python ?

    Git et PyCharm - ébauche