Rye is Armin Ronacher's new experimental Python packaging tool. I decided to take it for a test-run.
Rye is built in Rust, and currently needs to be installed using Cargo. I had Cargo from previous dalliances with Rust, so I could install Rye using:
cargo install --git https://github.com/mitsuhiko/rye rye
This resulted in a 6.4MB binary file in:
~/.cargo/bin/rye
I added the following line to my ~/.zshrc
file to make it available on my path:
export PATH=$PATH:$HOME/.cargo/bin
The Rye docs suggested running this:
rye pin cpython@3.11
As far as I can tell all this did was write 3.11.1
to a ~/.python-version
file. I'm not sure if there are any tools other than Rye which pay attention to this file. (UPDATE: pyenv uses this file too)
Actually fetching versions of Python can be done using rye toolchain fetch VERSION
, for example:
% rye toolchain fetch 3.9
Downloading cpython@3.9.16
success: Downloaded cpython@3.9.16
This placed a whole bunch of files in ~/.rye/py/cpython@3.9.16/
- find . | wc -l
reported 4,085 in that directory.
The one that matters most is:
~/.rye/py/cpython@3.9.16/install/bin/python3
Which gives me a 3.9.16 Python interpreter.
This is the feature of Rye I'm most excited about: the Python bundles it installs come from Gregory Szorc's indygreg/python-build-standalone project.
This should mean that they completely ignore the many other weird ways that Python can end up installed on a system. Admittedly, this is a new weird way to install Python - but at least it shouldn't clash with anything else.
Normally though you wouldn't use rye toolchain fetch
at all. The Rye suggested workflow is to run rye init
in a new directory to create a pyproject.toml
file:
% cd /tmp
/tmp % mkdir my-project
/tmp % cd my-project
my-project % rye init
success: Initialized project in /private/tmp/my-project/.
my-project % ls
README.md pyproject.toml
my-project % cat pyproject.toml
[project]
name = "my-project"
version = "0.1.0"
description = "Add a short description here"
authors = [
{ name = "Simon Willison", email = "...@gmail.com" }
]
dependencies = []
readme = "README.md"
requires-python = ">= 3.8"
license = { text = "MIT" }
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.rye]
managed = true
my-project % cat README.md
# my-project
Describe your project here.
* License: MIT
To add dependencies to that project, use rye add
:
rye add httpx
This added the following line to pyproject.toml
:
dependencies = ["httpx~=0.24.0"]
Then to actually install the dependencies, run rye sync
:
my-project % rye sync
Initializing new virtualenv in /private/tmp/my-project/.venv
Python version: cpython@3.11.1
Generating production lockfile: /private/tmp/my-project/requirements.lock
Generating dev lockfile: /private/tmp/my-project/requirements-dev.lock
Installing dependencies
...
Successfully built my-project
Installing collected packages: sniffio, idna, h11, certifi, anyio, httpcore, httpx, my-project
Successfully installed anyio-3.6.2 certifi-2022.12.7 h11-0.14.0 httpcore-0.17.0 httpx-0.24.0 idna-3.4 my-project-0.1.0 sniffio-1.3.0
Done!
This adds a requirements.lock
file that looks like this:
# generated by rye
# use `rye lock` or `rye sync` to update this lockfile
-e file:.
anyio==3.6.2
certifi==2022.12.7
h11==0.14.0
httpcore==0.17.0
httpx==0.24.0
idna==3.4
sniffio==1.3.0
And a requirements-dev.lock
file with identical contents. Presumably this starts to differ as you install dev requirements (another Rye feature).
Your folder will now have a .venv
hidden folder in it. Inside that is a Python virtual environment containing your installed dependencies and a file called rye-venv.json
which just contains:
{
"python": "cpython@3.11.1"
}
The rye add X
command adds a dependency to your current virtual environment / Rye project.
rye install
does something completely different: it installs new global packages, in a similar fashion to pipx
in that they get their own isolated environments so their dependencies don't clash with other installed applications.
% rye install cowsay
Collecting cowsay
Downloading cowsay-5.0.tar.gz (25 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: cowsay
Building wheel for cowsay (pyproject.toml) ... done
Created wheel for cowsay: filename=cowsay-5.0-py2.py3-none-any.whl size=25707 sha256=de872e9ef328d25cd9ac58df693c7bfd913033f696282c60562854d0db38737e
Stored in directory: /Users/simon/Library/Caches/pip/wheels/d4/2d/c7/c018bd8e6f825d6b47ae38f28baabd4588b3857e0e7dbc8cd3
Successfully built cowsay
Installing collected packages: cowsay
Successfully installed cowsay-5.0
installed script cowsay
You can now run cowsay
with ~/.rye/shims/cowsay
:
% ~/.rye/shims/cowsay hello
_____
| hello |
=====
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
You can add ~/.rye/shims
to your $PATH
to make these commands available everywhere.
I tried to install Datasette using rye install datasette
and got this error:
% ~/.rye/shims/datasette
Traceback (most recent call last):
File "/Users/simon/.rye/shims/datasette", line 5, in <module>
from datasette.cli import cli
File "/Users/simon/.rye/tools/datasette/lib/python3.11/site-packages/datasette/cli.py", line 17, in <module>
from .app import (
File "/Users/simon/.rye/tools/datasette/lib/python3.11/site-packages/datasette/app.py", line 14, in <module>
import pkg_resources
ModuleNotFoundError: No module named 'pkg_resources'
Rye has strong opinions, including omitting pip
and setuptools
entirely from the environments that it creates.
[ UPDATE: I released Datasette 0.64.3 with a fix for this and now it installs correctly under Rye ]
It turns out Datasette includes code that imports pkg_resources
, assuming that setuptools
will be present because it's usually there as a Python environment default!
I added setuptools
to Datasette's setup.py
dependencies in an attempt to fix that, in issue #2065.
When I'm using pip
I often install development copies of my projects by feeding them the URL to a .zip
generated by GitHub, for example:
pip install https://github.com/simonw/datasette/archive/main.zip
I tried that with rye install
and got an error:
% rye install https://github.com/simonw/datasette/archive/main.zip
Error: Expected one of `@`, `(`, `<`, `=`, `>`, `~`, `!`, `;`, found `:`
https://github.com/simonw/datasette/archive/main.zip
^
Evidently Rye doesn't (yet?) support installing from URLs.
UPDATE: Armin showed me a way to do this:
rye install 'datasette @ https://github.com/simonw/datasette/archive/main.zip'
This worked - running
~/.rye/shims/datasette --version
confirmed the installation.
Instead, I downloaded the main.zip
file and ran Rye install against that directly:
% rye install main.zip
Processing ./main.zip
Installing build dependencies ... done
Getting requirements to build wheel ... done
...
Successfully built datasette
...
That seemed to work. Oddly it didn't add datasette
to the .rye/shims
directory - but I did find a working installation here instead:
~/.rye/tools/main-zip/bin/datasette
Created 2023-04-26T21:50:27-07:00, updated 2023-04-27T08:19:21-07:00 · History · Edit