Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
La plupart des débogueurs Python standard prennent en charge le débogage du code Python uniquement, mais il est courant pour les développeurs d’utiliser Python avec C ou C++. Certains scénarios qui utilisent du code mixte sont des applications qui nécessitent des performances élevées ou la possibilité d’appeler directement des API de plateforme sont souvent codées en Python et C ou C++.
Visual Studio fournit un débogage en mode mixte intégré et simultané pour le code Python et C/C++ natif. La prise en charge est disponible lorsque vous sélectionnez l’option Outils de développement natifs Python pour la charge de travail Développement Python dans le programme d’installation de Visual Studio :
Dans cet article, vous allez découvrir comment utiliser les fonctionnalités de débogage en mode mixte suivantes :
- Piles d’appels combinées
- Étape entre Python et le code natif
- Points d’arrêt dans les deux types de code
- Afficher les représentations Python des objets dans des images natives et vice versa
- Débogage dans le contexte du projet Python ou du projet C++
Prerequisites
Visual Studio 2017 et versions ultérieures. Le débogage en mode mixte n’est pas disponible avec Python Tools pour Visual Studio 1.x dans Visual Studio 2015 et versions antérieures.
Visual Studio installé avec prise en charge des charges de travail Python. Pour plus d’informations, consultez Installer la prise en charge de Python dans Visual Studio.
Activer le débogage en mode mixte dans un projet Python
Les étapes suivantes décrivent comment activer le débogage en mode mixte dans un projet Python :
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet Python, puis sélectionnez Propriétés.
Dans le volet Propriétés , sélectionnez l’onglet Débogage , puis sélectionnez l’option Debug>Activer le débogage du code natif :
Cette option active le mode mixte pour toutes les sessions de débogage.
Conseil / Astuce
Lorsque vous activez le débogage de code natif, la fenêtre de sortie Python peut se fermer immédiatement une fois que le programme est terminé sans pause et sans afficher l’invite Appuyez sur n’importe quelle touche pour continuer. Pour forcer la pause et l’invite après avoir activé le débogage du code natif, ajoutez l’argument
-iau champ Exécuter>les arguments de l’interpréteur sous l’onglet Débogage . Cet argument place l’interpréteur Python en mode interactif après l’exécution du code. Le programme attend que vous deviez sélectionner Ctrl+Z+Entrée pour fermer la fenêtre.SélectionnezEnregistrer un > (ou Ctrl+S) pour enregistrer les modifications de propriété.
Pour attacher le débogueur en mode mixte à un processus existant, sélectionnez Déboguer>attacher au processus. Une boîte de dialogue s’ouvre.
Dans la boîte de dialogue Attacher au processus , sélectionnez le processus approprié dans la liste.
Pour le champ Attacher à , utilisez l’option Sélectionner pour ouvrir la boîte de dialogue Sélectionner le type de code .
Dans la boîte de dialogue Sélectionner un type de code , choisissez l’option Déboguer ces types de code .
Dans la liste, cochez la case Python (native), puis sélectionnez OK :
Sélectionnez Joindre pour démarrer le débogueur.
Les paramètres de type de code sont persistants. Si vous souhaitez désactiver le débogage en mode mixte et l’attacher à un autre processus ultérieurement, décochez la case de type de code Python (natif) et cochez la case type de code natif .
Vous pouvez sélectionner d’autres types de code en plus ou au lieu de l’option Native . Par exemple, si une application managée héberge CPython, qui utilise à son tour des modules d’extension natifs et que vous souhaitez déboguer les trois projets de code, sélectionnez les cases Python, Native et Managed . Cette approche vous offre une expérience de débogage unifiée, y compris les piles d’appels combinées et l’exécution pas à pas entre les trois environnements d'exécution.
Utiliser des environnements virtuels
Lorsque vous utilisez cette méthode de débogage en mode mixte pour les environnements virtuels (venvs), Python pour Windows utilise un python.exe fichier stub pour les venvs que Visual Studio recherche et charge en tant que sous-processus.
Pour Python 3.8 et versions ultérieures, le mode mixte ne prend pas en charge le débogage multiprocessus. Lorsque vous démarrez la session de débogage, le sous-processus stub est débogué au lieu de l’application. Pour les scénarios d'attachement, la solution consiste à attacher le fichier
python.exeadéquat. Lorsque vous lancez l’application avec débogage (par exemple, via le raccourci clavier F5 ), vous pouvez créer votre venv à l’aide de la commandeC:\Python310-64\python.exe -m venv venv --symlinks. Dans la commande, insérez votre version préférée de Python. Par défaut, seuls les administrateurs peuvent créer des liens symboliques sur Windows.Pour les versions de Python antérieures à la version 3.8, le débogage en mode mixte doit fonctionner comme prévu avec les venvs.
L’exécution dans un environnement global n’entraîne pas ces problèmes pour une version de Python.
Installer des symboles Python
Lorsque vous démarrez le débogage en mode mixte pour la première fois, vous pouvez voir une boîte de dialogue Symboles Python obligatoire . Vous devez installer les symboles une seule fois pour un environnement Python donné. Les symboles sont automatiquement inclus si vous installez la prise en charge de Python via Visual Studio Installer (Visual Studio 2017 et versions ultérieures). Pour plus d’informations, consultez Installer des symboles de débogage pour les interpréteurs Python dans Visual Studio.
Accéder au code source Python
Vous pouvez rendre le code source pour Python standard lui-même disponible lors du débogage.
Accédez à
https://www.python.org/downloads/source/.Téléchargez l’archive de code source Python appropriée pour votre version et extrayez le code dans un dossier.
Lorsque Visual Studio demande l'emplacement du code source Python, pointez vers les fichiers spécifiques dans le dossier d'extraction.
Activer le débogage en mode mixte dans un projet C/C++
Visual Studio 2017 version 15.5 et ultérieure prend en charge le débogage en mode mixte à partir d’un projet C/C++. Voici un exemple d’utilisation lorsque vous souhaitez incorporer Python dans une autre application, comme décrit sur python.org.
Les étapes suivantes décrivent comment activer le débogage en mode mixte pour un projet C/C++ :
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet C/C++, puis sélectionnez Propriétés.
Dans le volet Pages de propriétés, sélectionnez l’ongletDébogage> de configuration.
Développez le menu déroulant du débogueur pour lancer l’option et sélectionnez Python/Débogage natif.
Note
Si vous ne voyez pas l’option Débogage Python/Natif , vous devez d’abord installer les outils de développement natifs Python à l’aide de Visual Studio Installer. L’option de débogage native est disponible sous la charge de travail de développement Python. Pour plus d’informations, consultez Installer la prise en charge de Python dans Visual Studio.
Sélectionnez OK pour enregistrer les modifications.
Déboguer le lanceur de programmes
Lorsque vous utilisez cette méthode, vous ne pouvez pas déboguer le lanceur de py.exe programmes, car il génère un sous-processus enfant python.exe . Le débogueur n’est pas attaché au sous-processus. Pour ce scénario, la solution de contournement consiste à lancer le python.exe programme directement avec des arguments, comme suit :
Dans le volet Pages de propriétés du projet C/C++, accédez à l’ongletDébogage> de configuration.
Pour l’option Commande , spécifiez le chemin complet du
python.exefichier programme.Spécifiez vos arguments souhaités dans le champ Arguments de commande .
Attachez le débogueur en mode mixte
Pour Visual Studio 2017 version 15.4 et versions antérieures, le débogage en mode mixte direct est activé uniquement lors du lancement d’un projet Python dans Visual Studio. La prise en charge est limitée, car les projets C/C++ utilisent uniquement le débogueur natif.
Pour ce scénario, la solution de contournement est de connecter le débogueur séparément :
Démarrez le projet C++ sans débogage en sélectionnant Démarrer>sans débogage ou utilisez le raccourci clavier Ctrl+F5.
Pour attacher le débogueur en mode mixte à un processus existant, sélectionnez Déboguer>attacher au processus. Une boîte de dialogue s’ouvre.
Dans la boîte de dialogue Attacher au processus , sélectionnez le processus approprié dans la liste.
Pour le champ Attacher à , utilisez l’option Sélectionner pour ouvrir la boîte de dialogue Sélectionner le type de code .
Dans la boîte de dialogue Sélectionner un type de code , choisissez l’option Déboguer ces types de code .
Dans la liste, cochez la case Python , puis sélectionnez OK.
Sélectionnez Attacher pour démarrer le débogueur.
Conseil / Astuce
Vous pouvez ajouter une pause ou un retard dans l’application C++ pour vous assurer qu’elle n’appelle pas le code Python que vous souhaitez déboguer avant d’attacher le débogueur.
Explorer les fonctionnalités spécifiques en mode mixte
Visual Studio fournit plusieurs fonctionnalités de débogage en mode mixte pour faciliter le débogage de votre application :
- Pile d’appels combinée
- Étape entre Python et le code natif
- Affichage des valeurs PyObject dans le code natif
- Affichage des valeurs natives dans le code Python
Utiliser une pile d’appels combinée
La fenêtre Pile des appels affiche les trames de pile natif et Python entrelacées, avec des transitions marquées entre les deux :
- Pour que les transitions apparaissent sous la forme [Code externe] sans spécifier la direction de la transition, utilisez le voletOptions des >. Développez la section Tous les paramètres>Débogage>Général, cochez la case Activer uniquement mon code.
- Pour que les transitions apparaissent sous la forme [Code externe] sans spécifier la direction de la transition, utilisez la boîte de dialogueOptions des >. Développez la section Débogage>général , cochez la case Activer uniquement mon code , puis sélectionnez OK.
- Pour activer un cadre d’appel, double-cliquez sur le cadre. Cette action ouvre également le code source correspondant, si possible. Si le code source n’est pas disponible, le frame est toujours rendu actif et les variables locales peuvent être inspectées.
Étape entre Python et le code natif
Visual Studio fournit les commandes Step Into (F11) ou Step Out (Maj+F11) pour permettre au débogueur en mode mixte de gérer correctement les modifications entre les types de code.
Lorsque Python appelle une méthode d’un type implémenté en C, l’exécution pas à pas sur un appel à cette méthode s’arrête au début de la fonction native qui implémente la méthode.
Ce même comportement se produit lorsque le code natif appelle une fonction API Python qui entraîne l’appel du code Python. L’exécution d’un appel à
PyObject_CallObjectune valeur de fonction initialement définie dans Python s’arrête au début de la fonction Python.Le passage de Python vers Native est également pris en charge pour les fonctions Native appelées à partir de Python via ctypes.
Utiliser la vue valeurs PyObject dans le code natif
Lorsqu’une trame native (C ou C++) est active, ses variables locales s’affichent dans la fenêtre Locals du débogueur. Dans les modules d’extension Python natifs, la plupart de ces variables sont de type PyObject (qui est un typedef pour _object), ou quelques autres types Python fondamentaux. Dans le débogage en mode mixte, ces valeurs présentent un autre nœud enfant étiqueté [vue Python].
Pour afficher la représentation Python de la variable, développez le nœud. La vue des variables est identique à ce que vous voyez si une variable locale référençant le même objet est présente dans un cadre Python. Les enfants de ce nœud sont modifiables.
Pour désactiver cette fonctionnalité, cliquez avec le bouton droit n’importe où dans la fenêtre Locals et activez l’option de menuAfficher les nœuds d’affichage Python> :
Types C qui affichent les nœuds d’affichage Python
Les types C suivants affichent les nœuds [vue Python], s’ils sont activés :
PyObjectPyVarObjectPyTypeObjectPyByteArrayObjectPyBytesObjectPyTupleObjectPyListObjectPyDictObjectPySetObjectPyIntObjectPyLongObjectPyFloatObjectPyStringObjectPyUnicodeObject
[Vue Python] n’apparaît pas automatiquement pour les types que vous créez vous-même. Lorsque vous créez des extensions pour Python 3.x, ce manque n’est généralement pas un problème. Tout objet a finalement un ob_base champ d’un des types C répertoriés, ce qui provoque l’affichage [vue Python].
Afficher les valeurs natives dans le code Python
Vous pouvez activer une vue [C++] pour les valeurs natives dans la fenêtre Locals lorsqu’une trame Python est active. Cette fonctionnalité n’est pas activée par défaut.
Pour activer la fonctionnalité, cliquez avec le bouton droit dans la fenêtre Locals et définissez l’option de menuAfficher les nœuds C++>.
Le nœud [vue C++] fournit une représentation de la structure C/C++ sous-jacente pour une valeur, identique à ce que vous voyez dans une trame native. Il montre une instance de
_longobject(pour laquellePyLongObjectest un typedef) pour un entier long Python et tente de déduire des types pour les classes natives que vous créez vous-même. Les enfants de ce nœud sont modifiables.
Si un champ enfant d’un objet est de type PyObjectou d’un autre type pris en charge, il a un nœud de représentation [Vue Python] (si ces représentations sont activées). Ce comportement permet de naviguer dans les graphiques d’objets où les liens ne sont pas directement exposés à Python.
Contrairement aux nœuds [vue Python], qui utilisent des métadonnées d’objet Python pour déterminer le type de l’objet, il n’existe aucun mécanisme fiable similaire pour [vue C++]. En règle générale, étant donné une valeur Python (autrement dit, une PyObject référence), il n’est pas possible de déterminer de manière fiable la structure C/C++ sous-jacente dont elle dépend. Le débogueur en mode mixte tente de deviner le type en examinant différents champs du type de l’objet (par exemple, le PyTypeObject référencé par son ob_type champ) qui ont des types de pointeur de fonction. Si l’un de ces pointeurs de fonction fait référence à une fonction qui peut être résolue et que cette fonction a un paramètre avec un type self plus spécifique que PyObject*, ce type est supposé être le type sous-jacent.
Prenons l’exemple suivant, où la ob_type->tp_init valeur d’un objet donné pointe à la fonction suivante :
static int FobObject_init(FobObject* self, PyObject* args, PyObject* kwds) {
return 0;
}
Dans ce cas, le débogueur peut déduire correctement que le type C de l’objet est FobObject. Si le débogueur ne peut pas déterminer un type plus précis à partir de tp_init, il passe à d'autres champs. S’il n’est pas en mesure de déduire le type de l’un de ces champs, le nœud [vue C++] présente l’objet en tant qu’instance PyObject .
Pour toujours obtenir une représentation utile pour les types créés personnalisés, il est préférable d’inscrire au moins une fonction spéciale lors de l’inscription du type et d’utiliser un paramètre fortement typé self . La plupart des types répondent naturellement à cette exigence. Pour d’autres types, l’inspection tp_init est généralement l'option la plus pratique pour cela. Une implémentation factice de tp_init pour un type qui est présent uniquement pour permettre l'inférence de type du débogueur peut simplement renvoyer zéro immédiatement, comme dans l’exemple précédent.
Examiner les différences par rapport au débogage standard de Python
Le débogueur en mode mixte est distinct du débogueur Python standard. Il introduit certaines fonctionnalités supplémentaires, mais manque de fonctionnalités liées à Python, comme suit :
- Les fonctionnalités qui ne sont pas prises en charge comprennent les points d’arrêt conditionnels, la fenêtre de débogage interactive, et le débogage multiplateforme à distance.
- La fenêtre Immédiate est disponible, mais avec un sous-ensemble limité de ses fonctionnalités, y compris toutes les limitations répertoriées dans cette section.
- Les versions python prises en charge incluent uniquement CPython 2.7 et 3.3+.
- Pour utiliser Python avec Visual Studio Shell (par exemple, si vous l’installez avec le programme d’installation intégré), Visual Studio ne peut pas ouvrir de projets C++. Par conséquent, l’expérience d’édition pour les fichiers C++ est celle d’un éditeur de texte de base uniquement. Toutefois, le débogage C/C++ et le débogage en mode mixte sont entièrement pris en charge dans Shell avec le code source, l’exécution pas à pas dans le code natif et l’évaluation des expressions C++ dans les fenêtres du débogueur.
- Lorsque vous affichez des objets Python dans les fenêtres d’outils Locals et Espion , le débogueur en mode mixte affiche uniquement la structure des objets. Elle n’évalue pas automatiquement les propriétés ou n’affiche pas les attributs calculés. Pour les collections, il affiche uniquement les éléments pour les types de collection intégrés (
tuple, ,listdict,set). Les types de collection personnalisés ne sont pas visualisés en tant que collections, sauf s’ils sont hérités d’un type de collection intégré. - L’évaluation des expressions est gérée comme décrit dans la section suivante.
Utiliser l’évaluation des expressions
Le débogueur Python standard permet d’évaluer des expressions Python arbitraires dans les fenêtres Espion et Exécution lorsque le processus débogué est suspendu à tout moment dans le code, tant qu’il n’est pas bloqué dans une opération d’E/S ou d’un autre appel système similaire. Dans le débogage en mode mixte, les expressions arbitraires peuvent être évaluées uniquement lorsque l'exécution est arrêtée dans le code Python, après un point d'arrêt, ou lors de l'exécution pas à pas dans le code. Les expressions peuvent être évaluées uniquement sur le thread sur lequel le point d’arrêt ou l’opération pas à pas s’est produite.
Lorsque le débogueur s’arrête dans le code natif ou dans le code Python où les conditions décrites ne sont pas pertinentes, par exemple après une opération de saut ou sur un autre fil d'exécution). L’évaluation des expressions est limitée à l’accès à des variables locales et globales dans le cadre actuellement sélectionné, à l’accès à leurs champs et à l’indexation de types de collections intégrés à l'aide de littéraux. Par exemple, l’expression suivante peut être évaluée dans n’importe quel contexte (à condition que tous les identificateurs font référence aux variables et champs existants des types appropriés) :
foo.bar[0].baz['key']
Le débogueur en mode mixte résout également ces expressions différemment. Toutes les opérations d'accès aux membres recherchent uniquement les champs faisant directement partie de l'objet (par exemple, une entrée dans son __dict__ ou __slots__, ou un champ d'une structure native exposée à Python via tp_members) et ignorent toute logique__getattr__, __getattribute__ou descriptrice. De même, toutes les opérations d’indexation ignorent __getitem__et accèdent directement aux structures de données internes des collections.
Par souci de cohérence, ce schéma de résolution de noms est utilisé pour toutes les expressions qui correspondent aux contraintes pour l’évaluation d’expressions limitées. Ce schéma est appliqué, que des expressions arbitraires soient autorisées au point de pause actuel. Pour forcer la sémantique Python appropriée lorsqu’un évaluateur complet est disponible, placez l’expression entre parenthèses :
(foo.bar[0].baz['key'])