mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Variable view in Python Console.
This commit is contained in:
@@ -17,6 +17,8 @@ import traceback
|
||||
import fix_getpass
|
||||
fix_getpass.fixGetpass()
|
||||
|
||||
import pydevd_xml
|
||||
|
||||
try:
|
||||
if USE_LIB_COPY:
|
||||
import _pydev_Queue as _queue
|
||||
@@ -162,7 +164,13 @@ class InterpreterInterface(BaseInterpreterInterface):
|
||||
|
||||
traceback.print_exc()
|
||||
return []
|
||||
|
||||
|
||||
def getFrame(self):
|
||||
xml = "<xml>"
|
||||
xml += pydevd_xml.frameVarsToXML(self.namespace)
|
||||
xml += "</xml>"
|
||||
|
||||
return xml
|
||||
|
||||
def close(self):
|
||||
sys.exit(0)
|
||||
@@ -265,6 +273,7 @@ def start_server(host, port, interpreter):
|
||||
|
||||
server.register_function(interpreter.execLine)
|
||||
server.register_function(interpreter.getCompletions)
|
||||
server.register_function(interpreter.getFrame)
|
||||
server.register_function(interpreter.getDescription)
|
||||
server.register_function(interpreter.close)
|
||||
server.register_function(interpreter.interrupt)
|
||||
@@ -323,6 +332,8 @@ def get_completions(text, token, globals, locals):
|
||||
|
||||
return interpreterInterface.getCompletions(text, token)
|
||||
|
||||
def get_frame(globals, locals):
|
||||
return interpreterInterface.getFrame()
|
||||
|
||||
def exec_expression(expression, globals, locals):
|
||||
interpreterInterface = get_interpreter()
|
||||
|
||||
@@ -604,7 +604,7 @@ class NetCommandFactory:
|
||||
#print "line is ", myLine
|
||||
|
||||
#the variables are all gotten 'on-demand'
|
||||
#variables = pydevd_vars.frameVarsToXML(curFrame)
|
||||
#variables = pydevd_vars.frameVarsToXML(curFrame.f_locals)
|
||||
|
||||
variables = ''
|
||||
cmdTextList.append('<frame id="%s" name="%s" ' % (myId , pydevd_vars.makeValidXmlValue(myName)))
|
||||
@@ -839,7 +839,7 @@ class InternalGetFrame(InternalThreadCommand):
|
||||
frame = pydevd_vars.findFrame(self.thread_id, self.frame_id)
|
||||
if frame is not None:
|
||||
xml = "<xml>"
|
||||
xml += pydevd_vars.frameVarsToXML(frame)
|
||||
xml += pydevd_vars.frameVarsToXML(frame.f_locals)
|
||||
del frame
|
||||
xml += "</xml>"
|
||||
cmd = dbg.cmdFactory.makeGetFrameMessage(self.sequence, xml)
|
||||
|
||||
@@ -6,6 +6,7 @@ except:
|
||||
from urllib.parse import quote
|
||||
|
||||
import pydevd_constants
|
||||
import pydev_log
|
||||
|
||||
def to_number(x):
|
||||
if is_string(x):
|
||||
@@ -92,4 +93,7 @@ def quote_smart(s, safe='/'):
|
||||
s = s.encode('utf-8')
|
||||
|
||||
return quote(s, safe)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from types import * #@UnusedWildImport
|
||||
from code import compile_command
|
||||
from code import InteractiveInterpreter
|
||||
import pydevconsole
|
||||
import pydev_log
|
||||
from pydevd_xml import *
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
@@ -16,11 +16,6 @@ except ImportError:
|
||||
from io import StringIO
|
||||
import sys #@Reimport
|
||||
|
||||
try:
|
||||
from urllib import quote
|
||||
except:
|
||||
from urllib.parse import quote #@UnresolvedImport
|
||||
|
||||
if USE_LIB_COPY:
|
||||
import _pydev_threading as threading
|
||||
else:
|
||||
@@ -50,177 +45,6 @@ class VariableError(RuntimeError): pass
|
||||
class FrameNotFoundError(RuntimeError): pass
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------------------------------ 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
|
||||
|
||||
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
|
||||
|
||||
|
||||
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('"', '"')
|
||||
|
||||
|
||||
def varToXML(val, name, doTrim=True):
|
||||
""" 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__'):
|
||||
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__
|
||||
|
||||
xml = '<var name="%s" type="%s"' % (makeValidXmlValue(quote(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, ' />\n'))
|
||||
|
||||
|
||||
if USE_PSYCO_OPTIMIZATION:
|
||||
try:
|
||||
import psyco
|
||||
@@ -231,27 +55,7 @@ if USE_PSYCO_OPTIMIZATION:
|
||||
sys.exc_clear() #don't keep the traceback -- clients don't want to see it
|
||||
|
||||
|
||||
def frameVarsToXML(frame):
|
||||
""" 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 iterFrames(initialFrame):
|
||||
"""NO-YIELD VERSION: Iterates through all the frames starting at the specified frame (which will be the first returned item)"""
|
||||
@@ -378,10 +182,6 @@ def resolveCompoundVariable(thread_id, frame_id, scope, attrs):
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
class ExceptionOnEvaluate:
|
||||
def __init__(self, result):
|
||||
self.result = result
|
||||
|
||||
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
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
import pydev_log
|
||||
import traceback
|
||||
import pydevd_resolver
|
||||
from pydevd_constants import * #@UnusedWildImport
|
||||
from types import * #@UnusedWildImport
|
||||
|
||||
try:
|
||||
from urllib import quote
|
||||
except:
|
||||
from urllib.parse import quote #@UnresolvedImport
|
||||
|
||||
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
|
||||
|
||||
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):
|
||||
""" 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__'):
|
||||
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__
|
||||
|
||||
xml = '<var name="%s" type="%s"' % (makeValidXmlValue(quote(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, ' />\n'))
|
||||
Reference in New Issue
Block a user