簡體   English   中英

如何將 Emacs 的 Elpy 緩沖區內 python 解釋器連接到 docker 容器?

[英]How to connect Emacs' Elpy in-buffer python interpreter to docker container?

我開始研究將在 Docker 容器中運行的 Django 應用程序。 我希望能夠在 Emacs 中使用交互式 python ,它在 Docker 容器和 Django 應用程序的上下文中執行代碼。 本質上,我希望 Emacs 使用的 Python 解釋器在 Docker 容器中運行。

我已經設法通過創建一個修改后的 Dockerfile 來實現這一點,該 Dockerfile 僅與我實際的 Dockerfile 容器不同,而不是調用它以以下內容結尾的 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”腳本是運行容器的腳本。

這實際上是工作的大部分 我能夠突出顯示一行代碼,例如

from django.utils import timezone

並運行 Emacs 命令elpy-shell-send-region-or-buffer它將執行代碼。 然后我可以突出顯示

print(timezone.now())

它會打印當前時間。 我已經通過運行驗證此代碼實際上正在我的容器上運行:

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 代碼正在運行並查看你的/tmp目錄,你可能會看到很多像py271761jE這樣的文件。)
  • 為什么我的 Docker 容器中的 /tmp 目錄是空的? 似乎 Python 想要創建和讀取該目錄中的文件,但失敗了。
  • 我該如何調試?

如果有人對這些問題中的任何一個有任何答案,那將是一個巨大的幫助。 我一直無法提供有關此問題的任何信息。 在 /tmp 目錄中搜索 py* 文件只會找到 tempfile 包。

我不知道發生了什么,但我目前的理論是,當將具有多行的區域發送到 python shell 時,它需要處理換行符,因此它會嘗試使用編解碼器文件。 我認為這個文件在某種程度上依賴於臨時文件,而 docker 容器把它搞砸了。 我不知道這個理論有多接近,但我不知道如何進一步研究它。

為什么 codecs.py 試圖讀取 tmp 文件?

我很確定這就是正在發生的事情:

  1. Emacs 寫代碼到/tmp/py10324GOe
  2. Emacs 指示 Python 加載/tmp/py10324GOe
  3. Python 失敗,因為容器無法訪問主機的/tmp/ 容器有自己獨立的/tmp/目錄。

解決此問題的最簡單方法是將主機的/tmp/目錄鏈接到容器的/tmp/目錄。 一些谷歌搜索引導我到一個命令:

docker run ... -v /tmp:/tmp

我還沒有測試過那個代碼,但它似乎是正確的方向。

我通過修改/usr/local/share/emacs/26.3/lisp/progmodes/python.el.gz python-shell--save-temp-file函數取得了一些成功

(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))

希望有人能給出更聰明的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM