Eclipse、PyDev、Django:settings.py 中的断点有效,但在视图中无效

Ecplipse, PyDev, Django: Breakpoints in settings.py work, but in views do not

我已经在我的开发环境中开始了一个相当雄心勃勃的项目,因为我想我喜欢保持最新状态。所以多年来我一直在使用 Eclipse 和 PyDev 开发一个 Django 项目,它运行得非常好。

我使用 Python 3.7、Django 2.1 和 Eclipse Photon 已经有一段时间了。

我已经尝试了一种全新的开始,如下所示移动到最新版本的所有内容:

  1. 安装了最新的 Eclipse(2019-12 Eclipse IDE 用于 Web 和 JavaScript 开发人员(包括孵化组件)
  2. 将 PyDev 添加到其中(帮助 > 安装新软件,来自 http://www.pydev.org/updates
  3. 已安装 Python 3.8.
  4. 已安装 Django 3.0.1。
  5. 将我的项目依赖的所有包安装到我的本地 3.8 站点包中
  6. 在新的工作区中,我导入了我的旧项目(文件 > 导入 > 常规 > 现有项目进入工作区,选中Copy projects into workspace
  7. 使用 Python 3.8 解释器创建了调试配置并且(因为某些原因默认 sys.path 将我的本地站点包放在 python 3 dist-packages 之后)我添加了站点包到我的外部库并将其强制到我的 sys.path.
  8. 的顶部
  9. 开始调试 运行 ...

这很好用。它开始了,我可以使用我的网站指向 http://127.0.0.1:8000/ 并且它大部分功能正常,实际上不能抱怨,几乎可以期待更多的戏剧升级。不完美有一些调整使其与 Django 3.0.1 兼容但令人惊讶的是很少。

我卡在了崩溃的页面上,所以我设置了一个断点才发现它不起作用...嗯。我以前和 PyDev 一起来过这里,还有很多其他人。所以我已经完成了基本的诊断,并将分享我所知道的。但如果有人(尤其是 Fabio)有更多 gem 的智慧来帮助他们工作,我将不胜感激。

安装在 Eclipse 上的是:

  PyDev for Eclipse 7.4.0.201910251334  org.python.pydev.feature.feature.group  Fabio Zadrozny
  PyDev for Eclipse Developer Resources 7.4.0.201910251334  org.python.pydev.feature.source.feature.group   Fabio Zadrozny
  Pydev Mylyn Integration   0.6.0   org.python.pydev.mylyn.feature.feature.group    Fabio Zadrozny

主要观察结果:

  1. 如果我在 settings.py 中设置断点,它会正常中断。
  2. 如果我在视图中设置断点,它不会中断。
  3. 我知道我在正确的文件和位置,因为如果我在我想中断的地方添加控制台打印行,它会打印到控制台。所以我没有以任何方式查看错误的源文件。

法比奥在这里留下了一些非常好的(现在已过时)提示:pydev breakpoints not working 我可以回应这些:

  1. 如果我把它放在 views.py 的顶部,我在我的断点处:
import sys
print('DEBUG: current trace function', sys.gettrace())

我看到这个输出:

DEBUG: current trace function None

这似乎是问题所在。那个东西正在关闭调试。

根据 Fabio 的第一个提示并考虑自该提示以来 PyDev 结构的变化,我在 plugins/org.python.pydev.core_7.4.0.201910251334/pysrc/_pydevd_bundle 中找到 pydevd_constants.py 并且可以在其中设置:

DEBUG_TRACE_LEVEL = 3 
DEBUG_TRACE_BREAKPOINTS = 3

正如法比奥建议的那样。这揭示了一点点唉。本质上,在启动调试 运行 直到服务器 运行ning 时,我看到了很多很酷的跟踪。然后我看到标准输出说服务器现在是 运行ning:

System check identified no issues (0 silenced).
December 26, 2019 - 12:29:54
Django version 3.0.1, using settings 'MyProject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

它在 settings.py 中的断点处停了下来,我继续按 F8。

现在在我的浏览器中加载我正在调试的视图。唉,控制台上的 PyDev 跟踪为零,实际上我只得到了我放入视图的 get_queryset() 方法以确保我的代码(带有断点)是 运行ning 的小打印行。

所以这没有任何帮助。我可以在我的 views.py 文件中根据 Fabio 的建议在大海捞针中寻找针头:

import sys
print('DEBUG: current trace function', sys.gettrace())
def trace_func(frame, event, arg):
    with open('pydev-trace.txt', 'a') as f:
        print('Context: ', frame.f_code.co_name, '\tFile:', frame.f_code.co_filename, '\tLine:', frame.f_lineno, '\tEvent:', event, file=f)
    return trace_func

sys.settrace(trace_func)
print('DEBUG: current trace function', sys.gettrace())

我现在在控制台上看到:

DEBUG: current trace function None
DEBUG: current trace function <function trace_func at 0x7ffaa6f18b80>
System check identified no issues (0 silenced).
December 26, 2019 - 12:42:48
Django version 3.0.1, using settings 'MyProject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

哪种好看。

但输出轨迹似乎永远不会停止。它越来越大,越来越大,似乎陷入了一个无限循环的自动重新加载循环:

Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 370   Event: call
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 361   Event: line
Context:  watched_files     File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 260   Event: call
Context:  watched_files     File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 260   Event: return
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 362   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 758   Event: call
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 759   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: return
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 364   Event: line
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 365   Event: line
Context:  stat  File: /usr/lib/python3.8/pathlib.py     Line: 1186  Event: call
Context:  stat  File: /usr/lib/python3.8/pathlib.py     Line: 1191  Event: line
Context:  __fspath__    File: /usr/lib/python3.8/pathlib.py     Line: 721   Event: call
Context:  __fspath__    File: /usr/lib/python3.8/pathlib.py     Line: 722   Event: line
Context:  __str__   File: /usr/lib/python3.8/pathlib.py     Line: 711   Event: call
Context:  __str__   File: /usr/lib/python3.8/pathlib.py     Line: 714   Event: line
Context:  __str__   File: /usr/lib/python3.8/pathlib.py     Line: 715   Event: line
Context:  __str__   File: /usr/lib/python3.8/pathlib.py     Line: 715   Event: return
Context:  __fspath__    File: /usr/lib/python3.8/pathlib.py     Line: 722   Event: return
Context:  stat  File: /usr/lib/python3.8/pathlib.py     Line: 1191  Event: return
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 369   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 758   Event: call
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 759   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: return
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 370   Event: line
Context:  snapshot_files    File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 370   Event: return
Context:  tick  File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 346   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 758   Event: call
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 759   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: return
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 753   Event: call
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 754   Event: line
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 756   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 744   Event: call
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 747   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: return
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 744   Event: call
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 747   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: return
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 756   Event: return
Context:  tick  File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 347   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 758   Event: call
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 759   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: line
Context:  __hash__  File: /usr/lib/python3.8/pathlib.py     Line: 760   Event: return
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 753   Event: call
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 754   Event: line
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 756   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 744   Event: call
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 747   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: return
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 744   Event: call
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 747   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: line
Context:  _cparts   File: /usr/lib/python3.8/pathlib.py     Line: 748   Event: return
Context:  __eq__    File: /usr/lib/python3.8/pathlib.py     Line: 756   Event: return
Context:  tick  File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 348   Event: line
Context:  tick  File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 351   Event: line
Context:  tick  File: /home/me/.local/lib/python3.8/site-packages/django/utils/autoreload.py    Line: 345   Event: line

这是迄今为止我们掌握的最好线索。我怀疑这里有什么东西处于一个非常紧密的无休止的循环中。网页仍在加载,因此它不会以极快的速度耗尽资源,而且它 运行 已经存在了很长时间,并且没有溢出任何堆栈或任何东西,但显然似乎以某种方式损坏了。

但是很难在这里确定一些东西。

最后,在该回复中,Fabio 建议暴力修复可能是:

import pydevd;
pydevd.settrace()

唉,无法导入 pydevd,但如果我添加到我的外部库中:

...plugins/org.python.pydev.core_7.4.0.201910251334/pysrc

我可以,然后 运行 它会在我的控制台上产生无穷无尽的文本流,而我的网站在这种情况下不会响应。因此,从调试服务器关闭的意义上来说,这是蛮力 ;-)。这可能与上面的无限循环有关。

其他检查:

我查看了 Fabios 的需求清单:

http://www.pydev.org/manual_adv_django.html

在那些方面我很擅长。

  1. 项目被标记为 Django 项目。
  2. DJANGO_MANAGE_LOCATION 已设置。
  3. DJANGO_SETTINGS_MODULE 已设置。

我可以在 Project Properties > PyDev PYTONPATH > String Substitution Variables 上看到后两者].我可以从项目上下文菜单上存在 Django 菜单和缺少 Set as Django Project.

选项中推断出第一个

在这一点上,我希望得到一些进一步的指导。我在这里投入了大量时间进行诊断并试图找出原因,但我在这一点上的效率会随着一些注入的专业知识和建议而飙升。法比奥?

我在这里问,在很大程度上是因为很多其他人已经问过了,对于面临类似问题的任何人来说,这是一个非常有用且易于查找的资源。并且没有理由相信这种情况不太可能发生。所以我想解决这个问题,并发布一个解决方案,基本上是为了我和其他人。

一些要检查的东西:

  1. 它们在 2 个不同的进程中吗?即:如果您在设置和视图中 import os;print(os.getpid()),它是同一个 pid 吗? (我怀疑您看到的是进行自动重新加载的主进程的日志,而不是实际执行代码的辅助进程的日志)。

  2. PyDev 中是否开启了附加到子进程的设置? (即:preferences > pydev > debug > attach to subprocess automatically while debugging)。

  3. 如果您使用 --noreload 进行启动,是否有效?

2020 年 1 月 10 日发布的 PyDev 7.5.0 版修复了此问题。我的视图中的断点再次正常运行。我的发行说明包括:

  • 修复了对 Python 3.8(未正确添加到 7.4.0)的支持。
  • 调试器改进(更新到 pydevd 1.9.0)。
    • 改进了协程的单步执行
    • 附加到进程不再需要将目标程序的位数与解释器匹配。
    • 在 sys.path 个文件夹中搜索具有相对路径的文件(即:因此,cython 构建可以找到源)。

让我怀疑整个问题与 Python 3.8 有关(考虑到 Python 3.8 的最新版本,这不足为奇),尽管 pydevd 1.9.0 可能会进行一些调整发挥了作用。无论哪种方式,将 PyDev 更新到 7.5.0 都可以解决问题![​​=10=]