使文件名/行号在Emacs gud bu中可链接

2024-06-02 07:38:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我通过gud缓冲区在Python中运行pdb。当我在测试用例中得到stacktrace/failure时,它看起来像这样:

FAIL: test_foo_function (__main__.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test/testfoo.py", line 499, in test_foo_function
    self.assertEqual('foo', 'foo')

我希望能把台词写得像:

^{pr2}$

点击,进入第499行试验食品.py. 在

(编辑)python模式列表上的人把我带到pdbtrack,我可以让它在那里工作。请看下面的答案。。。在


Tags: pytestmostfailurefoomain测试用例function
3条回答

加上贾斯汀的回答:

我在slime配置中有以下内容,它应该从clojure堆栈跟踪跳转到文件和行。在

不幸的是,我必须承认它目前对我来说并不管用——函数无法找到正确的文件——但据我所知,应该可以通过改变project-root的定义方式或通过更改文件系统上项目的结构来解决(我只是没有时间或倾向于查看它)。在

虽然这是一个通用的项目,但它的功能性很好。在本例中,我们依赖于src目录,但这可能不适合您的python项目。在

因此,从Justin离开的地方继续,您应该能够从下面的函数中获得一些提示,解析来自测试用例错误的文件名和行号,创建到行号的链接,并使用compilation-parse-errors-filename-functionpropertizegud缓冲区中的行作为链接。在

如果你真的成功了,请给你自己的问题加一个答案。我想很多人会发现它很有用。在

  (defun slime-jump-to-trace (&optional on)
    "Jump to the file/line that the current stack trace line references.
    Only works with files in your project root's src/, not in dependencies."
    (interactive)
    (save-excursion
      (beginning-of-line)
      (search-forward-regexp "[0-9]: \\([^$(]+\\).*?\\([0-9]*\\))")
      (let ((line (string-to-number (match-string 2)))
            (ns-path (split-string (match-string 1) "\\."))
            (project-root (locate-dominating-file default-directory "src/")))

        (find-file (format "%s/src/%s.clj" project-root
                           (mapconcat 'identity ns-path "/")))
        (goto-line line))))

我还应该提到,我从网上的某个地方复制了这个函数,但是我记不起URL了。它似乎来自Phil Hagelberg(技术)优秀的Emacs入门套件。在

多亏了杰拉德B的暗示,我终于明白了。我是从pdbtrack(shell)而不是纯pdb来执行此操作的,但我相信它应该在这两种情况下都有效。您需要启用编译shell次要模式。并在.emacs中包含以下代码:

;; if compilation-shell-minor-mode is on, then these regexes
;; will make errors linkable
(defun matt-add-global-compilation-errors (list)
  (dolist (x list)
    (add-to-list 'compilation-error-regexp-alist (car x))
    (setq compilation-error-regexp-alist-alist
      (cons x
            (assq-delete-all (car x)
                             compilation-error-regexp-alist-alist)))))

(matt-add-global-compilation-errors
 `(
   (matt-python ,(concat "^ *File \\(\"?\\)\\([^,\" \n    <>]+\\)\\1"
                    ", lines? \\([0-9]+\\)-?\\([0-9]+\\)?")
           2 (3 . 4) nil 2 2)
   (matt-pdb-stack ,(concat "^>?[[:space:]]*\\(\\([-_./a-zA-Z0-9 ]+\\)"
                       "(\\([0-9]+\\))\\)"
                       "[_a-zA-Z0-9]+()[[:space:]]*->")
              2 3 nil 0 1)
   (matt-python-unittest-err "^  File \"\\([-_./a-zA-Z0-9 ]+\\)\", line \\([0-9]+\\).*" 1 2)
   )
 )

(defun matt-set-local-compilation-errors (errors)
  "Set the buffer local compilation errors.

Ensures than any symbols given are defined in
compilation-error-regexp-alist-alist."
  (dolist (e errors)
     (when (symbolp e)
      (unless (assoc e compilation-error-regexp-alist-alist)
        (error (concat "Error %s is not listed in "
                       "compilation-error-regexp-alist-alist")
               e))))
  (set (make-local-variable 'compilation-error-regexp-alist)
       errors))

然后可以使用标准编译模式导航来快速浏览错误堆栈跟踪。在

我想您想要定制的是compilation-parse-errors-filename-function,这是一个接受文件名并返回要显示的文件名修改版本的函数。这是一个buffer局部变量,因此您应该在每个显示python错误的缓冲区中设置它(可能有一个合适的钩子可以使用,我没有安装python模式,因此无法查找它)。您可以使用propertize返回输入文件名的一个版本,该文件名作为超链接来加载实际文件。属性在elisp手册中有详细的记录。在

如果compilation parse errors filename函数没有被调用,那么您需要向compilation-error-regexp-alist-alist(也就是说列表列表,不是打字错误)添加一个列表,它是一个模式名列表,后跟正则表达式以匹配错误,以及error regexp match中匹配行号、文件名等信息的数字索引。在

相关问题 更多 >