expressions.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import axdebug, gateways
  2. from .util import _wrap, _wrap_remove, RaiseNotImpl
  3. import io, traceback
  4. from pprint import pprint
  5. from win32com.server.exception import COMException
  6. import winerror
  7. import string
  8. import sys
  9. # Given an object, return a nice string
  10. def MakeNiceString(ob):
  11. stream = io.StringIO()
  12. pprint(ob, stream)
  13. return string.strip(stream.getvalue())
  14. class ProvideExpressionContexts(gateways.ProvideExpressionContexts):
  15. pass
  16. class ExpressionContext(gateways.DebugExpressionContext):
  17. def __init__(self, frame):
  18. self.frame = frame
  19. def ParseLanguageText(self, code, radix, delim, flags):
  20. return _wrap(Expression(self.frame, code, radix, delim, flags), axdebug.IID_IDebugExpression)
  21. def GetLanguageInfo(self):
  22. # print "GetLanguageInfo"
  23. return "Python", "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
  24. class Expression(gateways.DebugExpression):
  25. def __init__(self, frame, code, radix, delim, flags):
  26. self.callback = None
  27. self.frame = frame
  28. self.code = code
  29. self.radix = radix
  30. self.delim = delim
  31. self.flags = flags
  32. self.isComplete = 0
  33. self.result=None
  34. self.hresult = winerror.E_UNEXPECTED
  35. def Start(self, callback):
  36. try:
  37. try:
  38. try:
  39. self.result = eval(self.code, self.frame.f_globals, self.frame.f_locals)
  40. except SyntaxError:
  41. exec(self.code, self.frame.f_globals, self.frame.f_locals)
  42. self.result = ""
  43. self.hresult = 0
  44. except:
  45. l = traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])
  46. # l is a list of strings with trailing "\n"
  47. self.result = string.join(map(lambda s:s[:-1], l), "\n")
  48. self.hresult = winerror.E_FAIL
  49. finally:
  50. self.isComplete = 1
  51. callback.onComplete()
  52. def Abort(self):
  53. print("** ABORT **")
  54. def QueryIsComplete(self):
  55. return self.isComplete
  56. def GetResultAsString(self):
  57. # print "GetStrAsResult returning", self.result
  58. return self.hresult, MakeNiceString(self.result)
  59. def GetResultAsDebugProperty(self):
  60. result = _wrap(DebugProperty(self.code, self.result, None, self.hresult), axdebug.IID_IDebugProperty)
  61. return self.hresult, result
  62. def MakeEnumDebugProperty(object, dwFieldSpec, nRadix, iid, stackFrame = None):
  63. name_vals = []
  64. if hasattr(object, "items") and hasattr(object, "keys"): # If it is a dict.
  65. name_vals = iter(object.items())
  66. dictionary = object
  67. elif hasattr(object, "__dict__"): #object with dictionary, module
  68. name_vals = iter(object.__dict__.items())
  69. dictionary = object.__dict__
  70. infos = []
  71. for name, val in name_vals:
  72. infos.append(GetPropertyInfo(name, val, dwFieldSpec, nRadix, 0, dictionary, stackFrame))
  73. return _wrap(EnumDebugPropertyInfo(infos), axdebug.IID_IEnumDebugPropertyInfo)
  74. def GetPropertyInfo(obname, obvalue, dwFieldSpec, nRadix, hresult=0, dictionary = None, stackFrame = None):
  75. # returns a tuple
  76. name = typ = value = fullname = attrib = dbgprop = None
  77. if dwFieldSpec & axdebug.DBGPROP_INFO_VALUE:
  78. value = MakeNiceString(obvalue)
  79. if dwFieldSpec & axdebug.DBGPROP_INFO_NAME:
  80. name = obname
  81. if dwFieldSpec & axdebug.DBGPROP_INFO_TYPE:
  82. if hresult:
  83. typ = "Error"
  84. else:
  85. try:
  86. typ = type(obvalue).__name__
  87. except AttributeError:
  88. typ = str(type(obvalue))
  89. if dwFieldSpec & axdebug.DBGPROP_INFO_FULLNAME:
  90. fullname = obname
  91. if dwFieldSpec & axdebug.DBGPROP_INFO_ATTRIBUTES:
  92. if hasattr(obvalue, "has_key") or hasattr(obvalue, "__dict__"): # If it is a dict or object
  93. attrib = axdebug.DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE
  94. else:
  95. attrib = 0
  96. if dwFieldSpec & axdebug.DBGPROP_INFO_DEBUGPROP:
  97. dbgprop = _wrap(DebugProperty(name, obvalue, None, hresult, dictionary, stackFrame), axdebug.IID_IDebugProperty)
  98. return name, typ, value, fullname, attrib, dbgprop
  99. from win32com.server.util import ListEnumeratorGateway
  100. class EnumDebugPropertyInfo(ListEnumeratorGateway):
  101. """A class to expose a Python sequence as an EnumDebugCodeContexts
  102. Create an instance of this class passing a sequence (list, tuple, or
  103. any sequence protocol supporting object) and it will automatically
  104. support the EnumDebugCodeContexts interface for the object.
  105. """
  106. _public_methods_ = ListEnumeratorGateway._public_methods_ + ["GetCount"]
  107. _com_interfaces_ = [ axdebug.IID_IEnumDebugPropertyInfo]
  108. def GetCount(self):
  109. return len(self._list_)
  110. def _wrap(self, ob):
  111. return ob
  112. class DebugProperty:
  113. _com_interfaces_ = [axdebug.IID_IDebugProperty]
  114. _public_methods_ = ['GetPropertyInfo', 'GetExtendedInfo', 'SetValueAsString',
  115. 'EnumMembers', 'GetParent'
  116. ]
  117. def __init__(self, name, value, parent = None, hresult = 0, dictionary = None, stackFrame = None):
  118. self.name = name
  119. self.value = value
  120. self.parent = parent
  121. self.hresult = hresult
  122. self.dictionary = dictionary
  123. self.stackFrame = stackFrame
  124. def GetPropertyInfo(self, dwFieldSpec, nRadix):
  125. return GetPropertyInfo(self.name, self.value, dwFieldSpec, nRadix, self.hresult, dictionary, stackFrame)
  126. def GetExtendedInfo(self): ### Note - not in the framework.
  127. RaiseNotImpl("DebugProperty::GetExtendedInfo")
  128. def SetValueAsString(self, value, radix):
  129. if self.stackFrame and self.dictionary:
  130. self.dictionary[self.name]= eval(value,self.stackFrame.f_globals, self.stackFrame.f_locals)
  131. else:
  132. RaiseNotImpl("DebugProperty::SetValueAsString")
  133. def EnumMembers(self, dwFieldSpec, nRadix, iid):
  134. # Returns IEnumDebugPropertyInfo
  135. return MakeEnumDebugProperty(self.value, dwFieldSpec, nRadix, iid, self.stackFrame)
  136. def GetParent(self):
  137. # return IDebugProperty
  138. RaiseNotImpl("DebugProperty::GetParent")