From ac0825a7194c7045b87cf6320593e9de47e3a131 Mon Sep 17 00:00:00 2001 From: DMRobertson Date: Fri, 10 Jun 2022 14:48:27 +0000 Subject: deploy: 4579445cc54640341ef23cddad9c0518e90be63a --- develop/development/cas.html | 2 +- develop/development/contributing_guide.html | 2 +- develop/development/database_schema.html | 2 +- develop/development/demo.html | 2 +- develop/development/dependencies.html | 364 +++++++++++++++++++++ develop/development/experimental_features.html | 6 +- develop/development/git.html | 2 +- .../development/internal_documentation/index.html | 2 +- develop/development/releases.html | 2 +- develop/development/room-dag-concepts.html | 2 +- develop/development/saml.html | 2 +- .../synapse_architecture/cancellation.html | 6 +- develop/development/url_previews.html | 2 +- 13 files changed, 380 insertions(+), 16 deletions(-) create mode 100644 develop/development/dependencies.html (limited to 'develop/development') diff --git a/develop/development/cas.html b/develop/development/cas.html index 5adc9578da..d83c1ff4e5 100644 --- a/develop/development/cas.html +++ b/develop/development/cas.html @@ -76,7 +76,7 @@ diff --git a/develop/development/contributing_guide.html b/develop/development/contributing_guide.html index 1d4b261bb6..88f4bb7a5c 100644 --- a/develop/development/contributing_guide.html +++ b/develop/development/contributing_guide.html @@ -76,7 +76,7 @@ diff --git a/develop/development/database_schema.html b/develop/development/database_schema.html index 7c0c9a6eb2..fc76a6f99b 100644 --- a/develop/development/database_schema.html +++ b/develop/development/database_schema.html @@ -76,7 +76,7 @@ diff --git a/develop/development/demo.html b/develop/development/demo.html index b8e499587a..c4250f27a8 100644 --- a/develop/development/demo.html +++ b/develop/development/demo.html @@ -76,7 +76,7 @@ diff --git a/develop/development/dependencies.html b/develop/development/dependencies.html new file mode 100644 index 0000000000..a663ae5670 --- /dev/null +++ b/develop/development/dependencies.html @@ -0,0 +1,364 @@ + + + + + + Dependency management - Synapse + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + +
+
+ +
+ +
+ +

Managing dependencies with Poetry

+

This is a quick cheat sheet for developers on how to use poetry.

+

Background

+

Synapse uses a variety of third-party Python packages to function as a homeserver. +Some of these are direct dependencies, listed in pyproject.toml under the +[tool.poetry.dependencies] section. The rest are transitive dependencies (the +things that our direct dependencies themselves depend on, and so on recursively.)

+

We maintain a locked list of all our dependencies (transitive included) so that +we can track exactly which version of each dependency appears in a given release. +See here +for discussion of why we wanted this for Synapse. We chose to use +poetry to manage this locked list; see +this comment +for the reasoning.

+

The locked dependencies get included in our "self-contained" releases: namely, +our docker images and our debian packages. We also use the locked dependencies +in development and our continuous integration.

+

Separately, our "broad" dependencies—the version ranges specified in +pyproject.toml—are included as metadata in our "sdists" and "wheels" uploaded +to PyPI. Installing from PyPI or from +the Synapse source tree directly will not use the locked dependencies; instead, +they'll pull in the latest version of each package available at install time.

+

Example dependency

+

An example may help. We have a broad dependency on +phonenumbers, as declared in +this snippet from pyproject.toml as of Synapse 1.57:

+
[tool.poetry.dependencies]
+# ...
+phonenumbers = ">=8.2.0"
+
+

In our lockfile this is +pinned +to version 8.12.44, even though +newer versions are available.

+
[[package]]
+name = "phonenumbers"
+version = "8.12.44"
+description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
+category = "main"
+optional = false
+python-versions = "*"
+
+

The lockfile also includes a +cryptographic checksum +of the sdists and wheels provided for this version of phonenumbers.

+
[metadata.files]
+# ...
+phonenumbers = [
+    {file = "phonenumbers-8.12.44-py2.py3-none-any.whl", hash = "sha256:cc1299cf37b309ecab6214297663ab86cb3d64ae37fd5b88e904fe7983a874a6"},
+    {file = "phonenumbers-8.12.44.tar.gz", hash = "sha256:26cfd0257d1704fe2f88caff2caabb70d16a877b1e65b6aae51f9fbbe10aa8ce"},
+]
+
+

We can see this pinned version inside the docker image for that release:

+
$ docker pull matrixdotorg/synapse:v1.57.0
+...
+$ docker run --entrypoint pip matrixdotorg/synapse:v1.57.0 show phonenumbers
+Name: phonenumbers
+Version: 8.12.44
+Summary: Python version of Google's common library for parsing, formatting, storing and validating international phone numbers.
+Home-page: https://github.com/daviddrysdale/python-phonenumbers
+Author: David Drysdale
+Author-email: dmd@lurklurk.org
+License: Apache License 2.0
+Location: /usr/local/lib/python3.9/site-packages
+Requires:
+Required-by: matrix-synapse
+
+

Whereas the wheel metadata just contains the broad dependencies:

+
$ cd /tmp
+$ wget https://files.pythonhosted.org/packages/ca/5e/d722d572cc5b3092402b783d6b7185901b444427633bd8a6b00ea0dd41b7/matrix_synapse-1.57.0rc1-py3-none-any.whl
+...
+$ unzip -c matrix_synapse-1.57.0rc1-py3-none-any.whl matrix_synapse-1.57.0rc1.dist-info/METADATA | grep phonenumbers
+Requires-Dist: phonenumbers (>=8.2.0)
+
+

Tooling recommendation: direnv

+

direnv is a tool for activating environments in your +shell inside a given directory. Its support for poetry is unofficial (a +community wiki recipe only), but works solidly in our experience. We thoroughly +recommend it for daily use. To use it:

+
    +
  1. Install direnv - it's likely +packaged for your system already.
  2. +
  3. Teach direnv about poetry. The shell config here +needs to be added to ~/.config/direnv/direnvrc (or more generally $XDG_CONFIG_HOME/direnv/direnvrc).
  4. +
  5. Mark the synapse checkout as a poetry project: echo layout poetry > .envrc.
  6. +
  7. Convince yourself that you trust this .envrc configuration and project. +Then formally confirm this to direnv by running direnv allow.
  8. +
+

Then whenever you navigate to the synapse checkout, you should be able to run +e.g. mypy instead of poetry run mypy; python instead of +poetry run python; and your shell commands will automatically run in the +context of poetry's venv, without having to run poetry shell beforehand.

+

How do I...

+

...reset my venv to the locked environment?

+
poetry install --extras all --remove-untracked
+
+

...run a command in the poetry virtualenv?

+

Use poetry run cmd args when you need the python virtualenv context. +To avoid typing poetry run all the time, you can run poetry shell +to start a new shell in the poetry virtualenv context. Within poetry shell, +python, pip, mypy, trial, etc. are all run inside the project virtualenv +and isolated from the rest o the system.

+

Roughly speaking, the translation from a traditional virtualenv is:

+
    +
  • env/bin/activate -> poetry shell, and
  • +
  • deactivate -> close the terminal (Ctrl-D, exit, etc.)
  • +
+

See also the direnv recommendation above, which makes poetry run and +poetry shell unnecessary.

+

...inspect the poetry virtualenv?

+

Some suggestions:

+
# Current env only
+poetry env info
+# All envs: this allows you to have e.g. a poetry managed venv for Python 3.7,
+# and another for Python 3.10.
+poetry env list --full-path
+poetry run pip list
+
+

Note that poetry show describes the abstract lock file rather than your +on-disk environment. With that said, poetry show --tree can sometimes be +useful.

+

...add a new dependency?

+

Either:

+
    +
  • manually update pyproject.toml; then poetry lock --no-update; or else
  • +
  • poetry add packagename. See poetry add --help; note the --dev, +--extras and --optional flags in particular. +
      +
    • NB: this specifies the new package with a version given by a "caret bound". This won't get forced to its lowest version in the old deps CI job: see this TODO.
    • +
    +
  • +
+

Include the updated pyproject.toml and poetry.lock files in your commit.

+

...remove a dependency?

+

This is not done often and is untested, but

+
poetry remove packagename
+
+

ought to do the trick. Alternatively, manually update pyproject.toml and +poetry lock --no-update. Include the updated pyproject.toml and poetry.lock` +files in your commit.

+

...update the version range for an existing dependency?

+

Best done by manually editing pyproject.toml, then poetry lock --no-update. +Include the updated pyproject.toml and poetry.lock in your commit.

+

...update a dependency in the locked environment?

+

Use

+
poetry update packagename
+
+

to use the latest version of packagename in the locked environment, without +affecting the broad dependencies listed in the wheel.

+

There doesn't seem to be a way to do this whilst locking a specific version of +packagename. We can workaround this (crudely) as follows:

+
poetry add packagename==1.2.3
+# This should update pyproject.lock.
+
+# Now undo the changes to pyproject.toml. For example
+# git restore pyproject.toml
+
+# Get poetry to recompute the content-hash of pyproject.toml without changing
+# the locked package versions.
+poetry lock --no-update
+
+

Either way, include the updated poetry.lock file in your commit.

+

...export a requirements.txt file?

+
poetry export --extras all
+
+

Be wary of bugs in poetry export and pip install -r requirements.txt.

+

Note: poetry export will be made a plugin in Poetry 1.2. Additional config may +be required.

+

...build a test wheel?

+

I usually use

+
poetry run pip install build && poetry run python -m build
+
+

because build is a standardish tool which +doesn't require poetry. (It's what we use in CI too). However, you could try +poetry build too.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/develop/development/experimental_features.html b/develop/development/experimental_features.html index cd6104999e..723d989e20 100644 --- a/develop/development/experimental_features.html +++ b/develop/development/experimental_features.html @@ -76,7 +76,7 @@ @@ -187,7 +187,7 @@ configuration key (see the synapse.config.experimental file) and ei -
@@ -199,7 +199,7 @@ configuration key (see the synapse.config.experimental file) and ei - diff --git a/develop/development/git.html b/develop/development/git.html index 9a1c2bdd79..3011625077 100644 --- a/develop/development/git.html +++ b/develop/development/git.html @@ -76,7 +76,7 @@ diff --git a/develop/development/internal_documentation/index.html b/develop/development/internal_documentation/index.html index fe8ab238f2..23f81c8722 100644 --- a/develop/development/internal_documentation/index.html +++ b/develop/development/internal_documentation/index.html @@ -76,7 +76,7 @@ diff --git a/develop/development/releases.html b/develop/development/releases.html index 7a26758cb1..6453515b88 100644 --- a/develop/development/releases.html +++ b/develop/development/releases.html @@ -76,7 +76,7 @@ diff --git a/develop/development/room-dag-concepts.html b/develop/development/room-dag-concepts.html index 4b34c6d62f..bcc8460602 100644 --- a/develop/development/room-dag-concepts.html +++ b/develop/development/room-dag-concepts.html @@ -76,7 +76,7 @@ diff --git a/develop/development/saml.html b/develop/development/saml.html index 860d69cf8a..59f7779b02 100644 --- a/develop/development/saml.html +++ b/develop/development/saml.html @@ -76,7 +76,7 @@ diff --git a/develop/development/synapse_architecture/cancellation.html b/develop/development/synapse_architecture/cancellation.html index d67f9eb56c..e0ede3125c 100644 --- a/develop/development/synapse_architecture/cancellation.html +++ b/develop/development/synapse_architecture/cancellation.html @@ -76,7 +76,7 @@ @@ -498,7 +498,7 @@ with LoggingContext("request-1"):