You don't need to care about a Python installer, just use mise...
mise install python@3.13 # or anything as above 'requires-python'mise use python@3.13 # or anything as above 'requires-python'mise use -g uv@latest
debugpy is an implementation of the Debug Adapter Protocol for
Python 3; DAP is an abstraction between IDEs and specific debug
adapters (like debugpy for Python).
LSPs:
- basepyright / lsp-bridge
- python-lsp-server
python-lsp-serveris on of the possibilities.
# ensure you have pipx installed
$ pipx ensurepath
$ pipx install python-lsp-server
$ pipx runpip python-lsp-server install "python-lsp-server[all]"
$ which pylsp
/home/jiri/.local/bin/pylsp
$ pylsp --version
pylsp v1.12.2The next step is to have
lsp-mode
in Emacs; but that needs Emacs
MELPA repo:
# I preferred XDG structure
# below escaped back-ticks
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Comment/uncomment this line to enable MELPA Stable if desired. See \`package-archive-priorities\`
;; and \`package-pinned-packages\`. Most users will not need or want to do this.
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)
EOFOpen Emacs and:
M-x package-refresh-contents
M-x package-install lsp-mode
M-x package-install lsp-ui
M-x package-install company
M-x lsp-mode
$ pstree -Aal $(pgrep emacs) | fold -w80
emacs -nw
`-pylsp /home/jiri/.local/bin/pylsp
|-python /home/jiri/.local/pipx/venvs/python-lsp-server/lib/python3.11/sit
e-packages/jedi/inference/compiled/subprocess/__main__.py /home/jiri/.local/pipx
/venvs/python-lsp-server/lib/python3.11/site-packages 3.11.2
`-{pylsp}(Pdb) l 110,113
110 -> if IMPORT_PAGE_EXTRACTOR: # in self.site.config:
111 content = IMPORT_PAGE_EXTRACTOR(node)
112 else:
113 content = node.prettify()
(Pdb) p bool(IMPORT_PAGE_EXTRACTOR)
True
(Pdb) p IMPORT_PAGE_EXTRACTOR
<function CommandImportPage._import_page.<locals>.<lambda> at 0x7f093b64ab60>
(Pdb) import inspect
(Pdb) p inspect.getsource(IMPORT_PAGE_EXTRACTOR)
' IMPORT_PAGE_EXTRACTOR = lambda node: BeautifulSoup(node.decode_contents(), "html.parser").prettify()\n'
(Pdb) !IMPORT_PAGE_EXTRACTOR = None
(Pdb) p bool(IMPORT_PAGE_EXTRACTOR)
False
(pdb) n
(Pdb) l 110,113
110 if IMPORT_PAGE_EXTRACTOR: # in self.site.config:
111 content = IMPORT_PAGE_EXTRACTOR(node)
112 else:
113 -> content = node.prettify()So, here, an example how to make a lamba-based variable None; that
is, change the code flow in the condition.
Now, breakpoints:
(Pdb) l 69
64 doc_usage = "[options] page_url [page_url,...]"
65 doc_purpose = "import arbitrary web pages"
66
67 def _execute(self, options, args):
68 import pdb;pdb.set_trace()
69 -> """Import a Page."""
70 if BeautifulSoup is None:
71 utils.req_missing(['bs4'], 'use the import_page plugin')
72
73 urls = []
74 selector = None
(Pdb) l 86,90
86 if not urls:
87 LOGGER.error(f'No page URL or file path provided.')
88
89 for url in args:
90 self._import_page(url, selector, extractor)
(Pdb) b 86
Breakpoint 1 at /home/jiri/.nikola/plugins/import_page/import_page.py:86
(Pdb) b
Num Type Disp Enb Where
1 breakpoint keep yes at /home/jiri/.nikola/plugins/import_page/import_page.py:86
(Pdb) c
> /home/jiri/.nikola/plugins/import_page/import_page.py(86)_execute()
-> if not urls:
(Pdb) l 86
81 elif arg == "-e" and args:
82 extractor = args.pop(0)
83 else:
84 urls.append(arg) # Assume it's a page URL
85
86 B-> if not urls:
87 LOGGER.error(f'No page URL or file path provided.')
88
89 for url in args:
90 self._import_page(url, selector, extractor)
91 This is the simplest approach:
$ python -m venv .venv
$ pip install pyyaml remote_pdb
$ pip freeze > requirements.txt
cat requirements.txt
PyYAML==6.0.2
remote-pdb==2.1.0mise.toml for development setup, pyproject.toml for the actual
Python project.
This is good for simple projects, eg. scripts...
$ cat mise.toml
min_version = "2026.2.4"
[env]
_.python.venv = { path = ".venv", create = true }
[tools]
python = "3.14"
uv = "latest"
[tasks.test]
description = "Run tests"
run = "uv run pytest"
[tasks.lint]
description = "Lint the code"
run = "ruff check src/"$ cat pyproject.toml
[project]
name = "foobar"
version = "0.0.1"
description = "Foobar project"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"requests",
]
[project.scripts]
foobar = "foobar.cli:main"
[dependency-groups]
dev = [
"ruff",
"pytest",
]
[tool.ruff.lint]
select = ["Q"]
[tool.ruff.lint.flake8-quotes]
inline-quotes = "double"
multiline-quotes = "double"
docstring-quotes = "double"
[tool.uv]
package = trueThis way, you can setup development environment with mise install,
and use the application via pipx.
Modern way:
$ mise use -g poetry
$ poetry new wb-country-stats
$ find wb-country-stats/
wb-country-stats/
wb-country-stats/src
wb-country-stats/src/wb_country_stats
wb-country-stats/src/wb_country_stats/__init__.py
wb-country-stats/README.md
wb-country-stats/tests
wb-country-stats/tests/__init__.py
wb-country-stats/pyproject.tomlThis is a variation of uv
Installation, I needed
that this way, because I was setting HTTP proxy for current powershell
session, my Windows have no direct access to Internet.
- powershell
Set-ExecutionPolicy RemoteSigned -scope CurrentUser(irm https://astral.sh/uv/install.ps1) -replace '\bexit\b', '#exit removed' | iex$env:Path = "C:\Users\user\.local\bin;$env:Path"- Use a PEP 723 comfortant script, see https://realpython.com/python-script-structure/
uv run <python script>PS C:\Users\user> uv run .\a5_to_a4.py input.pdf output.pdf Installed 1 package in 103ms Done: output.pdf
One can also run it under mise.
winget install jdx.misemise use -g uv@latestmise exec -- uv run <script>
jinja-cli is nice tools to validate Jinja templates/syntax:
# here testing overload of apache_httpd_package variable
$ printf '%s\n%s\n' '{% set _pkg = apache_httpd_package | default("apache2", true) %}' '{{- _pkg }}' | \
jinja
apache2
# ...simulating the overload, eg. for a distro which has different package name
$ printf '%s\n%s\n' '{% set _pkg = apache_httpd_package | default("apache2", true) %}' '{{- _pkg }}' | \
jinja -D apache_httpd_package httpd
httpd