mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-02 06:22:25 +00:00
first commit
This commit is contained in:
4
.venv/Lib/site-packages/win32comext/axdebug/__init__.py
Normal file
4
.venv/Lib/site-packages/win32comext/axdebug/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
476
.venv/Lib/site-packages/win32comext/axdebug/adb.py
Normal file
476
.venv/Lib/site-packages/win32comext/axdebug/adb.py
Normal file
@ -0,0 +1,476 @@
|
||||
"""The glue between the Python debugger interface and the Active Debugger interface
|
||||
"""
|
||||
from win32com.axdebug.util import trace, _wrap, _wrap_remove
|
||||
from win32com.server.util import unwrap
|
||||
import win32com.client.connect
|
||||
from . import gateways
|
||||
import sys, bdb, traceback
|
||||
import axdebug, stackframe
|
||||
import win32api, pythoncom
|
||||
import _thread, os
|
||||
|
||||
|
||||
def fnull(*args):
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
os.environ["DEBUG_AXDEBUG"]
|
||||
debugging = 1
|
||||
except KeyError:
|
||||
debugging = 0
|
||||
|
||||
traceenter = fnull # trace enter of functions
|
||||
tracev = fnull # verbose trace
|
||||
|
||||
if debugging:
|
||||
traceenter = trace # trace enter of functions
|
||||
tracev = trace # verbose trace
|
||||
|
||||
|
||||
class OutputReflector:
|
||||
def __init__(self, file, writefunc):
|
||||
self.writefunc = writefunc
|
||||
self.file = file
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.file, name)
|
||||
|
||||
def write(self, message):
|
||||
self.writefunc(message)
|
||||
self.file.write(message)
|
||||
|
||||
|
||||
def _dumpf(frame):
|
||||
if frame is None:
|
||||
return "<None>"
|
||||
else:
|
||||
addn = "(with trace!)"
|
||||
if frame.f_trace is None:
|
||||
addn = " **No Trace Set **"
|
||||
return "Frame at %d, file %s, line: %d%s" % (
|
||||
id(frame),
|
||||
frame.f_code.co_filename,
|
||||
frame.f_lineno,
|
||||
addn,
|
||||
)
|
||||
|
||||
|
||||
g_adb = None
|
||||
|
||||
|
||||
def OnSetBreakPoint(codeContext, breakPointState, lineNo):
|
||||
try:
|
||||
fileName = codeContext.codeContainer.GetFileName()
|
||||
# inject the code into linecache.
|
||||
import linecache
|
||||
|
||||
linecache.cache[fileName] = 0, 0, codeContext.codeContainer.GetText(), fileName
|
||||
g_adb._OnSetBreakPoint(fileName, codeContext, breakPointState, lineNo + 1)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
class Adb(bdb.Bdb, gateways.RemoteDebugApplicationEvents):
|
||||
def __init__(self):
|
||||
self.debugApplication = None
|
||||
self.debuggingThread = None
|
||||
self.debuggingThreadStateHandle = None
|
||||
self.stackSnifferCookie = self.stackSniffer = None
|
||||
self.codeContainerProvider = None
|
||||
self.debuggingThread = None
|
||||
self.breakFlags = None
|
||||
self.breakReason = None
|
||||
self.appDebugger = None
|
||||
self.appEventConnection = None
|
||||
self.logicalbotframe = None # Anything at this level or below does not exist!
|
||||
self.currentframe = None # The frame we are currently in.
|
||||
self.recursiveData = [] # Data saved for each reentery on this thread.
|
||||
bdb.Bdb.__init__(self)
|
||||
self._threadprotectlock = _thread.allocate_lock()
|
||||
self.reset()
|
||||
|
||||
def canonic(self, fname):
|
||||
if fname[0] == "<":
|
||||
return fname
|
||||
return bdb.Bdb.canonic(self, fname)
|
||||
|
||||
def reset(self):
|
||||
traceenter("adb.reset")
|
||||
bdb.Bdb.reset(self)
|
||||
|
||||
def __xxxxx__set_break(self, filename, lineno, cond=None):
|
||||
# As per standard one, except no linecache checking!
|
||||
if filename not in self.breaks:
|
||||
self.breaks[filename] = []
|
||||
list = self.breaks[filename]
|
||||
if lineno in list:
|
||||
return "There is already a breakpoint there!"
|
||||
list.append(lineno)
|
||||
if cond is not None:
|
||||
self.cbreaks[filename, lineno] = cond
|
||||
|
||||
def stop_here(self, frame):
|
||||
traceenter("stop_here", _dumpf(frame), _dumpf(self.stopframe))
|
||||
# As per bdb.stop_here, except for logicalbotframe
|
||||
## if self.stopframe is None:
|
||||
## return 1
|
||||
if frame is self.stopframe:
|
||||
return 1
|
||||
|
||||
tracev("stop_here said 'No'!")
|
||||
return 0
|
||||
|
||||
def break_here(self, frame):
|
||||
traceenter("break_here", self.breakFlags, _dumpf(frame))
|
||||
self.breakReason = None
|
||||
if self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_HALT:
|
||||
self.breakReason = axdebug.BREAKREASON_DEBUGGER_HALT
|
||||
elif self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_BLOCK:
|
||||
self.breakReason = axdebug.BREAKREASON_DEBUGGER_BLOCK
|
||||
elif self.breakFlags == axdebug.APPBREAKFLAG_STEP:
|
||||
self.breakReason = axdebug.BREAKREASON_STEP
|
||||
else:
|
||||
print("Calling base 'break_here' with", self.breaks)
|
||||
if bdb.Bdb.break_here(self, frame):
|
||||
self.breakReason = axdebug.BREAKREASON_BREAKPOINT
|
||||
return self.breakReason is not None
|
||||
|
||||
def break_anywhere(self, frame):
|
||||
traceenter("break_anywhere", _dumpf(frame))
|
||||
if self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_HALT:
|
||||
self.breakReason = axdebug.BREAKREASON_DEBUGGER_HALT
|
||||
return 1
|
||||
rc = bdb.Bdb.break_anywhere(self, frame)
|
||||
tracev("break_anywhere", _dumpf(frame), "returning", rc)
|
||||
return rc
|
||||
|
||||
def dispatch_return(self, frame, arg):
|
||||
traceenter("dispatch_return", _dumpf(frame), arg)
|
||||
if self.logicalbotframe is frame:
|
||||
# We dont want to debug parent frames.
|
||||
tracev("dispatch_return resetting sys.trace")
|
||||
sys.settrace(None)
|
||||
return
|
||||
# self.bSetTrace = 0
|
||||
self.currentframe = frame.f_back
|
||||
return bdb.Bdb.dispatch_return(self, frame, arg)
|
||||
|
||||
def dispatch_line(self, frame):
|
||||
traceenter("dispatch_line", _dumpf(frame), _dumpf(self.botframe))
|
||||
# trace("logbotframe is", _dumpf(self.logicalbotframe), "botframe is", self.botframe)
|
||||
if frame is self.logicalbotframe:
|
||||
trace("dispatch_line", _dumpf(frame), "for bottom frame returing tracer")
|
||||
# The next code executed in the frame above may be a builtin (eg, apply())
|
||||
# in which sys.trace needs to be set.
|
||||
sys.settrace(self.trace_dispatch)
|
||||
# And return the tracer incase we are about to execute Python code,
|
||||
# in which case sys tracer is ignored!
|
||||
return self.trace_dispatch
|
||||
|
||||
if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None:
|
||||
trace(
|
||||
"dispatch_line has no document for", _dumpf(frame), "- skipping trace!"
|
||||
)
|
||||
return None
|
||||
self.currentframe = (
|
||||
frame # So the stack sniffer knows our most recent, debuggable code.
|
||||
)
|
||||
return bdb.Bdb.dispatch_line(self, frame)
|
||||
|
||||
def dispatch_call(self, frame, arg):
|
||||
traceenter("dispatch_call", _dumpf(frame))
|
||||
frame.f_locals["__axstack_address__"] = axdebug.GetStackAddress()
|
||||
if frame is self.botframe:
|
||||
trace("dispatch_call is self.botframe - returning tracer")
|
||||
return self.trace_dispatch
|
||||
# Not our bottom frame. If we have a document for it,
|
||||
# then trace it, otherwise run at full speed.
|
||||
if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None:
|
||||
trace(
|
||||
"dispatch_call has no document for", _dumpf(frame), "- skipping trace!"
|
||||
)
|
||||
## sys.settrace(None)
|
||||
return None
|
||||
return self.trace_dispatch
|
||||
|
||||
# rc = bdb.Bdb.dispatch_call(self, frame, arg)
|
||||
# trace("dispatch_call", _dumpf(frame),"returned",rc)
|
||||
# return rc
|
||||
|
||||
def trace_dispatch(self, frame, event, arg):
|
||||
traceenter("trace_dispatch", _dumpf(frame), event, arg)
|
||||
if self.debugApplication is None:
|
||||
trace("trace_dispatch has no application!")
|
||||
return # None
|
||||
return bdb.Bdb.trace_dispatch(self, frame, event, arg)
|
||||
|
||||
#
|
||||
# The user functions do bugger all!
|
||||
#
|
||||
# def user_call(self, frame, argument_list):
|
||||
# traceenter("user_call",_dumpf(frame))
|
||||
|
||||
def user_line(self, frame):
|
||||
traceenter("user_line", _dumpf(frame))
|
||||
# Traces at line zero
|
||||
if frame.f_lineno != 0:
|
||||
breakReason = self.breakReason
|
||||
if breakReason is None:
|
||||
breakReason = axdebug.BREAKREASON_STEP
|
||||
self._HandleBreakPoint(frame, None, breakReason)
|
||||
|
||||
def user_return(self, frame, return_value):
|
||||
# traceenter("user_return",_dumpf(frame),return_value)
|
||||
bdb.Bdb.user_return(self, frame, return_value)
|
||||
|
||||
def user_exception(self, frame, exc_info):
|
||||
# traceenter("user_exception")
|
||||
bdb.Bdb.user_exception(self, frame, exc_info)
|
||||
|
||||
def _HandleBreakPoint(self, frame, tb, reason):
|
||||
traceenter(
|
||||
"Calling HandleBreakPoint with reason", reason, "at frame", _dumpf(frame)
|
||||
)
|
||||
traceenter(" Current frame is", _dumpf(self.currentframe))
|
||||
try:
|
||||
resumeAction = self.debugApplication.HandleBreakPoint(reason)
|
||||
tracev("HandleBreakPoint returned with ", resumeAction)
|
||||
except pythoncom.com_error as details:
|
||||
# Eeek - the debugger is dead, or something serious is happening.
|
||||
# Assume we should continue
|
||||
resumeAction = axdebug.BREAKRESUMEACTION_CONTINUE
|
||||
trace("HandleBreakPoint FAILED with", details)
|
||||
|
||||
self.stack = []
|
||||
self.curindex = 0
|
||||
if resumeAction == axdebug.BREAKRESUMEACTION_ABORT:
|
||||
self.set_quit()
|
||||
elif resumeAction == axdebug.BREAKRESUMEACTION_CONTINUE:
|
||||
tracev("resume action is continue")
|
||||
self.set_continue()
|
||||
elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_INTO:
|
||||
tracev("resume action is step")
|
||||
self.set_step()
|
||||
elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OVER:
|
||||
tracev("resume action is next")
|
||||
self.set_next(frame)
|
||||
elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OUT:
|
||||
tracev("resume action is stop out")
|
||||
self.set_return(frame)
|
||||
else:
|
||||
raise ValueError("unknown resume action flags")
|
||||
self.breakReason = None
|
||||
|
||||
def set_trace(self):
|
||||
self.breakReason = axdebug.BREAKREASON_LANGUAGE_INITIATED
|
||||
bdb.Bdb.set_trace(self)
|
||||
|
||||
def CloseApp(self):
|
||||
traceenter("ClosingApp")
|
||||
self.reset()
|
||||
self.logicalbotframe = None
|
||||
if self.stackSnifferCookie is not None:
|
||||
try:
|
||||
self.debugApplication.RemoveStackFrameSniffer(self.stackSnifferCookie)
|
||||
|
||||
except pythoncom.com_error:
|
||||
trace(
|
||||
"*** Could not RemoveStackFrameSniffer %d"
|
||||
% (self.stackSnifferCookie)
|
||||
)
|
||||
if self.stackSniffer:
|
||||
_wrap_remove(self.stackSniffer)
|
||||
self.stackSnifferCookie = self.stackSniffer = None
|
||||
|
||||
if self.appEventConnection is not None:
|
||||
self.appEventConnection.Disconnect()
|
||||
self.appEventConnection = None
|
||||
self.debugApplication = None
|
||||
self.appDebugger = None
|
||||
if self.codeContainerProvider is not None:
|
||||
self.codeContainerProvider.Close()
|
||||
self.codeContainerProvider = None
|
||||
|
||||
def AttachApp(self, debugApplication, codeContainerProvider):
|
||||
# traceenter("AttachApp", debugApplication, codeContainerProvider)
|
||||
self.codeContainerProvider = codeContainerProvider
|
||||
self.debugApplication = debugApplication
|
||||
self.stackSniffer = _wrap(
|
||||
stackframe.DebugStackFrameSniffer(self), axdebug.IID_IDebugStackFrameSniffer
|
||||
)
|
||||
self.stackSnifferCookie = debugApplication.AddStackFrameSniffer(
|
||||
self.stackSniffer
|
||||
)
|
||||
# trace("StackFrameSniffer added (%d)" % self.stackSnifferCookie)
|
||||
|
||||
# Connect to the application events.
|
||||
self.appEventConnection = win32com.client.connect.SimpleConnection(
|
||||
self.debugApplication, self, axdebug.IID_IRemoteDebugApplicationEvents
|
||||
)
|
||||
|
||||
def ResetAXDebugging(self):
|
||||
traceenter("ResetAXDebugging", self, "with refcount", len(self.recursiveData))
|
||||
if win32api.GetCurrentThreadId() != self.debuggingThread:
|
||||
trace("ResetAXDebugging called on other thread")
|
||||
return
|
||||
|
||||
if len(self.recursiveData) == 0:
|
||||
# print "ResetAXDebugging called for final time."
|
||||
self.logicalbotframe = None
|
||||
self.debuggingThread = None
|
||||
self.currentframe = None
|
||||
self.debuggingThreadStateHandle = None
|
||||
return
|
||||
|
||||
(
|
||||
self.logbotframe,
|
||||
self.stopframe,
|
||||
self.currentframe,
|
||||
self.debuggingThreadStateHandle,
|
||||
) = self.recursiveData[0]
|
||||
self.recursiveData = self.recursiveData[1:]
|
||||
|
||||
def SetupAXDebugging(self, baseFrame=None, userFrame=None):
|
||||
"""Get ready for potential debugging. Must be called on the thread
|
||||
that is being debugged.
|
||||
"""
|
||||
# userFrame is for non AXScript debugging. This is the first frame of the
|
||||
# users code.
|
||||
if userFrame is None:
|
||||
userFrame = baseFrame
|
||||
else:
|
||||
# We have missed the "dispatch_call" function, so set this up now!
|
||||
userFrame.f_locals["__axstack_address__"] = axdebug.GetStackAddress()
|
||||
|
||||
traceenter("SetupAXDebugging", self)
|
||||
self._threadprotectlock.acquire()
|
||||
try:
|
||||
thisThread = win32api.GetCurrentThreadId()
|
||||
if self.debuggingThread is None:
|
||||
self.debuggingThread = thisThread
|
||||
else:
|
||||
if self.debuggingThread != thisThread:
|
||||
trace("SetupAXDebugging called on other thread - ignored!")
|
||||
return
|
||||
# push our context.
|
||||
self.recursiveData.insert(
|
||||
0,
|
||||
(
|
||||
self.logicalbotframe,
|
||||
self.stopframe,
|
||||
self.currentframe,
|
||||
self.debuggingThreadStateHandle,
|
||||
),
|
||||
)
|
||||
finally:
|
||||
self._threadprotectlock.release()
|
||||
|
||||
trace("SetupAXDebugging has base frame as", _dumpf(baseFrame))
|
||||
self.botframe = baseFrame
|
||||
self.stopframe = userFrame
|
||||
self.logicalbotframe = baseFrame
|
||||
self.currentframe = None
|
||||
self.debuggingThreadStateHandle = axdebug.GetThreadStateHandle()
|
||||
|
||||
self._BreakFlagsChanged()
|
||||
|
||||
# RemoteDebugApplicationEvents
|
||||
def OnConnectDebugger(self, appDebugger):
|
||||
traceenter("OnConnectDebugger", appDebugger)
|
||||
self.appDebugger = appDebugger
|
||||
# Reflect output to appDebugger
|
||||
writefunc = lambda s: appDebugger.onDebugOutput(s)
|
||||
sys.stdout = OutputReflector(sys.stdout, writefunc)
|
||||
sys.stderr = OutputReflector(sys.stderr, writefunc)
|
||||
|
||||
def OnDisconnectDebugger(self):
|
||||
traceenter("OnDisconnectDebugger")
|
||||
# Stop reflecting output
|
||||
if isinstance(sys.stdout, OutputReflector):
|
||||
sys.stdout = sys.stdout.file
|
||||
if isinstance(sys.stderr, OutputReflector):
|
||||
sys.stderr = sys.stderr.file
|
||||
self.appDebugger = None
|
||||
self.set_quit()
|
||||
|
||||
def OnSetName(self, name):
|
||||
traceenter("OnSetName", name)
|
||||
|
||||
def OnDebugOutput(self, string):
|
||||
traceenter("OnDebugOutput", string)
|
||||
|
||||
def OnClose(self):
|
||||
traceenter("OnClose")
|
||||
|
||||
def OnEnterBreakPoint(self, rdat):
|
||||
traceenter("OnEnterBreakPoint", rdat)
|
||||
|
||||
def OnLeaveBreakPoint(self, rdat):
|
||||
traceenter("OnLeaveBreakPoint", rdat)
|
||||
|
||||
def OnCreateThread(self, rdat):
|
||||
traceenter("OnCreateThread", rdat)
|
||||
|
||||
def OnDestroyThread(self, rdat):
|
||||
traceenter("OnDestroyThread", rdat)
|
||||
|
||||
def OnBreakFlagChange(self, abf, rdat):
|
||||
traceenter("Debugger OnBreakFlagChange", abf, rdat)
|
||||
self.breakFlags = abf
|
||||
self._BreakFlagsChanged()
|
||||
|
||||
def _BreakFlagsChanged(self):
|
||||
traceenter(
|
||||
"_BreakFlagsChanged to %s with our thread = %s, and debugging thread = %s"
|
||||
% (self.breakFlags, self.debuggingThread, win32api.GetCurrentThreadId())
|
||||
)
|
||||
trace("_BreakFlagsChanged has breaks", self.breaks)
|
||||
# If a request comes on our debugging thread, then do it now!
|
||||
# if self.debuggingThread!=win32api.GetCurrentThreadId():
|
||||
# return
|
||||
|
||||
if len(self.breaks) or self.breakFlags:
|
||||
|
||||
if self.logicalbotframe:
|
||||
trace("BreakFlagsChange with bot frame", _dumpf(self.logicalbotframe))
|
||||
# We have frames not to be debugged (eg, Scripting engine frames
|
||||
# (sys.settrace will be set when out logicalbotframe is hit -
|
||||
# this may not be the right thing to do, as it may not cause the
|
||||
# immediate break we desire.)
|
||||
self.logicalbotframe.f_trace = self.trace_dispatch
|
||||
else:
|
||||
trace("BreakFlagsChanged, but no bottom frame")
|
||||
if self.stopframe is not None:
|
||||
self.stopframe.f_trace = self.trace_dispatch
|
||||
# If we have the thread-state for the thread being debugged, then
|
||||
# we dynamically set its trace function - it is possible that the thread
|
||||
# being debugged is in a blocked call (eg, a message box) and we
|
||||
# want to hit the debugger the instant we return
|
||||
if (
|
||||
self.debuggingThreadStateHandle is not None
|
||||
and self.breakFlags
|
||||
and self.debuggingThread != win32api.GetCurrentThreadId()
|
||||
):
|
||||
axdebug.SetThreadStateTrace(
|
||||
self.debuggingThreadStateHandle, self.trace_dispatch
|
||||
)
|
||||
|
||||
def _OnSetBreakPoint(self, key, codeContext, bps, lineNo):
|
||||
traceenter("_OnSetBreakPoint", self, key, codeContext, bps, lineNo)
|
||||
if bps == axdebug.BREAKPOINT_ENABLED:
|
||||
problem = self.set_break(key, lineNo)
|
||||
if problem:
|
||||
print("*** set_break failed -", problem)
|
||||
trace("_OnSetBreakPoint just set BP and has breaks", self.breaks)
|
||||
else:
|
||||
self.clear_break(key, lineNo)
|
||||
self._BreakFlagsChanged()
|
||||
trace("_OnSetBreakPoint leaving with breaks", self.breaks)
|
||||
|
||||
|
||||
def Debugger():
|
||||
global g_adb
|
||||
if g_adb is None:
|
||||
g_adb = Adb()
|
||||
return g_adb
|
276
.venv/Lib/site-packages/win32comext/axdebug/codecontainer.py
Normal file
276
.venv/Lib/site-packages/win32comext/axdebug/codecontainer.py
Normal file
@ -0,0 +1,276 @@
|
||||
"""A utility class for a code container.
|
||||
|
||||
A code container is a class which holds source code for a debugger. It knows how
|
||||
to color the text, and also how to translate lines into offsets, and back.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from win32com.axdebug import axdebug
|
||||
import tokenize
|
||||
from .util import RaiseNotImpl, _wrap
|
||||
|
||||
from win32com.server.exception import Exception
|
||||
import win32api, winerror
|
||||
from . import contexts
|
||||
|
||||
_keywords = {} # set of Python keywords
|
||||
for name in """
|
||||
and assert break class continue def del elif else except exec
|
||||
finally for from global if import in is lambda not
|
||||
or pass print raise return try while
|
||||
""".split():
|
||||
_keywords[name] = 1
|
||||
|
||||
|
||||
class SourceCodeContainer:
|
||||
def __init__(
|
||||
self,
|
||||
text,
|
||||
fileName="<Remove Me!>",
|
||||
sourceContext=0,
|
||||
startLineNumber=0,
|
||||
site=None,
|
||||
debugDocument=None,
|
||||
):
|
||||
self.sourceContext = sourceContext # The source context added by a smart host.
|
||||
self.text = text
|
||||
if text:
|
||||
self._buildlines()
|
||||
self.nextLineNo = 0
|
||||
self.fileName = fileName
|
||||
self.codeContexts = {}
|
||||
self.site = site
|
||||
self.startLineNumber = startLineNumber
|
||||
self.debugDocument = None
|
||||
|
||||
def _Close(self):
|
||||
self.text = self.lines = self.lineOffsets = None
|
||||
self.codeContexts = None
|
||||
self.debugDocument = None
|
||||
self.site = None
|
||||
self.sourceContext = None
|
||||
|
||||
def GetText(self):
|
||||
return self.text
|
||||
|
||||
def GetName(self, dnt):
|
||||
assert 0, "You must subclass this"
|
||||
|
||||
def GetFileName(self):
|
||||
return self.fileName
|
||||
|
||||
def GetPositionOfLine(self, cLineNumber):
|
||||
self.GetText() # Prime us.
|
||||
try:
|
||||
return self.lineOffsets[cLineNumber]
|
||||
except IndexError:
|
||||
raise Exception(scode=winerror.S_FALSE)
|
||||
|
||||
def GetLineOfPosition(self, charPos):
|
||||
self.GetText() # Prime us.
|
||||
lastOffset = 0
|
||||
lineNo = 0
|
||||
for lineOffset in self.lineOffsets[1:]:
|
||||
if lineOffset > charPos:
|
||||
break
|
||||
lastOffset = lineOffset
|
||||
lineNo = lineNo + 1
|
||||
else: # for not broken.
|
||||
# print "Cant find", charPos, "in", self.lineOffsets
|
||||
raise Exception(scode=winerror.S_FALSE)
|
||||
# print "GLOP ret=",lineNo, (charPos-lastOffset)
|
||||
return lineNo, (charPos - lastOffset)
|
||||
|
||||
def GetNextLine(self):
|
||||
if self.nextLineNo >= len(self.lines):
|
||||
self.nextLineNo = 0 # auto-reset.
|
||||
return ""
|
||||
rc = self.lines[self.nextLineNo]
|
||||
self.nextLineNo = self.nextLineNo + 1
|
||||
return rc
|
||||
|
||||
def GetLine(self, num):
|
||||
self.GetText() # Prime us.
|
||||
return self.lines[num]
|
||||
|
||||
def GetNumChars(self):
|
||||
return len(self.GetText())
|
||||
|
||||
def GetNumLines(self):
|
||||
self.GetText() # Prime us.
|
||||
return len(self.lines)
|
||||
|
||||
def _buildline(self, pos):
|
||||
i = self.text.find("\n", pos)
|
||||
if i < 0:
|
||||
newpos = len(self.text)
|
||||
else:
|
||||
newpos = i + 1
|
||||
r = self.text[pos:newpos]
|
||||
return r, newpos
|
||||
|
||||
def _buildlines(self):
|
||||
self.lines = []
|
||||
self.lineOffsets = [0]
|
||||
line, pos = self._buildline(0)
|
||||
while line:
|
||||
self.lines.append(line)
|
||||
self.lineOffsets.append(pos)
|
||||
line, pos = self._buildline(pos)
|
||||
|
||||
def _ProcessToken(self, type, token, spos, epos, line):
|
||||
srow, scol = spos
|
||||
erow, ecol = epos
|
||||
self.GetText() # Prime us.
|
||||
linenum = srow - 1 # Lines zero based for us too.
|
||||
realCharPos = self.lineOffsets[linenum] + scol
|
||||
numskipped = realCharPos - self.lastPos
|
||||
if numskipped == 0:
|
||||
pass
|
||||
elif numskipped == 1:
|
||||
self.attrs.append(axdebug.SOURCETEXT_ATTR_COMMENT)
|
||||
else:
|
||||
self.attrs.append((axdebug.SOURCETEXT_ATTR_COMMENT, numskipped))
|
||||
kwSize = len(token)
|
||||
self.lastPos = realCharPos + kwSize
|
||||
attr = 0
|
||||
|
||||
if type == tokenize.NAME:
|
||||
if token in _keywords:
|
||||
attr = axdebug.SOURCETEXT_ATTR_KEYWORD
|
||||
elif type == tokenize.STRING:
|
||||
attr = axdebug.SOURCETEXT_ATTR_STRING
|
||||
elif type == tokenize.NUMBER:
|
||||
attr = axdebug.SOURCETEXT_ATTR_NUMBER
|
||||
elif type == tokenize.OP:
|
||||
attr = axdebug.SOURCETEXT_ATTR_OPERATOR
|
||||
elif type == tokenize.COMMENT:
|
||||
attr = axdebug.SOURCETEXT_ATTR_COMMENT
|
||||
# else attr remains zero...
|
||||
if kwSize == 0:
|
||||
pass
|
||||
elif kwSize == 1:
|
||||
self.attrs.append(attr)
|
||||
else:
|
||||
self.attrs.append((attr, kwSize))
|
||||
|
||||
def GetSyntaxColorAttributes(self):
|
||||
self.lastPos = 0
|
||||
self.attrs = []
|
||||
try:
|
||||
tokenize.tokenize(self.GetNextLine, self._ProcessToken)
|
||||
except tokenize.TokenError:
|
||||
pass # Ignore - will cause all subsequent text to be commented.
|
||||
numAtEnd = len(self.GetText()) - self.lastPos
|
||||
if numAtEnd:
|
||||
self.attrs.append((axdebug.SOURCETEXT_ATTR_COMMENT, numAtEnd))
|
||||
return self.attrs
|
||||
|
||||
# We also provide and manage DebugDocumentContext objects
|
||||
def _MakeDebugCodeContext(self, lineNo, charPos, len):
|
||||
return _wrap(
|
||||
contexts.DebugCodeContext(lineNo, charPos, len, self, self.site),
|
||||
axdebug.IID_IDebugCodeContext,
|
||||
)
|
||||
|
||||
# Make a context at the given position. It should take up the entire context.
|
||||
def _MakeContextAtPosition(self, charPos):
|
||||
lineNo, offset = self.GetLineOfPosition(charPos)
|
||||
try:
|
||||
endPos = self.GetPositionOfLine(lineNo + 1)
|
||||
except:
|
||||
endPos = charPos
|
||||
codecontext = self._MakeDebugCodeContext(lineNo, charPos, endPos - charPos)
|
||||
return codecontext
|
||||
|
||||
# Returns a DebugCodeContext. debugDocument can be None for smart hosts.
|
||||
def GetCodeContextAtPosition(self, charPos):
|
||||
# trace("GetContextOfPos", charPos, maxChars)
|
||||
# Convert to line number.
|
||||
lineNo, offset = self.GetLineOfPosition(charPos)
|
||||
charPos = self.GetPositionOfLine(lineNo)
|
||||
try:
|
||||
cc = self.codeContexts[charPos]
|
||||
# trace(" GetContextOfPos using existing")
|
||||
except KeyError:
|
||||
cc = self._MakeContextAtPosition(charPos)
|
||||
self.codeContexts[charPos] = cc
|
||||
return cc
|
||||
|
||||
|
||||
class SourceModuleContainer(SourceCodeContainer):
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
if hasattr(module, "__file__"):
|
||||
fname = self.module.__file__
|
||||
# Check for .pyc or .pyo or even .pys!
|
||||
if fname[-1] in ["O", "o", "C", "c", "S", "s"]:
|
||||
fname = fname[:-1]
|
||||
try:
|
||||
fname = win32api.GetFullPathName(fname)
|
||||
except win32api.error:
|
||||
pass
|
||||
else:
|
||||
if module.__name__ == "__main__" and len(sys.argv) > 0:
|
||||
fname = sys.argv[0]
|
||||
else:
|
||||
fname = "<Unknown!>"
|
||||
SourceCodeContainer.__init__(self, None, fname)
|
||||
|
||||
def GetText(self):
|
||||
if self.text is None:
|
||||
fname = self.GetFileName()
|
||||
if fname:
|
||||
try:
|
||||
self.text = open(fname, "r").read()
|
||||
except IOError as details:
|
||||
self.text = "# Exception opening file\n# %s" % (repr(details))
|
||||
else:
|
||||
self.text = "# No file available for module '%s'" % (self.module)
|
||||
self._buildlines()
|
||||
return self.text
|
||||
|
||||
def GetName(self, dnt):
|
||||
name = self.module.__name__
|
||||
try:
|
||||
fname = win32api.GetFullPathName(self.module.__file__)
|
||||
except win32api.error:
|
||||
fname = self.module.__file__
|
||||
except AttributeError:
|
||||
fname = name
|
||||
if dnt == axdebug.DOCUMENTNAMETYPE_APPNODE:
|
||||
return name.split(".")[-1]
|
||||
elif dnt == axdebug.DOCUMENTNAMETYPE_TITLE:
|
||||
return fname
|
||||
elif dnt == axdebug.DOCUMENTNAMETYPE_FILE_TAIL:
|
||||
return os.path.split(fname)[1]
|
||||
elif dnt == axdebug.DOCUMENTNAMETYPE_URL:
|
||||
return "file:%s" % fname
|
||||
else:
|
||||
raise Exception(scode=winerror.E_UNEXPECTED)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
sys.path.append(".")
|
||||
import ttest
|
||||
|
||||
sc = SourceModuleContainer(ttest)
|
||||
# sc = SourceCodeContainer(open(sys.argv[1], "rb").read(), sys.argv[1])
|
||||
attrs = sc.GetSyntaxColorAttributes()
|
||||
attrlen = 0
|
||||
for attr in attrs:
|
||||
if type(attr) == type(()):
|
||||
attrlen = attrlen + attr[1]
|
||||
else:
|
||||
attrlen = attrlen + 1
|
||||
text = sc.GetText()
|
||||
if attrlen != len(text):
|
||||
print("Lengths dont match!!! (%d/%d)" % (attrlen, len(text)))
|
||||
|
||||
# print "Attributes:"
|
||||
# print attrs
|
||||
print("GetLineOfPos=", sc.GetLineOfPosition(0))
|
||||
print("GetLineOfPos=", sc.GetLineOfPosition(4))
|
||||
print("GetLineOfPos=", sc.GetLineOfPosition(10))
|
61
.venv/Lib/site-packages/win32comext/axdebug/contexts.py
Normal file
61
.venv/Lib/site-packages/win32comext/axdebug/contexts.py
Normal file
@ -0,0 +1,61 @@
|
||||
""" A module for managing the AXDebug I*Contexts
|
||||
|
||||
"""
|
||||
import gateways, axdebug
|
||||
import pythoncom, win32com.server.util
|
||||
|
||||
# Utility function for wrapping object created by this module.
|
||||
from .util import _wrap, _wrap_remove, trace
|
||||
from . import adb
|
||||
|
||||
|
||||
class DebugCodeContext(gateways.DebugCodeContext, gateways.DebugDocumentContext):
|
||||
# NOTE: We also implement the IDebugDocumentContext interface for Simple Hosts.
|
||||
# Thus, debugDocument may be NULL when we have smart hosts - but in that case, we
|
||||
# wont be called upon to provide it.
|
||||
_public_methods_ = (
|
||||
gateways.DebugCodeContext._public_methods_
|
||||
+ gateways.DebugDocumentContext._public_methods_
|
||||
)
|
||||
_com_interfaces_ = (
|
||||
gateways.DebugCodeContext._com_interfaces_
|
||||
+ gateways.DebugDocumentContext._com_interfaces_
|
||||
)
|
||||
|
||||
def __init__(self, lineNo, charPos, len, codeContainer, debugSite):
|
||||
self.debugSite = debugSite
|
||||
self.offset = charPos
|
||||
self.length = len
|
||||
self.breakPointState = 0
|
||||
self.lineno = lineNo
|
||||
gateways.DebugCodeContext.__init__(self)
|
||||
self.codeContainer = codeContainer
|
||||
|
||||
def _Close(self):
|
||||
self.debugSite = None
|
||||
|
||||
def GetDocumentContext(self):
|
||||
if self.debugSite is not None:
|
||||
# We have a smart host - let him give it to us.
|
||||
return self.debugSite.GetDocumentContextFromPosition(
|
||||
self.codeContainer.sourceContext, self.offset, self.length
|
||||
)
|
||||
else:
|
||||
# Simple host - Fine - Ill do it myself!
|
||||
return _wrap(self, axdebug.IID_IDebugDocumentContext)
|
||||
|
||||
def SetBreakPoint(self, bps):
|
||||
self.breakPointState = bps
|
||||
adb.OnSetBreakPoint(self, bps, self.lineno)
|
||||
|
||||
# The DebugDocumentContext methods for simple hosts.
|
||||
def GetDocument(self):
|
||||
return self.codeContainer.debugDocument
|
||||
|
||||
def EnumCodeContexts(self):
|
||||
return _wrap(EnumDebugCodeContexts([self]), axdebug.IID_IEnumDebugCodeContexts)
|
||||
|
||||
|
||||
class EnumDebugCodeContexts(gateways.EnumDebugCodeContexts):
|
||||
def _wrap(self, obj):
|
||||
return _wrap(obj, axdebug.IID_IDebugCodeContext)
|
250
.venv/Lib/site-packages/win32comext/axdebug/debugger.py
Normal file
250
.venv/Lib/site-packages/win32comext/axdebug/debugger.py
Normal file
@ -0,0 +1,250 @@
|
||||
import sys, traceback, string
|
||||
|
||||
from win32com.axscript import axscript
|
||||
from win32com.axdebug import (
|
||||
codecontainer,
|
||||
axdebug,
|
||||
gateways,
|
||||
documents,
|
||||
contexts,
|
||||
adb,
|
||||
expressions,
|
||||
)
|
||||
from win32com.axdebug.util import trace, _wrap, _wrap_remove
|
||||
|
||||
import pythoncom
|
||||
import win32api, winerror
|
||||
import os
|
||||
|
||||
currentDebugger = None
|
||||
|
||||
|
||||
class ModuleTreeNode:
|
||||
"""Helper class for building a module tree"""
|
||||
|
||||
def __init__(self, module):
|
||||
modName = module.__name__
|
||||
self.moduleName = modName
|
||||
self.module = module
|
||||
self.realNode = None
|
||||
self.cont = codecontainer.SourceModuleContainer(module)
|
||||
|
||||
def __repr__(self):
|
||||
return "<ModuleTreeNode wrapping %s>" % (self.module)
|
||||
|
||||
def Attach(self, parentRealNode):
|
||||
self.realNode.Attach(parentRealNode)
|
||||
|
||||
def Close(self):
|
||||
self.module = None
|
||||
self.cont = None
|
||||
self.realNode = None
|
||||
|
||||
|
||||
def BuildModule(module, built_nodes, rootNode, create_node_fn, create_node_args):
|
||||
if module:
|
||||
keep = module.__name__
|
||||
keep = keep and (built_nodes.get(module) is None)
|
||||
if keep and hasattr(module, "__file__"):
|
||||
keep = string.lower(os.path.splitext(module.__file__)[1]) not in [
|
||||
".pyd",
|
||||
".dll",
|
||||
]
|
||||
# keep = keep and module.__name__=='__main__'
|
||||
if module and keep:
|
||||
# print "keeping", module.__name__
|
||||
node = ModuleTreeNode(module)
|
||||
built_nodes[module] = node
|
||||
realNode = create_node_fn(*(node,) + create_node_args)
|
||||
node.realNode = realNode
|
||||
|
||||
# Split into parent nodes.
|
||||
parts = string.split(module.__name__, ".")
|
||||
if parts[-1][:8] == "__init__":
|
||||
parts = parts[:-1]
|
||||
parent = string.join(parts[:-1], ".")
|
||||
parentNode = rootNode
|
||||
if parent:
|
||||
parentModule = sys.modules[parent]
|
||||
BuildModule(
|
||||
parentModule, built_nodes, rootNode, create_node_fn, create_node_args
|
||||
)
|
||||
if parentModule in built_nodes:
|
||||
parentNode = built_nodes[parentModule].realNode
|
||||
node.Attach(parentNode)
|
||||
|
||||
|
||||
def RefreshAllModules(builtItems, rootNode, create_node, create_node_args):
|
||||
for module in list(sys.modules.values()):
|
||||
BuildModule(module, builtItems, rootNode, create_node, create_node_args)
|
||||
|
||||
|
||||
# realNode = pdm.CreateDebugDocumentHelper(None) # DebugDocumentHelper node?
|
||||
# app.CreateApplicationNode() # doc provider node.
|
||||
|
||||
|
||||
class CodeContainerProvider(documents.CodeContainerProvider):
|
||||
def __init__(self, axdebugger):
|
||||
self.axdebugger = axdebugger
|
||||
documents.CodeContainerProvider.__init__(self)
|
||||
self.currentNumModules = len(sys.modules)
|
||||
self.nodes = {}
|
||||
self.axdebugger.RefreshAllModules(self.nodes, self)
|
||||
|
||||
def FromFileName(self, fname):
|
||||
### It appears we cant add modules during a debug session!
|
||||
# if self.currentNumModules != len(sys.modules):
|
||||
# self.axdebugger.RefreshAllModules(self.nodes, self)
|
||||
# self.currentNumModules = len(sys.modules)
|
||||
# for key in self.ccsAndNodes.keys():
|
||||
# print "File:", key
|
||||
return documents.CodeContainerProvider.FromFileName(self, fname)
|
||||
|
||||
def Close(self):
|
||||
documents.CodeContainerProvider.Close(self)
|
||||
self.axdebugger = None
|
||||
print("Closing %d nodes" % (len(self.nodes)))
|
||||
for node in self.nodes.values():
|
||||
node.Close()
|
||||
self.nodes = {}
|
||||
|
||||
|
||||
class OriginalInterfaceMaker:
|
||||
def MakeInterfaces(self, pdm):
|
||||
app = self.pdm.CreateApplication()
|
||||
self.cookie = pdm.AddApplication(app)
|
||||
root = app.GetRootNode()
|
||||
return app, root
|
||||
|
||||
def CloseInterfaces(self, pdm):
|
||||
pdm.RemoveApplication(self.cookie)
|
||||
|
||||
|
||||
class SimpleHostStyleInterfaceMaker:
|
||||
def MakeInterfaces(self, pdm):
|
||||
app = pdm.GetDefaultApplication()
|
||||
root = app.GetRootNode()
|
||||
return app, root
|
||||
|
||||
def CloseInterfaces(self, pdm):
|
||||
pass
|
||||
|
||||
|
||||
class AXDebugger:
|
||||
def __init__(self, interfaceMaker=None, processName=None):
|
||||
if processName is None:
|
||||
processName = "Python Process"
|
||||
if interfaceMaker is None:
|
||||
interfaceMaker = SimpleHostStyleInterfaceMaker()
|
||||
|
||||
self.pydebugger = adb.Debugger()
|
||||
|
||||
self.pdm = pythoncom.CoCreateInstance(
|
||||
axdebug.CLSID_ProcessDebugManager,
|
||||
None,
|
||||
pythoncom.CLSCTX_ALL,
|
||||
axdebug.IID_IProcessDebugManager,
|
||||
)
|
||||
|
||||
self.app, self.root = interfaceMaker.MakeInterfaces(self.pdm)
|
||||
self.app.SetName(processName)
|
||||
self.interfaceMaker = interfaceMaker
|
||||
|
||||
expressionProvider = _wrap(
|
||||
expressions.ProvideExpressionContexts(),
|
||||
axdebug.IID_IProvideExpressionContexts,
|
||||
)
|
||||
self.expressionCookie = self.app.AddGlobalExpressionContextProvider(
|
||||
expressionProvider
|
||||
)
|
||||
|
||||
contProvider = CodeContainerProvider(self)
|
||||
self.pydebugger.AttachApp(self.app, contProvider)
|
||||
|
||||
def Break(self):
|
||||
# Get the frame we start debugging from - this is the frame 1 level up
|
||||
try:
|
||||
1 + ""
|
||||
except:
|
||||
frame = sys.exc_info()[2].tb_frame.f_back
|
||||
|
||||
# Get/create the debugger, and tell it to break.
|
||||
self.app.StartDebugSession()
|
||||
# self.app.CauseBreak()
|
||||
|
||||
self.pydebugger.SetupAXDebugging(None, frame)
|
||||
self.pydebugger.set_trace()
|
||||
|
||||
def Close(self):
|
||||
self.pydebugger.ResetAXDebugging()
|
||||
self.interfaceMaker.CloseInterfaces(self.pdm)
|
||||
self.pydebugger.CloseApp()
|
||||
self.app.RemoveGlobalExpressionContextProvider(self.expressionCookie)
|
||||
self.expressionCookie = None
|
||||
|
||||
self.pdm = None
|
||||
self.app = None
|
||||
self.pydebugger = None
|
||||
self.root = None
|
||||
|
||||
def RefreshAllModules(self, nodes, containerProvider):
|
||||
RefreshAllModules(
|
||||
nodes, self.root, self.CreateApplicationNode, (containerProvider,)
|
||||
)
|
||||
|
||||
def CreateApplicationNode(self, node, containerProvider):
|
||||
realNode = self.app.CreateApplicationNode()
|
||||
|
||||
document = documents.DebugDocumentText(node.cont)
|
||||
document = _wrap(document, axdebug.IID_IDebugDocument)
|
||||
|
||||
node.cont.debugDocument = document
|
||||
|
||||
provider = documents.DebugDocumentProvider(document)
|
||||
provider = _wrap(provider, axdebug.IID_IDebugDocumentProvider)
|
||||
realNode.SetDocumentProvider(provider)
|
||||
|
||||
containerProvider.AddCodeContainer(node.cont, realNode)
|
||||
return realNode
|
||||
|
||||
|
||||
def _GetCurrentDebugger():
|
||||
global currentDebugger
|
||||
if currentDebugger is None:
|
||||
currentDebugger = AXDebugger()
|
||||
return currentDebugger
|
||||
|
||||
|
||||
def Break():
|
||||
_GetCurrentDebugger().Break()
|
||||
|
||||
|
||||
brk = Break
|
||||
set_trace = Break
|
||||
|
||||
|
||||
def dosomethingelse():
|
||||
a = 2
|
||||
b = "Hi there"
|
||||
|
||||
|
||||
def dosomething():
|
||||
a = 1
|
||||
b = 2
|
||||
dosomethingelse()
|
||||
|
||||
|
||||
def test():
|
||||
Break()
|
||||
input("Waiting...")
|
||||
dosomething()
|
||||
print("Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("About to test the debugging interfaces!")
|
||||
test()
|
||||
print(
|
||||
" %d/%d com objects still alive"
|
||||
% (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
|
||||
)
|
139
.venv/Lib/site-packages/win32comext/axdebug/documents.py
Normal file
139
.venv/Lib/site-packages/win32comext/axdebug/documents.py
Normal file
@ -0,0 +1,139 @@
|
||||
""" Management of documents for AXDebugging.
|
||||
"""
|
||||
|
||||
import axdebug, gateways
|
||||
import pythoncom
|
||||
from .util import _wrap, _wrap_remove, RaiseNotImpl, trace
|
||||
from win32com.server.util import unwrap
|
||||
from . import codecontainer
|
||||
from . import contexts
|
||||
from win32com.server.exception import Exception
|
||||
import win32api, winerror, os, string, sys
|
||||
|
||||
# def trace(*args):
|
||||
# pass
|
||||
|
||||
|
||||
def GetGoodFileName(fname):
|
||||
if fname[0] != "<":
|
||||
return win32api.GetFullPathName(fname)
|
||||
return fname
|
||||
|
||||
|
||||
class DebugDocumentProvider(gateways.DebugDocumentProvider):
|
||||
def __init__(self, doc):
|
||||
self.doc = doc
|
||||
|
||||
def GetName(self, dnt):
|
||||
return self.doc.GetName(dnt)
|
||||
|
||||
def GetDocumentClassId(self):
|
||||
return self.doc.GetDocumentClassId()
|
||||
|
||||
def GetDocument(self):
|
||||
return self.doc
|
||||
|
||||
|
||||
class DebugDocumentText(
|
||||
gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument
|
||||
):
|
||||
_com_interfaces_ = (
|
||||
gateways.DebugDocumentInfo._com_interfaces_
|
||||
+ gateways.DebugDocumentText._com_interfaces_
|
||||
+ gateways.DebugDocument._com_interfaces_
|
||||
)
|
||||
_public_methods_ = (
|
||||
gateways.DebugDocumentInfo._public_methods_
|
||||
+ gateways.DebugDocumentText._public_methods_
|
||||
+ gateways.DebugDocument._public_methods_
|
||||
)
|
||||
# A class which implements a DebugDocumentText, using the functionality
|
||||
# provided by a codeContainer
|
||||
def __init__(self, codeContainer):
|
||||
gateways.DebugDocumentText.__init__(self)
|
||||
gateways.DebugDocumentInfo.__init__(self)
|
||||
gateways.DebugDocument.__init__(self)
|
||||
self.codeContainer = codeContainer
|
||||
|
||||
def _Close(self):
|
||||
self.docContexts = None
|
||||
# self.codeContainer._Close()
|
||||
self.codeContainer = None
|
||||
|
||||
# IDebugDocumentInfo
|
||||
def GetName(self, dnt):
|
||||
return self.codeContainer.GetName(dnt)
|
||||
|
||||
def GetDocumentClassId(self):
|
||||
return "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
|
||||
|
||||
# IDebugDocument has no methods!
|
||||
#
|
||||
|
||||
# IDebugDocumentText methods.
|
||||
# def GetDocumentAttributes
|
||||
def GetSize(self):
|
||||
# trace("GetSize")
|
||||
return self.codeContainer.GetNumLines(), self.codeContainer.GetNumChars()
|
||||
|
||||
def GetPositionOfLine(self, cLineNumber):
|
||||
return self.codeContainer.GetPositionOfLine(cLineNumber)
|
||||
|
||||
def GetLineOfPosition(self, charPos):
|
||||
return self.codeContainer.GetLineOfPosition(charPos)
|
||||
|
||||
def GetText(self, charPos, maxChars, wantAttr):
|
||||
# Get all the attributes, else the tokenizer will get upset.
|
||||
# XXX - not yet!
|
||||
# trace("GetText", charPos, maxChars, wantAttr)
|
||||
cont = self.codeContainer
|
||||
attr = cont.GetSyntaxColorAttributes()
|
||||
return cont.GetText(), attr
|
||||
|
||||
def GetPositionOfContext(self, context):
|
||||
trace("GetPositionOfContext", context)
|
||||
context = unwrap(context)
|
||||
return context.offset, context.length
|
||||
|
||||
# Return a DebugDocumentContext.
|
||||
def GetContextOfPosition(self, charPos, maxChars):
|
||||
# Make one
|
||||
doc = _wrap(self, axdebug.IID_IDebugDocument)
|
||||
rc = self.codeContainer.GetCodeContextAtPosition(charPos)
|
||||
return rc.QueryInterface(axdebug.IID_IDebugDocumentContext)
|
||||
|
||||
|
||||
class CodeContainerProvider:
|
||||
"""An abstract Python class which provides code containers!
|
||||
|
||||
Given a Python file name (as the debugger knows it by) this will
|
||||
return a CodeContainer interface suitable for use.
|
||||
|
||||
This provides a simple base imlpementation that simply supports
|
||||
a dictionary of nodes and providers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.ccsAndNodes = {}
|
||||
|
||||
def AddCodeContainer(self, cc, node=None):
|
||||
fname = GetGoodFileName(cc.fileName)
|
||||
self.ccsAndNodes[fname] = cc, node
|
||||
|
||||
def FromFileName(self, fname):
|
||||
cc, node = self.ccsAndNodes.get(GetGoodFileName(fname), (None, None))
|
||||
# if cc is None:
|
||||
# print "FromFileName for %s returning None" % fname
|
||||
return cc
|
||||
|
||||
def Close(self):
|
||||
for cc, node in self.ccsAndNodes.values():
|
||||
try:
|
||||
# Must close the node before closing the provider
|
||||
# as node may make calls on provider (eg Reset breakpoints etc)
|
||||
if node is not None:
|
||||
node.Close()
|
||||
cc._Close()
|
||||
except pythoncom.com_error:
|
||||
pass
|
||||
self.ccsAndNodes = {}
|
61
.venv/Lib/site-packages/win32comext/axdebug/dump.py
Normal file
61
.venv/Lib/site-packages/win32comext/axdebug/dump.py
Normal file
@ -0,0 +1,61 @@
|
||||
import sys, string
|
||||
import traceback
|
||||
from win32com.axdebug import axdebug
|
||||
from win32com.client.util import Enumerator
|
||||
import pythoncom
|
||||
|
||||
|
||||
def DumpDebugApplicationNode(node, level=0):
|
||||
# Recursive dump of a DebugApplicationNode
|
||||
spacer = " " * level
|
||||
for desc, attr in [
|
||||
("Node Name", axdebug.DOCUMENTNAMETYPE_APPNODE),
|
||||
("Title", axdebug.DOCUMENTNAMETYPE_TITLE),
|
||||
("Filename", axdebug.DOCUMENTNAMETYPE_FILE_TAIL),
|
||||
("URL", axdebug.DOCUMENTNAMETYPE_URL),
|
||||
]:
|
||||
try:
|
||||
info = node.GetName(attr)
|
||||
except pythoncom.com_error:
|
||||
info = "<N/A>"
|
||||
print("%s%s: %s" % (spacer, desc, info))
|
||||
try:
|
||||
doc = node.GetDocument()
|
||||
except pythoncom.com_error:
|
||||
doc = None
|
||||
if doc:
|
||||
doctext = doc.QueryInterface(axdebug.IID_IDebugDocumentText)
|
||||
numLines, numChars = doctext.GetSize()
|
||||
# text, attr = doctext.GetText(0, 20, 1)
|
||||
text, attr = doctext.GetText(0, numChars, 1)
|
||||
print(
|
||||
"%sText is %s, %d bytes long" % (spacer, repr(text[:40] + "..."), len(text))
|
||||
)
|
||||
else:
|
||||
print("%s%s" % (spacer, "<No document available>"))
|
||||
|
||||
for child in Enumerator(node.EnumChildren()):
|
||||
DumpDebugApplicationNode(child, level + 1)
|
||||
|
||||
|
||||
def dumpall():
|
||||
dm = pythoncom.CoCreateInstance(
|
||||
axdebug.CLSID_MachineDebugManager,
|
||||
None,
|
||||
pythoncom.CLSCTX_ALL,
|
||||
axdebug.IID_IMachineDebugManager,
|
||||
)
|
||||
e = Enumerator(dm.EnumApplications())
|
||||
for app in e:
|
||||
print("Application: %s" % app.GetName())
|
||||
node = (
|
||||
app.GetRootNode()
|
||||
) # of type PyIDebugApplicationNode->PyIDebugDocumentProvider->PyIDebugDocumentInfo
|
||||
DumpDebugApplicationNode(node)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
dumpall()
|
||||
except:
|
||||
traceback.print_exc()
|
210
.venv/Lib/site-packages/win32comext/axdebug/expressions.py
Normal file
210
.venv/Lib/site-packages/win32comext/axdebug/expressions.py
Normal file
@ -0,0 +1,210 @@
|
||||
import axdebug, gateways
|
||||
from .util import _wrap, _wrap_remove, RaiseNotImpl
|
||||
import io, traceback
|
||||
from pprint import pprint
|
||||
from win32com.server.exception import COMException
|
||||
import winerror
|
||||
import string
|
||||
import sys
|
||||
|
||||
# Given an object, return a nice string
|
||||
def MakeNiceString(ob):
|
||||
stream = io.StringIO()
|
||||
pprint(ob, stream)
|
||||
return string.strip(stream.getvalue())
|
||||
|
||||
|
||||
class ProvideExpressionContexts(gateways.ProvideExpressionContexts):
|
||||
pass
|
||||
|
||||
|
||||
class ExpressionContext(gateways.DebugExpressionContext):
|
||||
def __init__(self, frame):
|
||||
self.frame = frame
|
||||
|
||||
def ParseLanguageText(self, code, radix, delim, flags):
|
||||
return _wrap(
|
||||
Expression(self.frame, code, radix, delim, flags),
|
||||
axdebug.IID_IDebugExpression,
|
||||
)
|
||||
|
||||
def GetLanguageInfo(self):
|
||||
# print "GetLanguageInfo"
|
||||
return "Python", "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
|
||||
|
||||
|
||||
class Expression(gateways.DebugExpression):
|
||||
def __init__(self, frame, code, radix, delim, flags):
|
||||
self.callback = None
|
||||
self.frame = frame
|
||||
self.code = code
|
||||
self.radix = radix
|
||||
self.delim = delim
|
||||
self.flags = flags
|
||||
self.isComplete = 0
|
||||
self.result = None
|
||||
self.hresult = winerror.E_UNEXPECTED
|
||||
|
||||
def Start(self, callback):
|
||||
try:
|
||||
try:
|
||||
try:
|
||||
self.result = eval(
|
||||
self.code, self.frame.f_globals, self.frame.f_locals
|
||||
)
|
||||
except SyntaxError:
|
||||
exec(self.code, self.frame.f_globals, self.frame.f_locals)
|
||||
self.result = ""
|
||||
self.hresult = 0
|
||||
except:
|
||||
l = traceback.format_exception_only(
|
||||
sys.exc_info()[0], sys.exc_info()[1]
|
||||
)
|
||||
# l is a list of strings with trailing "\n"
|
||||
self.result = string.join(map(lambda s: s[:-1], l), "\n")
|
||||
self.hresult = winerror.E_FAIL
|
||||
finally:
|
||||
self.isComplete = 1
|
||||
callback.onComplete()
|
||||
|
||||
def Abort(self):
|
||||
print("** ABORT **")
|
||||
|
||||
def QueryIsComplete(self):
|
||||
return self.isComplete
|
||||
|
||||
def GetResultAsString(self):
|
||||
# print "GetStrAsResult returning", self.result
|
||||
return self.hresult, MakeNiceString(self.result)
|
||||
|
||||
def GetResultAsDebugProperty(self):
|
||||
result = _wrap(
|
||||
DebugProperty(self.code, self.result, None, self.hresult),
|
||||
axdebug.IID_IDebugProperty,
|
||||
)
|
||||
return self.hresult, result
|
||||
|
||||
|
||||
def MakeEnumDebugProperty(object, dwFieldSpec, nRadix, iid, stackFrame=None):
|
||||
name_vals = []
|
||||
if hasattr(object, "items") and hasattr(object, "keys"): # If it is a dict.
|
||||
name_vals = iter(object.items())
|
||||
dictionary = object
|
||||
elif hasattr(object, "__dict__"): # object with dictionary, module
|
||||
name_vals = iter(object.__dict__.items())
|
||||
dictionary = object.__dict__
|
||||
infos = []
|
||||
for name, val in name_vals:
|
||||
infos.append(
|
||||
GetPropertyInfo(name, val, dwFieldSpec, nRadix, 0, dictionary, stackFrame)
|
||||
)
|
||||
return _wrap(EnumDebugPropertyInfo(infos), axdebug.IID_IEnumDebugPropertyInfo)
|
||||
|
||||
|
||||
def GetPropertyInfo(
|
||||
obname, obvalue, dwFieldSpec, nRadix, hresult=0, dictionary=None, stackFrame=None
|
||||
):
|
||||
# returns a tuple
|
||||
name = typ = value = fullname = attrib = dbgprop = None
|
||||
if dwFieldSpec & axdebug.DBGPROP_INFO_VALUE:
|
||||
value = MakeNiceString(obvalue)
|
||||
if dwFieldSpec & axdebug.DBGPROP_INFO_NAME:
|
||||
name = obname
|
||||
if dwFieldSpec & axdebug.DBGPROP_INFO_TYPE:
|
||||
if hresult:
|
||||
typ = "Error"
|
||||
else:
|
||||
try:
|
||||
typ = type(obvalue).__name__
|
||||
except AttributeError:
|
||||
typ = str(type(obvalue))
|
||||
if dwFieldSpec & axdebug.DBGPROP_INFO_FULLNAME:
|
||||
fullname = obname
|
||||
if dwFieldSpec & axdebug.DBGPROP_INFO_ATTRIBUTES:
|
||||
if hasattr(obvalue, "has_key") or hasattr(
|
||||
obvalue, "__dict__"
|
||||
): # If it is a dict or object
|
||||
attrib = axdebug.DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE
|
||||
else:
|
||||
attrib = 0
|
||||
if dwFieldSpec & axdebug.DBGPROP_INFO_DEBUGPROP:
|
||||
dbgprop = _wrap(
|
||||
DebugProperty(name, obvalue, None, hresult, dictionary, stackFrame),
|
||||
axdebug.IID_IDebugProperty,
|
||||
)
|
||||
return name, typ, value, fullname, attrib, dbgprop
|
||||
|
||||
|
||||
from win32com.server.util import ListEnumeratorGateway
|
||||
|
||||
|
||||
class EnumDebugPropertyInfo(ListEnumeratorGateway):
|
||||
"""A class to expose a Python sequence as an EnumDebugCodeContexts
|
||||
|
||||
Create an instance of this class passing a sequence (list, tuple, or
|
||||
any sequence protocol supporting object) and it will automatically
|
||||
support the EnumDebugCodeContexts interface for the object.
|
||||
|
||||
"""
|
||||
|
||||
_public_methods_ = ListEnumeratorGateway._public_methods_ + ["GetCount"]
|
||||
_com_interfaces_ = [axdebug.IID_IEnumDebugPropertyInfo]
|
||||
|
||||
def GetCount(self):
|
||||
return len(self._list_)
|
||||
|
||||
def _wrap(self, ob):
|
||||
return ob
|
||||
|
||||
|
||||
class DebugProperty:
|
||||
_com_interfaces_ = [axdebug.IID_IDebugProperty]
|
||||
_public_methods_ = [
|
||||
"GetPropertyInfo",
|
||||
"GetExtendedInfo",
|
||||
"SetValueAsString",
|
||||
"EnumMembers",
|
||||
"GetParent",
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self, name, value, parent=None, hresult=0, dictionary=None, stackFrame=None
|
||||
):
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.parent = parent
|
||||
self.hresult = hresult
|
||||
self.dictionary = dictionary
|
||||
self.stackFrame = stackFrame
|
||||
|
||||
def GetPropertyInfo(self, dwFieldSpec, nRadix):
|
||||
return GetPropertyInfo(
|
||||
self.name,
|
||||
self.value,
|
||||
dwFieldSpec,
|
||||
nRadix,
|
||||
self.hresult,
|
||||
dictionary,
|
||||
stackFrame,
|
||||
)
|
||||
|
||||
def GetExtendedInfo(self): ### Note - not in the framework.
|
||||
RaiseNotImpl("DebugProperty::GetExtendedInfo")
|
||||
|
||||
def SetValueAsString(self, value, radix):
|
||||
if self.stackFrame and self.dictionary:
|
||||
self.dictionary[self.name] = eval(
|
||||
value, self.stackFrame.f_globals, self.stackFrame.f_locals
|
||||
)
|
||||
else:
|
||||
RaiseNotImpl("DebugProperty::SetValueAsString")
|
||||
|
||||
def EnumMembers(self, dwFieldSpec, nRadix, iid):
|
||||
# Returns IEnumDebugPropertyInfo
|
||||
return MakeEnumDebugProperty(
|
||||
self.value, dwFieldSpec, nRadix, iid, self.stackFrame
|
||||
)
|
||||
|
||||
def GetParent(self):
|
||||
# return IDebugProperty
|
||||
RaiseNotImpl("DebugProperty::GetParent")
|
582
.venv/Lib/site-packages/win32comext/axdebug/gateways.py
Normal file
582
.venv/Lib/site-packages/win32comext/axdebug/gateways.py
Normal file
@ -0,0 +1,582 @@
|
||||
# Classes which describe interfaces.
|
||||
|
||||
from win32com.server.exception import Exception
|
||||
from win32com.server.util import ListEnumeratorGateway
|
||||
from win32com.axdebug import axdebug
|
||||
from win32com.axdebug.util import RaiseNotImpl, _wrap
|
||||
import pythoncom
|
||||
import win32com.server.connect
|
||||
import winerror
|
||||
|
||||
|
||||
class EnumDebugCodeContexts(ListEnumeratorGateway):
|
||||
"""A class to expose a Python sequence as an EnumDebugCodeContexts
|
||||
|
||||
Create an instance of this class passing a sequence (list, tuple, or
|
||||
any sequence protocol supporting object) and it will automatically
|
||||
support the EnumDebugCodeContexts interface for the object.
|
||||
|
||||
"""
|
||||
|
||||
_com_interfaces_ = [axdebug.IID_IEnumDebugCodeContexts]
|
||||
|
||||
|
||||
class EnumDebugStackFrames(ListEnumeratorGateway):
|
||||
"""A class to expose a Python sequence as an EnumDebugStackFrames
|
||||
|
||||
Create an instance of this class passing a sequence (list, tuple, or
|
||||
any sequence protocol supporting object) and it will automatically
|
||||
support the EnumDebugStackFrames interface for the object.
|
||||
|
||||
"""
|
||||
|
||||
_com_interfaces_ = [axdebug.IID_IEnumDebugStackFrames]
|
||||
|
||||
|
||||
class EnumDebugApplicationNodes(ListEnumeratorGateway):
|
||||
"""A class to expose a Python sequence as an EnumDebugStackFrames
|
||||
|
||||
Create an instance of this class passing a sequence (list, tuple, or
|
||||
any sequence protocol supporting object) and it will automatically
|
||||
support the EnumDebugApplicationNodes interface for the object.
|
||||
|
||||
"""
|
||||
|
||||
_com_interfaces_ = [axdebug.IID_IEnumDebugApplicationNodes]
|
||||
|
||||
|
||||
class EnumRemoteDebugApplications(ListEnumeratorGateway):
|
||||
_com_interfaces_ = [axdebug.IID_IEnumRemoteDebugApplications]
|
||||
|
||||
|
||||
class EnumRemoteDebugApplicationThreads(ListEnumeratorGateway):
|
||||
_com_interfaces_ = [axdebug.IID_IEnumRemoteDebugApplicationThreads]
|
||||
|
||||
|
||||
class DebugDocumentInfo:
|
||||
_public_methods_ = ["GetName", "GetDocumentClassId"]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocumentInfo]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetName(self, dnt):
|
||||
"""Get the one of the name of the document
|
||||
dnt -- int DOCUMENTNAMETYPE
|
||||
"""
|
||||
RaiseNotImpl("GetName")
|
||||
|
||||
def GetDocumentClassId(self):
|
||||
"""
|
||||
Result must be an IID object (or string representing one).
|
||||
"""
|
||||
RaiseNotImpl("GetDocumentClassId")
|
||||
|
||||
|
||||
class DebugDocumentProvider(DebugDocumentInfo):
|
||||
_public_methods_ = DebugDocumentInfo._public_methods_ + ["GetDocument"]
|
||||
_com_interfaces_ = DebugDocumentInfo._com_interfaces_ + [
|
||||
axdebug.IID_IDebugDocumentProvider
|
||||
]
|
||||
|
||||
def GetDocument(self):
|
||||
RaiseNotImpl("GetDocument")
|
||||
|
||||
|
||||
class DebugApplicationNode(DebugDocumentProvider):
|
||||
"""Provides the functionality of IDebugDocumentProvider, plus a context within a project tree."""
|
||||
|
||||
_public_methods_ = (
|
||||
"""EnumChildren GetParent SetDocumentProvider
|
||||
Close Attach Detach""".split()
|
||||
+ DebugDocumentProvider._public_methods_
|
||||
)
|
||||
_com_interfaces_ = [
|
||||
axdebug.IID_IDebugDocumentProvider
|
||||
] + DebugDocumentProvider._com_interfaces_
|
||||
|
||||
def __init__(self):
|
||||
DebugDocumentProvider.__init__(self)
|
||||
|
||||
def EnumChildren(self):
|
||||
# Result is type PyIEnumDebugApplicationNodes
|
||||
RaiseNotImpl("EnumChildren")
|
||||
|
||||
def GetParent(self):
|
||||
# result is type PyIDebugApplicationNode
|
||||
RaiseNotImpl("GetParent")
|
||||
|
||||
def SetDocumentProvider(self, pddp): # PyIDebugDocumentProvider pddp
|
||||
# void result.
|
||||
RaiseNotImpl("SetDocumentProvider")
|
||||
|
||||
def Close(self):
|
||||
# void result.
|
||||
RaiseNotImpl("Close")
|
||||
|
||||
def Attach(self, parent): # PyIDebugApplicationNode
|
||||
# void result.
|
||||
RaiseNotImpl("Attach")
|
||||
|
||||
def Detach(self):
|
||||
# void result.
|
||||
RaiseNotImpl("Detach")
|
||||
|
||||
|
||||
class DebugApplicationNodeEvents:
|
||||
"""Event interface for DebugApplicationNode object."""
|
||||
|
||||
_public_methods_ = "onAddChild onRemoveChild onDetach".split()
|
||||
_com_interfaces_ = [axdebug.IID_IDebugApplicationNodeEvents]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def onAddChild(self, child): # PyIDebugApplicationNode
|
||||
# void result.
|
||||
RaiseNotImpl("onAddChild")
|
||||
|
||||
def onRemoveChild(self, child): # PyIDebugApplicationNode
|
||||
# void result.
|
||||
RaiseNotImpl("onRemoveChild")
|
||||
|
||||
def onDetach(self):
|
||||
# void result.
|
||||
RaiseNotImpl("onDetach")
|
||||
|
||||
def onAttach(self, parent): # PyIDebugApplicationNode
|
||||
# void result.
|
||||
RaiseNotImpl("onAttach")
|
||||
|
||||
|
||||
class DebugDocument(DebugDocumentInfo):
|
||||
"""The base interface to all debug documents."""
|
||||
|
||||
_public_methods_ = DebugDocumentInfo._public_methods_
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocument] + DebugDocumentInfo._com_interfaces_
|
||||
|
||||
|
||||
class DebugDocumentText(DebugDocument):
|
||||
"""The interface to a text only debug document."""
|
||||
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocumentText] + DebugDocument._com_interfaces_
|
||||
_public_methods_ = [
|
||||
"GetDocumentAttributes",
|
||||
"GetSize",
|
||||
"GetPositionOfLine",
|
||||
"GetLineOfPosition",
|
||||
"GetText",
|
||||
"GetPositionOfContext",
|
||||
"GetContextOfPosition",
|
||||
] + DebugDocument._public_methods_
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
# IDebugDocumentText
|
||||
def GetDocumentAttributes(self):
|
||||
# Result is int (TEXT_DOC_ATTR)
|
||||
RaiseNotImpl("GetDocumentAttributes")
|
||||
|
||||
def GetSize(self):
|
||||
# Result is (numLines, numChars)
|
||||
RaiseNotImpl("GetSize")
|
||||
|
||||
def GetPositionOfLine(self, cLineNumber):
|
||||
# Result is int char position
|
||||
RaiseNotImpl("GetPositionOfLine")
|
||||
|
||||
def GetLineOfPosition(self, charPos):
|
||||
# Result is int, int (lineNo, offset)
|
||||
RaiseNotImpl("GetLineOfPosition")
|
||||
|
||||
def GetText(self, charPos, maxChars, wantAttr):
|
||||
"""Params
|
||||
charPos -- integer
|
||||
maxChars -- integer
|
||||
wantAttr -- Should the function compute attributes.
|
||||
|
||||
Return value must be (string, attribtues). attributes may be
|
||||
None if(not wantAttr)
|
||||
"""
|
||||
RaiseNotImpl("GetText")
|
||||
|
||||
def GetPositionOfContext(self, debugDocumentContext):
|
||||
"""Params
|
||||
debugDocumentContext -- a PyIDebugDocumentContext object.
|
||||
|
||||
Return value must be (charPos, numChars)
|
||||
"""
|
||||
RaiseNotImpl("GetPositionOfContext")
|
||||
|
||||
def GetContextOfPosition(self, charPos, maxChars):
|
||||
"""Params are integers.
|
||||
Return value must be PyIDebugDocumentContext object
|
||||
"""
|
||||
print(self)
|
||||
RaiseNotImpl("GetContextOfPosition")
|
||||
|
||||
|
||||
class DebugDocumentTextExternalAuthor:
|
||||
"""Allow external editors to edit file-based debugger documents, and to notify the document when the source file has been changed."""
|
||||
|
||||
_public_methods_ = ["GetPathName", "GetFileName", "NotifyChanged"]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocumentTextExternalAuthor]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetPathName(self):
|
||||
"""Return the full path (including file name) to the document's source file.
|
||||
|
||||
Result must be (filename, fIsOriginal), where
|
||||
- if fIsOriginalPath is TRUE if the path refers to the original file for the document.
|
||||
- if fIsOriginalPath is FALSE if the path refers to a newly created temporary file.
|
||||
|
||||
raise Exception(winerror.E_FAIL) if no source file can be created/determined.
|
||||
"""
|
||||
RaiseNotImpl("GetPathName")
|
||||
|
||||
def GetFileName(self):
|
||||
"""Return just the name of the document, with no path information. (Used for "Save As...")
|
||||
|
||||
Result is a string
|
||||
"""
|
||||
RaiseNotImpl("GetFileName")
|
||||
|
||||
def NotifyChanged(self):
|
||||
"""Notify the host that the document's source file has been saved and
|
||||
that its contents should be refreshed.
|
||||
"""
|
||||
RaiseNotImpl("NotifyChanged")
|
||||
|
||||
|
||||
class DebugDocumentTextEvents:
|
||||
_public_methods_ = """onDestroy onInsertText onRemoveText
|
||||
onReplaceText onUpdateTextAttributes
|
||||
onUpdateDocumentAttributes""".split()
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocumentTextEvents]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def onDestroy(self):
|
||||
# Result is void.
|
||||
RaiseNotImpl("onDestroy")
|
||||
|
||||
def onInsertText(self, cCharacterPosition, cNumToInsert):
|
||||
# Result is void.
|
||||
RaiseNotImpl("onInsertText")
|
||||
|
||||
def onRemoveText(self, cCharacterPosition, cNumToRemove):
|
||||
# Result is void.
|
||||
RaiseNotImpl("onRemoveText")
|
||||
|
||||
def onReplaceText(self, cCharacterPosition, cNumToReplace):
|
||||
# Result is void.
|
||||
RaiseNotImpl("onReplaceText")
|
||||
|
||||
def onUpdateTextAttributes(self, cCharacterPosition, cNumToUpdate):
|
||||
# Result is void.
|
||||
RaiseNotImpl("onUpdateTextAttributes")
|
||||
|
||||
def onUpdateDocumentAttributes(self, textdocattr): # TEXT_DOC_ATTR
|
||||
# Result is void.
|
||||
RaiseNotImpl("onUpdateDocumentAttributes")
|
||||
|
||||
|
||||
class DebugDocumentContext:
|
||||
_public_methods_ = ["GetDocument", "EnumCodeContexts"]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocumentContext]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetDocument(self):
|
||||
"""Return value must be a PyIDebugDocument object"""
|
||||
RaiseNotImpl("GetDocument")
|
||||
|
||||
def EnumCodeContexts(self):
|
||||
"""Return value must be a PyIEnumDebugCodeContexts object"""
|
||||
RaiseNotImpl("EnumCodeContexts")
|
||||
|
||||
|
||||
class DebugCodeContext:
|
||||
_public_methods_ = ["GetDocumentContext", "SetBreakPoint"]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugCodeContext]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetDocumentContext(self):
|
||||
"""Return value must be a PyIDebugDocumentContext object"""
|
||||
RaiseNotImpl("GetDocumentContext")
|
||||
|
||||
def SetBreakPoint(self, bps):
|
||||
"""bps -- an integer with flags."""
|
||||
RaiseNotImpl("SetBreakPoint")
|
||||
|
||||
|
||||
class DebugStackFrame:
|
||||
"""Abstraction representing a logical stack frame on the stack of a thread."""
|
||||
|
||||
_public_methods_ = [
|
||||
"GetCodeContext",
|
||||
"GetDescriptionString",
|
||||
"GetLanguageString",
|
||||
"GetThread",
|
||||
"GetDebugProperty",
|
||||
]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugStackFrame]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetCodeContext(self):
|
||||
"""Returns the current code context associated with the stack frame.
|
||||
|
||||
Return value must be a IDebugCodeContext object
|
||||
"""
|
||||
RaiseNotImpl("GetCodeContext")
|
||||
|
||||
def GetDescriptionString(self, fLong):
|
||||
"""Returns a textual description of the stack frame.
|
||||
|
||||
fLong -- A flag indicating if the long name is requested.
|
||||
"""
|
||||
RaiseNotImpl("GetDescriptionString")
|
||||
|
||||
def GetLanguageString(self):
|
||||
"""Returns a short or long textual description of the language.
|
||||
|
||||
fLong -- A flag indicating if the long name is requested.
|
||||
"""
|
||||
RaiseNotImpl("GetLanguageString")
|
||||
|
||||
def GetThread(self):
|
||||
"""Returns the thread associated with this stack frame.
|
||||
|
||||
Result must be a IDebugApplicationThread
|
||||
"""
|
||||
RaiseNotImpl("GetThread")
|
||||
|
||||
def GetDebugProperty(self):
|
||||
RaiseNotImpl("GetDebugProperty")
|
||||
|
||||
|
||||
class DebugDocumentHost:
|
||||
"""The interface from the IDebugDocumentHelper back to
|
||||
the smart host or language engine. This interface
|
||||
exposes host specific functionality such as syntax coloring.
|
||||
"""
|
||||
|
||||
_public_methods_ = [
|
||||
"GetDeferredText",
|
||||
"GetScriptTextAttributes",
|
||||
"OnCreateDocumentContext",
|
||||
"GetPathName",
|
||||
"GetFileName",
|
||||
"NotifyChanged",
|
||||
]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugDocumentHost]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetDeferredText(self, dwTextStartCookie, maxChars, bWantAttr):
|
||||
RaiseNotImpl("GetDeferredText")
|
||||
|
||||
def GetScriptTextAttributes(self, codeText, delimterText, flags):
|
||||
# Result must be an attribute sequence of same "length" as the code.
|
||||
RaiseNotImpl("GetScriptTextAttributes")
|
||||
|
||||
def OnCreateDocumentContext(self):
|
||||
# Result must be a PyIUnknown
|
||||
RaiseNotImpl("OnCreateDocumentContext")
|
||||
|
||||
def GetPathName(self):
|
||||
# Result must be (string, int) where the int is a BOOL
|
||||
# - TRUE if the path refers to the original file for the document.
|
||||
# - FALSE if the path refers to a newly created temporary file.
|
||||
# - raise Exception(scode=E_FAIL) if no source file can be created/determined.
|
||||
RaiseNotImpl("GetPathName")
|
||||
|
||||
def GetFileName(self):
|
||||
# Result is a string with just the name of the document, no path information.
|
||||
RaiseNotImpl("GetFileName")
|
||||
|
||||
def NotifyChanged(self):
|
||||
RaiseNotImpl("NotifyChanged")
|
||||
|
||||
|
||||
# Additional gateway related functions.
|
||||
|
||||
|
||||
class DebugDocumentTextConnectServer:
|
||||
_public_methods_ = (
|
||||
win32com.server.connect.IConnectionPointContainer_methods
|
||||
+ win32com.server.connect.IConnectionPoint_methods
|
||||
)
|
||||
_com_interfaces_ = [
|
||||
pythoncom.IID_IConnectionPoint,
|
||||
pythoncom.IID_IConnectionPointContainer,
|
||||
]
|
||||
# IConnectionPoint interfaces
|
||||
def __init__(self):
|
||||
self.cookieNo = -1
|
||||
self.connections = {}
|
||||
|
||||
def EnumConnections(self):
|
||||
RaiseNotImpl("EnumConnections")
|
||||
|
||||
def GetConnectionInterface(self):
|
||||
RaiseNotImpl("GetConnectionInterface")
|
||||
|
||||
def GetConnectionPointContainer(self):
|
||||
return _wrap(self)
|
||||
|
||||
def Advise(self, pUnk):
|
||||
# Creates a connection to the client. Simply allocate a new cookie,
|
||||
# find the clients interface, and store it in a dictionary.
|
||||
interface = pUnk.QueryInterface(axdebug.IID_IDebugDocumentTextEvents, 1)
|
||||
self.cookieNo = self.cookieNo + 1
|
||||
self.connections[self.cookieNo] = interface
|
||||
return self.cookieNo
|
||||
|
||||
def Unadvise(self, cookie):
|
||||
# Destroy a connection - simply delete interface from the map.
|
||||
try:
|
||||
del self.connections[cookie]
|
||||
except KeyError:
|
||||
return Exception(scode=winerror.E_UNEXPECTED)
|
||||
|
||||
# IConnectionPointContainer interfaces
|
||||
def EnumConnectionPoints(self):
|
||||
RaiseNotImpl("EnumConnectionPoints")
|
||||
|
||||
def FindConnectionPoint(self, iid):
|
||||
# Find a connection we support. Only support the single event interface.
|
||||
if iid == axdebug.IID_IDebugDocumentTextEvents:
|
||||
return _wrap(self)
|
||||
raise Exception(scode=winerror.E_NOINTERFACE) # ??
|
||||
|
||||
|
||||
class RemoteDebugApplicationEvents:
|
||||
_public_methods_ = [
|
||||
"OnConnectDebugger",
|
||||
"OnDisconnectDebugger",
|
||||
"OnSetName",
|
||||
"OnDebugOutput",
|
||||
"OnClose",
|
||||
"OnEnterBreakPoint",
|
||||
"OnLeaveBreakPoint",
|
||||
"OnCreateThread",
|
||||
"OnDestroyThread",
|
||||
"OnBreakFlagChange",
|
||||
]
|
||||
_com_interfaces_ = [axdebug.IID_IRemoteDebugApplicationEvents]
|
||||
|
||||
def OnConnectDebugger(self, appDebugger):
|
||||
"""appDebugger -- a PyIApplicationDebugger"""
|
||||
RaiseNotImpl("OnConnectDebugger")
|
||||
|
||||
def OnDisconnectDebugger(self):
|
||||
RaiseNotImpl("OnDisconnectDebugger")
|
||||
|
||||
def OnSetName(self, name):
|
||||
RaiseNotImpl("OnSetName")
|
||||
|
||||
def OnDebugOutput(self, string):
|
||||
RaiseNotImpl("OnDebugOutput")
|
||||
|
||||
def OnClose(self):
|
||||
RaiseNotImpl("OnClose")
|
||||
|
||||
def OnEnterBreakPoint(self, rdat):
|
||||
"""rdat -- PyIRemoteDebugApplicationThread"""
|
||||
RaiseNotImpl("OnEnterBreakPoint")
|
||||
|
||||
def OnLeaveBreakPoint(self, rdat):
|
||||
"""rdat -- PyIRemoteDebugApplicationThread"""
|
||||
RaiseNotImpl("OnLeaveBreakPoint")
|
||||
|
||||
def OnCreateThread(self, rdat):
|
||||
"""rdat -- PyIRemoteDebugApplicationThread"""
|
||||
RaiseNotImpl("OnCreateThread")
|
||||
|
||||
def OnDestroyThread(self, rdat):
|
||||
"""rdat -- PyIRemoteDebugApplicationThread"""
|
||||
RaiseNotImpl("OnDestroyThread")
|
||||
|
||||
def OnBreakFlagChange(self, abf, rdat):
|
||||
"""abf -- int - one of the axdebug.APPBREAKFLAGS constants
|
||||
rdat -- PyIRemoteDebugApplicationThread
|
||||
RaiseNotImpl("OnBreakFlagChange")
|
||||
"""
|
||||
|
||||
|
||||
class DebugExpressionContext:
|
||||
_public_methods_ = ["ParseLanguageText", "GetLanguageInfo"]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugExpressionContext]
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def ParseLanguageText(self, code, radix, delim, flags):
|
||||
"""
|
||||
result is IDebugExpression
|
||||
"""
|
||||
RaiseNotImpl("ParseLanguageText")
|
||||
|
||||
def GetLanguageInfo(self):
|
||||
"""
|
||||
result is (string langName, iid langId)
|
||||
"""
|
||||
RaiseNotImpl("GetLanguageInfo")
|
||||
|
||||
|
||||
class DebugExpression:
|
||||
_public_methods_ = [
|
||||
"Start",
|
||||
"Abort",
|
||||
"QueryIsComplete",
|
||||
"GetResultAsString",
|
||||
"GetResultAsDebugProperty",
|
||||
]
|
||||
_com_interfaces_ = [axdebug.IID_IDebugExpression]
|
||||
|
||||
def Start(self, callback):
|
||||
"""
|
||||
callback -- an IDebugExpressionCallback
|
||||
|
||||
result - void
|
||||
"""
|
||||
RaiseNotImpl("Start")
|
||||
|
||||
def Abort(self):
|
||||
"""
|
||||
no params
|
||||
result -- void
|
||||
"""
|
||||
RaiseNotImpl("Abort")
|
||||
|
||||
def QueryIsComplete(self):
|
||||
"""
|
||||
no params
|
||||
result -- void
|
||||
"""
|
||||
RaiseNotImpl("QueryIsComplete")
|
||||
|
||||
def GetResultAsString(self):
|
||||
RaiseNotImpl("GetResultAsString")
|
||||
|
||||
def GetResultAsDebugProperty(self):
|
||||
RaiseNotImpl("GetResultAsDebugProperty")
|
||||
|
||||
|
||||
class ProvideExpressionContexts:
|
||||
_public_methods_ = ["EnumExpressionContexts"]
|
||||
_com_interfaces_ = [axdebug.IID_IProvideExpressionContexts]
|
||||
|
||||
def EnumExpressionContexts(self):
|
||||
RaiseNotImpl("EnumExpressionContexts")
|
180
.venv/Lib/site-packages/win32comext/axdebug/stackframe.py
Normal file
180
.venv/Lib/site-packages/win32comext/axdebug/stackframe.py
Normal file
@ -0,0 +1,180 @@
|
||||
"""Support for stack-frames.
|
||||
|
||||
Provides Implements a nearly complete wrapper for a stack frame.
|
||||
"""
|
||||
import sys
|
||||
from .util import _wrap, RaiseNotImpl
|
||||
import expressions, gateways, axdebug, winerror
|
||||
import pythoncom
|
||||
from win32com.server.exception import COMException
|
||||
|
||||
from .util import 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")
|
140
.venv/Lib/site-packages/win32comext/axdebug/util.py
Normal file
140
.venv/Lib/site-packages/win32comext/axdebug/util.py
Normal file
@ -0,0 +1,140 @@
|
||||
# Utility function for wrapping objects. Centralising allows me to turn
|
||||
# debugging on and off for the entire package in a single spot.
|
||||
|
||||
import sys
|
||||
import win32com.server.util
|
||||
from win32com.server.exception import Exception
|
||||
import winerror
|
||||
import win32api
|
||||
import os
|
||||
|
||||
try:
|
||||
os.environ["DEBUG_AXDEBUG"]
|
||||
debugging = 1
|
||||
except KeyError:
|
||||
debugging = 0
|
||||
|
||||
|
||||
def trace(*args):
|
||||
if not debugging:
|
||||
return
|
||||
print(str(win32api.GetCurrentThreadId()) + ":", end=" ")
|
||||
for arg in args:
|
||||
print(arg, end=" ")
|
||||
print()
|
||||
|
||||
|
||||
# The AXDebugging implementation assumes that the returned COM pointers are in
|
||||
# some cases identical. Eg, from a C++ perspective:
|
||||
# p->GetSomeInterface( &p1 );
|
||||
# p->GetSomeInterface( &p2 );
|
||||
# p1==p2
|
||||
# By default, this is _not_ true for Python.
|
||||
# (Now this is only true for Document objects, and Python
|
||||
# now does ensure this.
|
||||
|
||||
all_wrapped = {}
|
||||
|
||||
|
||||
def _wrap_nodebug(object, iid):
|
||||
return win32com.server.util.wrap(object, iid)
|
||||
|
||||
|
||||
def _wrap_debug(object, iid):
|
||||
import win32com.server.policy
|
||||
|
||||
dispatcher = win32com.server.policy.DispatcherWin32trace
|
||||
return win32com.server.util.wrap(object, iid, useDispatcher=dispatcher)
|
||||
|
||||
|
||||
if debugging:
|
||||
_wrap = _wrap_debug
|
||||
else:
|
||||
_wrap = _wrap_nodebug
|
||||
|
||||
|
||||
def _wrap_remove(object, iid=None):
|
||||
# Old - no longer used or necessary!
|
||||
return
|
||||
|
||||
|
||||
def _dump_wrapped():
|
||||
from win32com.server.util import unwrap
|
||||
|
||||
print("Wrapped items:")
|
||||
for key, items in all_wrapped.items():
|
||||
print(key, end=" ")
|
||||
try:
|
||||
ob = unwrap(key)
|
||||
print(ob, sys.getrefcount(ob))
|
||||
except:
|
||||
print("<error>")
|
||||
|
||||
|
||||
def RaiseNotImpl(who=None):
|
||||
if who is not None:
|
||||
print("********* Function %s Raising E_NOTIMPL ************" % (who))
|
||||
|
||||
# Print a sort-of "traceback", dumping all the frames leading to here.
|
||||
try:
|
||||
1 / 0
|
||||
except:
|
||||
frame = sys.exc_info()[2].tb_frame
|
||||
while frame:
|
||||
print("File: %s, Line: %d" % (frame.f_code.co_filename, frame.f_lineno))
|
||||
frame = frame.f_back
|
||||
|
||||
# and raise the exception for COM
|
||||
raise Exception(scode=winerror.E_NOTIMPL)
|
||||
|
||||
|
||||
import win32com.server.policy
|
||||
|
||||
|
||||
class Dispatcher(win32com.server.policy.DispatcherWin32trace):
|
||||
def __init__(self, policyClass, object):
|
||||
win32com.server.policy.DispatcherTrace.__init__(self, policyClass, object)
|
||||
import win32traceutil # Sets up everything.
|
||||
|
||||
# print "Object with win32trace dispatcher created (object=%s)" % `object`
|
||||
|
||||
def _QueryInterface_(self, iid):
|
||||
rc = win32com.server.policy.DispatcherBase._QueryInterface_(self, iid)
|
||||
# if not rc:
|
||||
# self._trace_("in _QueryInterface_ with unsupported IID %s (%s)\n" % (IIDToInterfaceName(iid),iid))
|
||||
return rc
|
||||
|
||||
def _Invoke_(self, dispid, lcid, wFlags, args):
|
||||
print(
|
||||
"In Invoke with",
|
||||
dispid,
|
||||
lcid,
|
||||
wFlags,
|
||||
args,
|
||||
"with object",
|
||||
self.policy._obj_,
|
||||
)
|
||||
try:
|
||||
rc = win32com.server.policy.DispatcherBase._Invoke_(
|
||||
self, dispid, lcid, wFlags, args
|
||||
)
|
||||
# print "Invoke of", dispid, "returning", rc
|
||||
return rc
|
||||
except Exception:
|
||||
t, v, tb = sys.exc_info()
|
||||
tb = None # A cycle
|
||||
scode = v.scode
|
||||
try:
|
||||
desc = " (" + str(v.description) + ")"
|
||||
except AttributeError:
|
||||
desc = ""
|
||||
print(
|
||||
"*** Invoke of %s raised COM exception 0x%x%s" % (dispid, scode, desc)
|
||||
)
|
||||
except:
|
||||
print("*** Invoke of %s failed:" % dispid)
|
||||
typ, val, tb = sys.exc_info()
|
||||
import traceback
|
||||
|
||||
traceback.print_exception(typ, val, tb)
|
||||
raise
|
Reference in New Issue
Block a user