web-dev-qa-db-fra.com

les points d'arrêt pydev ne fonctionnent pas

Je travaille sur un projet utilisant python 2.7.2, sqlalchemy 0.7, unittest, Eclipse 3.7.2 et pydev 2.4. Je suis en train de définir des points d'arrêt dans des fichiers python (fichiers de test unitaires), mais ils sont complètement ignorés (avant, à un moment donné, ils fonctionnaient). À ce jour, j'ai mis à niveau tous les logiciels associés (voir ci-dessus), démarré de nouveaux projets, joué avec des paramètres, hypnotisé mon écran, mais rien ne fonctionne.

La seule idée que je tire de certains articles est qu’il a quelque chose à changer avec la modification de certains noms de fichiers .py en minuscules.

Quelqu'un a-t-il une idée?

ajouté: J'ai même installé la version aptana d’Eclipse et y ai copié les fichiers .py => même résultat; les points d'arrêt sont toujours ignorés.

toujours pas de progrès: J'ai modifié un code qui peut sembler inhabituel et je l'ai remplacé par une solution plus simple.

quelques informations supplémentaires: il a probablement quelque chose à voir avec le module unittest:

  • les points d'arrêt dans mes fichiers définissant les suites de tests fonctionnent,
  • les points d'arrêt dans les fichiers unittest standard fonctionnent
  • les points d'arrêt dans mes méthodes de test dans les classes dérivées de unittest.TestCase ne fonctionnent pas
  • les points d'arrêt de mon code en cours de test dans les cas de test ne fonctionnent pas
  • à un moment donné avant que je puisse définir des points d'arrêt de travail dans les méthodes de test ou le code testé
  • certaines choses que j'ai modifiées par la suite sont les suivantes: commencé à utiliser des suites de tests, changé certains noms de fichiers en minuscules, ...
  • ce problème se produit également si mon code fonctionne sans exception ni échec de test.

ce que j'ai déjà essayé est:

  • supprimer les fichiers .pyc
  • définir un nouveau projet et y copier uniquement les fichiers .py
  • redémarré plusieurs fois entre
  • mis à niveau vers Eclipse 3.7.2
  • installé la dernière version de pydev sur Eclipse 3.7.2
  • passer à aptana (et retour)
  • code supprimé que 'manuellement' a ajouté des classes à mon module
  • bricolé avec certaines configurations

Ce que je peux encore faire, c'est:

  • démarrer un nouveau projet avec mon code, commencer à supprimer/modifier le code jusqu'à ce que les points d'arrêt fonctionnent et trier une boîte noire pour déterminer si cela a quelque chose à voir avec une partie de mon code

  • Est-ce que quelqu'un a une idée de ce qui pourrait causer ces problèmes ou comment ils pourraient être résolus?
  • Y a-t-il un autre endroit où je pourrais chercher une solution?
  • Les développeurs de pydev se penchent-ils sur les questions relatives à stackoverflow?
  • Existe-t-il une version plus ancienne de pydev que je pourrais essayer?

Je travaille avec pydev/Eclipse depuis longtemps et cela fonctionne bien pour moi, mais sans débogage, je devais changer d'IDE.

En réponse aux questions de Fabio ci-dessous:

  • La version python est 2.7.2,
  • Sys.gettrace ne donne aucun (mais je n'ai aucune idée de ce qui dans mon code pourrait influencer cela)
  • Voici la sortie du débogueur après avoir modifié les paramètres suggérés:

pydev debugger:

starting
('Executing file ', 'D:\\.Eclipse\\org.Eclipse.platform_3.7.0_248562372\\plugins\\org.python.pydev.debug_2.4.0.2012020116\\pysrc\\runfiles.py')
('arguments:', "['D:\\\\.Eclipse\\\\org.Eclipse.platform_3.7.0_248562372\\\\plugins\\\\org.python.pydev.debug_2.4.0.2012020116\\\\pysrc\\\\runfiles.py', 'D:\\\\Documents\\\\Code\\\\Eclipse\\\\workspace\\\\sqladata\\\\src\\\\unit_test.py', '--port', '49856', '--verbosity', '0']")
('Connecting to ', '127.0.0.1', ':', '49857')
('Connected.',)
('received command ', '501\t1\t1.1')
sending cmd: CMD_VERSION 501    1   1.1

sending cmd: CMD_THREAD_CREATE 103  2   <xml><thread name="pydevd.reader" id="-1"/></xml>

sending cmd: CMD_THREAD_CREATE 103  4   <xml><thread name="pydevd.writer" id="-1"/></xml>

('received command ', '111\t3\tD:\\Documents\\Code\\Eclipse\\workspace\\sqladata\\src\\testData.py\t85\t**FUNC**testAdjacency\tNone')
Added breakpoint:d:\documents\code\Eclipse\workspace\sqladata\src\testdata.py - line:85 - func_name:testAdjacency
('received command ', '122\t5\t;;')
Exceptions to hook : []
('received command ', '124\t7\t')
('received command ', '101\t9\t')
Finding files... done.
Importing test modules ... testAtomic (testTypes.TypeTest) ... ok
testCyclic (testTypes.TypeTest) ... 

Le reste est sorti du test unitaire.

Suite de la réponse de Fabio, partie 2:

J'ai ajouté le code au début du programme et le débogueur cesse de fonctionner à la dernière ligne de la méthode dans sqlalchemy\orm\attributs.py (c'est un descripteur, mais la manière dont elle gêne le débogage dépasse mon connaissances actuelles):

class InstrumentedAttribute (QueryableAttribute): "" "Attribut instrumenté lié à une classe qui ajoute des méthodes de descripteur." ""

def __set__(self, instance, value):
    self.impl.set(instance_state(instance), 
                    instance_dict(instance), value, None)

def __delete__(self, instance):
    self.impl.delete(instance_state(instance), instance_dict(instance))

def __get__(self, instance, owner):
    if instance is None:
        return self

    dict_ = instance_dict(instance)
    if self._supports_population and self.key in dict_:
        return dict_[self.key]
    else:
        return self.impl.get(instance_state(instance),dict_) #<= last line of debugging

À partir de là, le débogueur passe à la méthode __getattr__ de l’une de mes propres classes, dérivée d’une classe declarative_base () de sqlalchemy.

Probablement résolu (mais pas compris):

Le problème semblait être que le __getattr__ mentionné ci-dessus, créait quelque chose de similaire à la récursion infinie, mais le programme/unittest/sqlalchemy a récupéré sans signaler d'erreur. Je ne comprends pas suffisamment le code sqlalchemy pour comprendre pourquoi la méthode __getattr__ a été appelée.
J'ai changé la méthode __getattr__ pour appeler super pour le nom de l'attribut pour lequel la récursivité s'est produite (ce n'est probablement pas ma solution finale) et le problème des points d'arrêt semble avoir disparu. Si je peux formuler le problème de manière cohérente, je vais probablement essayer d’obtenir des informations supplémentaires sur le groupe de discussion google sqlalchemy, ou du moins de vérifier la validité de ma solution.

Merci Fabio pour votre soutien, la fonction trace_func () a identifié le problème pour moi.

22
Lars

Cela semble vraiment étrange ... J'ai besoin d'informations supplémentaires pour mieux diagnostiquer le problème:

Ouvrez\plugins\org.python.pydev.debug\pysrc\pydevd_constants.py et changez

DEBUG_TRACE_LEVEL = 3 
DEBUG_TRACE_BREAKPOINTS = 3

lancez votre cas d'utilisation avec le problème et ajoutez le résultat à votre question ...

En outre, il se peut que, pour une raison quelconque, la fonction de débogage soit réinitialisée dans une bibliothèque que vous utilisez ou dans votre code, procédez ainsi: procédez comme suit: au même endroit que vous placeriez le point d'arrêt do:

import sys
print 'current trace function', sys.gettrace()

(Remarque: lors de l'exécution dans le débogueur, on s'attend à ce que la fonction de trace se présente sous la forme suivante: <bound method PyDB.trace_dispatch of <__main__.PyDB instance at 0x01D44878>>)

Aussi, veuillez publier la version de Python que vous utilisez.


Réponse partie 2:

Le fait que sys.gettrace () ne renvoie Aucun est probablement le problème réel ... Je connais certaines bibliothèques externes qui le dérangent (par exemple: DecoratorTools - read: http://pydev.blogspot.com/2007/06 /why-cant-pydev-debugger-work.with.html ) et j'ai même vu des bugs Python et des extensions compilées le détruire ...

Néanmoins, la raison la plus courante est la suivante: Python va silencieusement désactiver le traçage (et donc le débogueur) lorsqu'une récursion génère une erreur de débordement de pile (c'est-à-dire: RuntimeError: récursivité maximale profondeur dépassée).

Vous pouvez probablement mettre un point d'arrêt au tout début de votre programme et entrer dans le débogueur jusqu'à ce qu'il cesse de fonctionner.

Ou peut-être plus simplement, voici ce qui suit: Ajoutez le code ci-dessous au tout début de votre programme et voyez jusqu'où il va avec l'impression ... La dernière chose imprimée est le code juste avant sa rupture (vous pouvez donc placer un point d'arrêt à la dernière ligne imprimée sachant que c’est la dernière ligne où cela fonctionnerait) - notez que s’il s’agit d’un programme volumineux, l’impression peut prendre beaucoup de temps - il peut même être plus rapide d’imprimer dans un fichier au lieu d’une console (tel que comme cmd, bash ou Eclipse) et plus tard ouvrir ce fichier (il suffit de rediriger l'impression de l'exemple vers un fichier).

import sys

def trace_func(frame, event, arg):
    print 'Context: ', frame.f_code.co_name, '\tFile:', frame.f_code.co_filename, '\tLine:', frame.f_lineno, '\tEvent:', event
    return trace_func

sys.settrace(trace_func)

Si vous ne parvenez toujours pas à comprendre, merci de poster plus d'informations sur les résultats obtenus ...

Remarque: une solution de contournement jusqu'à ce que vous ne trouviez pas le lieu réel utilise:

import pydevd;pydevd.settrace()

à l'endroit où vous placeriez le point d'arrêt - de cette façon, vous auriez un point d'arrêt dans le code qui devrait fonctionner, car cela forcerait le paramétrage de la fonction de traçage à cet endroit (il est très similaire au débogage distant: http://pydev.org/manual_adv_remote_debugger.html sauf que, comme le débogueur était déjà connecté, vous n'avez pas vraiment besoin de démarrer le débogueur distant, il suffit de faire la trace pour émuler un point d'arrêt)

13
Fabio Zadrozny

Arriver en retard dans la conversation, mais au cas où cela aiderait. Je viens de rencontrer un problème similaire et j'ai trouvé que le débogueur est très particulier w.r.t. quelles lignes il considère comme "exécutables" et disponibles pour la rupture.

Si vous utilisez des continuations de ligne ou des expressions multilignes (dans une liste, par exemple), placez le point d'arrêt dans la dernière ligne de l'instruction.

J'espère que ça aide.

5
Miguel

Essayez de supprimer le fichier .pyc correspondant (compilé), puis de l'exécuter. De plus, j’ai parfois réalisé que j’exécutais plus d’une instance de programme .. ce qui a dérouté pydev. J'ai certainement vu cela aussi auparavant. Plusieurs fois.

2
Luke Codewalker

J'ai eu des symptômes similaires. Il s'est avéré que ma séquence d'importation de module était en train de redécrire mon module python d'entrée-point car une bibliothèque binaire (non-Python) devait être chargée dynamiquement, c'est-à-dire que LD_LIBRARY_PATH avait été réinitialisé de manière dynamique. Je ne sais pas pourquoi cela amène le débogueur à ignorer les points d'arrêt ultérieurs. Peut-être que l'appel rexec ne spécifie pas debug = true; il devrait spécifier debug = true/false en fonction de l'état du contexte de l'appel?

Essayez de définir un point d'arrêt lors de votre première instruction d'importation en sachant si vous êtes alors en train de (tep) 'ing ou de n (ext) sur les importations. Lorsque j'exécuterais "ensuite" sur l'importation en tierce partie nécessitant le chargement dynamique de la bibliothèque, l'interpréteur de débogage continuerait juste après tous les points d'arrêt.

1
Jim Coles

Couru dans une situation similaire en exécutant une application Django dans Eclipse/pydev. ce qui se passait, c’est que le code en cours d’exécution était celui installé dans virtualenv, pas mon code source. J'ai retiré mon projet de mon paquet de site env virtuel, relancé Django dans le débogueur Eclipse/pydev et tout s'est bien passé.

1
Ricardo Villamil