如何将 Emacs 的 Elpy 缓冲区内 python 解释器连接到 docker 容器?
How to connect Emacs' Elpy in-buffer python interpreter to docker container?
我开始开发一个 Django 应用程序,它将 运行 在 Docker 容器中。我希望能够在 Emacs 中使用 interactive python,它在 Docker 容器和 Django 应用程序的上下文中执行代码。本质上,我希望 Emacs 使用的 Python 解释器在 Docker 容器中 运行ning。
我在很大程度上通过创建一个修改过的 Docker 文件来实现这一点,它与我实际的 Docker 文件容器唯一不同的是,它不是调用 Django 命令,而是以结尾:
CMD ./manage.py shell
这意味着当我 运行 那个 Docker 容器时,我得到一个 Django 解释器,它实际上 运行 正在容器中。我让 Elpy 在启动 python shell 时调用它,方法是添加:
(setq python-shell-interpreter "/path_to_my_script/run_shell.sh")
到我的 .emacs.d/init.el 文件。其中“/path_to_my_script/run_shell.sh”脚本是 运行 容器的脚本。
这实际上适用于 most 部分。我能够突出显示一行代码,例如
from django.utils import timezone
和 运行 Emacs 命令 elpy-shell-send-region-or-buffer 它将执行代码。然后我可以突出显示
print(timezone.now())
它会打印当前时间。我已经通过 运行ning:
验证了这段代码实际上是 运行ning 在我的容器上
import os
print(os.getcwd())
并看到我的 Docker 容器用户的主目录。
我仍然遇到此设置的问题是当我尝试使用相同的 elpy-shell-send-region-or-buffer 同时执行多行 python命令。当我突出显示多行并执行该命令时,我在 python shell:
中收到以下错误
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.5/codecs.py", line 895, in open
file = builtins.open(filename, mode, buffering)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/py10324GOe'
我找不到以下问题的任何答案:
- 为什么 codecs.py 试图读取 tmp 文件?
- Python 创建的所有临时文件有什么用? (如果你有一些 python 代码 运行ning 并查看你的 /tmp 目录,你可能会看到很多像 py271761jE.)
- 为什么我的 Docker 容器中的 /tmp 目录是空的?似乎 Python 想要在该目录中创建和读取文件但失败了。
- 我该如何调试它?
如果有人对这些问题中的任何一个有任何答案,那将是一个巨大的帮助。我无法找到有关此问题的任何信息。谷歌搜索 /tmp 目录中的 py* 文件只会出现临时文件包。
我不知道发生了什么,但我目前的理论是,当一个有多行的区域被发送到 python shell 它需要处理换行符,所以它会尝试使用编解码器文件。我认为这个文件不知何故依赖于临时文件,而 docker 容器把它搞砸了。我不知道这个理论有多接近,但我不知道如何进一步调查它。
Why is codecs.py trying to read a tmp file?
我很确定这就是正在发生的事情:
- Emacs 将代码写入
/tmp/py10324GOe
- Emacs 指示 Python 加载
/tmp/py10324GOe
- Python 失败,因为容器无法访问主机的
/tmp/
。容器有自己独立的 /tmp/
目录。
解决此问题的最简单方法是 link 主机的 /tmp/
目录到容器的 /tmp/
目录。一些谷歌搜索引导我执行如下命令:
docker run ... -v /tmp:/tmp
我还没有测试过那个代码,但它似乎是正确的方向。
我通过修改 python-shell--save-temp-file
函数取得了一些成功
/usr/local/share/emacs/26.3/lisp/progmodes/python.el.gz
(defun python-shell--save-temp-file (string)
(let* ((temporary-file-directory
(if (file-remote-p default-directory)
(concat (file-remote-p default-directory) "/tmp")
temporary-file-directory))
(temp-file-name (make-temp-file "py"))
(coding-system-for-write (python-info-encoding)))
;; vvvv asychronous won't work ;;; change ownership of the tmp file to the user firing python proc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; inside the container and
(call-process "docker" nil nil nil "exec" "-u" "root" "mycontainer" "chown" "pythonuser:" temp-file-name)
(call-process "docker" nil nil nil "exec" "-u" "root" "mycontainer" "chmod" "606" temp-file-name)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; my user on the host need also access to that file so o+rw
(with-temp-file temp-file-name
(insert string)
(delete-trailing-whitespace))
temp-file-name))
希望有人能给出更巧妙的解决方案。
我开始开发一个 Django 应用程序,它将 运行 在 Docker 容器中。我希望能够在 Emacs 中使用 interactive python,它在 Docker 容器和 Django 应用程序的上下文中执行代码。本质上,我希望 Emacs 使用的 Python 解释器在 Docker 容器中 运行ning。
我在很大程度上通过创建一个修改过的 Docker 文件来实现这一点,它与我实际的 Docker 文件容器唯一不同的是,它不是调用 Django 命令,而是以结尾:
CMD ./manage.py shell
这意味着当我 运行 那个 Docker 容器时,我得到一个 Django 解释器,它实际上 运行 正在容器中。我让 Elpy 在启动 python shell 时调用它,方法是添加:
(setq python-shell-interpreter "/path_to_my_script/run_shell.sh")
到我的 .emacs.d/init.el 文件。其中“/path_to_my_script/run_shell.sh”脚本是 运行 容器的脚本。
这实际上适用于 most 部分。我能够突出显示一行代码,例如
from django.utils import timezone
和 运行 Emacs 命令 elpy-shell-send-region-or-buffer 它将执行代码。然后我可以突出显示
print(timezone.now())
它会打印当前时间。我已经通过 运行ning:
验证了这段代码实际上是 运行ning 在我的容器上import os
print(os.getcwd())
并看到我的 Docker 容器用户的主目录。
我仍然遇到此设置的问题是当我尝试使用相同的 elpy-shell-send-region-or-buffer 同时执行多行 python命令。当我突出显示多行并执行该命令时,我在 python shell:
中收到以下错误Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.5/codecs.py", line 895, in open
file = builtins.open(filename, mode, buffering)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/py10324GOe'
我找不到以下问题的任何答案:
- 为什么 codecs.py 试图读取 tmp 文件?
- Python 创建的所有临时文件有什么用? (如果你有一些 python 代码 运行ning 并查看你的 /tmp 目录,你可能会看到很多像 py271761jE.)
- 为什么我的 Docker 容器中的 /tmp 目录是空的?似乎 Python 想要在该目录中创建和读取文件但失败了。
- 我该如何调试它?
如果有人对这些问题中的任何一个有任何答案,那将是一个巨大的帮助。我无法找到有关此问题的任何信息。谷歌搜索 /tmp 目录中的 py* 文件只会出现临时文件包。
我不知道发生了什么,但我目前的理论是,当一个有多行的区域被发送到 python shell 它需要处理换行符,所以它会尝试使用编解码器文件。我认为这个文件不知何故依赖于临时文件,而 docker 容器把它搞砸了。我不知道这个理论有多接近,但我不知道如何进一步调查它。
Why is codecs.py trying to read a tmp file?
我很确定这就是正在发生的事情:
- Emacs 将代码写入
/tmp/py10324GOe
- Emacs 指示 Python 加载
/tmp/py10324GOe
- Python 失败,因为容器无法访问主机的
/tmp/
。容器有自己独立的/tmp/
目录。
解决此问题的最简单方法是 link 主机的 /tmp/
目录到容器的 /tmp/
目录。一些谷歌搜索引导我执行如下命令:
docker run ... -v /tmp:/tmp
我还没有测试过那个代码,但它似乎是正确的方向。
我通过修改 python-shell--save-temp-file
函数取得了一些成功
/usr/local/share/emacs/26.3/lisp/progmodes/python.el.gz
(defun python-shell--save-temp-file (string)
(let* ((temporary-file-directory
(if (file-remote-p default-directory)
(concat (file-remote-p default-directory) "/tmp")
temporary-file-directory))
(temp-file-name (make-temp-file "py"))
(coding-system-for-write (python-info-encoding)))
;; vvvv asychronous won't work ;;; change ownership of the tmp file to the user firing python proc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; inside the container and
(call-process "docker" nil nil nil "exec" "-u" "root" "mycontainer" "chown" "pythonuser:" temp-file-name)
(call-process "docker" nil nil nil "exec" "-u" "root" "mycontainer" "chmod" "606" temp-file-name)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; my user on the host need also access to that file so o+rw
(with-temp-file temp-file-name
(insert string)
(delete-trailing-whitespace))
temp-file-name))
希望有人能给出更巧妙的解决方案。