Pylint在OS X的Emacs GUI中不工作;从命令行正常
从命令行运行时(比如输入 emacs filename.py
),flymake 和 pylint 可以很好地配合使用,错误会被正确高亮显示。(不过因为是在文本模式下,我无法悬停查看错误的详细信息。)
但是在图形界面(Carbon Emacs)中运行时,Flymake 会立即返回,文件的第一行会被标记为错误 "in <module>
"。即使是一个简单的 "Hello World" 脚本,第一行也会显示错误。我希望在图形界面模式下能正常工作,这样我就可以用鼠标导航(我知道,我知道),并使用工具提示查看 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 变量,内容是我在终端中看到的完整 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)))
更新 2011-04-05,回应 @sanityinc 的回答:
flymake 在 *messages*
中的详细输出级别为 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)
1 个回答
为了更清楚地了解问题出在哪里,可以提高flymake的日志级别,然后查看*messages*
里的内容:
(setq flymake-log-level 3)
如果没有这些信息,我也不敢随便猜测可能的问题。
顺便提一下,有一个方法可以避免使用environment.plist
;你可以让Emacs询问你常用的shell来获取你喜欢的PATH:
(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配置,里面有很多flymake的代码,包括一个使用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")