diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..f2ff74399e --- /dev/null +++ b/404.html @@ -0,0 +1,776 @@ + + + +
+ + + + + + + + + + + + + + + +Here you can find all the released changes to Rye. If you want to also see +the in-development changes that were not released yet, refer to the +CHANGELOG.md file +in the repository.
+ + +Released on 2024-01-15
+Fixed default generated script reference. #527
+Correctly fall back to home folder if HOME is unset. #533
+Released on 2023-12-17
+By default a script with the name of the project is now also configured. #519
+Rye now configures hatchling better in rye init
so that it works with
+ hatchling 1.19 and later. #521
Rye now detects the dummy Python shim that starts the windows store and + refuses to consider it. #486
+Released on 2023-10-04
+Released on 2023-10-03
+Released on 2023-10-03
+Released on 2023-10-01
+Add support for fetching alternative CPU architectures. #447
+The order of git submodule initialization was changed. This improves the
+ automatic author detection when includeIf
is used. #443
The linux shim installer code will no longer fall back to symlinks when a
+ hardlink cannot be created. This is done as a symlinked shim will not
+ ever function correctly on Linux. This prevents the shim executables like
+ python
to instead act as if they are rye
. The fallback behavior is now
+ to copy the executable instead. #441
The installer now detects fish
and will spit out additional instructions
+ for configuring the shell.
Fix the wrong behavior when bump version. #454
+Released on 2023-08-29
+Add a python3
shim on windows. Previously entering python3
in the
+ command line would always bring up the windows store python proxy even
+ when global shims were enabled. As virtualenvs do not support the
+ python3
executable on windows, the internal shim handling is now also
+ changed so that trying to launch python3
will fall back to python
.
+ This makes it possible to run maturin build
.
Add maturin
build command to start a new maturin PyO3 project.
Released on 2023-08-27
+Improve handling of the pth files for TCL on pypy. #409
+The rye tools list
command now accepts -v
to also print out the
+ versions of the installed tools. #396
Fixed parsing of versions by rye version
. #397
Improved the help message for rye init
. #401
The email address now defaults to a syntactically valid email address + if not known to prevent errors with some build tools.
+Added new Python versions.
+The rye installer now detects NOEXEC
temporary folders and prints out
+ a more helpful error message. #394
Fixed an issue where the author email was incorrectly detected. #382
+The prompt of new virtualenvs is now set to the project name. #383
+Released on 2023-07-18
+Added new Python versions.
+Added a new config key default.author
to configure the default author
+ that should be set. This overrides the default author that is normally
+ loaded from the git config. #377
When importing with rye init
and no src
folder exists, it will not be
+ created. #375
Added support for shell
command on Windows. #363
Pin down pip to an older version to avoid issues with an incompatible
+ pip-tools
version. This does not yet update pip-tools to 7.0 as there
+ are significant regressions in 7.x. #374
The version
command can show dynamic versions now. #355
rye add
now properly checks some incompatible argument combinations. #347
There is now more toolchain validation. This better supports cases where + rye was interrupted during sync. #351
+Released on 2023-07-07
+Fixed a bug with rye init
not operating correctly due to a argument conflict. #346
Scripts now support a PDM style call
script type. #345
The init
command is now capable of importing existing projects. #265
Fixed the global shim behavior on Windows. #344
+Released on 2023-06-21
+The internal Rye Python version is now 3.11.
+Rye now emits most messages, most of the time to stdout rather than stderr. #342
+rye add
now accepts --pin
to let one override the type of pin to use. #341
Added rye config
to read and manipulate the config.toml
file. #339
Added support for the new behavior.global-python
flag which turns on global
+ Python shimming. When enabled then the python
shim works even outside of
+ Rye managed projects. Additionally the shim (when run outside of Rye managed
+ projects) supports a special first parameter +VERSION
which requests a
+ specific version of Python (eg: python +3.8
to request Python 3.8). #336
Renamed the config key default.dependency_operator
to default.dependency-operator
+ and behavior.force_rye_managed
to behavior.force-rye-managed
. #338
Released on 2023-06-18
+Rye for now prefers >=
over ~=
for newly added dependencies.
The workspace member declaration is now platform independent. If members
is
+ now explicitly set to an empty list it will not fall back to auto discovery. #331
rye add
now pins versions with ==
instead of ~=
when the version of the
+ package does not use at least two components. This means that for instance it
+ will now correctly use openai-whisper==20230314
rather than
+ openai-whisper~=20230314
which is not actually satisfiable. #328
rye install
now lets you install dependencies into the tool's virtualenv
+ during installation that are undeclared via the new --extra-requirement
+ option. #326
Improved handling of relative path installations by setting PROJECT_ROOT
+ the same way as PDM does. #321
Workspaces will now never discover pyproject.toml
files in any dot
+ directories. (Name starting with .
) #329
Fixed rye build
not working correctly on Windows. #327
Released on 2023-06-12
+rye sync
and rye lock
now accept --pyproject
. #296
Added JSON output to rye toolchain list
by adding --format=json
. #306
rye version
can bump version by --bump
option now. #298
Fixed members not handled correctly in workspaces. #300
+Add --clean
for build
command. #297
Fixed an issue where pip was not invoked from the right working directory + causing issues for workspace installations. #292
+rye init
now accepts --private
to set the Private :: Do Not Upload
classifier
+ that prevents uploads to PyPI. #291
Released on 2023-06-03
+Add version
subcommand for rye. #285
Fixed rye pin
pinning the wrong version. #288
Calling rye init
on the root directory no longer fails. #274
rye run
, show
, pin
, shell
and build
now take a --pyproject
+ argument. #232
Released on 2023-05-31
+Rye will no longer enforce a downloaded interpreter for the internal
+ toolchain. If one has been registered that is compatible it will be
+ used. Additionally the installer now supports the RYE_TOOLCHAIN
+ environment variable which allows a user to supply an already existing
+ Python interpreter at install time. #267
The publish
command now supports --yes
to disable prompts. #270
When a Python debug build (Py_DEBUG
) is registered as custom toolchain,
+ -dbg
is automatically appended to the name by default. #269
lto+pgo builds are now preferred for the Python toolchain builds when + available. #268
+It's now possible for .python-version
to request partial Python versions
+ in which case the latest available is used. In particular this means that
+ a version like 3.10
can be written into .python-version
rather than
+ 3.10.11
. This can be accomplished by invoking pin
with the new
+ --relaxed
flag. #255
Workspaces will no longer discover pyproject.toml
files in virtualenvs
+ or .git
folders. #266
Adding or removing dependencies with add
or remove
now reformats
+ the dependencies
array in the pyproject.toml
file to multi-line
+ with trailing commas. This should result in significantly better
+ diffing behavior out of the box. #263
Default build-system and license can be specified in global config. #244
+Fixed an issue where the init
command would not let you create
+ flit
based projects. #254
Resolve an error ("No such file or directory") shown after updates on + Linux machines. #252
+The built-in updater now validates checksums of updates when updates have + SHA-256 hashes available. #253
+init
now accepts --no-pin
to not create a .python-version
file. #247
Released on 2023-05-29
+Releases starting with 0.4.0
onwards are published with SHA256 checksum
+ files for all release assets. These files are not yet validated by the
+ installer or updater however.
The install
command can now install tools from custom indexes. #240
Virtualenvs on Unix are now created with a hack to pre-configure TCL and + TKinter. #233
+Fix invalid version error when using rye init with custom toolchain. #234
+Failed tool installations now properly clean up. #225
+Correctly swap the rye executable on windows when performing an update
+ to a git version via self update
.
Released on 2023-05-27
+Support retrieving username and repository-url from credentials if not
+ provided for the publish
command. #217
The installer now validates the availability of shared libraries
+ on Linux with ldd
and emits an error with additional information
+ if necessary shared libraries are missing. #220
It's now possible to configure http and https proxies. #215
+If a package is not found because it only has matching pre-releases,
+ a warning is now printed to tell the user to pass --pre
. #218
Add --username
parameter for rye publish. #211
The shims are now more resilient. Previously a pyproject.toml
file
+ caused in all cases a virtualenv to be created. Now this will only
+ happen when the rye.tool.managed
flag is set to true
. The old
+ behavior can be forced via the global config. #212
Released on 2023-05-23
+Resolved a bug where on Windows hitting the shift key (or some other keys) + in confirm prompts would cause an error.
+The installer on Windows now warns if symlinks are not enabled and directs
+ the user to enable developer mode. The --version
output now also
+ shows if symlinks are available. #205
Support auto fix requires-python when there is a conflict. #160
+Added support for custom indexes. #199
+rye add
no longer complains when a local version information is
+ in the version. #199
Released on 2023-05-22
+Fixed dev-dependencies not being installed when using workspace. #170
+init
no longer creates invalid flit config. #195
Support direct references when adding a package. #158
+Fixed a bug with uninstall on Unix platforms. #197
+Released on 2023-05-18
+The installer on windows will now ask for a key to be pressed so it does + not close the window without information. #183
+Fixed an issue on macOS where the installer would die with "os error 24" + when directly piped to bash. #184
+Released on 2023-05-17
+Rye now comes with binary releases for some platforms.
+A new self uninstall
command was added to uninstall rye and the new
+ self update
command updates to the latest release version.
Rye now includes a publish
command for publishing Python packages to a
+ package repository. #86
Script declarations in pyproject.toml
now permit chaining and custom
+ environment variables. #153
Added tools install
and tools uninstall
as aliases for install
and
+ uninstall
and added tools list
to show all installed tools.
Rye is now capable of downloading a selected set of PyPy releases. To do
+ so use rye pin pypy@3.9.16
or any other supported PyPy release.
Custom cpython toolchains are now registered just as cpython
rather
+ than custom-cpython
.
Rye now supports Python down to 3.7.
+Rye's self
command now includes a completion
subcommand to generate
+ a completion script for your shell.
The downloaded Python distributions are now validated against the + SHA-256 hashes.
+Rye now builds on windows. This is even more experimental though + than support for Linux and macOS.
+Added --features
and --all-features
for lock
and sync
.
Rye will now look at the RYE_HOME
to determine the location of the
+ .rye
folder. If it's not set, $HOME/.rye
is used as before.
Rye now has a most consistent handling for virtualenv versions. If
+ .python-version
is provided, that version is used. Otherwise if
+ requires-python
is set in the pyproject.toml
, that version is used
+ instead. When a new project is created the .python-version
file is
+ written and the current latest cpython version is picked.
It's now possible to explicitly set the name
of the project when
+ initializing a new one.
Rye's init
command now attempts to initialize projects with git
and
+ will automatically create a src/project_name/__init__.py
file.
Rye can now also generate a license text when initializing projects.
+Rye now supports negative (exclusion) dependencies. These can be used to
+ prevent a dependency from installing, even if something else in the graph
+ depends on it. Use rye add --exclude package-name
to add such a dependency.
sync
now accepts --no-lock
to prevent updating the lock file.
Rye's add
command now accepts a --pre
parameter to include pre-release.
Rye's pin
command now updates the pyproject.toml requires-python.
Rye's install
command now accepts a --include-dep
parameter to include
+ scripts from one or more given dependencies.
Rye now honors requires-python
in the add
command. This means the the
+ initial resolution will not pick a version higher than what's supported by
+ the lower boundary.
When installing packages as global tools, a warning is now emitted if there + were no scripts in the package. Additionally installing packages from local + paths and zip files is now supported.
+A rye self update
command was added to compile and install the latest
+ version via cargo.
Added more convenient ways to install from git/urls by supplying a --git
+ or --url
parameter. This will behind the scenes format a PEP 508 requirement
+ string.
Added a shell
command which will spawn a shell with the virtualenv activated.
Added a make-req
command to conveniently format out PEP 508 requirement
+ strings from parts.
The internal virtualenv used to manage pip-tools
and other libraries now
+ automatically updates when necessary.
rye toolchain register
can now be used to register a local python installation
+ as toolchain with rye.
rye build
was added to allow building sdist
and bdist_wheel
distributions.
Rye now correctly handles whitespace in folder names.
+Rye is a new project and feedback is greatly appreciated. Lots of it. Because +of this there are various different ways in which you can engage with either +the developer or other members of the community:
+You can also reach out via Twitter or +Bluesky.
+ + + + + + + + +To use Rye you need to have a pyproject.toml
based Python project. For this guide you can
+create one with rye init
which will create a new folder with a new project inside:
rye init my-project
+cd my-project
+
The following structure will be created:
+.
+├── .git
+├── .gitignore
+├── .python-version
+├── README.md
+├── pyproject.toml
+└── src
+ └── my_project
+ └── __init__.py
+
Good to Know
+The init
command accepts a lot of options to customize what it generates. Run
+rye init --help
to see all the options available in the version you have installed.
A pyproject.toml
is used to store metadata about your project as well as some Rye
+configuration. Most of Rye's commands will require a pyproject.toml
to work. Note
+that Rye today does not support setup.py
based projects. Note that when Rye initializes
+a project it also writes a .python-version
file. This file contains the version number
+of the Python version that should be used for this project. It can be changed by
+running rye pin
. For instance to tell Rye to use Python 3.10:
$ rye pin 3.10
+
Once that is done, you can use rye sync
to get the first synchronization. After that,
+Rye will have created a virtualenv in .venv
and written lockfiles into requirements.lock
+and requirements-dev.lock
.
rye sync
+
The virtualenv that Rye manages is placed in .venv
next to your pyproject.toml
.
+The first time you run this you will notice that Rye automatically downloaded and
+installed a compatible CPython interpreter for you. If you have already another
+Python installation on your system it will not be used! For more information about
+this behavior read about toolchains.
You can activate and work with it as normal with one notable exception: the Python
+installation in it does not contain pip
. If you have correctly installed Rye
+with the shims enabled, after the sync you can run python
and you will automatically
+be operating in that virtualenv, even if it's not enabled. You can validate this
+by printing out sys.prefix
:
python -c "import sys; print(sys.prefix)"
+
It will print out the full path to the managed virtualenv.
+Use the add
command to add dependencies to your project.
rye add "flask>=2.0"
+
Note that after add
you need to run sync
again to actually install it. If you
+want to add packages from custom indexes, you have to configure the source
+first.
Use the remove
command to remove a dependency from the project again.
rye remove flask
+
To run executables in the context of the virtualenv you can use the run
command. For
+instance if you want to use black
you can add and run it like this:
rye add black
+rye sync
+rye run black
+
If you want to have the commands available directly you will need to activate the +virtualenv like you do normally. To activate the virtualenv, use the standard methods:
+. .venv/bin/activate
+
.venv\Scripts\activate
+
To deactivate it again run deactivate
:
deactivate
+
The rye show
command can print out information about the project's state. By
+just running rye show
you can see which Python version is used, where the
+virtualenv is located and more. You can also invoke rye show --installed-deps
+to get a dump of all installed dependencies.
rye show
+rye show --installed-deps
+
Most of Rye's configuration is contained within the pyproject.toml
file. There is however
+also a bit of global configuration to influence how it works.
By default Rye places all it's configuration in ~/.rye
on Unix and %USERPROFILE%\.rye
on
+Windows. This behavior can be changed via the RYE_HOME
environment variable. This is useful
+if you do not like the default location of where Rye places it's configuration or if you need
+to isolate it.
The .rye
home folder contains both user configuration as well as Rye managed state such
+as installed toolchains. The following files and folders are placed within the
+.rye
folder. Note that not all are there always.
config.toml
This is a configuration file that influences how Rye operates. Today very little configuration +is available there. For the available config keys see Config File.
+self
While Rye is written in Rust, it uses a lot of Python tools internally. These are maintained in +an internal virtualenv stored in this location.
+py
In this folder Rye stores the different toolchains. Normally those are folders +containing downloaded Python distributions, but they can also be symlinks or special reference +files.
+shims
This folder contains shim binaries. These binaries are for instance the python
executable
+which automatically proxies to the current virtualenv or globally installed tools.
The config file config.toml
in the .rye
folder today only is used to manage defaults. This
+is a fully annotated config file:
[default]
+# This is the default value that is written into new pyproject.toml
+# files for the `project.requires-python` key
+requires-python = ">= 3.8"
+
+# This is the default toolchain that is used
+toolchain = "cpython@3.11.1"
+
+# This is the default build system that is used
+build-system = "hatchling"
+
+# This is the default license that is used
+license = "MIT"
+
+# This sets the default author (overrides the defaults from git). The
+# format here is "Name <email>".
+author = "Full Name <email@address.invalid>"
+
+# The dependency operator to use by default for dependencies. The options are
+# '>=', '~=', and '=='. The default currently is '>='. This affects the behavior
+# of `rye add`.
+dependency-operator = ">="
+
+[proxy]
+# the proxy to use for HTTP (overridden by the http_proxy environment variable)
+http = "http://127.0.0.1:4000"
+# the proxy to use for HTTPS (overridden by the https_proxy environment variable)
+https = "http://127.0.0.1:4000"
+
+[behavior]
+# When set to true the `managed` flag is always assumed to be true.
+force-rye-managed = false
+
+# Enables global shims when set to `true`. This means that the installed
+# `python` shim will resolve to a Rye managed toolchain even outside of
+# virtual environments.
+global-python = false
+
+# a array of tables with optional sources. Same format as in pyproject.toml
+[[sources]]
+name = "default"
+url = "http://pypi.org/simple/"
+
new in 0.9.0
+The configuration can be read and modified with rye config
. The
+keys are in dotted notation. --get
reads a key, --set
, --set-int
,
+--set-bool
, or --unset
modify one.
rye config --set proxy.http=http://127.0.0.1:4000
+rye config --set-bool behavior.force-rye-managed=true
+rye config --get default.requires-python
+
For the project specific pyproject.toml
config see pyproject.toml.
Dependencies are declared in pyproject.toml however adding them can be
+simplified with the rye add
command. In the most simple invocation it adds a regular
+dependency, but it can be customized.
To add a regular dependency just invoke rye add
with the name of the Python package:
rye add Flask
+
If you also want to define a version, use a PEP 508 +requirement:
+rye add "Flask>=2.0"
+
For extra/feature dependencies you can either use PEP 508 syntax or use --features
:
rye add "Flask[dotenv]"
+rye add Flask --features=dotenv
+
These dependencies are stored in project.dependencies
.
Note about pre-releases
+By default add
will not consider pre-releases. This means if you add a dependency
+that has .dev
or similar in the version number you will not find a match. To
+consider them, add them with --pre
:
rye add "Flask==2.0.0rc2" --pre
+
For dependencies that should only be installed during development pass --dev
rye add --dev black
+
These dependencies are stored in the non-standard
+tool.rye.dev-dependencies
key.
To run tools added this way without enabling the virtualenv use rye run
:
rye run black
+
To add a local or git dependency, you can pass additional parameters like --path
+or --git
:
rye add Flask --git=https://github.com/pallets/flask
+rye add My-Utility --path ./my-utility
+
Note that when adding such dependencies, it's necessary to also provide the name
+of the package. Additionally for git dependencies all kinds of extra parameters
+such as --tag
, --rev
or --branch
are supported.
When working with local dependencies it's strongly encouraged to configure a +workspace.
+ + + + + + +This section should cover some commonly asked questions. If you do not find an answer +here, consider reaching out to the community.
+Rye does not require symlinks but it works significantly better with them. On Windows +support for symlinks is restricted to privileged accounts. The reason for this is that +Symlinks were a late addition to Windows and some applications are not developed with +them in mind which can cause misbehavior or in the worst case security issues in those +applications. Symlinks support however is enabled when the "developer mode" is activated +on modern Windows versions. Here is how you can enable it:
+Enabling symlinks is not strictly required as Rye automatically falls back to +hardlinks and junction points. However not having symlinks enabled will ultimately +result in a worse user experience for the following reasons:
+.rye\py
path are non executable.The Python builds that Rye uses require a Linux installation compatible to the
+Linux Standard Base Core Specification (LSB). Unfortunately not all Linux
+distributions are strictly adhering to that specification out of the box. In
+particularly the library libcrypt.so.1
is commonly not installed on certain
+Linux distributions but the _crypt
standard library module depends on it.
+Depending on the Linux distributions you need to run different commands to
+resolve this:
pacman -S libxcrypt-compat
dnf install libxcrypt-compat
There have also been reports of an error being generated at installation time
+despite libcrypt.so.1
being installed when a different ldd
(eg: Homebrew)
+shadows the system one. In that case try the installation again after giving
+the default one higher priority in the `PATH:
export PATH="/usr/bin:$PATH"
+curl -sSf https://rye-up.com/get | bash
+
TKinter uses TCL behind the scenes. Unfortunately this also means that some runtime
+support is required. This runtime support is provided by the portable Python builds,
+however the way TCL is initialized on macOS and Linux won't find these files in
+virtualenvs. Newer versions of Rye will automatically export the TCL_LIBRARY
+and TK_LIBRARY
environment variables for you in a manner very similar to this:
import os
+import sys
+os.environ["TCL_LIBRARY"] = sys.base_prefix + "/lib/tcl8.6"
+os.environ["TK_LIBRARY"] = sys.base_prefix + "/lib/tk8.6"
+
The Python builds that Rye uses are compiled against libedit
rather than readline
+for licensing reasons. You might run into unicode issues on input as a result of this
+due to limitations in libedit
. In some cases though you might also discover that
+the backspace key does not work or arrow keys don't work as expected. This can be
+because the terminfo database cannot be found.
For solutions to this issue, read the behavior quirks guide in the +Standalone Python Builds documentation for solutions.
+Rye given it's experimental nature does not want to disrupt already existing Python
+workflows. As such using it alongside other Python installations is intentionally
+supported. Even if the Rye shims come first on the PATH
, Rye will automatically
+resolve to a different Python installation on the search path when invoked in a
+folder that contains a non Rye managed project.
As such the answer is a clear yes!
+You might be encountering missing files in wheels when running rye build
and you
+are using hatchling. The reason for this is that rye build
uses
+"build" behind the scenes to build wheels. There
+are two build modes and in some cases the wheel is first built from an sdist. So
+if your sdists does not include the necessary data files, the resulting wheel will
+also be incorrect.
This can be corrected by adding the files to the include
in the hatch config
+for sdists. For instance the following lines added to pyproject.toml
will add
+the data files in my_package
and all the tests to the sdist from which the
+wheel is built:
[tool.hatch.build.targets.sdist]
+include = ["src/my_package", "tests"]
+
Rye is still a very experimental tool, but this guide is here to help you get +started. Before we dive into the installation and basic usage guide it's +important for you to understand what Rye actually is.
+Rye is a one-stop-shop tool. The idea is that as a Python developer all you +need to know is Rye, because Rye is your start into the experience. As a Rye +user you do not even need to install Python yourself as Rye does this for you. +This means to use Rye, you just need to install Rye, the rest is done by Rye +itself.
+Once Rye is on your system, it can automatically install Python interpreters +for you, install packages from package indexes, manage virtualenvs behind +the scenes and more.
+Interested? Then head over to Installation to learn about +how to get Rye onto your system. Once that is done, read the Basics +to learn about how Rye can be used.
+ + + + + + +Rye is built in Rust. It can either be manually compiled and installed or it can +be installed from a binary distribution. It has support for Linux, macOS and +Windows.
+Rye is installed per-user and self manages itself. It will install itself into +a folder in your home directory and mange itself there.
+ +To install run you can curl a command which will install the right binary for your +operating system and CPU architecture and install it:
+curl -sSf https://rye-up.com/get | bash
+
Alternatively if you don't trust this approach, you can download the latest release +binary. On first run it will install itself.
+gunzip rye-x86_64-linux.gz
+chmod +x ./rye-x86_64-linux
+./rye-x86_64-linux
+
To install run you can curl a command which will install the right binary for your +operating system and CPU architecture and install it:
+curl -sSf https://rye-up.com/get | bash
+
Alternatively if you don't trust this approach, you can download the latest release +binary. On first run it will install itself.
+gunzip rye-aarch64-macos.gz
+chmod +x ./rye-aarch64-macos
+./rye-aarch64-macos
+
To install Rye on windows download the latest release and run the binary. Upon +first run it will install itself. Please note that it's strongly recommended +to have "Developer Mode" activated when using Rye and before starting the +installation. Learn more.
+Note
+Rye does not yet use signed binaries which means that you will need to allow +the execution of the downloaded executable. If there is no obvious way to do so, click +on "More info" on the error message that shows up and then on "Run anyway".
+You need to have Rust and Cargo installed. If you don't have, you can use +rustup to get them onto your machine.
+Afterwards you can install Rye
via cargo
:
cargo install --git https://github.com/mitsuhiko/rye rye
+
Rye will automatically download suitable Python toolchains as needed. For more +information about this read about toolchains. To install +a specific version download a binary directly +from GitHub.
+On some platforms there is some limited support for customizing the installation +experience.
+
+The install script that is piped to bash
can be customized with some environment
+variables:
RYE_VERSION
Defaults to latest
. Can be set to an explicit version to install a specific one.
RYE_INSTALL_OPTION
Can optionally be set to "--yes"
to skip all prompts.
RYE_TOOLCHAIN
Optionally this environment variable can be set to point to a Python +interpreter that should be used as the internal interpreter. If not +provided a suitable interpreter is automatically downloaded.
+At present only CPython 3.9 to 3.11 are supported.
+This for instance installs a specific version of Rye without asking questions:
+curl -sSf https://rye-up.com/get | RYE_VERSION="0.4.0" RYE_INSTALL_OPTION="--yes" bash
+
+The install script that is piped to bash
can be customized with some environment
+variables:
RYE_VERSION
Defaults to latest
. Can be set to an explicit version to install a specific one.
RYE_INSTALL_OPTION
Can optionally be set to "--yes"
to skip all prompts.
RYE_TOOLCHAIN
Optionally this environment variable can be set to point to a Python +interpreter that should be used as the internal interpreter. If not +provided a suitable interpreter is automatically downloaded.
+At present only CPython 3.9 to 3.11 are supported.
+This for instance installs a specific version of Rye without asking questions:
+curl -sSf https://rye-up.com/get | RYE_VERSION="0.4.0" RYE_INSTALL_OPTION="--yes" bash
+
The Windows installer has limited support for customizations via environment
+variables. To set these you need to run the installer from cmd.exe
.
RYE_TOOLCHAIN
Optionally this environment variable can be set to point to a Python +interpreter that should be used as the internal interpreter. If not +provided a suitable interpreter is automatically downloaded.
+At present only CPython 3.9 to 3.11 are supported.
+This for instance installs Rye with a specific toolchain:
+set RYE_TOOLCHAIN=%USERPROFILE%\AppData\Local\Programs\Python\Python310\python.exe
+rye-x86_64-windows.exe
+
Once rye
is installed you need to add the shims
folder into your PATH
.
+This folder is a folder that contains "shims" which are executables that
+Rye manages for you as well as the rye
executable itself. For instance any
+Python installation managed by Rye will be available via a shim placed there.
On macOS or Linux you can accomplish this by adding it to your .bashrc
, .zshrc
+or similar. This step is technically optional but required if you want to be able to
+just type python
or rye
into the shell to pick up the current virtualenv's Python
+interpreter.
Rye ships an env
file which should be sourced to update PATH
automatically.
echo 'source "$HOME/.rye/env"' >> ~/.bashrc
+
Rye ships an env
file which should be sourced to update PATH
automatically.
echo 'source "$HOME/.rye/env"' >> ~/.zshrc
+
Since fish does not support env
files, you instead need to add
+the shims directly. This can be accomplished by running this
+command once:
set -Ua fish_user_paths "$HOME/.rye/shims"
+
Rye ships an env
file which should be sourced to update PATH
automatically.
echo '. "$HOME/.rye/env"' >> ~/.profile
+
To modify the Windows PATH environment variable
+sysdm.cpl
and hit Enter.Path
variable.%USERPROFILE%\.rye\shims
and hit Enter.Note that you might need to restart your login session for this to take effect.
+There is a quite a bit to shims and their behavior. Make sure to read up on shims +to learn more.
+Rye supports generating completion scripts for Bash, Zsh, Fish or Powershell. Here are some common locations for each shell:
+mkdir -p ~/.local/share/bash-completion/completions
+rye self completion > ~/.local/share/bash-completion/completions/rye.bash
+
# Make sure ~/.zfunc is added to fpath, before compinit.
+rye self completion -s zsh > ~/.zfunc/_rye
+
Oh-My-Zsh:
+mkdir $ZSH_CUSTOM/plugins/rye
+rye self completion -s zsh > $ZSH_CUSTOM/plugins/rye/_rye
+
Then make sure rye plugin is enabled in ~/.zshrc
+rye self completion -s fish > ~/.config/fish/completions/rye.fish
+
# Create a directory to store completion scripts
+mkdir $PROFILE\..\Completions
+echo @'
+Get-ChildItem "$PROFILE\..\Completions\" | ForEach-Object {
+ . $_.FullName
+}
+'@ | Out-File -Append -Encoding utf8 $PROFILE
+# Generate script
+Set-ExecutionPolicy Unrestricted -Scope CurrentUser
+rye self completion -s powershell | Out-File -Encoding utf8 $PROFILE\..\Completions\rye_completion.ps1
+
To update rye to the latest version you can use rye
itself:
rye self update
+
If you don't want to use Rye any more, you can ask it to uninstall it again:
+rye self uninstall
+
Additionally you should delete the remaining .rye
folder from your home directory and
+remove .rye/shims
from the PATH
again. Rye itself does not place any data
+in other locations. Note though that virtual environments created by rye will
+no longer function after Rye was uninstalled.
Rye when launched will normally perform an auto installation. This can be annoying
+in certain development situations. This can be prevented by exporting the
+RYE_NO_AUTO_INSTALL
environment variable. It needs to be set to 1
to disable
+the feature.
export RYE_NO_AUTO_INSTALL=1
+
export RYE_NO_AUTO_INSTALL=1
+
set RYE_NO_AUTO_INSTALL=1
+
Rye currently uses build to build the package and uses twine to publish it.
+By default, rye
will build the both sdist and wheel target in the dist
directory.
rye build
+
You can use the --sdist
or --wheel
flag to build the specific target, or specify the output directory with --out
.
rye build --wheel --out target
+
If you want to clean the build directory before building, run:
+rye build --clean
+
Rye will publish the distribution files under the dist
directory to PyPI by default.
rye publish
+
You might be asked to input your access token and some other info if needed.
+No access token found, generate one at: https://pypi.org/manage/account/token/
+Access token:
+
You can also specify the distribution files to be published:
+rye publish dist/example-0.1.0.tar.gz
+
Rye supports publishing the package to a different repository by using the --repository
and --repository-url
flags. For example, to publish to the test PyPI repository:
rye publish --repository testpypi --repository-url https://test.pypi.org/legacy/
+
You can optionally set the --yes
flag to skip the confirmation prompt. This can be useful for CI/CD pipelines.
rye publish --token <your_token> --yes
+
Rye will store your repository info in $HOME/.rye/credentials
for future use.
pyproject.toml
)Rye tries to avoid a lot of proprietary configuration in the pyproject.toml
file but a bit
+is necessary. Here are the most important keys that Rye expects:
project.dependencies
This key is used to manage dependencies. They work exactly like you expect from a regular
+pyproject.toml
file and in fact Rye changes nothing about this. However Rye is capable
+of modifying these entries with the rye add
and rye remove
commands.
[project]
+dependencies = [
+ "mkdocs~=1.4.3",
+ "mkdocs-material~=9.1.12",
+ "pymdown-extensions~=9.11",
+]
+
project.scripts
This key specifies the scripts that are to be generated and installed into the virtual environment during sync
.
+These scripts will invoke the configured entry point.
[project.scripts]
+my-hello-script = 'hello:main'
+
my-hello-script
that will call the main
function of the
+hello
module.
+Scripts can be installed using rye sync
and run using rye run
:
$ rye sync
+$ rye run my-hello-script
+Hello from hello!
+
tool.rye.dev-dependencies
This works similar to project.dependencies
but holds development only dependencies. These
+can be added here automatically via rye add --dev
.
[tool.rye]
+dev-dependencies = ["black~=23.3.0"]
+
Dev dependencies are installed automatically unless --no-dev
is passed to sync
.
tool.rye.excluded-dependencies
This is a special key that contains dependencies which are never installed, even if they are
+pulled in as indirect dependencies. These are added here automatically with rye add --excluded
.
[tool.rye]
+excluded-dependencies = ["cffi"]
+
tool.rye.lock-with-sources
new in 0.18.0
+When this flag is enabled all lock
and sync
operations in the project or workspace
+operate as if --with-sources
is passed. This means that all lock files contain the
+full source references. Note that this can create lock files that contain credentials
+if the sources have credentials included in the URL.
[tool.rye]
+lock-with-sources = true
+
tool.rye.managed
new in 0.3.0
+This key tells rye that this project is supposed to be managed by Rye. This key +primarily affects some automatic creation of virtualenvs. For instance Rye +will not try to initialize a virtualenv when using shims without this flag. It +can be forced enabled in the global config.
+[tool.rye]
+managed = true
+
tool.rye.sources
This is an array of tables with sources that should be used for locating dependencies.
+This lets you use indexes other than PyPI. These sources can also be configured in the
+main config.toml
config file with the same syntax.
[[tool.rye.sources]]
+name = "default"
+url = "http://pypi.org/simple/"
+
For more information about configuring sources see Dependency Sources.
+tool.rye.scripts
This key can be used to register custom scripts that are exposed via rye run
. Each key is
+a script, and each value is the configuration for that script. Normally the value is an object
+with different keys with the most important key being cmd
which holds the command to execute.
+However if only cmd
is set, then the object is optional. cmd
itself can either be set to a
+string or an array of arguments.
[tool.rye.scripts]
+# These three options are equivalent:
+devserver = "flask run --app ./hello.py --debug"
+devserver-alt = ["flask", "run", "--app", "./hello.py", "--debug"]
+devserver-explicit = { cmd = "flask run --app ./hello.py --debug" }
+
The following keys are possible for a script:
+cmd
The command to execute. This is either a string
or an array
of arguments. In either case
+shell specific interpolation is unavailable. The command will invoke one of the tools in the
+virtualenv if it's available there.
[tool.rye.scripts]
+devserver = { cmd = "flask run --app ./hello.py --debug" }
+http = { cmd = ["python", "-mhttp.server", "8000"] }
+
env
This key can be used to provide environment variables with a script:
+[tool.rye.scripts]
+devserver = { cmd = "flask run --debug", env = { FLASK_APP = "./hello.py" } }
+
chain
This is a special key that can be set instead of cmd
to make a command invoke multiple
+other commands. Each command will be executed one after another. If any of the commands
+fails the rest of the commands won't be executed and instead the chain fails.
[tool.rye.scripts]
+lint = { chain = ["lint:black", "lint:flake8" ] }
+"lint:black" = "black --check src"
+"lint:flake8" = "flake8 src"
+
call
This is a special key that can be set instead of cmd
to make a command invoke python
+functions or modules. The format is one of the three following formats:
<module_name>
: equivalent to python -m <module_name>
<module_name>:<function_name>
: runs <function_name>
from <module_name>
and exits with the return value<module_name>:<function_name>(<args>)
: passes specific arguments to the functionExtra arguments provided on the command line are passed in sys.argv
.
[tool.rye.scripts]
+serve = { call = "http.server" }
+help = { call = "builtins:help" }
+hello-world = { call = "builtins:print('Hello World!')" }
+
tool.rye.workspace
When a table with that key is stored, then a project is declared to be a workspace root. By
+default all Python projects discovered in sub folders will then become members of this workspace
+and share a virtualenv. Optionally the members
key (an array) can be used to restrict these
+members. In that list globs can be used. The root project itself is always a member.
[tool.rye.workspace]
+members = ["mylib-*"]
+
Rye recommends using maturin to develop Rust Python
+extension modules. This process is largely automated and new projects can be created
+with rye init
.
rye init my-project --build-system maturin
+cd my-project
+
The following structure will be created:
+.
+├── .git
+├── .gitignore
+├── .python-version
+├── README.md
+├── pyproject.toml
+├── Cargo.toml
+├── python
+ └── my_project
+ └── __init__.py
+└── src
+ └── lib.rs
+
When you use maturin as a build system then rye sync
will automatically build the rust
+extension module into your venv. Likewise rye build
will use maturin to trigger a
+wheel build. For faster iteration it's recommended to use maturin
directly.
If you want to use other maturin commands such as maturin develop
you can install
+it as a global tool:
rye install maturin
+
Note that maturin develop
requires pip
to be installed into the virtualenv. Before
+you can use it you need to add it:
rye add --dev pip
+rye sync
+
Rye recommends mixed python/rust modules. In that case you can save some valuable
+iteration time by running maturin develop --skip-install
:
maturin develop --skip-install
+
After installation Rye places two shims on your PATH
: python
and python3
. These
+shims have specific behavior that changes depending on if they are used within a Rye
+managed project or outside.
Inside a Rye managed project they resolve to the Python interpreter of the virtualenv.
+This means that even if you do not enable the virtualenv, you can just run python
+in a shell, and it will automatically operate in the right environment.
Outside a Rye managed project it typically resolves to your system Python, though you +can also opt to have it resolve to a Rye managed Python installation for you. This is +done so that it's not disruptive to your existing workflows which might depend on the +System python installation.
+new in 0.9.0
+To enable global shims, you need to enable the global-python
flag in
+the config.toml
file:
rye config --set-bool behavior.global-python=true
+
Afterwards if you run python
outside of a Rye managed project it will
+spawn a Python interpreter that is shipped with Rye. It will honor the
+closest .python-version
file for you. Additionally you can also
+explicitly request a specific Python version by adding +VERSION
after
+the python
command. For instance this runs a script with Python 3.8:
python +3.8 my-script.py
+
Note
+Selecting a specific Python version this way only works outside of
+Rye managed projects. Within Rye managed projects, the version needs
+to be explicitly selected via .python-version
or with the
+requires-python
key in pyproject.toml
.
new in 0.2.0
+Normally Rye loads packages from PyPI only. However it is possible to instruct it to +load packages from other indexes as well.
+An index can be added to a project or workspace (via pyproject.toml
) or into the
+global config. Rye will always consult both files where the
+pyproject.toml
file wins over the global config.
Each source needs to have a unique name. The default source is always called default
+and out of the box points to PyPI.
Add this to ~/.rye/config.toml
:
[[sources]]
+name = "company-internal"
+url = "https://company.internal/simple/"
+
Add this to pyproject.toml
:
[[tool.rye.sources]]
+name = "company-internal"
+url = "https://company.internal/simple/"
+
changed in 0.4.0
+Sources in the global config are also considered for tool installations.
+Rye supports different types of sources and also allows overriding the default
+PyPI index. If you give another source the name default
, PyPI will no longer be
+used for resolution.
[[sources]]
+name = "company-internal"
+url = "https://company.internal/simple/"
+type = "index" # this is implied
+
[[sources]]
+name = "company-internal"
+url = "https://company.internal/"
+type = "find-links"
+
[[sources]]
+name = "default"
+url = "https://company.internal/simple/"
+
Warning
+Please take note that the default index cannot be of type find-links
.
The two sources types (index
vs find-links
) are determined by the underlying pip
+infrastructure:
index
This is a PEP 503 type index as provided
+by tools such as PyPI or devpi. It corresponds to
+the arguments --index-url
or --extra-index-url
in pip.
find-links
This is a source that can be of a variety of types and has to point to a file path
+or hosted HTML page linking to packages. It corresponds to the --find-links
+argument. The format of the HTML page is somewhat underspecified but generally
+all HTML links pointing to .tar.gz
or .whl
files are considered.
HTTP basic auth is supported for index authentication. It can be supplied in two
+ways. username
and password
can be directly embedded in the config, or they
+can be supplied with environment variables.
[[sources]]
+name = "company-internal"
+url = "https://company.internal/simple/"
+username = "username"
+password = "super secret"
+
[[sources]]
+name = "company-internal"
+url = "https://${INDEX_USERNAME}:${INDEX_PASSWORD}@company.internal/simple/"
+
Rye currently uses pip-tools to download and install
+dependencies. For this purpose it creates two "lockfiles" (called requirements.lock
and
+requirements-dev.lock
). These are not real lockfiles but they fulfill a similar purpose
+until a better solution has been implemented.
Whenever rye sync
is called, it will update lockfiles as well as the virtualenv. If you only
+want to update the lockfiles, then rye lock
can be used.
When locking, some options can be provided to change the locking behavior. These flags are
+also all available on rye sync
.
--update
/ --update-all
Updates a specific or all requirements to the latest and greatest version. Without this flag +a dependency will only be updated if necessary.
+rye lock --update-all
+
--features
/ --all-features
Python packages can have extra dependencies. By default the local package that is installed +will only be installed with the default features. If for instance you have an extra dependency +this will only be installed if the feature is enabled.
+rye add --optional=web flask
+rye lock --features=web
+
When working with workspaces, the package name needs to be prefixed with a slash:
+rye lock --features=package-name/feature-name
+
The --features
parameter can be passed multiple times and features can also be comma
+separated. To turn on all features, the --all-features
parameter can be used.
rye lock --all-features
+
--pre
By default updates and version resolution will not consider pre-releases of packages. If you
+do want to include those, pass --pre
rye lock Flask --pre
+
--with-sources
new in 0.18.0
+By default (unless the tool.rye.lock-with-sources
config key is set to true
in the
+pyproject.toml
) lock files are not generated with source references. This means that
+if custom sources are used the lock file cannot be installed via pip
unless also
+--find-links
and other parameters are manually passed. This can be particularly useful
+when the lock file is used for docker image builds.
When this flag is passed then the lock file is generated with references to --index-url
,
+--extra-index-url
or --find-links
.
rye lock --with-sources
+
Syncing takes the same parameters as lock
and then some. Sync will usually first do what
+lock
does and then use the lockfiles to update the virtualenv.
--no-lock
To prevent the lock step from automatically running, pass --no-lock
.
rye sync --no-lock
+
--no-dev
Only sync based on the production lockfile (requirements.lock
) instead of the development
+lockfile (requirements-dev.lock
).
rye sync --no-dev
+
Rye is capable (and prefers) to download its own Python distribution over what +you might already have on your computer. For CPython, the +indygreg/python-build-standalone +builds from the PyOxidizer project are used.
+The motivation for this is that it makes it easy to switch between Python +versions, to have a common experience across different Rye users and to +avoid odd bugs caused by changes in behavior.
+Unfortunately Python itself does not release binaries (or the right types of +binaries) for all operating systems which is why Rye leverages the portable +Python builds from PyOxidizer.
+Unlike many other Python versions you can install on your computer are +non-portable which means that if you move them to a new location on your +machine, or you copy it onto another computer (even with the same operating +system) they will no longer run. This is undesirable for what Rye wants to do. +For one we want the same experience for any of the Python developers, no matter +which operating system they used. Secondly we want to enable self-contained +Python builds later, which requires that the Python installation is portable.
+To achieve this, the Python builds we use come with some changes that are +different from a regular Python build.
+The following changes to a regular Python versions you should be aware of:
+libedit
instead of readline
: unfortunately readline
is GPL2 licensed
+ and this is a hazard for redistributions. As such, the portable Python
+ builds link against the more freely licensed libedit
instead.
dbm.gnu
is unavailable. This is a rather uncommonly used module and the
+ standard library provides alternatives.
Additionally due to how these builds are created, there are some other quirks +you might run into related to terminal support or TKinter. Some of these +issues are collected in the FAQ. Additionally the Python +Standalone Builds have a Behavior Quirks +page.
+Portable CPython builds are downloaded from GitHub +(indygreg/python-build-standalone/releases) +and SHA256 hashes are generally validated. Some older versions might not +have hashes available in which case the validation is skipped.
+When you pin a Python version to cpython@major.minor.patch
(or just
+major.minor.patch
) then Rye will automatically download the right version
+for you whenever it is needed. If a custom toolchain has already been registered with that name and
+version, that this is used instead.
Rye is unique in that it does not use system Python installations. Instead it downloads +and manages Python installations itself (called toolchains). Today there are +three types of toolchains supported by Rye and they require some understanding:
+To make a project use a specific toolchain write the name of the toolchain into the
+.python-version
file or use the pin
command. For pinning cpython
the cpython@
+prefix can be omitted.
rye pin cpython@3.11.4
+
Pinning a downloadable version means that Rye will automatically fetch it when necessary.
+By default, toolchains are pinned to a precise version. This means that even if you
+write rye pin cpython@3.11
, a very specific version of cpython is written into the
+.python-version
file. With Rye 0.5.0 onwards it's possible to perform "relaxed" pins:
rye pin --relaxed cpython@3.11
+
This will then persist 3.11
in the .python-version
file and Rye will use the latest
+available compatible version for the virtual environment.
changed in 0.5.0
+Relaxed pinning with rye pin --relaxed
was added.
new in 0.14.0
+Support for fetching and pinning of non-native architectures was added.
+By default, the pin is for the architecture of the running machine. This means that
+if you pin cpython@3.11
on a mac with aarch64 architecture, you will use a cpython
+interpreter of that CPU architecture. A different architecture can be selected by
+adding -{arch}
to the python family name. So for instance to force a x86_64
version
+you need to pin like this:
rye pin cpython-x86_64@3.11
+
Note that such custom pins are not reflected in pyproject.toml
but only .python-version
.
To see which toolchains are installed, rye toolchain list
prints a list:
rye toolchain list
+
cpython@3.11.1 (C:\Users\armin\.rye\py\cpython@3.11.1\install\python.exe)
+pypy@3.9.16 (C:\Users\armin\.rye\py\pypy@3.9.16\python.exe)
+
To see which toolchains can be installed, additionally pass the --include-downloadable
:
rye toolchain list --include-downloadable
+
Generally Rye automatically downloads toolchains, but they can be explicitly fetched
+with rye toolchain fetch
(also aliased to rye fetch
):
rye toolchain fetch cpython@3.8.5
+
Toolchains are fetched from two sources:
+Additionally, it's possible to register an external toolchain with the rye toolchain register
+command.
rye toolchain register /path/to/python
+
The name of the toolchain is picked based on the interpreter. For instance
+linking a regular cpython installation will be called cpython@version
, whereas
+linking pypy would show up as pypy@version
. From Rye 0.5.0 onwards -dbg
is
+appended to the name of the toolchain if it's a debug build. To override the
+name you can pass --name
:
rye toolchain register --name=custom /path/to/python
+
To remove an already fetched toolchain run rye toolchain remove
. Note that this
+also works for linked toolchains:
rye toolchain remove cpython@3.8.5
+
Warning
+Removing an actively used toolchain will render the virtualenvs that refer to use broken.
+PyPy is supported as alternative Python distribution.
+Like the portable CPython builds it's downloaded automatically. The name for
+PyPy distributions is pypy
.
PyPy has some limitations compared to regular Python builds when it comes to +working with Rye. Most specifically PyPy uses some internal pypi dependencies +and you might notice warnings show up when syching. PyPy also lags behind +regular Python installations quite a bit these days so you likely need to +target older Python packages.
+PyPy builds are downloaded from +downloads.python.org. These downloads +are not verified today.
+When you pin a Python version to pypy@major.minor.patch
then Rye will
+automatically download the right version for you whenever it is needed. If a
+custom toolchain has already been registered
+with that name and version, that this is used instead. Note that the version
+refers to the PyPy CPython version.
That means for instance that PyPy 7.3.11 is identified as pypy@3.9.16
as this
+is the Python version it provides. As PyPy also lacks builds for some CPU
+architectures, not all platforms might provide the right PyPy versions.
Rye supports global tool installations. This for instance allows you to install
+tools like black
or ruff
globally.
Use the rye tools install
(aliased to rye install
) command to install a tool
+globally with a shim:
rye install ruff
+
Afterwards the tool is installed into ~/.rye/tools/ruff
and the necessary shims
+are placed in ~/.rye/shims
.
changed in 0.4.0
+The install
command now considers custom sources configured
+in the config.toml
file. For more information see Dependency Sources.
Some tools do not declare all of their dependencies since they might be optional. +In some cases these can be declared by passing extra features to the installer:
+rye install black --features colorama
+
If dependencies are not at all specified, then they can be provided with --extra-requirement
.
+This is particularly sometimes necessary if the tool uses pkg_resources
(part of
+setuptools
) but forgets to declare that dependency:
rye install gradio --extra-requirement setuptools
+
If you want to see which tools are installed, you can use rye tools list
:
rye tools list
+
black
+ black
+ blackd
+ruff
+ ruff
+
To also see which scripts those tools provide, also pass --include-scripts
rye tools list --include-scripts
+
To uninstall a tool again, use rye tools uninstall
(aliased to rye uninstall
):
rye uninstall black
+
Rye is Armin's personal one-stop-shop for all
+his Python needs. It installs and manages Python installations, helps working with
+pyproject.toml
files, installs and uninstalls dependencies, creates and updates
+virtualenvs behind the scenes. It supports monorepos and global tool installations.
Rye is an experimental endeavour to build a new type of packaging experience to
+Python inspired by rustup
and cargo
from Rust. It's not yet production ready
+but feedback and suggestions are greatly appreciated.
Installation Instructions
+ +To install run you can curl a command which will install the right binary for your +operating system and CPU architecture and install it:
+curl -sSf https://rye-up.com/get | bash
+
Alternatively if you don't trust this approach, you can download the latest release +binary. On first run it will install itself.
+gunzip rye-x86_64-linux.gz
+chmod +x ./rye-x86_64-linux
+./rye-x86_64-linux
+
To install run you can curl a command which will install the right binary for your +operating system and CPU architecture and install it:
+curl -sSf https://rye-up.com/get | bash
+
Alternatively if you don't trust this approach, you can download the latest release +binary. On first run it will install itself.
+gunzip rye-aarch64-macos.gz
+chmod +x ./rye-aarch64-macos
+./rye-aarch64-macos
+
To install Rye on windows download the latest release and run the binary. Upon +first run it will install itself. Please note that it's strongly recommended +to have "Developer Mode" activated when using Rye and before starting the +installation. Learn more.
+Note
+Rye does not yet use signed binaries which means that you will need to allow +the execution of the downloaded executable. If there is no obvious way to do so, click +on "More info" on the error message that shows up and then on "Run anyway".
+You need to have Rust and Cargo installed. If you don't have, you can use +rustup to get them onto your machine.
+Afterwards you can install Rye
via cargo
:
cargo install --git https://github.com/mitsuhiko/rye rye
+
For the next steps or ways to customize the installation, head over to the detailed +installation guide.
+Rye was built to solve my problems. Here is what was +on my mind when I built it:
+Virtualenvs: while I personally do not like virtualenvs that much, they are
+ so widespread and have reasonable tooling support, so I chose this over
+ __pypackages__
.
No Default Dependencies: the virtualenvs when they come up are completely void
+ of dependencies. Not even pip
or setuptools
are installed into it. Rye
+ manages the virtualenv from outside the virtualenv.
No Core Non Standard Stuff: Rye (with the exception of it's own tool
section
+ in the pyproject.toml
) uses standardized keys. That means it uses regular
+ requirements as you would expect. It also does not use a custom lock file
+ format and uses pip-tools
behind the scenes.
No Pip: Rye uses pip, but it does not expose it. It manage dependencies in
+ pyproject.toml
only.
No System Python: I can't deal with any more linux distribution weird Python + installations or whatever mess there is on macOS. I used to build my own Pythons + that are the same everywhere, now I use indygreg's Python builds. + Rye will automatically download and manage Python builds from there. No compiling, + no divergence.
+Project Local Shims: Rye maintains a python
shim that auto discovers the
+ current pyproject.toml
and automatically operates below it. Just add the
+ shims to your shell and you can run python
and it will automatically always
+ operate in the right project.
There are a few shortcomings in the Python packaging world, largely as a result of +lack of standardization. Here is what this project ran into over the years:
+No Python Binary Distributions: CPython builds from python.org are completely + inadequate. On some platforms you only get an .msi installer, on some you + literally only get tarballs. The various Python distributions that became popular + over the years are diverging greatly and cause all kinds of nonsense downstream. + This is why this Project uses the indygreg standalone builds. I hope that with + time someone will start distributing well maintained and reliable Python builds + to replace the mess we are dealing with today.
+No Dev Dependencies: Rye currently needs a custom section in the pyproject.toml
+ to represent dev dependencies. There is no standard in the ecosystem for this. It
+ really should be added.
No Local Dependency Overlays: There is no standard for how to represent local
+ dependencies. Rust for this purpose has something like { path = "../foo" }
+ which allows both remote and local references to co-exist and it rewrites them
+ on publish.
No Exposed Pip: pip is intentionally not exposed. If you were to install something
+ into the virtualenv, it disappears next time you sync. If you symlink rye
to
+ ~/.rye/shims/pip
you can get access to pip without installing it into the
+ virtualenv. There be dragons.
No Workspace Spec: for monorepos and things of that nature, the Python ecosystem + would need a definition of workspaces. Today that does not exist which forces every + tool to come up with it's own solutions to this problem.
+No Basic Script Section: There should be a standard in pyproject.toml
to
+ represent scripts like rye
does in rye.tools.scripts
.
This describes of what I envision Python packaging and project management could +look like in an ideal world:
+Coming from a Rust environment there are two tools which work together: rustup
and
+cargo
. The first one of those is used to ensure that you have the correct Rust
+toolchain on your machine. Rust greatly prefers binary distributions of the language
+from the official website over external distributions.
cargo
is the main entry point to development in Rust. It acts as the tool to
+trigger test runs, start the build process, shell out to the documentation building
+tool, linters but also things such as workspace management, dependency management and
+package publishing.
Crucially a very important aspect of the Rust development experience is the strong
+commitment to semver and the built-in support for it. This goes very deep. The
+resolver for instance will deduplicate matching dependencies throughout the graph.
+This means that if four libraries depend on libc@0.2
, they will all resolve to
+that dependency. However if another need arises for libc@1.0
, then it's possible
+for the dependency graph to result in both being loaded!
The ecosystem greatly depends on this. For instance when a new major release is made
+of a very core library, in some cases extra care is taken to unify the now incompatible
+versions by re-exporting core types from the newer to the older version. Thus it's
+for instance possible for important-lib@0.2.32
to depend on
+important-lib@1.0
internally so it can make the transition easier.
Additionally Rust heavily leverages lockfiles. Whenever you compile, the dependencies +are locked in place and future builds reuse the same dependency versions unless you +update.
+Most importantly though the Rust ecosystem has embraced rustup
and cargo
that the
+vast majority of people are using these tools on a daily basis. Even developers who
+pick other tools like buck, are still using cargo
regularly.
Rye wants to explore if such an experience is possible with Python. I believe it can! +There is quite a lot of the ecosystem that can be leveraged for this purpose but there +is even more that would need to be built.
+Important note: when you read "rye" in the context of the document it talks about +what a potential tool like rye could be. It might as well be that one of the many +tools that exist today, turn into that very tool that is described here.
+My sentiment is that unless "the one tool" can emerge in the Python world, the +introduction of yet another tool might be a net-negative to the ecosystem. Plenty of +tools have been created over the years, and unfortunately it hasn't been able to +rally the majority of the Python community behind any tool. I do however believe it is +possible.
+I believe the right approach is that >95% of users get a Python distribution via rye
+and not to have rye
pick up a system installed Python distribution. There are good
+reasons for using a system Python installation, but it should be the exception not the
+rule. Most importantly because a Python distribution that rye
puts in place can be
+made to have reliable and simple rules that do not differ between systems.
A huge cause of confusion and user frustration currently comes from Linux distribution +specific patches on top of Python that break tools and change behavior, particularly +in the python packaging ecosystem.
+Bootstrapping Python via an independent tool has other benefits as well. It for instance +allows much easier cross-python version testing via tox or CI.
+What needs to be done:
+Today there are a ton of different resolvers in the Python ecosystem. Pip has two, poetry +has one, pdm has one, different independent Python and Rust resolvers exist on top of that. +Resolvers are important, but unfortunately are are both too many and too many issues with +the existing ones. Here is what I believe a resolver needs to be able to accomplish:
+Allow resolving across markers: most resolvers in the Python ecosystem today can only + resolve for the current interpreter and platform (eg: pip, pip-tools). This means it cannot + create a resolution that is equally valid for a different platform. In part this is + a problem because of how environment markers in Python are defined. They allow a level of + expressiveness that cannot be reflected by most tools, however a subset could be supported.
+Multi-version resolution support: this is a bit foreshadowing, but I believe for a
+ variety of reasons it needs to be possible for a resolver to not unify all requirements
+ to a single version, but to support multiple independent resolutions across major versions
+ of libraries. A future resolver should be able to permit package==2.0
and package==1.1
+ to both be resolved for different parts of the tree.
Resolver API: access to the resolver is important. For editor plugins, or custom
+ tools it's always necessary to be able to resolve packages. For instance if you want
+ something as trivial as "add latest supported version of 'flask' to my pyproject.toml
"
+ you need to be able to work with the resolver.
Filters: I strongly believe that a good resolver also needs a filter on top. For + instance it must be possible for a developer to restrict the resolver to stay within the + bounds of the target Python version and to never upgrade into a tree containing Python + versions that are too new. Likewise for supply chain safety a resolver should be able to + restrict itself to a set of vetted dependencies.
+What needs to be done:
+Because of the rather simplistic nature of Python packages and package indexes a resolver
+will always be restricted by the metadata that it can reliably pull. This is particularly
+bad if the system needs to fall back to sdist
uploads which in the worst case requires
+executing python code to determine the dependencies, and those dependencies might not even
+match on different platforms.
However this is a solvable problem with sufficient caching, and with the right design for +the cache, this cache could be shared. It might even be quite interesting for PyPI to +serve up "fake" metadata records for popular sdist only packages to help resolvers. +This might go a long way in improving the quality of the developer experience.
+What needs to be done:
+It's unclear if a standard can emerge for lock files given the different requirements, but a +Python packaging solution needs to have support for these. There are a lot of different +approaches to lockfiles today (poetry and pdm for instance have them) but it's not entirely +clear to me that the way they are handled today is sufficiently pragmatic to enable a tool +that is based on lockfiles to get majority adoption.
+The reason in part relates the suboptimal situation with resolvers (eg: large projects can +take ten minutes or longer to dependency check in poetry), on the other hand however also +because of the reality of how dependencies are currently declared. For instance certain +libraries will "over" depend on third party libraries, even if they are not needed for a +developer. These pulled in dependencies however will still influence the resolver.
+Most importantly a good lockfile also covers platforms other than the current developer's +machine. This means that if a project supports Windows and Linux, the lockfile should be +handling either dependency trees. This is what cargo accomplishes today, but cargo has a +a much simpler problem to solve here because it has perfect access to package metadata which +resolvers in Python do not have today. What is also problematic in Python is that certain +parts of the dependency tree can be version dependent. In Rust a library A either depends +on library B or it does not, but it does not depend on it conditional to a Python version.
+The total expressiveness of Python dependencies is challenging. The lack of good metadata +access for the resolver combined with the ability to make dependencies optional conditional +to the Python version is tricky by itself. The complexity however is compounded by the +fact that the resolver needs to come to a solution that can only result in a single resolved +version per package.
+What needs to be done:
+Resolving Python dependencies is particularly challenging because a single solution must be +found per package. A reason this works at all in the Python ecosystem is that most libraries +do not set upper bounds. This means that they will be eagerly accepting future libraries even +at the cost of not supporting them. That's largely possible because Python is a dynamic +language and a lot of flexibility is usually possible here. However with increased utilization +of type information in the Python world, and maybe with stronger desires for proper locking, +it might be quite likely that upper version bounds become more common.
+Once that happens however, the Python ecosystem will quite quickly run into blocking future +upgrades until the entire dependency graph has moved up which creates a lot of friction. +Other ecosystems have solved this problem by strictly enforcing semver semantics onto packages +and by permitting multiple semver incompatible libraries to be loaded simultaneously. While +usually a library is only allowed to permit on a single version of a dependency, that dependency +can exist in different versions throughout the dependency tree.
+In Python there is a perceived worry that this cannot be accomplished because of how site-packages,
+PYTHONPATH
and sys.modules
works. However I believe these to be solvable issues. On the one
+hand because .pth
files can be used to completely change how the import system works, secondly
+because the importlib.metadata
API is strong enough these days to allow a package to resolve
+it's own metadata. The combination of the two can be used to "redirect" imports in sys.modules
+and import statements to ensure that if a library imports a dependency of itself, it ends up with
+the right version.
What needs to be done:
+pyproject.toml
that declares that a package supports multi-versioningWith growing development teams one of the most frustrating experiences is the inability to +break up a monolithic Python module into smaller modules without having to constantly publish +minor versions to a package index. The way the Rust ecosystem deals with this issue is two-fold: +on the one hand Rust supports workspaces natively. Workspaces share dependencies and the +resolver results. The equivalent in Python would be that a workspace shares a virtualenv +across all of the projects within in. The second way in which Rust solves this problem is +to permit a dependency to both support declaration of the package name, index but also local +reference.
+While also Rust does not permit a crate to be published to a package index with references to +packages outside of the index, a separate rewrite step kicks in ahead of publish to clean out +invalid dependency references. If no valid reference remains, the package will not publish.
+What needs to be done:
+While virtualenv is not my favorite tool, it's the closest we have to a standard. I proposed
+that there is always one path for a virtualenv .venv
and when Rye manages it, users should
+not interact with it manually. It's at that point rye's responsibility to manage it, and it
+shall manage it as if it was a throw-away, always re-creatable scratch-pad for dependencies.
Preferably over time the structure of virtualenvs aligns between different Python versions
+(eg: Windows vs Linux) and the deeply nested lib/py-ver/site-packages
structure is flattened
+out.
What needs to be done:
+.venv
in the workspace root)Another topic that is currently unresolved across tools in the ecosystem is how to work with
+dependencies that are not used in production. For instance it's quite common that a certain
+dependency really only matters on the developer's machine. Today pdm and some other tools
+have custom sections in the pyproject.toml
file to mark development dependencies, but there
+is no agreement across tools on it.
What needs to be done:
+There needs to be an agreed upon standard for all tools. See this discussion
+Python against PEP-8's wishes just has too many ways in which things can be laid out. There +should be a much stronger push towards encouraging common standards:
+What needs to be done:
+package-foo
does not provide a package_foo
moduleSome of the existing tools in the ecosystem are close, and there is a good chance that some +of these might be able to combine forces to create that one-true tool. I hope that there +is enough shared interest, that we don't end up with three tools that all try to be Rye.
+ + + + + + +Rye is Armin's personal one-stop-shop for all his Python needs. It installs and manages Python installations, helps working with pyproject.toml
files, installs and uninstalls dependencies, creates and updates virtualenvs behind the scenes. It supports monorepos and global tool installations.
Rye is an experimental endeavour to build a new type of packaging experience to Python inspired by rustup
and cargo
from Rust. It's not yet production ready but feedback and suggestions are greatly appreciated.
Star Discuss Sponsor
Installation Instructions
LinuxmacOSWindowsCompile YourselfTo install run you can curl a command which will install the right binary for your operating system and CPU architecture and install it:
curl -sSf https://rye-up.com/get | bash\n
Alternatively if you don't trust this approach, you can download the latest release binary. On first run it will install itself.
gunzip rye-x86_64-linux.gz\nchmod +x ./rye-x86_64-linux\n./rye-x86_64-linux\n
To install run you can curl a command which will install the right binary for your operating system and CPU architecture and install it:
curl -sSf https://rye-up.com/get | bash\n
Alternatively if you don't trust this approach, you can download the latest release binary. On first run it will install itself.
gunzip rye-aarch64-macos.gz\nchmod +x ./rye-aarch64-macos\n./rye-aarch64-macos\n
To install Rye on windows download the latest release and run the binary. Upon first run it will install itself. Please note that it's strongly recommended to have \"Developer Mode\" activated when using Rye and before starting the installation. Learn more.
Note
Rye does not yet use signed binaries which means that you will need to allow the execution of the downloaded executable. If there is no obvious way to do so, click on \"More info\" on the error message that shows up and then on \"Run anyway\".
You need to have Rust and Cargo installed. If you don't have, you can use rustup to get them onto your machine.
Afterwards you can install Rye
via cargo
:
cargo install --git https://github.com/mitsuhiko/rye rye\n
For the next steps or ways to customize the installation, head over to the detailed installation guide.
"},{"location":"changelog/","title":"Changelog","text":"Here you can find all the released changes to Rye. If you want to also see the in-development changes that were not released yet, refer to the CHANGELOG.md file in the repository.
"},{"location":"changelog/#0170","title":"0.17.0","text":"Released on 2024-01-15
Fixed default generated script reference. #527
Correctly fall back to home folder if HOME is unset. #533
Released on 2023-12-17
By default a script with the name of the project is now also configured. #519
Rye now configures hatchling better in rye init
so that it works with hatchling 1.19 and later. #521
Rye now detects the dummy Python shim that starts the windows store and refuses to consider it. #486
Released on 2023-10-04
Released on 2023-10-03
Released on 2023-10-03
Released on 2023-10-01
Add support for fetching alternative CPU architectures. #447
The order of git submodule initialization was changed. This improves the automatic author detection when includeIf
is used. #443
The linux shim installer code will no longer fall back to symlinks when a hardlink cannot be created. This is done as a symlinked shim will not ever function correctly on Linux. This prevents the shim executables like python
to instead act as if they are rye
. The fallback behavior is now to copy the executable instead. #441
The installer now detects fish
and will spit out additional instructions for configuring the shell.
Fix the wrong behavior when bump version. #454
Released on 2023-08-29
Add a python3
shim on windows. Previously entering python3
in the command line would always bring up the windows store python proxy even when global shims were enabled. As virtualenvs do not support the python3
executable on windows, the internal shim handling is now also changed so that trying to launch python3
will fall back to python
. This makes it possible to run maturin build
.
Add maturin
build command to start a new maturin PyO3 project.
Released on 2023-08-27
Improve handling of the pth files for TCL on pypy. #409
The rye tools list
command now accepts -v
to also print out the versions of the installed tools. #396
Fixed parsing of versions by rye version
. #397
Improved the help message for rye init
. #401
The email address now defaults to a syntactically valid email address if not known to prevent errors with some build tools.
Added new Python versions.
The rye installer now detects NOEXEC
temporary folders and prints out a more helpful error message. #394
Fixed an issue where the author email was incorrectly detected. #382
The prompt of new virtualenvs is now set to the project name. #383
Released on 2023-07-18
Added new Python versions.
Added a new config key default.author
to configure the default author that should be set. This overrides the default author that is normally loaded from the git config. #377
When importing with rye init
and no src
folder exists, it will not be created. #375
Added support for shell
command on Windows. #363
Pin down pip to an older version to avoid issues with an incompatible pip-tools
version. This does not yet update pip-tools to 7.0 as there are significant regressions in 7.x. #374
The version
command can show dynamic versions now. #355
rye add
now properly checks some incompatible argument combinations. #347
There is now more toolchain validation. This better supports cases where rye was interrupted during sync. #351
Released on 2023-07-07
Fixed a bug with rye init
not operating correctly due to a argument conflict. #346
Scripts now support a PDM style call
script type. #345
The init
command is now capable of importing existing projects. #265
Fixed the global shim behavior on Windows. #344
Released on 2023-06-21
The internal Rye Python version is now 3.11.
Rye now emits most messages, most of the time to stdout rather than stderr. #342
rye add
now accepts --pin
to let one override the type of pin to use. #341
Added rye config
to read and manipulate the config.toml
file. #339
Added support for the new behavior.global-python
flag which turns on global Python shimming. When enabled then the python
shim works even outside of Rye managed projects. Additionally the shim (when run outside of Rye managed projects) supports a special first parameter +VERSION
which requests a specific version of Python (eg: python +3.8
to request Python 3.8). #336
Renamed the config key default.dependency_operator
to default.dependency-operator
and behavior.force_rye_managed
to behavior.force-rye-managed
. #338
Released on 2023-06-18
Rye for now prefers >=
over ~=
for newly added dependencies.
The workspace member declaration is now platform independent. If members
is now explicitly set to an empty list it will not fall back to auto discovery. #331
rye add
now pins versions with ==
instead of ~=
when the version of the package does not use at least two components. This means that for instance it will now correctly use openai-whisper==20230314
rather than openai-whisper~=20230314
which is not actually satisfiable. #328
rye install
now lets you install dependencies into the tool's virtualenv during installation that are undeclared via the new --extra-requirement
option. #326
Improved handling of relative path installations by setting PROJECT_ROOT
the same way as PDM does. #321
Workspaces will now never discover pyproject.toml
files in any dot directories. (Name starting with .
) #329
Fixed rye build
not working correctly on Windows. #327
Released on 2023-06-12
rye sync
and rye lock
now accept --pyproject
. #296
Added JSON output to rye toolchain list
by adding --format=json
. #306
rye version
can bump version by --bump
option now. #298
Fixed members not handled correctly in workspaces. #300
Add --clean
for build
command. #297
Fixed an issue where pip was not invoked from the right working directory causing issues for workspace installations. #292
rye init
now accepts --private
to set the Private :: Do Not Upload
classifier that prevents uploads to PyPI. #291
Released on 2023-06-03
Add version
subcommand for rye. #285
Fixed rye pin
pinning the wrong version. #288
Calling rye init
on the root directory no longer fails. #274
rye run
, show
, pin
, shell
and build
now take a --pyproject
argument. #232
Released on 2023-05-31
Rye will no longer enforce a downloaded interpreter for the internal toolchain. If one has been registered that is compatible it will be used. Additionally the installer now supports the RYE_TOOLCHAIN
environment variable which allows a user to supply an already existing Python interpreter at install time. #267
The publish
command now supports --yes
to disable prompts. #270
When a Python debug build (Py_DEBUG
) is registered as custom toolchain, -dbg
is automatically appended to the name by default. #269
lto+pgo builds are now preferred for the Python toolchain builds when available. #268
It's now possible for .python-version
to request partial Python versions in which case the latest available is used. In particular this means that a version like 3.10
can be written into .python-version
rather than 3.10.11
. This can be accomplished by invoking pin
with the new --relaxed
flag. #255
Workspaces will no longer discover pyproject.toml
files in virtualenvs or .git
folders. #266
Adding or removing dependencies with add
or remove
now reformats the dependencies
array in the pyproject.toml
file to multi-line with trailing commas. This should result in significantly better diffing behavior out of the box. #263
Default build-system and license can be specified in global config. #244
Fixed an issue where the init
command would not let you create flit
based projects. #254
Resolve an error (\"No such file or directory\") shown after updates on Linux machines. #252
The built-in updater now validates checksums of updates when updates have SHA-256 hashes available. #253
init
now accepts --no-pin
to not create a .python-version
file. #247
Released on 2023-05-29
Releases starting with 0.4.0
onwards are published with SHA256 checksum files for all release assets. These files are not yet validated by the installer or updater however.
The install
command can now install tools from custom indexes. #240
Virtualenvs on Unix are now created with a hack to pre-configure TCL and TKinter. #233
Fix invalid version error when using rye init with custom toolchain. #234
Failed tool installations now properly clean up. #225
Correctly swap the rye executable on windows when performing an update to a git version via self update
.
Released on 2023-05-27
Support retrieving username and repository-url from credentials if not provided for the publish
command. #217
The installer now validates the availability of shared libraries on Linux with ldd
and emits an error with additional information if necessary shared libraries are missing. #220
It's now possible to configure http and https proxies. #215
If a package is not found because it only has matching pre-releases, a warning is now printed to tell the user to pass --pre
. #218
Add --username
parameter for rye publish. #211
The shims are now more resilient. Previously a pyproject.toml
file caused in all cases a virtualenv to be created. Now this will only happen when the rye.tool.managed
flag is set to true
. The old behavior can be forced via the global config. #212
Released on 2023-05-23
Resolved a bug where on Windows hitting the shift key (or some other keys) in confirm prompts would cause an error.
The installer on Windows now warns if symlinks are not enabled and directs the user to enable developer mode. The --version
output now also shows if symlinks are available. #205
Support auto fix requires-python when there is a conflict. #160
Added support for custom indexes. #199
rye add
no longer complains when a local version information is in the version. #199
Released on 2023-05-22
Fixed dev-dependencies not being installed when using workspace. #170
init
no longer creates invalid flit config. #195
Support direct references when adding a package. #158
Fixed a bug with uninstall on Unix platforms. #197
Released on 2023-05-18
The installer on windows will now ask for a key to be pressed so it does not close the window without information. #183
Fixed an issue on macOS where the installer would die with \"os error 24\" when directly piped to bash. #184
Released on 2023-05-17
Rye now comes with binary releases for some platforms.
A new self uninstall
command was added to uninstall rye and the new self update
command updates to the latest release version.
Rye now includes a publish
command for publishing Python packages to a package repository. #86
Script declarations in pyproject.toml
now permit chaining and custom environment variables. #153
Added tools install
and tools uninstall
as aliases for install
and uninstall
and added tools list
to show all installed tools.
Rye is now capable of downloading a selected set of PyPy releases. To do so use rye pin pypy@3.9.16
or any other supported PyPy release.
Custom cpython toolchains are now registered just as cpython
rather than custom-cpython
.
Rye now supports Python down to 3.7.
Rye's self
command now includes a completion
subcommand to generate a completion script for your shell.
The downloaded Python distributions are now validated against the SHA-256 hashes.
Rye now builds on windows. This is even more experimental though than support for Linux and macOS.
Added --features
and --all-features
for lock
and sync
.
Rye will now look at the RYE_HOME
to determine the location of the .rye
folder. If it's not set, $HOME/.rye
is used as before.
Rye now has a most consistent handling for virtualenv versions. If .python-version
is provided, that version is used. Otherwise if requires-python
is set in the pyproject.toml
, that version is used instead. When a new project is created the .python-version
file is written and the current latest cpython version is picked.
It's now possible to explicitly set the name
of the project when initializing a new one.
Rye's init
command now attempts to initialize projects with git
and will automatically create a src/project_name/__init__.py
file.
Rye can now also generate a license text when initializing projects.
Rye now supports negative (exclusion) dependencies. These can be used to prevent a dependency from installing, even if something else in the graph depends on it. Use rye add --exclude package-name
to add such a dependency.
sync
now accepts --no-lock
to prevent updating the lock file.
Rye's add
command now accepts a --pre
parameter to include pre-release.
Rye's pin
command now updates the pyproject.toml requires-python.
Rye's install
command now accepts a --include-dep
parameter to include scripts from one or more given dependencies.
Rye now honors requires-python
in the add
command. This means the the initial resolution will not pick a version higher than what's supported by the lower boundary.
When installing packages as global tools, a warning is now emitted if there were no scripts in the package. Additionally installing packages from local paths and zip files is now supported.
A rye self update
command was added to compile and install the latest version via cargo.
Added more convenient ways to install from git/urls by supplying a --git
or --url
parameter. This will behind the scenes format a PEP 508 requirement string.
Added a shell
command which will spawn a shell with the virtualenv activated.
Added a make-req
command to conveniently format out PEP 508 requirement strings from parts.
The internal virtualenv used to manage pip-tools
and other libraries now automatically updates when necessary.
rye toolchain register
can now be used to register a local python installation as toolchain with rye.
rye build
was added to allow building sdist
and bdist_wheel
distributions.
Rye now correctly handles whitespace in folder names.
Rye is a new project and feedback is greatly appreciated. Lots of it. Because of this there are various different ways in which you can engage with either the developer or other members of the community:
You can also reach out via Twitter or Bluesky.
"},{"location":"philosophy/","title":"Philosophy and Vision","text":"Rye was built to solve my problems. Here is what was on my mind when I built it:
Virtualenvs: while I personally do not like virtualenvs that much, they are so widespread and have reasonable tooling support, so I chose this over __pypackages__
.
No Default Dependencies: the virtualenvs when they come up are completely void of dependencies. Not even pip
or setuptools
are installed into it. Rye manages the virtualenv from outside the virtualenv.
No Core Non Standard Stuff: Rye (with the exception of it's own tool
section in the pyproject.toml
) uses standardized keys. That means it uses regular requirements as you would expect. It also does not use a custom lock file format and uses pip-tools
behind the scenes.
No Pip: Rye uses pip, but it does not expose it. It manage dependencies in pyproject.toml
only.
No System Python: I can't deal with any more linux distribution weird Python installations or whatever mess there is on macOS. I used to build my own Pythons that are the same everywhere, now I use indygreg's Python builds. Rye will automatically download and manage Python builds from there. No compiling, no divergence.
Project Local Shims: Rye maintains a python
shim that auto discovers the current pyproject.toml
and automatically operates below it. Just add the shims to your shell and you can run python
and it will automatically always operate in the right project.
There are a few shortcomings in the Python packaging world, largely as a result of lack of standardization. Here is what this project ran into over the years:
No Python Binary Distributions: CPython builds from python.org are completely inadequate. On some platforms you only get an .msi installer, on some you literally only get tarballs. The various Python distributions that became popular over the years are diverging greatly and cause all kinds of nonsense downstream. This is why this Project uses the indygreg standalone builds. I hope that with time someone will start distributing well maintained and reliable Python builds to replace the mess we are dealing with today.
No Dev Dependencies: Rye currently needs a custom section in the pyproject.toml
to represent dev dependencies. There is no standard in the ecosystem for this. It really should be added.
No Local Dependency Overlays: There is no standard for how to represent local dependencies. Rust for this purpose has something like { path = \"../foo\" }
which allows both remote and local references to co-exist and it rewrites them on publish.
No Exposed Pip: pip is intentionally not exposed. If you were to install something into the virtualenv, it disappears next time you sync. If you symlink rye
to ~/.rye/shims/pip
you can get access to pip without installing it into the virtualenv. There be dragons.
No Workspace Spec: for monorepos and things of that nature, the Python ecosystem would need a definition of workspaces. Today that does not exist which forces every tool to come up with it's own solutions to this problem.
No Basic Script Section: There should be a standard in pyproject.toml
to represent scripts like rye
does in rye.tools.scripts
.
This describes of what I envision Python packaging and project management could look like in an ideal world:
"},{"location":"philosophy/#the-rust-experience","title":"The Rust Experience","text":"Coming from a Rust environment there are two tools which work together: rustup
and cargo
. The first one of those is used to ensure that you have the correct Rust toolchain on your machine. Rust greatly prefers binary distributions of the language from the official website over external distributions.
cargo
is the main entry point to development in Rust. It acts as the tool to trigger test runs, start the build process, shell out to the documentation building tool, linters but also things such as workspace management, dependency management and package publishing.
Crucially a very important aspect of the Rust development experience is the strong commitment to semver and the built-in support for it. This goes very deep. The resolver for instance will deduplicate matching dependencies throughout the graph. This means that if four libraries depend on libc@0.2
, they will all resolve to that dependency. However if another need arises for libc@1.0
, then it's possible for the dependency graph to result in both being loaded!
The ecosystem greatly depends on this. For instance when a new major release is made of a very core library, in some cases extra care is taken to unify the now incompatible versions by re-exporting core types from the newer to the older version. Thus it's for instance possible for important-lib@0.2.32
to depend on important-lib@1.0
internally so it can make the transition easier.
Additionally Rust heavily leverages lockfiles. Whenever you compile, the dependencies are locked in place and future builds reuse the same dependency versions unless you update.
Most importantly though the Rust ecosystem has embraced rustup
and cargo
that the vast majority of people are using these tools on a daily basis. Even developers who pick other tools like buck, are still using cargo
regularly.
Rye wants to explore if such an experience is possible with Python. I believe it can! There is quite a lot of the ecosystem that can be leveraged for this purpose but there is even more that would need to be built.
Important note: when you read \"rye\" in the context of the document it talks about what a potential tool like rye could be. It might as well be that one of the many tools that exist today, turn into that very tool that is described here.
My sentiment is that unless \"the one tool\" can emerge in the Python world, the introduction of yet another tool might be a net-negative to the ecosystem. Plenty of tools have been created over the years, and unfortunately it hasn't been able to rally the majority of the Python community behind any tool. I do however believe it is possible.
"},{"location":"philosophy/#bootstrapping-python","title":"Bootstrapping Python","text":"I believe the right approach is that >95% of users get a Python distribution via rye
and not to have rye
pick up a system installed Python distribution. There are good reasons for using a system Python installation, but it should be the exception not the rule. Most importantly because a Python distribution that rye
puts in place can be made to have reliable and simple rules that do not differ between systems.
A huge cause of confusion and user frustration currently comes from Linux distribution specific patches on top of Python that break tools and change behavior, particularly in the python packaging ecosystem.
Bootstrapping Python via an independent tool has other benefits as well. It for instance allows much easier cross-python version testing via tox or CI.
What needs to be done:
Today there are a ton of different resolvers in the Python ecosystem. Pip has two, poetry has one, pdm has one, different independent Python and Rust resolvers exist on top of that. Resolvers are important, but unfortunately are are both too many and too many issues with the existing ones. Here is what I believe a resolver needs to be able to accomplish:
Allow resolving across markers: most resolvers in the Python ecosystem today can only resolve for the current interpreter and platform (eg: pip, pip-tools). This means it cannot create a resolution that is equally valid for a different platform. In part this is a problem because of how environment markers in Python are defined. They allow a level of expressiveness that cannot be reflected by most tools, however a subset could be supported.
Multi-version resolution support: this is a bit foreshadowing, but I believe for a variety of reasons it needs to be possible for a resolver to not unify all requirements to a single version, but to support multiple independent resolutions across major versions of libraries. A future resolver should be able to permit package==2.0
and package==1.1
to both be resolved for different parts of the tree.
Resolver API: access to the resolver is important. For editor plugins, or custom tools it's always necessary to be able to resolve packages. For instance if you want something as trivial as \"add latest supported version of 'flask' to my pyproject.toml
\" you need to be able to work with the resolver.
Filters: I strongly believe that a good resolver also needs a filter on top. For instance it must be possible for a developer to restrict the resolver to stay within the bounds of the target Python version and to never upgrade into a tree containing Python versions that are too new. Likewise for supply chain safety a resolver should be able to restrict itself to a set of vetted dependencies.
What needs to be done:
Because of the rather simplistic nature of Python packages and package indexes a resolver will always be restricted by the metadata that it can reliably pull. This is particularly bad if the system needs to fall back to sdist
uploads which in the worst case requires executing python code to determine the dependencies, and those dependencies might not even match on different platforms.
However this is a solvable problem with sufficient caching, and with the right design for the cache, this cache could be shared. It might even be quite interesting for PyPI to serve up \"fake\" metadata records for popular sdist only packages to help resolvers. This might go a long way in improving the quality of the developer experience.
What needs to be done:
It's unclear if a standard can emerge for lock files given the different requirements, but a Python packaging solution needs to have support for these. There are a lot of different approaches to lockfiles today (poetry and pdm for instance have them) but it's not entirely clear to me that the way they are handled today is sufficiently pragmatic to enable a tool that is based on lockfiles to get majority adoption.
The reason in part relates the suboptimal situation with resolvers (eg: large projects can take ten minutes or longer to dependency check in poetry), on the other hand however also because of the reality of how dependencies are currently declared. For instance certain libraries will \"over\" depend on third party libraries, even if they are not needed for a developer. These pulled in dependencies however will still influence the resolver.
Most importantly a good lockfile also covers platforms other than the current developer's machine. This means that if a project supports Windows and Linux, the lockfile should be handling either dependency trees. This is what cargo accomplishes today, but cargo has a a much simpler problem to solve here because it has perfect access to package metadata which resolvers in Python do not have today. What is also problematic in Python is that certain parts of the dependency tree can be version dependent. In Rust a library A either depends on library B or it does not, but it does not depend on it conditional to a Python version.
The total expressiveness of Python dependencies is challenging. The lack of good metadata access for the resolver combined with the ability to make dependencies optional conditional to the Python version is tricky by itself. The complexity however is compounded by the fact that the resolver needs to come to a solution that can only result in a single resolved version per package.
What needs to be done:
Resolving Python dependencies is particularly challenging because a single solution must be found per package. A reason this works at all in the Python ecosystem is that most libraries do not set upper bounds. This means that they will be eagerly accepting future libraries even at the cost of not supporting them. That's largely possible because Python is a dynamic language and a lot of flexibility is usually possible here. However with increased utilization of type information in the Python world, and maybe with stronger desires for proper locking, it might be quite likely that upper version bounds become more common.
Once that happens however, the Python ecosystem will quite quickly run into blocking future upgrades until the entire dependency graph has moved up which creates a lot of friction. Other ecosystems have solved this problem by strictly enforcing semver semantics onto packages and by permitting multiple semver incompatible libraries to be loaded simultaneously. While usually a library is only allowed to permit on a single version of a dependency, that dependency can exist in different versions throughout the dependency tree.
In Python there is a perceived worry that this cannot be accomplished because of how site-packages, PYTHONPATH
and sys.modules
works. However I believe these to be solvable issues. On the one hand because .pth
files can be used to completely change how the import system works, secondly because the importlib.metadata
API is strong enough these days to allow a package to resolve it's own metadata. The combination of the two can be used to \"redirect\" imports in sys.modules
and import statements to ensure that if a library imports a dependency of itself, it ends up with the right version.
What needs to be done:
pyproject.toml
that declares that a package supports multi-versioningWith growing development teams one of the most frustrating experiences is the inability to break up a monolithic Python module into smaller modules without having to constantly publish minor versions to a package index. The way the Rust ecosystem deals with this issue is two-fold: on the one hand Rust supports workspaces natively. Workspaces share dependencies and the resolver results. The equivalent in Python would be that a workspace shares a virtualenv across all of the projects within in. The second way in which Rust solves this problem is to permit a dependency to both support declaration of the package name, index but also local reference.
While also Rust does not permit a crate to be published to a package index with references to packages outside of the index, a separate rewrite step kicks in ahead of publish to clean out invalid dependency references. If no valid reference remains, the package will not publish.
What needs to be done:
While virtualenv is not my favorite tool, it's the closest we have to a standard. I proposed that there is always one path for a virtualenv .venv
and when Rye manages it, users should not interact with it manually. It's at that point rye's responsibility to manage it, and it shall manage it as if it was a throw-away, always re-creatable scratch-pad for dependencies.
Preferably over time the structure of virtualenvs aligns between different Python versions (eg: Windows vs Linux) and the deeply nested lib/py-ver/site-packages
structure is flattened out.
What needs to be done:
.venv
in the workspace root)Another topic that is currently unresolved across tools in the ecosystem is how to work with dependencies that are not used in production. For instance it's quite common that a certain dependency really only matters on the developer's machine. Today pdm and some other tools have custom sections in the pyproject.toml
file to mark development dependencies, but there is no agreement across tools on it.
What needs to be done:
There needs to be an agreed upon standard for all tools. See this discussion
"},{"location":"philosophy/#opinionated-defaults","title":"Opinionated Defaults","text":"Python against PEP-8's wishes just has too many ways in which things can be laid out. There should be a much stronger push towards encouraging common standards:
What needs to be done:
package-foo
does not provide a package_foo
moduleSome of the existing tools in the ecosystem are close, and there is a good chance that some of these might be able to combine forces to create that one-true tool. I hope that there is enough shared interest, that we don't end up with three tools that all try to be Rye.
"},{"location":"guide/","title":"Introduction","text":"Rye is still a very experimental tool, but this guide is here to help you get started. Before we dive into the installation and basic usage guide it's important for you to understand what Rye actually is.
Rye is a one-stop-shop tool. The idea is that as a Python developer all you need to know is Rye, because Rye is your start into the experience. As a Rye user you do not even need to install Python yourself as Rye does this for you. This means to use Rye, you just need to install Rye, the rest is done by Rye itself.
Once Rye is on your system, it can automatically install Python interpreters for you, install packages from package indexes, manage virtualenvs behind the scenes and more.
Interested? Then head over to Installation to learn about how to get Rye onto your system. Once that is done, read the Basics to learn about how Rye can be used.
"},{"location":"guide/basics/","title":"Basics","text":"To use Rye you need to have a pyproject.toml
based Python project. For this guide you can create one with rye init
which will create a new folder with a new project inside:
rye init my-project\ncd my-project\n
The following structure will be created:
.\n\u251c\u2500\u2500 .git\n\u251c\u2500\u2500 .gitignore\n\u251c\u2500\u2500 .python-version\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 pyproject.toml\n\u2514\u2500\u2500 src\n \u2514\u2500\u2500 my_project\n \u2514\u2500\u2500 __init__.py\n
Good to Know
The init
command accepts a lot of options to customize what it generates. Run rye init --help
to see all the options available in the version you have installed.
A pyproject.toml
is used to store metadata about your project as well as some Rye configuration. Most of Rye's commands will require a pyproject.toml
to work. Note that Rye today does not support setup.py
based projects. Note that when Rye initializes a project it also writes a .python-version
file. This file contains the version number of the Python version that should be used for this project. It can be changed by running rye pin
. For instance to tell Rye to use Python 3.10:
$ rye pin 3.10\n
"},{"location":"guide/basics/#first-sync","title":"First Sync","text":"Once that is done, you can use rye sync
to get the first synchronization. After that, Rye will have created a virtualenv in .venv
and written lockfiles into requirements.lock
and requirements-dev.lock
.
rye sync\n
The virtualenv that Rye manages is placed in .venv
next to your pyproject.toml
. The first time you run this you will notice that Rye automatically downloaded and installed a compatible CPython interpreter for you. If you have already another Python installation on your system it will not be used! For more information about this behavior read about toolchains.
You can activate and work with it as normal with one notable exception: the Python installation in it does not contain pip
. If you have correctly installed Rye with the shims enabled, after the sync you can run python
and you will automatically be operating in that virtualenv, even if it's not enabled. You can validate this by printing out sys.prefix
:
python -c \"import sys; print(sys.prefix)\"\n
It will print out the full path to the managed virtualenv.
"},{"location":"guide/basics/#adding-dependencies","title":"Adding Dependencies","text":"Use the add
command to add dependencies to your project.
rye add \"flask>=2.0\"\n
Note that after add
you need to run sync
again to actually install it. If you want to add packages from custom indexes, you have to configure the source first.
Use the remove
command to remove a dependency from the project again.
rye remove flask\n
"},{"location":"guide/basics/#working-with-the-project","title":"Working with the Project","text":"To run executables in the context of the virtualenv you can use the run
command. For instance if you want to use black
you can add and run it like this:
rye add black\nrye sync\nrye run black\n
If you want to have the commands available directly you will need to activate the virtualenv like you do normally. To activate the virtualenv, use the standard methods:
UnixWindows. .venv/bin/activate\n
.venv\\Scripts\\activate\n
To deactivate it again run deactivate
:
deactivate\n
"},{"location":"guide/basics/#inspecting-the-project","title":"Inspecting the Project","text":"The rye show
command can print out information about the project's state. By just running rye show
you can see which Python version is used, where the virtualenv is located and more. You can also invoke rye show --installed-deps
to get a dump of all installed dependencies.
rye show\nrye show --installed-deps\n
"},{"location":"guide/config/","title":"Configuration","text":"Most of Rye's configuration is contained within the pyproject.toml
file. There is however also a bit of global configuration to influence how it works.
By default Rye places all it's configuration in ~/.rye
on Unix and %USERPROFILE%\\.rye
on Windows. This behavior can be changed via the RYE_HOME
environment variable. This is useful if you do not like the default location of where Rye places it's configuration or if you need to isolate it.
The .rye
home folder contains both user configuration as well as Rye managed state such as installed toolchains. The following files and folders are placed within the .rye
folder. Note that not all are there always.
config.toml
","text":"This is a configuration file that influences how Rye operates. Today very little configuration is available there. For the available config keys see Config File.
"},{"location":"guide/config/#self","title":"self
","text":"While Rye is written in Rust, it uses a lot of Python tools internally. These are maintained in an internal virtualenv stored in this location.
"},{"location":"guide/config/#py","title":"py
","text":"In this folder Rye stores the different toolchains. Normally those are folders containing downloaded Python distributions, but they can also be symlinks or special reference files.
"},{"location":"guide/config/#shims","title":"shims
","text":"This folder contains shim binaries. These binaries are for instance the python
executable which automatically proxies to the current virtualenv or globally installed tools.
The config file config.toml
in the .rye
folder today only is used to manage defaults. This is a fully annotated config file:
[default]\n# This is the default value that is written into new pyproject.toml\n# files for the `project.requires-python` key\nrequires-python = \">= 3.8\"\n\n# This is the default toolchain that is used\ntoolchain = \"cpython@3.11.1\"\n\n# This is the default build system that is used\nbuild-system = \"hatchling\"\n\n# This is the default license that is used\nlicense = \"MIT\"\n\n# This sets the default author (overrides the defaults from git). The\n# format here is \"Name <email>\".\nauthor = \"Full Name <email@address.invalid>\"\n\n# The dependency operator to use by default for dependencies. The options are\n# '>=', '~=', and '=='. The default currently is '>='. This affects the behavior\n# of `rye add`.\ndependency-operator = \">=\"\n\n[proxy]\n# the proxy to use for HTTP (overridden by the http_proxy environment variable)\nhttp = \"http://127.0.0.1:4000\"\n# the proxy to use for HTTPS (overridden by the https_proxy environment variable)\nhttps = \"http://127.0.0.1:4000\"\n\n[behavior]\n# When set to true the `managed` flag is always assumed to be true.\nforce-rye-managed = false\n\n# Enables global shims when set to `true`. This means that the installed\n# `python` shim will resolve to a Rye managed toolchain even outside of\n# virtual environments.\nglobal-python = false\n\n# a array of tables with optional sources. Same format as in pyproject.toml\n[[sources]]\nname = \"default\"\nurl = \"http://pypi.org/simple/\"\n
"},{"location":"guide/config/#manipulating-config","title":"Manipulating Config","text":"new in 0.9.0
The configuration can be read and modified with rye config
. The keys are in dotted notation. --get
reads a key, --set
, --set-int
, --set-bool
, or --unset
modify one.
rye config --set proxy.http=http://127.0.0.1:4000\nrye config --set-bool behavior.force-rye-managed=true\nrye config --get default.requires-python\n
"},{"location":"guide/config/#per-project-config","title":"Per Project Config","text":"For the project specific pyproject.toml
config see pyproject.toml.
Dependencies are declared in pyproject.toml however adding them can be simplified with the rye add
command. In the most simple invocation it adds a regular dependency, but it can be customized.
To add a regular dependency just invoke rye add
with the name of the Python package:
rye add Flask\n
If you also want to define a version, use a PEP 508 requirement:
rye add \"Flask>=2.0\"\n
For extra/feature dependencies you can either use PEP 508 syntax or use --features
:
rye add \"Flask[dotenv]\"\nrye add Flask --features=dotenv\n
These dependencies are stored in project.dependencies
.
Note about pre-releases
By default add
will not consider pre-releases. This means if you add a dependency that has .dev
or similar in the version number you will not find a match. To consider them, add them with --pre
:
rye add \"Flask==2.0.0rc2\" --pre\n
"},{"location":"guide/deps/#development-dependencies","title":"Development Dependencies","text":"For dependencies that should only be installed during development pass --dev
rye add --dev black\n
These dependencies are stored in the non-standard tool.rye.dev-dependencies
key.
To run tools added this way without enabling the virtualenv use rye run
:
rye run black\n
"},{"location":"guide/deps/#git-local-dependencies","title":"Git / Local Dependencies","text":"To add a local or git dependency, you can pass additional parameters like --path
or --git
:
rye add Flask --git=https://github.com/pallets/flask\nrye add My-Utility --path ./my-utility\n
Note that when adding such dependencies, it's necessary to also provide the name of the package. Additionally for git dependencies all kinds of extra parameters such as --tag
, --rev
or --branch
are supported.
When working with local dependencies it's strongly encouraged to configure a workspace.
"},{"location":"guide/faq/","title":"FAQ","text":"This section should cover some commonly asked questions. If you do not find an answer here, consider reaching out to the community.
"},{"location":"guide/faq/#windows-developer-mode","title":"Windows Developer Mode","text":"Rye does not require symlinks but it works significantly better with them. On Windows support for symlinks is restricted to privileged accounts. The reason for this is that Symlinks were a late addition to Windows and some applications are not developed with them in mind which can cause misbehavior or in the worst case security issues in those applications. Symlinks support however is enabled when the \"developer mode\" is activated on modern Windows versions. Here is how you can enable it:
Enabling symlinks is not strictly required as Rye automatically falls back to hardlinks and junction points. However not having symlinks enabled will ultimately result in a worse user experience for the following reasons:
.rye\\py
path are non executable.The Python builds that Rye uses require a Linux installation compatible to the Linux Standard Base Core Specification (LSB). Unfortunately not all Linux distributions are strictly adhering to that specification out of the box. In particularly the library libcrypt.so.1
is commonly not installed on certain Linux distributions but the _crypt
standard library module depends on it. Depending on the Linux distributions you need to run different commands to resolve this:
pacman -S libxcrypt-compat
dnf install libxcrypt-compat
There have also been reports of an error being generated at installation time despite libcrypt.so.1
being installed when a different ldd
(eg: Homebrew) shadows the system one. In that case try the installation again after giving the default one higher priority in the `PATH:
export PATH=\"/usr/bin:$PATH\"\ncurl -sSf https://rye-up.com/get | bash\n
"},{"location":"guide/faq/#tkinter-support","title":"TKinter Support","text":"TKinter uses TCL behind the scenes. Unfortunately this also means that some runtime support is required. This runtime support is provided by the portable Python builds, however the way TCL is initialized on macOS and Linux won't find these files in virtualenvs. Newer versions of Rye will automatically export the TCL_LIBRARY
and TK_LIBRARY
environment variables for you in a manner very similar to this:
import os\nimport sys\nos.environ[\"TCL_LIBRARY\"] = sys.base_prefix + \"/lib/tcl8.6\"\nos.environ[\"TK_LIBRARY\"] = sys.base_prefix + \"/lib/tk8.6\"\n
"},{"location":"guide/faq/#python-interactive-prompt-input-messed-up","title":"Python Interactive Prompt Input Messed Up","text":"The Python builds that Rye uses are compiled against libedit
rather than readline
for licensing reasons. You might run into unicode issues on input as a result of this due to limitations in libedit
. In some cases though you might also discover that the backspace key does not work or arrow keys don't work as expected. This can be because the terminfo database cannot be found.
For solutions to this issue, read the behavior quirks guide in the Standalone Python Builds documentation for solutions.
"},{"location":"guide/faq/#can-i-use-rye-alongside-other-python-installations","title":"Can I use Rye Alongside Other Python Installations?","text":"Rye given it's experimental nature does not want to disrupt already existing Python workflows. As such using it alongside other Python installations is intentionally supported. Even if the Rye shims come first on the PATH
, Rye will automatically resolve to a different Python installation on the search path when invoked in a folder that contains a non Rye managed project.
As such the answer is a clear yes!
"},{"location":"guide/faq/#wheels-appear-to-be-missing-files","title":"Wheels Appear to be Missing Files","text":"You might be encountering missing files in wheels when running rye build
and you are using hatchling. The reason for this is that rye build
uses \"build\" behind the scenes to build wheels. There are two build modes and in some cases the wheel is first built from an sdist. So if your sdists does not include the necessary data files, the resulting wheel will also be incorrect.
This can be corrected by adding the files to the include
in the hatch config for sdists. For instance the following lines added to pyproject.toml
will add the data files in my_package
and all the tests to the sdist from which the wheel is built:
[tool.hatch.build.targets.sdist]\ninclude = [\"src/my_package\", \"tests\"]\n
"},{"location":"guide/installation/","title":"Installation","text":"Rye is built in Rust. It can either be manually compiled and installed or it can be installed from a binary distribution. It has support for Linux, macOS and Windows.
"},{"location":"guide/installation/#installing-rye","title":"Installing Rye","text":"Rye is installed per-user and self manages itself. It will install itself into a folder in your home directory and mange itself there.
LinuxmacOSWindowsCompile YourselfTo install run you can curl a command which will install the right binary for your operating system and CPU architecture and install it:
curl -sSf https://rye-up.com/get | bash\n
Alternatively if you don't trust this approach, you can download the latest release binary. On first run it will install itself.
gunzip rye-x86_64-linux.gz\nchmod +x ./rye-x86_64-linux\n./rye-x86_64-linux\n
To install run you can curl a command which will install the right binary for your operating system and CPU architecture and install it:
curl -sSf https://rye-up.com/get | bash\n
Alternatively if you don't trust this approach, you can download the latest release binary. On first run it will install itself.
gunzip rye-aarch64-macos.gz\nchmod +x ./rye-aarch64-macos\n./rye-aarch64-macos\n
To install Rye on windows download the latest release and run the binary. Upon first run it will install itself. Please note that it's strongly recommended to have \"Developer Mode\" activated when using Rye and before starting the installation. Learn more.
Note
Rye does not yet use signed binaries which means that you will need to allow the execution of the downloaded executable. If there is no obvious way to do so, click on \"More info\" on the error message that shows up and then on \"Run anyway\".
You need to have Rust and Cargo installed. If you don't have, you can use rustup to get them onto your machine.
Afterwards you can install Rye
via cargo
:
cargo install --git https://github.com/mitsuhiko/rye rye\n
Rye will automatically download suitable Python toolchains as needed. For more information about this read about toolchains. To install a specific version download a binary directly from GitHub.
"},{"location":"guide/installation/#customized-installation","title":"Customized Installation","text":"On some platforms there is some limited support for customizing the installation experience.
LinuxmacOSWindows The install script that is piped to bash
can be customized with some environment variables:
RYE_VERSION
Defaults to latest
. Can be set to an explicit version to install a specific one.
RYE_INSTALL_OPTION
Can optionally be set to \"--yes\"
to skip all prompts.
RYE_TOOLCHAIN
Optionally this environment variable can be set to point to a Python interpreter that should be used as the internal interpreter. If not provided a suitable interpreter is automatically downloaded.
At present only CPython 3.9 to 3.11 are supported.
This for instance installs a specific version of Rye without asking questions:
curl -sSf https://rye-up.com/get | RYE_VERSION=\"0.4.0\" RYE_INSTALL_OPTION=\"--yes\" bash\n
The install script that is piped to bash
can be customized with some environment variables:
RYE_VERSION
Defaults to latest
. Can be set to an explicit version to install a specific one.
RYE_INSTALL_OPTION
Can optionally be set to \"--yes\"
to skip all prompts.
RYE_TOOLCHAIN
Optionally this environment variable can be set to point to a Python interpreter that should be used as the internal interpreter. If not provided a suitable interpreter is automatically downloaded.
At present only CPython 3.9 to 3.11 are supported.
This for instance installs a specific version of Rye without asking questions:
curl -sSf https://rye-up.com/get | RYE_VERSION=\"0.4.0\" RYE_INSTALL_OPTION=\"--yes\" bash\n
The Windows installer has limited support for customizations via environment variables. To set these you need to run the installer from cmd.exe
.
RYE_TOOLCHAIN
Optionally this environment variable can be set to point to a Python interpreter that should be used as the internal interpreter. If not provided a suitable interpreter is automatically downloaded.
At present only CPython 3.9 to 3.11 are supported.
This for instance installs Rye with a specific toolchain:
set RYE_TOOLCHAIN=%USERPROFILE%\\AppData\\Local\\Programs\\Python\\Python310\\python.exe\nrye-x86_64-windows.exe\n
"},{"location":"guide/installation/#add-shims-to-path","title":"Add Shims to Path","text":"Once rye
is installed you need to add the shims
folder into your PATH
. This folder is a folder that contains \"shims\" which are executables that Rye manages for you as well as the rye
executable itself. For instance any Python installation managed by Rye will be available via a shim placed there.
On macOS or Linux you can accomplish this by adding it to your .bashrc
, .zshrc
or similar. This step is technically optional but required if you want to be able to just type python
or rye
into the shell to pick up the current virtualenv's Python interpreter.
Rye ships an env
file which should be sourced to update PATH
automatically.
echo 'source \"$HOME/.rye/env\"' >> ~/.bashrc\n
Rye ships an env
file which should be sourced to update PATH
automatically.
echo 'source \"$HOME/.rye/env\"' >> ~/.zshrc\n
Since fish does not support env
files, you instead need to add the shims directly. This can be accomplished by running this command once:
set -Ua fish_user_paths \"$HOME/.rye/shims\"\n
Rye ships an env
file which should be sourced to update PATH
automatically.
echo '. \"$HOME/.rye/env\"' >> ~/.profile\n
To modify the Windows PATH environment variable
sysdm.cpl
and hit Enter.Path
variable.%USERPROFILE%\\.rye\\shims
and hit Enter.Note that you might need to restart your login session for this to take effect.
There is a quite a bit to shims and their behavior. Make sure to read up on shims to learn more.
"},{"location":"guide/installation/#shell-completion","title":"Shell Completion","text":"Rye supports generating completion scripts for Bash, Zsh, Fish or Powershell. Here are some common locations for each shell:
BashZshFishPowershellmkdir -p ~/.local/share/bash-completion/completions\nrye self completion > ~/.local/share/bash-completion/completions/rye.bash\n
# Make sure ~/.zfunc is added to fpath, before compinit.\nrye self completion -s zsh > ~/.zfunc/_rye\n
Oh-My-Zsh:
mkdir $ZSH_CUSTOM/plugins/rye\nrye self completion -s zsh > $ZSH_CUSTOM/plugins/rye/_rye\n
Then make sure rye plugin is enabled in ~/.zshrc
rye self completion -s fish > ~/.config/fish/completions/rye.fish\n
# Create a directory to store completion scripts\nmkdir $PROFILE\\..\\Completions\necho @'\nGet-ChildItem \"$PROFILE\\..\\Completions\\\" | ForEach-Object {\n . $_.FullName\n}\n'@ | Out-File -Append -Encoding utf8 $PROFILE\n# Generate script\nSet-ExecutionPolicy Unrestricted -Scope CurrentUser\nrye self completion -s powershell | Out-File -Encoding utf8 $PROFILE\\..\\Completions\\rye_completion.ps1\n
"},{"location":"guide/installation/#updating-rye","title":"Updating Rye","text":"To update rye to the latest version you can use rye
itself:
rye self update\n
"},{"location":"guide/installation/#uninstalling","title":"Uninstalling","text":"If you don't want to use Rye any more, you can ask it to uninstall it again:
rye self uninstall\n
Additionally you should delete the remaining .rye
folder from your home directory and remove .rye/shims
from the PATH
again. Rye itself does not place any data in other locations. Note though that virtual environments created by rye will no longer function after Rye was uninstalled.
Rye when launched will normally perform an auto installation. This can be annoying in certain development situations. This can be prevented by exporting the RYE_NO_AUTO_INSTALL
environment variable. It needs to be set to 1
to disable the feature.
export RYE_NO_AUTO_INSTALL=1\n
export RYE_NO_AUTO_INSTALL=1\n
set RYE_NO_AUTO_INSTALL=1\n
"},{"location":"guide/publish/","title":"Building and Publishing","text":"Rye currently uses build to build the package and uses twine to publish it.
"},{"location":"guide/publish/#build","title":"Build","text":"By default, rye
will build the both sdist and wheel target in the dist
directory.
rye build\n
You can use the --sdist
or --wheel
flag to build the specific target, or specify the output directory with --out
.
rye build --wheel --out target\n
If you want to clean the build directory before building, run:
rye build --clean\n
"},{"location":"guide/publish/#publish","title":"Publish","text":"Rye will publish the distribution files under the dist
directory to PyPI by default.
rye publish\n
You might be asked to input your access token and some other info if needed.
No access token found, generate one at: https://pypi.org/manage/account/token/\nAccess token:\n
You can also specify the distribution files to be published:
rye publish dist/example-0.1.0.tar.gz\n
"},{"location":"guide/publish/#-repository","title":"--repository","text":"Rye supports publishing the package to a different repository by using the --repository
and --repository-url
flags. For example, to publish to the test PyPI repository:
rye publish --repository testpypi --repository-url https://test.pypi.org/legacy/\n
"},{"location":"guide/publish/#-yes","title":"--yes","text":"You can optionally set the --yes
flag to skip the confirmation prompt. This can be useful for CI/CD pipelines.
rye publish --token <your_token> --yes\n
Rye will store your repository info in $HOME/.rye/credentials
for future use.
pyproject.toml
)","text":"Rye tries to avoid a lot of proprietary configuration in the pyproject.toml
file but a bit is necessary. Here are the most important keys that Rye expects:
project.dependencies
","text":"This key is used to manage dependencies. They work exactly like you expect from a regular pyproject.toml
file and in fact Rye changes nothing about this. However Rye is capable of modifying these entries with the rye add
and rye remove
commands.
[project]\ndependencies = [\n\"mkdocs~=1.4.3\",\n\"mkdocs-material~=9.1.12\",\n\"pymdown-extensions~=9.11\",\n]\n
"},{"location":"guide/pyproject/#projectscripts","title":"project.scripts
","text":"This key specifies the scripts that are to be generated and installed into the virtual environment during sync
. These scripts will invoke the configured entry point.
[project.scripts]\nmy-hello-script = 'hello:main'\n
This configuration will generate a script my-hello-script
that will call the main
function of the hello
module. Scripts can be installed using rye sync
and run using rye run
:
$ rye sync\n$ rye run my-hello-script\nHello from hello!\n
"},{"location":"guide/pyproject/#toolryedev-dependencies","title":"tool.rye.dev-dependencies
","text":"This works similar to project.dependencies
but holds development only dependencies. These can be added here automatically via rye add --dev
.
[tool.rye]\ndev-dependencies = [\"black~=23.3.0\"]\n
Dev dependencies are installed automatically unless --no-dev
is passed to sync
.
tool.rye.excluded-dependencies
","text":"This is a special key that contains dependencies which are never installed, even if they are pulled in as indirect dependencies. These are added here automatically with rye add --excluded
.
[tool.rye]\nexcluded-dependencies = [\"cffi\"]\n
"},{"location":"guide/pyproject/#toolryelock-with-sources","title":"tool.rye.lock-with-sources
","text":"new in 0.18.0
When this flag is enabled all lock
and sync
operations in the project or workspace operate as if --with-sources
is passed. This means that all lock files contain the full source references. Note that this can create lock files that contain credentials if the sources have credentials included in the URL.
[tool.rye]\nlock-with-sources = true\n
"},{"location":"guide/pyproject/#toolryemanaged","title":"tool.rye.managed
","text":"new in 0.3.0
This key tells rye that this project is supposed to be managed by Rye. This key primarily affects some automatic creation of virtualenvs. For instance Rye will not try to initialize a virtualenv when using shims without this flag. It can be forced enabled in the global config.
[tool.rye]\nmanaged = true\n
"},{"location":"guide/pyproject/#toolryesources","title":"tool.rye.sources
","text":"This is an array of tables with sources that should be used for locating dependencies. This lets you use indexes other than PyPI. These sources can also be configured in the main config.toml
config file with the same syntax.
[[tool.rye.sources]]\nname = \"default\"\nurl = \"http://pypi.org/simple/\"\n
For more information about configuring sources see Dependency Sources.
"},{"location":"guide/pyproject/#toolryescripts","title":"tool.rye.scripts
","text":"This key can be used to register custom scripts that are exposed via rye run
. Each key is a script, and each value is the configuration for that script. Normally the value is an object with different keys with the most important key being cmd
which holds the command to execute. However if only cmd
is set, then the object is optional. cmd
itself can either be set to a string or an array of arguments.
[tool.rye.scripts]\n# These three options are equivalent:\ndevserver = \"flask run --app ./hello.py --debug\"\ndevserver-alt = [\"flask\", \"run\", \"--app\", \"./hello.py\", \"--debug\"]\ndevserver-explicit = { cmd = \"flask run --app ./hello.py --debug\" }\n
The following keys are possible for a script:
"},{"location":"guide/pyproject/#cmd","title":"cmd
","text":"The command to execute. This is either a string
or an array
of arguments. In either case shell specific interpolation is unavailable. The command will invoke one of the tools in the virtualenv if it's available there.
[tool.rye.scripts]\ndevserver = { cmd = \"flask run --app ./hello.py --debug\" }\nhttp = { cmd = [\"python\", \"-mhttp.server\", \"8000\"] }\n
"},{"location":"guide/pyproject/#env","title":"env
","text":"This key can be used to provide environment variables with a script:
[tool.rye.scripts]\ndevserver = { cmd = \"flask run --debug\", env = { FLASK_APP = \"./hello.py\" } }\n
"},{"location":"guide/pyproject/#chain","title":"chain
","text":"This is a special key that can be set instead of cmd
to make a command invoke multiple other commands. Each command will be executed one after another. If any of the commands fails the rest of the commands won't be executed and instead the chain fails.
[tool.rye.scripts]\nlint = { chain = [\"lint:black\", \"lint:flake8\" ] }\n\"lint:black\" = \"black --check src\"\n\"lint:flake8\" = \"flake8 src\"\n
"},{"location":"guide/pyproject/#call","title":"call
","text":"This is a special key that can be set instead of cmd
to make a command invoke python functions or modules. The format is one of the three following formats:
<module_name>
: equivalent to python -m <module_name>
<module_name>:<function_name>
: runs <function_name>
from <module_name>
and exits with the return value<module_name>:<function_name>(<args>)
: passes specific arguments to the functionExtra arguments provided on the command line are passed in sys.argv
.
[tool.rye.scripts]\nserve = { call = \"http.server\" }\nhelp = { call = \"builtins:help\" }\nhello-world = { call = \"builtins:print('Hello World!')\" }\n
"},{"location":"guide/pyproject/#toolryeworkspace","title":"tool.rye.workspace
","text":"When a table with that key is stored, then a project is declared to be a workspace root. By default all Python projects discovered in sub folders will then become members of this workspace and share a virtualenv. Optionally the members
key (an array) can be used to restrict these members. In that list globs can be used. The root project itself is always a member.
[tool.rye.workspace]\nmembers = [\"mylib-*\"]\n
"},{"location":"guide/rust/","title":"Rust Modules","text":"Rye recommends using maturin to develop Rust Python extension modules. This process is largely automated and new projects can be created with rye init
.
rye init my-project --build-system maturin\ncd my-project\n
The following structure will be created:
.\n\u251c\u2500\u2500 .git\n\u251c\u2500\u2500 .gitignore\n\u251c\u2500\u2500 .python-version\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 pyproject.toml\n\u251c\u2500\u2500 Cargo.toml\n\u251c\u2500\u2500 python\n \u2514\u2500\u2500 my_project\n \u2514\u2500\u2500 __init__.py\n\u2514\u2500\u2500 src\n \u2514\u2500\u2500 lib.rs\n
"},{"location":"guide/rust/#iterating","title":"Iterating","text":"When you use maturin as a build system then rye sync
will automatically build the rust extension module into your venv. Likewise rye build
will use maturin to trigger a wheel build. For faster iteration it's recommended to use maturin
directly.
If you want to use other maturin commands such as maturin develop
you can install it as a global tool:
rye install maturin\n
Note that maturin develop
requires pip
to be installed into the virtualenv. Before you can use it you need to add it:
rye add --dev pip\nrye sync\n
Rye recommends mixed python/rust modules. In that case you can save some valuable iteration time by running maturin develop --skip-install
:
maturin develop --skip-install\n
"},{"location":"guide/shims/","title":"Shims","text":"After installation Rye places two shims on your PATH
: python
and python3
. These shims have specific behavior that changes depending on if they are used within a Rye managed project or outside.
Inside a Rye managed project they resolve to the Python interpreter of the virtualenv. This means that even if you do not enable the virtualenv, you can just run python
in a shell, and it will automatically operate in the right environment.
Outside a Rye managed project it typically resolves to your system Python, though you can also opt to have it resolve to a Rye managed Python installation for you. This is done so that it's not disruptive to your existing workflows which might depend on the System python installation.
"},{"location":"guide/shims/#global-shims","title":"Global Shims","text":"new in 0.9.0
To enable global shims, you need to enable the global-python
flag in the config.toml
file:
rye config --set-bool behavior.global-python=true\n
Afterwards if you run python
outside of a Rye managed project it will spawn a Python interpreter that is shipped with Rye. It will honor the closest .python-version
file for you. Additionally you can also explicitly request a specific Python version by adding +VERSION
after the python
command. For instance this runs a script with Python 3.8:
python +3.8 my-script.py\n
Note
Selecting a specific Python version this way only works outside of Rye managed projects. Within Rye managed projects, the version needs to be explicitly selected via .python-version
or with the requires-python
key in pyproject.toml
.
new in 0.2.0
Normally Rye loads packages from PyPI only. However it is possible to instruct it to load packages from other indexes as well.
"},{"location":"guide/sources/#adding-a-source","title":"Adding a Source","text":"An index can be added to a project or workspace (via pyproject.toml
) or into the global config. Rye will always consult both files where the pyproject.toml
file wins over the global config.
Each source needs to have a unique name. The default source is always called default
and out of the box points to PyPI.
Add this to ~/.rye/config.toml
:
[[sources]]\nname = \"company-internal\"\nurl = \"https://company.internal/simple/\"\n
Add this to pyproject.toml
:
[[tool.rye.sources]]\nname = \"company-internal\"\nurl = \"https://company.internal/simple/\"\n
changed in 0.4.0
Sources in the global config are also considered for tool installations.
"},{"location":"guide/sources/#index-types","title":"Index Types","text":"Rye supports different types of sources and also allows overriding the default
PyPI index. If you give another source the name default
, PyPI will no longer be used for resolution.
[[sources]]\nname = \"company-internal\"\nurl = \"https://company.internal/simple/\"\ntype = \"index\" # this is implied\n
[[sources]]\nname = \"company-internal\"\nurl = \"https://company.internal/\"\ntype = \"find-links\"\n
[[sources]]\nname = \"default\"\nurl = \"https://company.internal/simple/\"\n
Warning
Please take note that the default index cannot be of type find-links
.
The two sources types (index
vs find-links
) are determined by the underlying pip infrastructure:
index
","text":"This is a PEP 503 type index as provided by tools such as PyPI or devpi. It corresponds to the arguments --index-url
or --extra-index-url
in pip.
find-links
","text":"This is a source that can be of a variety of types and has to point to a file path or hosted HTML page linking to packages. It corresponds to the --find-links
argument. The format of the HTML page is somewhat underspecified but generally all HTML links pointing to .tar.gz
or .whl
files are considered.
HTTP basic auth is supported for index authentication. It can be supplied in two ways. username
and password
can be directly embedded in the config, or they can be supplied with environment variables.
[[sources]]\nname = \"company-internal\"\nurl = \"https://company.internal/simple/\"\nusername = \"username\"\npassword = \"super secret\"\n
[[sources]]\nname = \"company-internal\"\nurl = \"https://${INDEX_USERNAME}:${INDEX_PASSWORD}@company.internal/simple/\"\n
"},{"location":"guide/sync/","title":"Syncing and Locking","text":"Rye currently uses pip-tools to download and install dependencies. For this purpose it creates two \"lockfiles\" (called requirements.lock
and requirements-dev.lock
). These are not real lockfiles but they fulfill a similar purpose until a better solution has been implemented.
Whenever rye sync
is called, it will update lockfiles as well as the virtualenv. If you only want to update the lockfiles, then rye lock
can be used.
When locking, some options can be provided to change the locking behavior. These flags are also all available on rye sync
.
--update
/ --update-all
","text":"Updates a specific or all requirements to the latest and greatest version. Without this flag a dependency will only be updated if necessary.
rye lock --update-all\n
"},{"location":"guide/sync/#-features-all-features","title":"--features
/ --all-features
","text":"Python packages can have extra dependencies. By default the local package that is installed will only be installed with the default features. If for instance you have an extra dependency this will only be installed if the feature is enabled.
rye add --optional=web flask\nrye lock --features=web\n
When working with workspaces, the package name needs to be prefixed with a slash:
rye lock --features=package-name/feature-name\n
The --features
parameter can be passed multiple times and features can also be comma separated. To turn on all features, the --all-features
parameter can be used.
rye lock --all-features\n
"},{"location":"guide/sync/#-pre","title":"--pre
","text":"By default updates and version resolution will not consider pre-releases of packages. If you do want to include those, pass --pre
rye lock Flask --pre\n
"},{"location":"guide/sync/#-with-sources","title":"--with-sources
","text":"new in 0.18.0
By default (unless the tool.rye.lock-with-sources
config key is set to true
in the pyproject.toml
) lock files are not generated with source references. This means that if custom sources are used the lock file cannot be installed via pip
unless also --find-links
and other parameters are manually passed. This can be particularly useful when the lock file is used for docker image builds.
When this flag is passed then the lock file is generated with references to --index-url
, --extra-index-url
or --find-links
.
rye lock --with-sources\n
"},{"location":"guide/sync/#sync","title":"Sync","text":"Syncing takes the same parameters as lock
and then some. Sync will usually first do what lock
does and then use the lockfiles to update the virtualenv.
--no-lock
","text":"To prevent the lock step from automatically running, pass --no-lock
.
rye sync --no-lock\n
"},{"location":"guide/sync/#-no-dev","title":"--no-dev
","text":"Only sync based on the production lockfile (requirements.lock
) instead of the development lockfile (requirements-dev.lock
).
rye sync --no-dev\n
"},{"location":"guide/tools/","title":"Tools","text":"Rye supports global tool installations. This for instance allows you to install tools like black
or ruff
globally.
Use the rye tools install
(aliased to rye install
) command to install a tool globally with a shim:
rye install ruff\n
Afterwards the tool is installed into ~/.rye/tools/ruff
and the necessary shims are placed in ~/.rye/shims
.
changed in 0.4.0
The install
command now considers custom sources configured in the config.toml
file. For more information see Dependency Sources.
Some tools do not declare all of their dependencies since they might be optional. In some cases these can be declared by passing extra features to the installer:
rye install black --features colorama\n
If dependencies are not at all specified, then they can be provided with --extra-requirement
. This is particularly sometimes necessary if the tool uses pkg_resources
(part of setuptools
) but forgets to declare that dependency:
rye install gradio --extra-requirement setuptools\n
"},{"location":"guide/tools/#listing-tools","title":"Listing Tools","text":"If you want to see which tools are installed, you can use rye tools list
:
rye tools list\n
black\n black\n blackd\nruff\n ruff\n
To also see which scripts those tools provide, also pass --include-scripts
rye tools list --include-scripts\n
"},{"location":"guide/tools/#uninstalling-tools","title":"Uninstalling Tools","text":"To uninstall a tool again, use rye tools uninstall
(aliased to rye uninstall
):
rye uninstall black\n
"},{"location":"guide/toolchains/","title":"Toolchain Management","text":"Rye is unique in that it does not use system Python installations. Instead it downloads and manages Python installations itself (called toolchains). Today there are three types of toolchains supported by Rye and they require some understanding:
To make a project use a specific toolchain write the name of the toolchain into the .python-version
file or use the pin
command. For pinning cpython
the cpython@
prefix can be omitted.
rye pin cpython@3.11.4\n
Pinning a downloadable version means that Rye will automatically fetch it when necessary. By default, toolchains are pinned to a precise version. This means that even if you write rye pin cpython@3.11
, a very specific version of cpython is written into the .python-version
file. With Rye 0.5.0 onwards it's possible to perform \"relaxed\" pins:
rye pin --relaxed cpython@3.11\n
This will then persist 3.11
in the .python-version
file and Rye will use the latest available compatible version for the virtual environment.
changed in 0.5.0
Relaxed pinning with rye pin --relaxed
was added.
new in 0.14.0
Support for fetching and pinning of non-native architectures was added.
By default, the pin is for the architecture of the running machine. This means that if you pin cpython@3.11
on a mac with aarch64 architecture, you will use a cpython interpreter of that CPU architecture. A different architecture can be selected by adding -{arch}
to the python family name. So for instance to force a x86_64
version you need to pin like this:
rye pin cpython-x86_64@3.11\n
Note that such custom pins are not reflected in pyproject.toml
but only .python-version
.
To see which toolchains are installed, rye toolchain list
prints a list:
rye toolchain list\n
cpython@3.11.1 (C:\\Users\\armin\\.rye\\py\\cpython@3.11.1\\install\\python.exe)\npypy@3.9.16 (C:\\Users\\armin\\.rye\\py\\pypy@3.9.16\\python.exe)\n
To see which toolchains can be installed, additionally pass the --include-downloadable
:
rye toolchain list --include-downloadable\n
"},{"location":"guide/toolchains/#fetching-toolchains","title":"Fetching Toolchains","text":"Generally Rye automatically downloads toolchains, but they can be explicitly fetched with rye toolchain fetch
(also aliased to rye fetch
):
rye toolchain fetch cpython@3.8.5\n
Toolchains are fetched from two sources:
Additionally, it's possible to register an external toolchain with the rye toolchain register
command.
rye toolchain register /path/to/python\n
The name of the toolchain is picked based on the interpreter. For instance linking a regular cpython installation will be called cpython@version
, whereas linking pypy would show up as pypy@version
. From Rye 0.5.0 onwards -dbg
is appended to the name of the toolchain if it's a debug build. To override the name you can pass --name
:
rye toolchain register --name=custom /path/to/python\n
"},{"location":"guide/toolchains/#removing-toolchains","title":"Removing Toolchains","text":"To remove an already fetched toolchain run rye toolchain remove
. Note that this also works for linked toolchains:
rye toolchain remove cpython@3.8.5\n
Warning
Removing an actively used toolchain will render the virtualenvs that refer to use broken.
"},{"location":"guide/toolchains/cpython/","title":"Portable CPython","text":"Rye is capable (and prefers) to download its own Python distribution over what you might already have on your computer. For CPython, the indygreg/python-build-standalone builds from the PyOxidizer project are used.
The motivation for this is that it makes it easy to switch between Python versions, to have a common experience across different Rye users and to avoid odd bugs caused by changes in behavior.
Unfortunately Python itself does not release binaries (or the right types of binaries) for all operating systems which is why Rye leverages the portable Python builds from PyOxidizer.
Unlike many other Python versions you can install on your computer are non-portable which means that if you move them to a new location on your machine, or you copy it onto another computer (even with the same operating system) they will no longer run. This is undesirable for what Rye wants to do. For one we want the same experience for any of the Python developers, no matter which operating system they used. Secondly we want to enable self-contained Python builds later, which requires that the Python installation is portable.
To achieve this, the Python builds we use come with some changes that are different from a regular Python build.
"},{"location":"guide/toolchains/cpython/#limitations","title":"Limitations","text":"The following changes to a regular Python versions you should be aware of:
libedit
instead of readline
: unfortunately readline
is GPL2 licensed and this is a hazard for redistributions. As such, the portable Python builds link against the more freely licensed libedit
instead.
dbm.gnu
is unavailable. This is a rather uncommonly used module and the standard library provides alternatives.
Additionally due to how these builds are created, there are some other quirks you might run into related to terminal support or TKinter. Some of these issues are collected in the FAQ. Additionally the Python Standalone Builds have a Behavior Quirks page.
"},{"location":"guide/toolchains/cpython/#sources","title":"Sources","text":"Portable CPython builds are downloaded from GitHub (indygreg/python-build-standalone/releases) and SHA256 hashes are generally validated. Some older versions might not have hashes available in which case the validation is skipped.
"},{"location":"guide/toolchains/cpython/#usage","title":"Usage","text":"When you pin a Python version to cpython@major.minor.patch
(or just major.minor.patch
) then Rye will automatically download the right version for you whenever it is needed. If a custom toolchain has already been registered with that name and version, that this is used instead.
PyPy is supported as alternative Python distribution. Like the portable CPython builds it's downloaded automatically. The name for PyPy distributions is pypy
.
PyPy has some limitations compared to regular Python builds when it comes to working with Rye. Most specifically PyPy uses some internal pypi dependencies and you might notice warnings show up when syching. PyPy also lags behind regular Python installations quite a bit these days so you likely need to target older Python packages.
"},{"location":"guide/toolchains/pypy/#sources","title":"Sources","text":"PyPy builds are downloaded from downloads.python.org. These downloads are not verified today.
"},{"location":"guide/toolchains/pypy/#usage","title":"Usage","text":"When you pin a Python version to pypy@major.minor.patch
then Rye will automatically download the right version for you whenever it is needed. If a custom toolchain has already been registered with that name and version, that this is used instead. Note that the version refers to the PyPy CPython version.
That means for instance that PyPy 7.3.11 is identified as pypy@3.9.16
as this is the Python version it provides. As PyPy also lacks builds for some CPU architectures, not all platforms might provide the right PyPy versions.