|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- """Support for stack-frames.
-
- Provides Implements a nearly complete wrapper for a stack frame.
- """
-
- import pythoncom
- from win32com.server.exception import COMException
-
- from . import axdebug, expressions, gateways
- from .util import RaiseNotImpl, _wrap, trace
-
- # def trace(*args):
- # pass
-
-
- class EnumDebugStackFrames(gateways.EnumDebugStackFrames):
- """A class that given a debugger object, can return an enumerator
- of DebugStackFrame objects.
- """
-
- def __init__(self, debugger):
- infos = []
- frame = debugger.currentframe
- # print "Stack check"
- while frame:
- # print " Checking frame", frame.f_code.co_filename, frame.f_lineno-1, frame.f_trace,
- # Get a DebugCodeContext for the stack frame. If we fail, then it
- # is not debuggable, and therefore not worth displaying.
- cc = debugger.codeContainerProvider.FromFileName(frame.f_code.co_filename)
- if cc is not None:
- try:
- address = frame.f_locals["__axstack_address__"]
- except KeyError:
- # print "Couldnt find stack address for",frame.f_code.co_filename, frame.f_lineno-1
- # Use this one, even tho it is wrong :-(
- address = axdebug.GetStackAddress()
- frameInfo = (
- DebugStackFrame(frame, frame.f_lineno - 1, cc),
- address,
- address + 1,
- 0,
- None,
- )
- infos.append(frameInfo)
- # print "- Kept!"
- # else:
- # print "- rejected"
- frame = frame.f_back
-
- gateways.EnumDebugStackFrames.__init__(self, infos, 0)
-
- # def __del__(self):
- # print "EnumDebugStackFrames dieing"
-
- def Next(self, count):
- return gateways.EnumDebugStackFrames.Next(self, count)
-
- # def _query_interface_(self, iid):
- # from win32com.util import IIDToInterfaceName
- # print "EnumDebugStackFrames QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid))
- # return 0
- def _wrap(self, obj):
- # This enum returns a tuple, with 2 com objects in it.
- obFrame, min, lim, fFinal, obFinal = obj
- obFrame = _wrap(obFrame, axdebug.IID_IDebugStackFrame)
- if obFinal:
- obFinal = _wrap(obFinal, pythoncom.IID_IUnknown)
- return obFrame, min, lim, fFinal, obFinal
-
-
- class DebugStackFrame(gateways.DebugStackFrame):
- def __init__(self, frame, lineno, codeContainer):
- self.frame = frame
- self.lineno = lineno
- self.codeContainer = codeContainer
- self.expressionContext = None
-
- # def __del__(self):
- # print "DSF dieing"
- def _query_interface_(self, iid):
- if iid == axdebug.IID_IDebugExpressionContext:
- if self.expressionContext is None:
- self.expressionContext = _wrap(
- expressions.ExpressionContext(self.frame),
- axdebug.IID_IDebugExpressionContext,
- )
- return self.expressionContext
- # from win32com.util import IIDToInterfaceName
- # print "DebugStackFrame QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid))
- return 0
-
- #
- # The following need implementation
- def GetThread(self):
- """Returns the thread associated with this stack frame.
-
- Result must be a IDebugApplicationThread
- """
- RaiseNotImpl("GetThread")
-
- def GetCodeContext(self):
- offset = self.codeContainer.GetPositionOfLine(self.lineno)
- return self.codeContainer.GetCodeContextAtPosition(offset)
-
- #
- # The following are usefully implemented
- def GetDescriptionString(self, fLong):
- filename = self.frame.f_code.co_filename
- s = ""
- if 0: # fLong:
- s = s + filename
- if self.frame.f_code.co_name:
- s = s + self.frame.f_code.co_name
- else:
- s = s + "<lambda>"
- return s
-
- def GetLanguageString(self, fLong):
- if fLong:
- return "Python ActiveX Scripting Engine"
- else:
- return "Python"
-
- def GetDebugProperty(self):
- return _wrap(StackFrameDebugProperty(self.frame), axdebug.IID_IDebugProperty)
-
-
- class DebugStackFrameSniffer:
- _public_methods_ = ["EnumStackFrames"]
- _com_interfaces_ = [axdebug.IID_IDebugStackFrameSniffer]
-
- def __init__(self, debugger):
- self.debugger = debugger
- trace("DebugStackFrameSniffer instantiated")
-
- # def __del__(self):
- # print "DSFS dieing"
- def EnumStackFrames(self):
- trace("DebugStackFrameSniffer.EnumStackFrames called")
- return _wrap(
- EnumDebugStackFrames(self.debugger), axdebug.IID_IEnumDebugStackFrames
- )
-
-
- # A DebugProperty for a stack frame.
- class StackFrameDebugProperty:
- _com_interfaces_ = [axdebug.IID_IDebugProperty]
- _public_methods_ = [
- "GetPropertyInfo",
- "GetExtendedInfo",
- "SetValueAsString",
- "EnumMembers",
- "GetParent",
- ]
-
- def __init__(self, frame):
- self.frame = frame
-
- def GetPropertyInfo(self, dwFieldSpec, nRadix):
- RaiseNotImpl("StackFrameDebugProperty::GetPropertyInfo")
-
- def GetExtendedInfo(self): ### Note - not in the framework.
- RaiseNotImpl("StackFrameDebugProperty::GetExtendedInfo")
-
- def SetValueAsString(self, value, radix):
- #
- RaiseNotImpl("DebugProperty::SetValueAsString")
-
- def EnumMembers(self, dwFieldSpec, nRadix, iid):
- print("EnumMembers", dwFieldSpec, nRadix, iid)
- from . import expressions
-
- return expressions.MakeEnumDebugProperty(
- self.frame.f_locals, dwFieldSpec, nRadix, iid, self.frame
- )
-
- def GetParent(self):
- # return IDebugProperty
- RaiseNotImpl("DebugProperty::GetParent")
|