Pylint无法在OS X上与Emacs GUI一起工作;但可以从命令行使用

4

当使用命令行运行 (emacs filename.py) 时,Flymake 和 pylint 可以完美地配合工作。错误会被正确地突出显示。(尽管我无法悬停鼠标以获取错误详细信息,因为它是文本模式。)

当从 GUI (Carbon Emacs) 运行时,Flymake 立即返回,并且文件中的第一行用错误 "in <module>" 高亮显示。即使在 "Hello World" 脚本上,第一行也会显示错误。我希望在 GUI 模式下正常工作,这样我就可以用鼠标导航 (我知道,我知道),并使用工具提示获取有关 pylint 报告的错误的详细信息。

我使用 "easy_install pylint" 安装了 pylint,并且 pylint 和 epylint 脚本位于 "~/py/scripts" 中。我在我的 .bashrc 中将该目录添加到了我的 PATH 中:

export PATH=$PATH:~/py/scripts

(我的 .profile 是指向我的 .bashrc 的符号链接。)

我意识到 Emacs-GUI 没有从我的 .bashrc 中加载路径,因此我创建了一个 ~/.MacOSX/environment.plist 文件,并使用终端中看到的完整路径设置了 PATH 变量。

现在在 Emacs-GUI 中 "(getenv "PATH")" 的输出看起来是正确的:

"/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin:/Users/schof/py/scripts:/usr/X11R6/bin"

同样地,"C-h v exec-path" 的输出看起来是正确的:

("/usr/bin" "/bin" "/usr/sbin" "/sbin" "/usr/local/bin" "/usr/local/git/bin" "/usr/X11/bin" "/Users/schof/py/scripts" "/Applications/Emacs.app/Contents/MacOS/libexec" "/Applications/Emacs.app/Contents/MacOS/bin" "/usr/X11R6/bin")

这让我无法想出如何解决这个问题。我并不是一个Emacs大师,所以很可能我在这里忽略了一些显而易见的东西; 如需更多细节,请随时提问。

操作系统为OS X 10.6.7;使用Carbon Emacs 22.3.1;使用Pylint 0.23.0。

Flymake / Pylint相关代码位于.emacs文件中:

  (when (load "flymake" t)
      (defun flymake-pylint-init ()
        (let* ((temp-file (flymake-init-create-temp-buffer-copy
                           'flymake-create-temp-inplace))
           (local-file (file-relative-name
                        temp-file
                        (file-name-directory buffer-file-name))))
          (list "epylint" (list local-file))))

      (add-to-list 'flymake-allowed-file-name-masks
               '("\\.py\\'" flymake-pylint-init)))


;; Auto-start flymake-mode when you go into python-mode
(add-hook 'python-mode-hook
          '(lambda ()
                   (setq python-indent 4)
                   (flymake-mode)))

回应@sanityinc的答案,更新2011-04-05:

*messages*中flymake的详细程度为3:(这对我来说并没有使问题的来源显而易见。)

starting syntax check as new-line has been seen
flymake is running: nil
file /Users/schof/pytest.py, init=flymake-pylint-init [3 times]
create-temp-inplace: file=/Users/schof/pytest.py temp=/Users/schof/pytest_flymake.py
saved buffer pytest.py in file /Users/schof/pytest_flymake.py
started process 3221, command=(epylint pytest_flymake.py), dir=/Users/schof/
received 704 byte(s) of output from process 3221
file /Users/schof/pytest.py, init=flymake-pylint-init
parsed 'Traceback (most recent call last):', no line-err-info
parse line: file-idx=2 line-idx=3 file=/Users/schof/py/scripts/epylint line=4 text=in <module>
get-real-file-name: file-name=/Users/schof/py/scripts/epylint real-name=~/py/scripts/epylint
parsed '  File "/Users/schof/py/scripts/epylint", line 4, in <module>', got line-err-info
parsed '    import pkg_resources', no line-err-info
parse line: file-idx=2 line-idx=3 file=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py line=2556 text=in <module>
get-real-file-name: file-name=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py real-name=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py
parsed '  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 2556, in <module>', got line-err-info
parsed '    working_set.require(__requires__)', no line-err-info
parse line: file-idx=2 line-idx=3 file=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py line=620 text=in require
get-real-file-name: file-name=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py real-name=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py
parsed '  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 620, in require', got line-err-info
parsed '    needed = self.resolve(parse_requirements(requirements))', no line-err-info
parse line: file-idx=2 line-idx=3 file=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py line=518 text=in resolve
get-real-file-name: file-name=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py real-name=/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py
parsed '  File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 518, in resolve', got line-err-info
parsed '    raise DistributionNotFound(req)  # XXX put more info here', no line-err-info
parsed 'pkg_resources.DistributionNotFound: pylint==0.23.0', no line-err-info
file /Users/schof/pytest.py, init=flymake-pylint-init
process 3221 exited with code 1
cleaning up using flymake-simple-cleanup
deleted file /Users/schof/pytest_flymake.py
created an overlay at (1-18)
pytest.py: 4 error(s), 0 warning(s) in 0.47 second(s)

为了对比,这里展示了在emacs文本模式下运行flymake详细度为3时的输出结果。"hello world"文件通过了所有pylint测试。

starting syntax check as new-line has been seen                                                                         
flymake is running: nil                                                                                                 
file /Users/schof/pytest.py, init=flymake-pylint-init [3 times]                                                         
create-temp-inplace: file=/Users/schof/pytest.py temp=/Users/schof/pytest_flymake.py                                    
saved buffer pytest.py in file /Users/schof/pytest_flymake.py                                                           
started process 3395, command=(epylint pytest_flymake.py), dir=/Users/schof/                                            
file /Users/schof/pytest.py, init=flymake-pylint-init                                                                   
process 3395 exited with code 0                                                                                         
cleaning up using flymake-simple-cleanup                                                                                
deleted file /Users/schof/pytest_flymake.py                                                                             
pytest.py: 0 error(s), 0 warning(s) in 0.30 second(s) 

完整的错误信息会很有帮助。看起来 flymake 确实被运行了,否则你可能不会得到一个“in <module>”的错误。我猜测你在终端和 GUI 中的 PYTHONPATH 不同。我也很惊讶 .MacOSX/environment 的技巧能够起作用。你是在运行 Snow Leopard 吗? - milkypostman
出门旅行,没有网络访问(没想到这个问题需要这么长时间才能解决)。将于4月11日回来,并回复其他问题/测试建议。 - Schof
1个回答

2
为了更清楚地了解出现了什么问题,可以增加flymake的日志级别,然后查看*messages*
(setq flymake-log-level 3)

没有这些信息,我不会猜测可能的问题。

顺便说一下,有一个避免使用 environment.plist 方法的技巧;你可以让Emacs向你的常规shell请求首选路径:

(defun set-exec-path-from-shell-PATH ()
  (let ((path-from-shell (replace-regexp-in-string
                          "[ \t\n]*$"
                          ""
                          (shell-command-to-string "$SHELL --login -i -c 'echo $PATH'"))))
    (setenv "PATH" path-from-shell)
    (setq exec-path (split-string path-from-shell path-separator))))

(when (and window-system (eq system-type 'darwin))
  ;; When started from Emacs.app or similar, ensure $PATH
  ;; is the same the user would see in Terminal.app
  (set-exec-path-from-shell-PATH))

(这是从我的Emacs配置中提取出来的,其中包括使用pyflakes的python配置。因此,您可能需要查看一下。) 更新:现在您已经添加了详细输出,我发现您的~/py/epylint程序找不到pkg_resources,这表明PYTHONPATH有误。因此,使用上述技术的变体,请尝试以下操作:
(defun setenv-from-shell (varname)
  (setenv varname (replace-regexp-in-string
                   "[ \t\n]*$"
                   ""
                   (shell-command-to-string (concat "$SHELL --login -i -c 'echo $" varname "'")))))

(setenv-from-shell "PYTHONPATH")

我按照你的要求编辑了我的问题,并附上了详细的日志输出。我还按照你建议的将.emacs路径添加到我的.emacs中,但症状没有改变。 - Schof
我在我的答案中添加了一些其他你可以尝试的东西。 - sanityinc
太棒了,Sanityinc!谢谢! - Schof

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