Managing dependencies
Contents
Managing dependencies¶
Packages¶
conda-forge vs. PyPI
We want
to specify the package versions we depend on (is it a
==
requirement? or a>=
requirement?)to solve version conflicts automatically (and know beforehand of incompatibilities)
to distribute our code so that people can install compatible versions of libraries, or even install exactly the same package versions that worked on our computer
Example: https://github.com/openlawlibrary/pygls/pull/148
pydantic seems to make breaking changes at minor releases; however 1.8 works just fine so I’ve allowed 1.7.x and 1.8.x
We will use Poetry
Options for virtual environments:¶
If you are happy with the system Python version:
mkdir testproj
python -m venv .venv
If you are not happy with the system Python version, use pyenv (I haven’t tried those)
for these two last options, and you do not need to do anything special to use Poetry.
If you want to use Conda:
Use Conda to set non-Python-package things, such as the Python interpreter
conda create -n testproj_env python==3.10
conda activate testproj_env
.. but you’ll need to activate the Conda environment before using Poetry on the command line.
Note: the only weak spot of Poetry is publishing packages with C/C++/Fortran/Cython code. The workaround I’d recommend is this: put the C/C++/Fortran/Cython parts in a separate package managed by an old-style setup.py
script, where you can use wonderful legacy tools such a f2py
etc. Then add this separate package as a requirement in your main project.
Starting a project with Poetry¶
Setup Poetry and the environments¶
Optional: use Conda to create a Conda environment with the Python version you want to use (and potentially external tools required for the project, but avoid if possible)
$ mkdir testproj
$ cd testproj
$ conda activate testproj_env
or
$ mkdir testproj
$ cd testproj
$ python -m venv .venv
Now it’s time to generate the pyproject.toml
info file.
(testproj_env) $ poetry init
This command will guide you through creating your pyproject.toml config.
Package name [testproj]:
Version [0.1.0]:
Description []:
Author [Denis Rosset <physics@denisrosset.com>, n to skip]:
License []:
Compatible Python versions [^3.10]:
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file
[tool.poetry]
name = "testproj"
version = "0.1.0"
description = ""
authors = ["Denis Rosset <physics@denisrosset.com>"]
[tool.poetry.dependencies]
python = "^3.10"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Do you confirm generation? (yes/no) [yes] yes
(testproj_env) $
This generated a pyproject.toml
file.
Add the development dependencies:¶
(testproj_env) $ poetry add --dev black mypy pytest isort
Using version ^22.1.0 for black
Using version ^0.941 for mypy
Using version ^7.1.1 for pytest
Using version ^5.10.1 for isort
Updating dependencies
Resolving dependencies... (1.1s)
Writing lock file
Package operations: 16 installs, 0 updates, 0 removals
• Installing pyparsing (3.0.7)
• Installing attrs (21.4.0)
• Installing click (8.0.4)
• Installing iniconfig (1.1.1)
• Installing mypy-extensions (0.4.3)
• Installing packaging (21.3)
• Installing pathspec (0.9.0)
• Installing platformdirs (2.5.1)
• Installing pluggy (1.0.0)
• Installing py (1.11.0)
• Installing tomli (2.0.1)
• Installing typing-extensions (4.1.1)
• Installing black (22.1.0)
• Installing isort (5.10.1)
• Installing mypy (0.941)
• Installing pytest (7.1.1)
Open the project in VS Code¶
Now you can open the testproj
folder in VS Code.
Formatting¶
Add to pyproject.toml
the defaults for the formatting tools:
[tool.black]
line-length = 99
target_version = ['py310'] # replace by your Python version
[tool.doc8]
max-line-length = 99
[tool.isort]
line_length = 99
profile = "black"
py_version = 310
.gitignore¶
Create a minimal .gitignore
file:
.venv/
__pycache__/
.mypy_cache/
.pytest_cache/
build/
dist/
.pytest_cache/
VS code¶
Create a testproj/.vscode
folder and add the following bare-bones settings.json
file:
{
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.linting.mypyEnabled": true,
"editor.formatOnSave": true,
"python.formatting.provider": "black",
"editor.rulers": [
99
],
"[python]": {
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"files.exclude": {
".venv/": true,
"**/__pycache__": true,
"**/.mypy_cache": true,
"**/.pytest_cache": true,
"**/build": true,
"**/dist": true,
},
}
Test the stuff¶
Create a adder.py
file with the following:
def addition(x: float, y: float) -> float:
return x + y
Verify that Black reformats the code on save.
Now let’s write a test script test_addition.py
:
from adder import addition
def test_addition() -> None:
assert addition(2, 2) == 4