Check out the final code here.
¶What we’ll cover:
- python-mode
- lsp-mode
- Debugging with dap-mode
- Running tests with Projectile
- Using virtualenv
¶Our example project
¶Installing requirements
pip install -r requirements.txt
¶Using python-mode
(use-package python-mode :ensure nil :custom (python-shell-interpreter "python3"))
Commands:
- Interactive Python shell:
M-x run-python(C-c C-porg zin evil-mode) python-shell-send-file(C-c C-l)python-shell-send-buffer(C-c C-c)python-shell-send-region(C-c C-r)
¶Setting up lsp-mode
¶Installing pyls
https://emacs-lsp.github.io/lsp-mode/page/languages/
pip install --user python-language-server[all]
Ensure that it’s on the PATH! If not, you may need to add ~/.local/bin to PATH
¶Activating lsp-mode
We are starting with the lsp-mode configuration from “Build Your Own IDE with lsp-mode”, check that out for more details on lsp-mode!
:hook (python-mode . lsp-deferred))
¶Completion error!
If you see an error complaining about company-capf, this may be a bug with lsp-mode.
As a workaround, run package-reinstall to reinstall lsp-mode and lsp-ui packages and then restart Emacs.
¶lsp-mode features
¶Completions
¶Documentation hover
¶Signature help
¶Linting / diagnostics - flycheck-list-errors
¶Code navigation - lsp-find-definition and lsp-find-references
¶Symbol renaming - lsp-rename
¶Code formatting - lsp-format-buffer
¶Symbol tree - lsp-treemacs-symbols
¶Running unit tests
Using pytest:
pip install pytest
Skip test_results.py, it’s slow!
Use Projectile’s projectile-test-project command:
- Set a directory-local variable for
projectile-project-test-cmdwithadd-dir-local-variable - Set
compilation-read-commandtonilto skip asking every time you want to run the test (might be unsafe!) - You can use
g rinside of the unit test buffer to rerun the tests or callrecompileinteractively
Induce a failure!
¶Debugging
I recommend watching “Emacs IDE - How to Debug Your Code with dap-mode” to learn more about the features!
Configuration instructions: https://emacs-lsp.github.io/dap-mode/page/configuration/#python
However, we will use debugpy (ptvsd is deprecated):
pip install debugpy
(dap-python-debugger 'debugpy)
Run dap-debug and select the pytest configuration. Fails due to python2!
Set dap-python-executable to python3
(dap-python-executable "python3")
Running the default pytest configuration doesn’t launch from the correct path, let’s edit the configuration with dap-debug-edit-template:
(dap-register-debug-template "Python :: Run pytest (gallery-dl)" (list :type "python" :cwd "/home/daviwil/Projects/Code/gallery-dl" :module "pytest" :request "launch" :debugger 'debugpy :name "Python :: Run pytest (gallery-dl)"))
However, this still doesn’t work correctly from within a file in the project folder. dap-mode bug?
¶Virtual Environments
This part is only necessary if you use virtualenv in your Python development workflow!
virtualenv env . env/bin/activate
Use pyvenv for setting up the right virtualenv in Emacs:
(use-package pyvenv :config (pyvenv-mode 1))
Run pyvenv-activate and select the env folder, now lsp-mode and dap-mode will use it!
