PyDev多线程调试

3
我正在尝试调试一个使用pynetdicom库的应用程序。我不确定这个具体细节有多重要,但是重要的是它大量使用多线程来运行后台套接字监听任务,而不会阻塞主线程。storescp.py示例可用于复制此操作。
每当我放置一个遇到断点(无论在哪个线程中,主线程或子线程)时,我都会得到以下回溯:
Traceback (most recent call last):
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd.py", line 1397, in <module>
    debugger.run(setup['file'], None, None)
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd.py", line 1090, in run
    pydev_imports.execfile(file, globals, locals) #execute the script
  File "/Users/alexw/Development/Python/kreport2/KReport2/dicomdatascraper.py", line 183, in <module>
    oldDicomList = copy.copy(newData)
  File "/Users/alexw/Development/Python/kreport2/KReport2/dicomdatascraper.py", line 183, in <module>
    oldDicomList = copy.copy(newData)
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd_frame.py", line 135, in trace_dispatch
    self.doWaitSuspend(thread, frame, event, arg)
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd_frame.py", line 25, in doWaitSuspend
    self._args[0].doWaitSuspend(*args, **kwargs)
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd.py", line 832, in doWaitSuspend
    self.processInternalCommands()
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd.py", line 360, in processInternalCommands
    thread_id = GetThreadId(t)
  File "/Applications/Aptana Studio 3/plugins/org.python.pydev_2.7.0.2013012902/pysrc/pydevd_constants.py", line 140, in GetThreadId
    return thread.__pydevd_id__
  File "/Users/alexw/.virtualenvs/kreport2dev/devlibs/pynetdicom/source/netdicom/applicationentity.py", line 73, in __getattr__
    obj = eval(attr)()
  File "<string>", line 1, in <module>
NameError: name '__pydevd_id__' is not defined

我的想法是,为了使事情正常工作,PyDev可能会对生成的线程进行__pydevd_id__的猴子补丁,但由于它们实际上是子类而不是直接实例化threading.Thread(在这种情况下,工作者是class Association(threading.Thread):的实例),因此未能将其修补到这些线程中。
当然,我不太了解PyDev,无法确认这个理论或修复它。并且似乎互联网也不知道。
子类化Thread是如此罕见的模式,以至于它在PyDev架构中根本没有被考虑吗?如果不重新设计库,该如何解决这个问题?
1个回答

2

我只需要更仔细地查看那个回溯信息。

pynetdicom库在其对threading.Thread的子类化中,覆盖了__getattr__并且有些地方出现问题。问题是:

def __getattr__(self, attr):
    #while not self.AssociationEstablished:
    #    time.sleep(0.001)
    obj = eval(attr)

    # do some stuff

    return obj

当传递一个不存在的属性时,会引发NameError错误。这个错误不会被pydev的monkeypatching例程(if thread.__pydevd_id__ raises AttributeError, thread.__pydevd_id__ = stuff)捕获。

解决方法是更新该部分如下:

def __getattr__(self, attr):
    #while not self.AssociationEstablished:
    #    time.sleep(0.001)
    try:
        obj = eval(attr)
    except NameError:
        raise AttributeError

    # do some stuff

    return obj

这会拦截NameError并抛出AttributeError,就像__getattr__应该在查询的属性不存在时一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接