Aller au contenu

Dépannage

Le journal de diagnostics de l'éditeur porte chaque ligne pertinente. Sous Windows, il est dans %LOCALAPPDATA%/MTE/log/. Regardez le fichier le plus récent après avoir lancé l'éditeur.

« Python plugins disabled »

Quatre variantes ; le message exact vous dit laquelle.

PluginHost: MTE_PYTHON is not set; falling back to PATH.

Neutre — l'hôte va chercher Python dans le PATH. Sans gravité, sauf si suivi de « no Python interpreter found ».

PluginHost: MTE_PYTHON path '<value>' does not exist.

Vous avez pointé MTE_PYTHON vers un chemin avec séparateur de dossiers, mais le fichier à ce chemin manque. Correctif : pointez vers le vrai python.exe.

$env:MTE_PYTHON = "C:\Users\me\AppData\Local\Programs\Python\Python313\python.exe"

PluginHost: MTE_PYTHON='<name>' not found on PATH.

Vous avez mis dans MTE_PYTHON un simple nom (sans séparateur), mais ce nom n'est pas dans le PATH. Correctif : ajoutez le dossier au PATH, ou utilisez la forme chemin complet ci-dessus.

PluginHost: no Python interpreter found (…); Python plugins disabled.

Ni MTE_PYTHON ni aucun des noms standards de la plateforme (py.exe, python.exe, python3.exe sous Windows ; python3 sous macOS/Linux) n'est dans le PATH. Installez Python 3.9+ et ajoutez-le au PATH ou définissez MTE_PYTHON.

Vérifiez ce que voit le PATH, depuis le même shell qui a lancé l'éditeur :

(Get-Command py.exe -ErrorAction SilentlyContinue).Source
(Get-Command python.exe -ErrorAction SilentlyContinue).Source

« python worker script … not found »

L'éditeur journalise :

PluginHost: python worker script '<path>' not found; Python plugins disabled.

Le script hôte du worker (mte_python_host.py) n'est pas à côté de l'exe. Cela arrive avec un build de l'éditeur dont l'étape POST_BUILD de mise en place de Python/ a été sautée. Reconstruisez :

cmake --build Build\.cmake\x64-debug --target ModularTextEditor --config Debug

Confirmez que le fichier existe après le build :

Test-Path Build\MTE_Windows_d\Python\host\mte_python_host.py

Extension listée mais pas chargée

Ouvrez la page Extensions (Préférences → Extensions). Causes courantes :

Symptôme Ligne du journal Cause
Marque de conflit apiVersion à côté du nom PythonPluginBackend: not loading '…': apiVersion does not match host 1. Votre plugin.json déclare une apiVersion différente de celle de l'éditeur en cours.
L'extension apparaît grisée PythonPluginBackend: '…' is disabled; listed but not loaded. Quelqu'un l'a désactivée dans la page Extensions. Réactivez et redémarrez.
Absente entièrement PythonPluginBackend: skipping '…': module '…/main.py' does not declare a top-level 'def register(...)'. La sonde statique a rejeté votre module. Placez register au niveau supérieur (colonne 0).
Absente entièrement PythonPluginBackend: skipping '…': module file '…' is missing or unreadable. plugin.json.module vaut "main" mais il n'y a pas de main.py à côté.
Absente entièrement PythonPluginBackend: skipping '…': plugin.json missing required field 'id'. Ajoutez id.

La commande ne se déclenche pas

Vous avez cliqué l'entrée de menu / appuyé le raccourci et rien ne s'est passé.

  • Cherchez des lignes [python:<votre.id>] … issues de vos ctx.log.info(...). Si elles manquent, le rappel n'a jamais atteint le worker.
  • Cherchez des lignes [worker stderr] …. Les exceptions dans votre rappel y atterrissent.
  • Confirmez que l'id de commande de votre appel add_item correspond mot pour mot à votre command(id=...) — la comparaison de chaînes est exacte.

Erreurs « worker died »

L'hôte journalise :

… worker exited with code N
… worker crashed (code N)

Le sous-processus Python s'est terminé. Regardez au-dessus de cette ligne le stderr du worker — Python écrit les tracebacks sur stderr et l'hôte les retransmet en [worker stderr] …. Un plantage correspond presque toujours à une exception non gérée dans register() ou dans un rappel ayant récursé dans l'API C de Python.

Réparez le code et redémarrez l'éditeur. L'hôte ne redémarre pas automatiquement un worker planté.

Provisionnement du venv échoué (extension listée mais pas chargée)

Une extension déclarant pyRequires reçoit un environnement virtuel provisionné à son premier lancement. En cas d'échec, le journal porte la raison :

PluginHost: 'org.example.x' needs a venv (no venv provisioned yet).
PythonRuntime: provisioning venv at '...' (1 requirement(s)); ...
PluginHost: venv provisioning for 'org.example.x' failed: pip install
failed: ... No matching distribution found for no-such-package ...

Causes courantes : pas de réseau au premier lancement, une exigence mal orthographiée, un paquet sans wheel pour la version de Python de l'utilisateur. Corrigez la cause et redémarrez — le provisionnement réessaie à chaque lancement jusqu'au succès (le venv n'est estampillé complet qu'à la fin). Pour forcer une reconstruction propre, supprimez <AppLocalData>/PluginVenv/<plugin-id>/. Les machines hors ligne peuvent à la place livrer un venv/ pré-construit dans le paquet — voir Empaquetage.

L'installeur a refusé mon .mteplugin

Chaque rejet vient avec un message de dialogue précis ; les plus courants :

Le message dit… Correctif
missing the required 'module' field Ajoutez "module": "main" à plugin.json.
no Python module (.py file) L'archive n'a aucun .py — avez-vous zippé le bon dossier ?
does not contain the declared Python module 'X.py' module dans plugin.json ne correspond pas au nom de fichier de l'archive.
does not declare a top-level def register(...) Même règle qu'à la découverte : def register( doit commencer en colonne 0 de <module>.py.
targets API version N Reconstruisez contre l'apiVersion actuelle (voir plugin.json).
unsafe path / too large / too many files L'archive a déclenché une protection — remballez-la simplement (pas d'entrées .., < 256 Mio décompressé).

Le paquet est validé sur une copie de travail : une installation refusée ne touche jamais une extension existante.

Rien n'est journalisé du tout

Confirmez que votre gestionnaire est bien installé. register(ctx) s'exécute exactement une fois par extension et par lancement de l'éditeur. Si register n'est pas défini au niveau supérieur du module, la sonde statique rejette l'extension avant tout chargement (voir « Extension listée mais pas chargée » ci-dessus).

Ajoutez une ligne de démarrage à votre register :

def register(ctx):
    ctx.log.info("wordcount: register() ran")
    # …

Si vous ne la voyez pas dans le journal, le worker n'exécute pas votre register — cherchez la raison dans les journaux précédents.

Où regarder ensuite

  • Journal côté éditeur : %LOCALAPPDATA%/MTE/log/…
  • Stderr du worker : même journal, marqué [worker stderr]
  • Référence : API ctx, Événements, plugin.json
  • Notes de conception : PYTHON_PLUGIN_ARCHITECTURE.md (racine du dépôt)