| import pydev_log |
| import traceback |
| import pydevd_resolver |
| import sys |
| from pydevd_constants import * #@UnusedWildImport |
| |
| from pydev_imports import quote |
| |
| try: |
| import types |
| frame_type = types.FrameType |
| except: |
| frame_type = None |
| |
| try: |
| from xml.sax.saxutils import escape |
| |
| def makeValidXmlValue(s): |
| return escape(s, {'"': '"'}) |
| except: |
| #Simple replacement if it's not there. |
| def makeValidXmlValue(s): |
| return s.replace('<', '<').replace('>', '>').replace('"', '"') |
| |
| class ExceptionOnEvaluate: |
| def __init__(self, result): |
| self.result = result |
| |
| #------------------------------------------------------------------------------------------------------ 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 |
| (type(None), None,), |
| (int, None), |
| (float, None), |
| (complex, None), |
| (str, None), |
| (tuple, pydevd_resolver.tupleResolver), |
| (list, pydevd_resolver.tupleResolver), |
| (dict, pydevd_resolver.dictResolver), |
| ] |
| |
| try: |
| typeMap.append((long, None)) |
| except: |
| pass #not available on all python versions |
| |
| try: |
| typeMap.append((unicode, None)) |
| except: |
| pass #not available on all python versions |
| |
| try: |
| typeMap.append((set, pydevd_resolver.setResolver)) |
| except: |
| pass #not available on all python versions |
| |
| try: |
| typeMap.append((frozenset, pydevd_resolver.setResolver)) |
| except: |
| pass #not available on all python versions |
| |
| try: |
| import numpy |
| typeMap.append((numpy.ndarray, pydevd_resolver.ndarrayResolver)) |
| except: |
| pass #numpy may not be installed |
| |
| if frame_type is not None: |
| typeMap.append((frame_type, pydevd_resolver.frameResolver)) |
| |
| |
| 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), |
| ] |
| |
| if hasattr(core, 'PyJavaInstance'): |
| #Jython 2.5b3 removed it. |
| typeMap.append((core.PyJavaInstance, pydevd_resolver.instanceResolver)) |
| |
| |
| def getType(o): |
| """ returns a triple (typeObject, typeString, resolver |
| resolver != None means that variable is a container, |
| and should be displayed as a hierarchy. |
| Use the resolver to get its attributes. |
| |
| All container objects should have a resolver. |
| """ |
| |
| 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 frameVarsToXML(frame_f_locals): |
| """ dumps frame variables to XML |
| <var name="var_name" scope="local" type="type" value="value"/> |
| """ |
| xml = "" |
| |
| keys = frame_f_locals.keys() |
| if hasattr(keys, 'sort'): |
| keys.sort() #Python 3.0 does not have it |
| else: |
| keys = sorted(keys) #Jython 2.1 does not have it |
| |
| for k in keys: |
| try: |
| v = frame_f_locals[k] |
| xml += varToXML(v, str(k)) |
| except Exception: |
| traceback.print_exc() |
| pydev_log.error("Unexpected error, recovered safely.\n") |
| |
| return xml |
| |
| |
| def varToXML(val, name, doTrim=True, additionalInXml=''): |
| """ single variable or dictionary to xml representation """ |
| |
| is_exception_on_eval = isinstance(val, ExceptionOnEvaluate) |
| |
| if is_exception_on_eval: |
| v = val.result |
| else: |
| v = val |
| |
| type, typeName, resolver = getType(v) |
| |
| try: |
| if hasattr(v, '__class__'): |
| if v.__class__ == frame_type: |
| value = pydevd_resolver.frameResolver.getFrameName(v) |
| else: |
| try: |
| cName = str(v.__class__) |
| if cName.find('.') != -1: |
| cName = cName.split('.')[-1] |
| |
| elif cName.find("'") != -1: #does not have '.' (could be something like <type 'int'>) |
| cName = cName[cName.index("'") + 1:] |
| |
| if cName.endswith("'>"): |
| cName = cName[:-2] |
| except: |
| cName = str(v.__class__) |
| value = '%s: %s' % (cName, v) |
| else: |
| value = str(v) |
| except: |
| try: |
| value = repr(v) |
| except: |
| value = 'Unable to get repr for %s' % v.__class__ |
| |
| try: |
| name = quote(name, '/>_= ') #TODO: Fix PY-5834 without using quote |
| except: |
| pass |
| xml = '<var name="%s" type="%s"' % (makeValidXmlValue(name), makeValidXmlValue(typeName)) |
| |
| if value: |
| #cannot be too big... communication may not handle it. |
| if len(value) > MAXIMUM_VARIABLE_REPRESENTATION_SIZE and doTrim: |
| value = value[0:MAXIMUM_VARIABLE_REPRESENTATION_SIZE] |
| value += '...' |
| |
| #fix to work with unicode values |
| try: |
| if not IS_PY3K: |
| if isinstance(value, unicode): |
| value = value.encode('utf-8') |
| else: |
| if isinstance(value, bytes): |
| value = value.encode('utf-8') |
| except TypeError: #in java, unicode is a function |
| pass |
| |
| xmlValue = ' value="%s"' % (makeValidXmlValue(quote(value, '/>_= '))) |
| else: |
| xmlValue = '' |
| |
| if is_exception_on_eval: |
| xmlCont = ' isErrorOnEval="True"' |
| else: |
| if resolver is not None: |
| xmlCont = ' isContainer="True"' |
| else: |
| xmlCont = '' |
| |
| return ''.join((xml, xmlValue, xmlCont, additionalInXml, ' />\n')) |
| |
| if USE_PSYCO_OPTIMIZATION: |
| try: |
| import psyco |
| |
| varToXML = psyco.proxy(varToXML) |
| except ImportError: |
| if hasattr(sys, 'exc_clear'): #jython does not have it |
| sys.exc_clear() #don't keep the traceback -- clients don't want to see it |