How to upgrade


Why upgrade?

See Pants v1 vs. v2 engine.

Step 1: Upgrade to newer Pants releases

We recommend upgrading to 1.28.0 or newer for a more polished experience. See Upgrade tips for some tips with upgrading.

Step 2: Decide on mixed mode vs. pure v2 mode

Pants supports either running in pure v2 mode or "mixed" mode, where you use the v2 engine for Python builds and the v1 engine for other languages.

If you are using Pants for JVM, Go, or Node—or if you have custom v1 plugins—you will want to use mixed mode. Otherwise, we recommend pure v2 mode.

Step 3: Update your pants.toml

Pure v2 mode

v1 = false
v2 = true
dynamic_ui = true
backend_packages = []
backend_packages2 = ["pants.backend.python"]

See Linters and formatters for how to activate linters and formatters.

Mixed mode

v1 = true
v2 = true
dynamic_ui = true
# Remove the v1 Python implementation, which is used by default.
backend_packages.remove = ["pants.backend.python"]
backend_packages2.add = ["pants.backend.python"]

When running goals like fmt, lint, and test, Pants will use the v2 implementation for Python and v1 for your other languages.

To temporarily disable v1 or v2, use the flags --no-v1 and --no-v2. For example, this will only run the v2 Python linters:

./pants --no-v1 lint ::


Tip: create a ./v1 and/or a ./v2 script

It can be helpful to add another script in addition to ./pants, which simply calls ./pants but hardcodes either --no-v1 or --no-v2.

For example, a ./v1 script might look like:

#!/usr/bin/env bash

./pants --v1 --no-v2 "$@"

This way, you can teach your Python developers to continue to use ./pants and your other developers to use a ./v1 script.

Key differences to be aware of


Missing features? Let us know!

Please message us on Slack if you are having issues upgrading or find something missing. We would love to help.

--cache-ignore doesn't impact v2

The v2 engine handles caching very differently than the v1 engine. Rather than having monolithic tasks like test.pytest, each build step is broken up into several composable "rules". Because of this design, options like --cache-ignore and --test-pytest-cache-ignore will no longer do anything.

Instead, you can use --no-process-execution-use-local-cache. This will avoid reading from the global cache in ~/.cache/pants/lmbd_store. Warning: this means that you will re-resolve Python requirements, which is slow.

If you're trying to rerun a test, you can instead run ./pants test --debug to run the tests in the foreground and to force re-running of the tests, but use the cache for everything else. (See test).

Tests run in the background by default

In v1, tests run in the foreground. That is, you can see tests run in real-time in your terminal, and you can use breakpoints and debuggers.

In v2, tests instead run in the background. Why? So that Pants can run multiple test targets in parallel.

To instead run a test interactively, run ./pants test --debug path/to/test.py. (See test).

Tests now run in a chroot

Before Pants 1.25.0, tests would run in the build root, rather than in a temporary directory (chroot). We changed the default for v1 in 1.25.0 to default to running in a chroot, but you might have still set chroot = false in the [test.pytest] scope.

If you have set chroot = false, then we recommend first getting all of your tests to pass with chroot = true while still using the v1 Python backend. Usually, you will need to declare dependencies that you previously left off, such as declaring a files() or resource() target for resource files.

(Why do we now run in a chroot? This allows us to safely run multiple tests in parallel.)

Linter config files must be specified

Because linters and formatters now run in a chroot (temporary directory), you must explicitly specify your config files to make sure that they get copied into the directory. See Linters and formatters.

(Running in a chroot means that Pants can run all of your linters in parallel.)

IPython is activated differently


ipython = true


shell = "ipython"