[Pydev-cvs] org.python.pydev.debug/pysrc pydevd_comm.py, 1.40, 1.41 pydevd_vars.py, 1.45, 1.46 pyde
Brought to you by:
fabioz
From: Fabio Z. <fa...@us...> - 2008-07-05 19:42:06
|
Update of /cvsroot/pydev/org.python.pydev.debug/pysrc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6084/pysrc Modified Files: pydevd_comm.py pydevd_vars.py pydevd_resolver.py Log Message: <li><strong>Debugger</strong>: Better inspection of internal variables for dict, list, tuple, set and frozenset</li> Index: pydevd_resolver.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/pysrc/pydevd_resolver.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pydevd_resolver.py 18 Mar 2008 02:55:03 -0000 1.5 --- pydevd_resolver.py 5 Jul 2008 19:42:13 -0000 1.6 *************** *** 8,12 **** --- 8,24 ---- __builtin__.True = 1 __builtin__.False = 0 + + + + #======================================================================================================================= + # UnableToResolveVariableException + #======================================================================================================================= + class UnableToResolveVariableException(Exception): + pass + + #======================================================================================================================= + # InspectStub + #======================================================================================================================= class InspectStub: def isbuiltin(self, _args): *************** *** 27,36 **** #types does not include a MethodWrapperType try: ! MethodWrapperType = type([].__str__) except: ! MethodWrapperType = None ! class Resolver: def resolve(self, var, attribute): --- 39,87 ---- #types does not include a MethodWrapperType try: ! MethodWrapperType = type([].__str__) except: ! MethodWrapperType = None ! #======================================================================================================================= ! # AbstractResolver ! #======================================================================================================================= ! class AbstractResolver: ! ''' ! This class exists only for documentation purposes to explain how to create a resolver. ! ! Some examples on how to resolve things: ! - list: getDictionary could return a dict with index->item and use the index to resolve it later ! - set: getDictionary could return a dict with id(object)->object and reiterate in that array to resolve it later ! - arbitrary instance: getDictionary could return dict with attr_name->attr and use getattr to resolve it later ! ''' ! ! def resolve(self, var, attribute): ! ''' ! In this method, we'll resolve some child item given the string representation of the item in the key ! representing the previously asked dictionary. ! ! @param var: this is the actual variable to be resolved. ! @param attribute: this is the string representation of a key previously returned in getDictionary. ! ''' ! raise NotImplementedError ! ! def getDictionary(self, var): ! ''' ! @param var: this is the variable that should have its children gotten. ! ! @return: a dictionary where each pair key, value should be shown to the user as children items ! in the variables view for the given var. ! ''' ! raise NotImplementedError ! ! ! #======================================================================================================================= ! # DefaultResolver ! #======================================================================================================================= ! class DefaultResolver: ! ''' ! DefaultResolver is the class that'll actually resolve how to show some variable. ! ''' def resolve(self, var, attribute): *************** *** 97,102 **** pass - ret['type'] = type(obj).__name__ - return ret --- 148,151 ---- *************** *** 144,159 **** d[ n ] = attr - d['type'] = type(var).__name__ return d ! class DictResolver(Resolver): def resolve(self, dict, key): ! return dict[key] def getDictionary(self, dict): ! return dict - class TupleResolver(Resolver): #to enumerate tuples and lists def resolve(self, var, attribute): return var[int(attribute)] --- 193,247 ---- d[ n ] = attr return d + ! #======================================================================================================================= ! # DictResolver ! #======================================================================================================================= ! class DictResolver: ! def resolve(self, dict, key): ! if key == '__len__': ! return None ! ! if '(' not in key: ! #we have to treat that because the dict resolver is also used to directly resolve the global and local ! #scopes (which already have the items directly) ! return dict[key] ! ! #ok, we have to iterate over the items to find the one that matches the id, because that's the only way ! #to actually find the reference from the string we have before. ! expected_id = int(key.split('(')[-1][:-1]) ! for key, val in dict.items(): ! if id(key) == expected_id: ! return val ! ! raise UnableToResolveVariableException() def getDictionary(self, dict): ! ret = {} ! ! for key, val in dict.items(): ! #we need to add the id because otherwise we cannot find the real object to get its contents later on. ! key = '%s (%s)' % (key, id(key)) ! ret[key] = val ! ! ret['__len__'] = len(dict) ! return ret ! ! ! ! #======================================================================================================================= ! # TupleResolver ! #======================================================================================================================= ! class TupleResolver: #to enumerate tuples and lists def resolve(self, var, attribute): + ''' + @param var: that's the original attribute + @param attribute: that's the key passed in the dict (as a string) + ''' + if attribute == '__len__': + return None return var[int(attribute)] *************** *** 163,170 **** d = {} for i, item in zip(range(len(var)), var): ! d[ i ] = item return d ! class InstanceResolver(Resolver): def resolve(self, var, attribute): field = var.__class__.getDeclaredField( attribute ) --- 251,292 ---- d = {} for i, item in zip(range(len(var)), var): ! d[ i ] = item ! d['__len__'] = len(var) return d ! ! ! #======================================================================================================================= ! # SetResolver ! #======================================================================================================================= ! class SetResolver: ! ''' ! Resolves a set as dict id(object)->object ! ''' ! ! def resolve(self, var, attribute): ! if attribute == '__len__': ! return None ! ! attribute = int(attribute) ! for v in var: ! if id(v) == attribute: ! return v ! ! raise UnableToResolveVariableException('Unable to resolve %s in %s' % (attribute, var)) ! ! def getDictionary(self, var): ! d = {} ! for item in var: ! d[ id(item) ] = item ! d['__len__'] = len(var) ! return d ! ! ! #======================================================================================================================= ! # InstanceResolver ! #======================================================================================================================= ! class InstanceResolver: ! def resolve(self, var, attribute): field = var.__class__.getDeclaredField( attribute ) *************** *** 184,194 **** traceback.print_exc() - ret['type'] = type(obj).__name__ return ret ! class JyArrayResolver(Resolver): ! def resolve(self, var, _attribute): ! return var def getDictionary(self,obj): --- 306,324 ---- traceback.print_exc() return ret ! #======================================================================================================================= ! # JyArrayResolver ! #======================================================================================================================= ! class JyArrayResolver: ! ''' ! This resolves a regular Object[] array from java ! ''' ! ! def resolve(self, var, attribute): ! if attribute == '__len__': ! return None ! return var[int(attribute)] def getDictionary(self,obj): *************** *** 196,212 **** for i in range(len(obj)): ! try: ! ret[ obj[i] ] = obj[i] ! except: ! traceback.print_exc() ! # I don't know why I'm getting an exception ! pass ! ret['type'] = type(obj).__name__ return ret ! defaultResolver = Resolver() dictResolver = DictResolver() tupleResolver = TupleResolver() instanceResolver = InstanceResolver() jyArrayResolver = JyArrayResolver() --- 326,338 ---- for i in range(len(obj)): ! ret[ i ] = obj[i] ! ret['__len__'] = len(obj) return ret ! defaultResolver = DefaultResolver() dictResolver = DictResolver() tupleResolver = TupleResolver() instanceResolver = InstanceResolver() jyArrayResolver = JyArrayResolver() + setResolver = SetResolver() Index: pydevd_comm.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/pysrc/pydevd_comm.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** pydevd_comm.py 12 Apr 2008 16:19:51 -0000 1.40 --- pydevd_comm.py 5 Jul 2008 19:42:13 -0000 1.41 *************** *** 100,103 **** --- 100,106 ---- #--------------------------------------------------------------------------------------------------- UTILITIES + #======================================================================================================================= + # PydevdLog + #======================================================================================================================= def PydevdLog(level, *args): """ levels are: *************** *** 114,118 **** #======================================================================================================================= ! # GlobacDbgHolder #======================================================================================================================= class GlobalDebuggerHolder: --- 117,121 ---- #======================================================================================================================= ! # GlobalDebuggerHolder #======================================================================================================================= class GlobalDebuggerHolder: *************** *** 122,128 **** --- 125,137 ---- globalDbg = None + #======================================================================================================================= + # GetGlobalDebugger + #======================================================================================================================= def GetGlobalDebugger(): return GlobalDebuggerHolder.globalDbg + #======================================================================================================================= + # SetGlobalDebugger + #======================================================================================================================= def SetGlobalDebugger(dbg): GlobalDebuggerHolder.globalDbg = dbg *************** *** 131,134 **** --- 140,146 ---- #------------------------------------------------------------------- ACTUAL COMM + #======================================================================================================================= + # PyDBDaemonThread + #======================================================================================================================= class PyDBDaemonThread(threading.Thread): *************** *** 160,163 **** --- 172,178 ---- # pass + #======================================================================================================================= + # ReaderThread + #======================================================================================================================= class ReaderThread(PyDBDaemonThread): """ reader thread reads and dispatches commands in an infinite loop """ *************** *** 191,194 **** --- 206,212 ---- #----------------------------------------------------------------------------------- SOCKET UTILITIES - WRITER + #======================================================================================================================= + # WriterThread + #======================================================================================================================= class WriterThread(PyDBDaemonThread): """ writer thread writes out the commands in an infinite loop """ *************** *** 236,239 **** --- 254,260 ---- #--------------------------------------------------- CREATING THE SOCKET THREADS + #======================================================================================================================= + # StartServer + #======================================================================================================================= def StartServer(port): """ binds to a port, waits for the debugger to connect """ *************** *** 244,247 **** --- 265,271 ---- return newSock + #======================================================================================================================= + # StartClient + #======================================================================================================================= def StartClient(host, port): """ connects to a host/port """ *************** *** 262,265 **** --- 286,292 ---- #------------------------------------------------------------------------------------ MANY COMMUNICATION STUFF + #======================================================================================================================= + # NetCommand + #======================================================================================================================= class NetCommand: """ Commands received/sent over the network. *************** *** 293,296 **** --- 320,326 ---- return str(cmd) + '\t' + str(seq) + '\t' + encoded + "\n" + #======================================================================================================================= + # NetCommandFactory + #======================================================================================================================= class NetCommandFactory: *************** *** 432,435 **** --- 462,468 ---- + #======================================================================================================================= + # InternalThreadCommand + #======================================================================================================================= class InternalThreadCommand: """ internal commands are generated/executed by the debugger. *************** *** 448,451 **** --- 481,487 ---- raise NotImplementedError("you have to override doIt") + #======================================================================================================================= + # InternalTerminateThread + #======================================================================================================================= class InternalTerminateThread(InternalThreadCommand): def __init__(self, thread_id): *************** *** 463,466 **** --- 499,505 ---- sys.exit(0) + #======================================================================================================================= + # InternalGetVariable + #======================================================================================================================= class InternalGetVariable(InternalThreadCommand): """ gets the value of a variable """ *************** *** 490,493 **** --- 529,535 ---- + #======================================================================================================================= + # InternalChangeVariable + #======================================================================================================================= class InternalChangeVariable(InternalThreadCommand): """ changes the value of a variable """ *************** *** 509,512 **** --- 551,557 ---- + #======================================================================================================================= + # InternalGetFrame + #======================================================================================================================= class InternalGetFrame(InternalThreadCommand): """ gets the value of a variable """ *************** *** 539,542 **** --- 584,590 ---- + #======================================================================================================================= + # InternalEvaluateExpression + #======================================================================================================================= class InternalEvaluateExpression(InternalThreadCommand): """ gets the value of a variable """ *************** *** 565,568 **** --- 613,619 ---- + #======================================================================================================================= + # PydevdFindThreadById + #======================================================================================================================= def PydevdFindThreadById(thread_id): try: Index: pydevd_vars.py =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.debug/pysrc/pydevd_vars.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** pydevd_vars.py 12 Apr 2008 18:09:10 -0000 1.45 --- pydevd_vars.py 5 Jul 2008 19:42:13 -0000 1.46 *************** *** 27,66 **** #------------------------------------------------------------------------------------------------------ resolvers in map ! typeMap = {} ! try: ! #jython does not have this types try: ! typeMap[BooleanType] = (BooleanType, BooleanType.__name__, None) ! except NameError: ! pass #early versions of python do not have it. ! typeMap[BufferType] = (BufferType, BufferType.__name__, None) ! typeMap = { ! NoneType : (NoneType, NoneType.__name__, None), ! IntType : (IntType, IntType.__name__, None), ! LongType : (LongType, LongType.__name__, None), ! FloatType : (FloatType, FloatType.__name__, None), ! ComplexType : (ComplexType, ComplexType.__name__, None), ! StringType : (StringType, StringType.__name__, None), ! UnicodeType : (UnicodeType, UnicodeType.__name__, None), ! TupleType : (TupleType, TupleType.__name__, pydevd_resolver.tupleResolver), ! ListType : (ListType, ListType.__name__, pydevd_resolver.tupleResolver), ! DictType : (DictType, DictType.__name__, pydevd_resolver.dictResolver) ! } ! except: from org.python import core #@UnresolvedImport ! typeMap = { ! core.PyNone : ( core.PyNone, core.PyNone.__name__, None), ! core.PyInteger : ( core.PyInteger, core.PyInteger.__name__, None), ! core.PyLong : ( core.PyLong, core.PyLong.__name__, None), ! core.PyFloat : ( core.PyFloat, core.PyFloat.__name__, None), ! core.PyComplex : ( core.PyComplex, core.PyComplex.__name__, None), ! core.PyString : ( core.PyString, core.PyString.__name__, None), ! core.PyTuple : ( core.PyTuple, core.PyTuple.__name__, pydevd_resolver.tupleResolver), ! core.PyList : ( core.PyList, core.PyList.__name__, pydevd_resolver.tupleResolver), ! core.PyDictionary: (core.PyDictionary, core.PyDictionary.__name__, pydevd_resolver.dictResolver), ! core.PyJavaInstance: (core.PyJavaInstance, core.PyJavaInstance.__name__, pydevd_resolver.instanceResolver), ! core.PyStringMap: (core.PyStringMap, core.PyStringMap.__name__, pydevd_resolver.dictResolver) ! } --- 27,68 ---- #------------------------------------------------------------------------------------------------------ resolvers in map ! if not sys.platform.startswith("java"): ! typeMap = [ ! #None means that it should not be treated as a compound variable ! ! #isintance does not accept a tuple on some versions of python, so, we must declare it expanded ! (NoneType, None,), ! (IntType, None), ! (LongType, None), ! (FloatType, None), ! (ComplexType, None), ! (StringType, None), ! (UnicodeType, None), ! (TupleType, pydevd_resolver.tupleResolver), ! (ListType, pydevd_resolver.tupleResolver), ! (DictType, pydevd_resolver.dictResolver), ! ] ! try: ! typeMap.append(set, pydevd_resolver.setResolver) ! typeMap.append(frozenset, pydevd_resolver.setResolver) ! except: ! pass #not available on all python versions ! else: #platform is java from org.python import core #@UnresolvedImport ! typeMap = [ ! (core.PyNone, None), ! (core.PyInteger, None), ! (core.PyLong, None), ! (core.PyFloat, None), ! (core.PyComplex, None), ! (core.PyString, None), ! (core.PyTuple, pydevd_resolver.tupleResolver), ! (core.PyList, pydevd_resolver.tupleResolver), ! (core.PyDictionary, pydevd_resolver.dictResolver), ! (core.PyStringMap, pydevd_resolver.dictResolver), ! (core.PyJavaInstance, pydevd_resolver.instanceResolver), ! ] *************** *** 74,98 **** """ try: - if type(o).__name__=='org.python.core.PyJavaInstance': - return (type(o), type(o).__name__, pydevd_resolver.instanceResolver) ! if type(o).__name__=='org.python.core.PyArray': ! return (type(o), type(o).__name__, pydevd_resolver.jyArrayResolver) ! for t in typeMap.keys(): ! if isinstance(o, t): ! return typeMap[t] except: traceback.print_exc() - print typeMap - print typeMap.__class__ - print dir( typeMap ) #no match return default ! return (type(o), type(o).__name__, pydevd_resolver.defaultResolver) ! def makeValidXmlValue( s): return s.replace('<', '<').replace('>', '>') --- 76,105 ---- """ + try: + type_object = type(o) + type_name = type_object.__name__ + except: + #This happens for org.python.core.InitModule + return 'Unable to get Type', 'Unable to get Type', None + try: ! if type_name =='org.python.core.PyJavaInstance': ! return (type_object, type_name, pydevd_resolver.instanceResolver) ! if type_name =='org.python.core.PyArray': ! return (type_object, type_name, pydevd_resolver.jyArrayResolver) ! ! for t in typeMap: ! if isinstance(o, t[0]): ! return (type_object, type_name, t[1]) except: traceback.print_exc() #no match return default ! return (type_object, type_name, pydevd_resolver.defaultResolver) ! def makeValidXmlValue(s): return s.replace('<', '<').replace('>', '>') *************** *** 174,178 **** except Exception, e: traceback.print_exc() ! print >>sys.stderr,"unexpected error, recovered safely", str(e) return xml --- 181,185 ---- except Exception, e: traceback.print_exc() ! print >>sys.stderr, "unexpected error, recovered safely", str(e) return xml *************** *** 255,268 **** for k in attrList: ! type, typeName, resolver = getType(var) var = resolver.resolve(var, k) try: ! type, typeName, resolver = getType(var) return resolver.getDictionary(var) except: traceback.print_exc() ! def evaluateExpression( thread_id, frame_id, expression, doExec ): '''returns the result of the evaluated expression @param doExec: determines if we should do an exec or an eval --- 262,275 ---- for k in attrList: ! type, _typeName, resolver = getType(var) var = resolver.resolve(var, k) try: ! type, _typeName, resolver = getType(var) return resolver.getDictionary(var) except: traceback.print_exc() ! def evaluateExpression(thread_id, frame_id, expression, doExec): '''returns the result of the evaluated expression @param doExec: determines if we should do an exec or an eval *************** *** 279,283 **** exec expression in frame.f_globals, frame.f_locals else: ! result = eval( compiled, frame.f_globals, frame.f_locals ) print result return --- 286,290 ---- exec expression in frame.f_globals, frame.f_locals else: ! result = eval(compiled, frame.f_globals, frame.f_locals) print result return *************** *** 286,295 **** result = None try: ! result = eval( expression, frame.f_globals, frame.f_locals ) except Exception, e: ! result = str( e ) return result ! def changeAttrExpression( thread_id, frame_id, attr, expression ): '''Changes some attribute in a given frame. @note: it will not (currently) work if we're not in the topmost frame (that's a python --- 293,302 ---- result = None try: ! result = eval(expression, frame.f_globals, frame.f_locals) except Exception, e: ! result = str(e) return result ! def changeAttrExpression(thread_id, frame_id, attr, expression): '''Changes some attribute in a given frame. @note: it will not (currently) work if we're not in the topmost frame (that's a python |