Commit Graph

273 Commits

Author SHA1 Message Date
Aria Desires 5021840919
Add `[tool.uv.dependency-groups].mygroup.requires-python` (#13735)
This allows you to specify requires-python on individual dependency-groups,
with the intended usecase being "oh my dev-dependencies have a higher
requires-python than my actual project".

This includes a large driveby move of the RequiresPython type to
uv-distribution-types to allow us to generate the appropriate markers at
this point in the code. It also migrates RequiresPython from
pubgrub::Range to version_ranges::Ranges, and makes several pub(crate)
items pub, as it's no longer defined in uv_resolver.

Fixes #11606
2025-06-13 22:04:13 +00:00
konsti 56203484a2
Add `uv add --bounds` to configure the version constraint (#12946)
By default, uv uses only a lower bound in `uv add`, which avoids
dependency conflicts due to upper bounds. With this PR, this cna be
changed by setting a different bound kind. The bound kind can be
configured in `uv.toml`, as a user preference, in `pyproject.toml`, as a
project preference, or on the CLI, when adding a specific project.

We add two options that add an upper bound on the constraint, one for
SemVer (`>=1.2.3,<2.0.0`, dubbed "major", modeled after the SemVer
caret) and another one for dependencies that make breaking changes in
minor version (`>=1.2.3,<1.3.0`, dubbed "minor", modeled after the
SemVer tilde). Intuitively, the major option bumps the most significant
version component, while the minor option bumps the second most
significant version component. There is also an exact bounds option
(`==1.2.3`), though generally we recommend setting a wider bound and
using the lockfile for pinning.

Versions can have leading zeroes, such as `0.1` or `0.0.1`. For a single
leading 0, we shift the the meaning of major and minor similar to cargo.
For two or more leading zeroes, the difference between major and minor
becomes inapplicable, instead both bump the most significant component:
- major: `0.1` -> `>=0.1,<0.2`
- major: `0.0.1` -> `>=0.0.1,<0.0.2`
- major: `0.0.1.1` -> `>=0.0.1.1,<0.0.2.0`
- major: `0.0.0.1` -> `>=0.0.0.1,<0.0.0.2`
- minor: `0.1` -> `>=0.1,<0.1.1`
- minor: `0.0.1` -> `>=0.0.1,<0.0.2`
- minor: `0.0.1.1` -> `>=0.0.1.1,<0.0.2.0`
- minor: `0.0.0.1` -> `>=0.0.0.1,<0.0.0.2`

For a consistent appearance, we try to preserve the number of components
in the upper bound. For example, adding a version `2.17` with the major
option is stored as `>=2.17,<3.0`. If a version uses three components
and is greater than 0, both bounds will also use three components
(SemVer versions always have three components). Of the top 100 PyPI
packages, 8 use a non-three-component version (docutils, idna, pycparser
and soupsieve with two components, packaging, pytz and tzdata with two
component, CalVer and trove-classifiers with four component CalVer).
Example `pyproject.toml` files with the top 100 packages: [`--bounds
major`](https://gist.github.com/konstin/0aaffa9ea53c4834c22759e8865409f4)
and [`--bounds
minor`](https://gist.github.com/konstin/e77f5e990a7efe8a3c8a97c5c5b76964).
While many projects follow version scheme that roughly or directly
matches the major or minor options, these compatibility ranges are
usually not applicable for the also popular CalVer versioning.

For pre-release versions, there are two framings we could take: One is
that pre-releases generally make no guarantees about compatibility
between them and are used to introduce breaking changes, so we should
pin them exactly. In many cases however, pre-release specifiers are used
because a project needs a bugfix or a feature that hasn't made it into a
stable release, or because a project is compatible with the next version
before a final version for that release is published. In those cases,
compatibility with other packages that depend on the same library is
more important, so the desired bound is the same as it would be for the
stable release, except with the lower bound lowered to include
pre-release.

The names of the bounds and the name of the flag is up for bikeshedding.
Currently, the option is call `tool.uv.bounds`, but we could also move
it under `tool.uv.edit.bounds`, where it would be the first/only entry.

Fixes #6783

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-05-28 13:11:31 +00:00
John Mumm c19a294a48
Add `DisplaySafeUrl` newtype to prevent leaking of credentials by default (#13560)
Prior to this PR, there were numerous places where uv would leak
credentials in logs. We had a way to mask credentials by calling methods
or a recently-added `redact_url` function, but this was not secure by
default. There were a number of other types (like `GitUrl`) that would
leak credentials on display.

This PR adds a `DisplaySafeUrl` newtype to prevent leaking credentials
when logging by default. It takes a maximalist approach, replacing the
use of `Url` almost everywhere. This includes when first parsing config
files, when storing URLs in types like `GitUrl`, and also when storing
URLs in types that in practice will never contain credentials (like
`DirectorySourceUrl`). The idea is to make it easy for developers to do
the right thing and for the compiler to support this (and to minimize
ever having to manually convert back and forth). Displaying credentials
now requires an active step. Note that despite this maximalist approach,
the use of the newtype should be zero cost.

One conspicuous place this PR does not use `DisplaySafeUrl` is in the
`uv-auth` crate. That would require new clones since there are calls to
`request.url()` that return a `&Url`. One option would have been to make
`DisplaySafeUrl` wrap a `Cow`, but this would lead to lifetime
annotations all over the codebase. I've created a separate PR based on
this one (#13576) that updates `uv-auth` to use `DisplaySafeUrl` with
one new clone. We can discuss the tradeoffs there.

Most of this PR just replaces `Url` with `DisplaySafeUrl`. The core is
`uv_redacted/lib.rs`, where the newtype is implemented. To make it
easier to review the rest, here are some points of note:

* `DisplaySafeUrl` has a `Display` implementation that masks
credentials. Currently, it will still display the username when there is
both a username and password. If we think is the wrong choice, it can
now be changed in one place.
* `DisplaySafeUrl` has a `remove_credentials()` method and also a
`.to_string_with_credentials()` method. This allows us to use it in a
variety of scenarios.
* `IndexUrl::redacted()` was renamed to
`IndexUrl::removed_credentials()` to make it clearer that we are not
masking.
* We convert from a `DisplaySafeUrl` to a `Url` when calling `reqwest`
methods like `.get()` and `.head()`.
* We convert from a `DisplaySafeUrl` to a `Url` when creating a
`uv_auth::Index`. That is because, as mentioned above, I will be
updating the `uv_auth` crate to use this newtype in a separate PR.
* A number of tests (e.g., in `pip_install.rs`) that formerly used
filters to mask tokens in the test output no longer need those filters
since tokens in URLs are now masked automatically.
* The one place we are still knowingly writing credentials to
`pyproject.toml` is when a URL with credentials is passed to `uv add`
with `--raw`. Since displaying credentials is no longer automatic, I
have added a `to_string_with_credentials()` method to the `Pep508Url`
trait. This is used when `--raw` is passed. Adding it to that trait is a
bit weird, but it's the simplest way to achieve the goal. I'm open to
suggestions on how to improve this, but note that because of the way
we're using generic bounds, it's not as simple as just creating a
separate trait for that method.
2025-05-27 00:05:30 +02:00
Charlie Marsh c5032aee80
Bump MSRV to 1.85 and Edition 2024 (#13516)
## Summary

Builds on https://github.com/astral-sh/uv/pull/11724.

Closes https://github.com/astral-sh/uv/issues/13476.
2025-05-18 19:38:43 -04:00
konsti 5d37c7ecc5
Apply first set of Rustfmt edition 2024 changes (#13478)
Rustfmt introduces a lot of formatting changes in the 2024 edition. To
not break everything all at once, we split out the set of formatting
changes compatible with both the 2021 and 2024 edition by first
formatting with the 2024 style, and then again with the currently used
2021 style.

Notable changes are the formatting of derive macro attributes and lines
with overly long strings and adding trailing semicolons after statements
consistently.
2025-05-16 20:19:02 -04:00
konsti 23261b7e2e
Apply some Edition 2024 fixes (#13479)
Some `ref`-removal and `use<>` fixes for the Rust Edition 2024
migration, which are also compatible with Rust Edition 2021.
2025-05-16 10:34:22 +02:00
Frazer McLean 62692b4e1b
Fix detection of sorted dependencies when include-group is used (#13354)
This follows on from #13334 to fix another case.

<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

If a dependency group contained any `{ include-group = "..." }` entries,
the sort detection would bail out. The root cause of the problem was
gating the sort detection behind `deps.iter().all(Value::is_str)`.

A public code search reveals that keeping include-groups at the top is
by far the most common, but keeping them at the bottom isn't uncommon.
In both of these cases, uv will now preserve the convention that is in
use.

Unless I've missed it, I don't think uv supports `uv add`ing an
include-group, and so that wasn't tested here.

## Test Plan

cargo test

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-05-10 14:00:27 -04:00
Frazer McLean d242c47821
Preserve order of dependencies which are sorted naively (#13334)
## Summary

The prior implementation only looks for dependencies which are sorted by
name then specifier.

I knew uv was meant to preserve sorted dependencies, but it never seemed
to work for me.

I've always used the "sort lines" feature of PyCharm/Sublime to sort
these lists, and I guess I'm not the only one. In such a case,
`flask-wtf>=1.2.1` is sorted before `flask>=3.0.2`.

After digging into the code I realised what was happening, hence this
merge request.

Maybe there's a tool I'm not aware of that people are using to sort
dependencies "properly", or are doing it by hand, but I think this is
worth supporting.

Relevant issues: https://github.com/astral-sh/uv/issues/9076,
https://github.com/astral-sh/uv/issues/10738

## Test Plan

`cargo test`
2025-05-07 18:18:20 -04:00
Aria Desires f401d9ba8f change `uv version` to be an interface for project version reads and edits (#12349)
This is a reimplementation of #7248 with a new CLI interface.

The old `uv version` is now `uv self version` (also it has gained a
`--short` flag for parity).
The new `uv version` is now an interface for getting/setting the project
version.

To give a modicum of support for migration, if `uv version` is run and
we fail to find/read a `pyproject.toml` we will fallback to `uv self
version`. `uv version --project .` prevents this fallback from being
allowed.

The new API of `uv version` is as follows:

* pass nothing to read the project version
* pass a version to set the project version
* `--bump major|minor|patch` to semver-bump the project version
* `--dry-run` to show the result but not apply it
* `--short` to have the final printout contain only the final version
* `--output-format json` to get the final printout as json

```
$ uv version
myfast 0.1.0

$ uv version --bump major --dry-run
myfast 0.1.0 => 1.0.0

$ uv version 1.2.3 --dry-run
myfast 0.1.0 => 1.2.3

$ uv version 1.2.3
myfast 0.1.0 => 1.2.3

$ uv version  --short
1.2.3

$ uv version  --output-format json
{
  "package_name": "myfast",
  "version": "1.2.3",
  "commit_info": null
}
```

Fixes #6298
2025-04-29 16:37:00 -05:00
Aria Desires 318949ade6 Error on unknown dependency object specifiers (#12841)
This reverts commit dd788a0f47.

And relands #12811, for 0.7.0
2025-04-29 16:37:00 -05:00
konsti da09ece8a9
Build backend: Add reference docs and schema (#12803)
Add reference documentation and schema integration for the uv build
backend. The reference documentation comes with a preview note upfront.
2025-04-21 12:27:49 +02:00
konsti 2b96dbdd49
Refactor adding bounds to dependencies in `pyproject.toml` (#12945)
Preparation work for making the kind of bound added configurable.

No functional changes, just moving some methods around.
2025-04-21 12:25:27 +02:00
Max Mynter 2608f742b2
Allow updating Git sources by name (#12897)
Closes: #4567

## Summary

When adding a package with Git reference options (`--rev`, `--tag`,
`--branch`) that already has a Git source defined, use the existing Git
URL with the new reference instead of reporting an error.

This allows commands like `uv add requests --branch main` to work when
requests is already defined with a Git source in the project
configuration.

Previously, you would need to provide the whole Git url again for this
to work:
```bash
uv add git+https://github.com/psf/requests --branch main
```
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
- [x] Add unit tests for project
- [x] Add unit tests for script
- [x] Tested locally for project and script environments like below

### Testing Project
In a directory using the `uv` executable from this PR (via replacing
every `uv` with `cargo run --`) initialize a project and virtual
environment
```bash
uv init
uv venv
```
move into the environment 
```bash
# on mac
source .venv/bin/activate
```
and add a dependency with a git url
```bash
uv add git+https://github.com/Textualize/rich --branch master
```
Then change the branch of the project to see that the branch can be
changed without need of the whole git url:
```bash
uv add rich --branch py310
```

### Testing Script
Create the following file, e.g. `script.py`:
```python
import time
from rich.progress import track

print("Starting")
for i in track(range(20), description="For example:"):
    time.sleep(0.05)
print("Done")
```
Now using `uv` (referencing the executable of this PR) add the
dependency
```bash
uv add --script script.py 'git+https://github.com/Textualize/rich' --branch master
```
and check we can execute the script:
```bash
uv run script.py
```
To test the change update the branch

```bash
uv add --script script.py rich --branch py310
```
and check that the dependency is updated and the script is executed:
```bash
uv run script.py
```

<!-- How was it tested? -->

----
This is my first time contributing to `uv` (yay, 🤗) so let me know if
there is something obvious i am missing.
Unit tests will follow soon.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-04-21 02:58:38 +00:00
johnthagen 3d340e83b7
Improve formatting for `"all"` `default-groups` setting documentation (#12963)
## Summary

Make the documentation for `"all"` `defauilt-groups` a little easier to
read by monospacing the literal.
2025-04-18 11:34:39 -04:00
Aria Desires dd788a0f47
Revert "feat: Error on dependency object specifier (#12811)" (#12840)
This reverts commit c117acf905.

This is a minor breaking change, to be relanded in 0.7.0.
2025-04-11 18:32:48 +00:00
Chandra Kiran G c117acf905
feat: Error on dependency object specifier (#12811)
## Summary

This PR errors out when an Unknown Dependency Object Specifier is used
in dependency groups.


Fixes #12638 

## Test Plan

The current behaviour is as follows:

```bash
➜  example git:(12638/dependency-object-specifier) ✗ cargo run -- sync
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.21s
     Running `/home/luna/Documents/uv/target/debug/uv sync`
error: Failed to generate package metadata for `example==0.1.0 @ virtual+.`
  Caused by: Group `bar` contains a Dependency Object Specifier, which is not supported by uv
  ```


And the pyproject.toml to produce this is:

```toml
[project]
name = "example"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13.2"
dependencies = []

[dependency-groups]
foo = ["pyparsing"]
bar = [{set-phasers-to = "stun"}]
```
2025-04-10 16:56:47 -04:00
Charlie Marsh 8a1967d299
Split workspace members onto their own lines in `uv init` (#12756)
## Summary

See the test cases. Previously, you could end up with something like:

```toml
[tool.uv.workspace]
members = [
    "foo",
    "bar",
    "baz", "bop",
]
```
2025-04-08 19:51:23 +00:00
Charlie Marsh 42dcea0ee2
Bump MSRV to 1.84 (#12670)
## Summary

Closes https://github.com/astral-sh/uv/issues/12649.
2025-04-04 11:49:26 -04:00
Charlie Marsh 3dad8fef2d
Normalize extra and group names in `uv add` and `uv remove` (#12586)
## Summary

Closes https://github.com/astral-sh/uv/issues/12585.
2025-03-31 10:51:28 -04:00
Charlie Marsh e4c98e976f
Use `Box<Path>` in lieu of `PathBuf` for immutable structs (#12346)
## Summary

I don't know if I actually want to commit this, but I did it on the
plane last time and just polished it off (got it to compile) while
waiting to board.
2025-03-25 21:56:06 +00:00
Charlie Marsh 149102a4e7
Use a boxed slice for extras and groups (#12391)
## Summary

A very common struct, and these are immutable. Easy to optimize.
2025-03-22 11:53:36 -04:00
Christopher Tee bdef77c3fe
Retain end-of-line comment position when adding dependency (#12360)
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

This fixes a case described in #12333, where trailing comments in
dependencies can be unexpectedly shifted when a new dependency is added.

Fixes #12333.

## Test Plan

<!-- How was it tested? -->

`cargo test` (Added a snapshot test)
2025-03-21 10:16:15 -04:00
Charlie Marsh 46967723bb
Move lowered requirement source type out of `uv-pypi-types` (#12356)
## Summary

This crate is for standards-compliant types, but this is explicitly a
type that's custom to uv. It's also strange because we kind of want to
reference `IndexUrl` on the registry type, but that's in a crate that
_depends_ on `uv-pypi-types`, which to me is a sign that this is off.
2025-03-20 21:16:12 -04:00
Aria Desires 26cad18635
add `default-groups = "all"` sugar to `pyproject.toml` (#12289)
Suggested by @zanieb in #10934

* [x] agree we want to do this
* [x] add docs

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-03-18 13:42:06 -05:00
Charlie Marsh 2a9bade4df
Use `uv sync` in workspace tests (#12181) 2025-03-15 20:52:43 +00:00
konsti 82212bb439
Show ambiguous requirements when `uv add` failed (#12106)
Improves the error message.

Fixes #12105

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-03-10 23:00:09 -04:00
konsti e843433b07
Cache workspace discovery (#12096)
Reduce the overhead of `uv run` in large workspaces. Instead of
re-discovering the entire workspace each time we resolve the metadata of
a member, we can the discovered set of workspace members. Care needs to
be taken to not cache the discovery for `uv init`, `uv add` and `uv
remove`, which change the definitions of workspace members.

Below is apache airflow e3fe06382df4b19f2c0de40ce7c0bdc726754c74 `uv run
python` with a minimal payload. With this change, we avoid a ~350ms
overhead of each `uv run` invocation.

```
$ hyperfine --warmup 2 \
    "uv run --no-dev python -c \"print('hi')\"" \
    "uv-profiling run --no-dev python -c \"print('hi')\""
Benchmark 1: uv run --no-dev python -c "print('hi')"
  Time (mean ± σ):     492.6 ms ±   7.0 ms    [User: 393.2 ms, System: 97.1 ms]
  Range (min … max):   482.3 ms … 501.5 ms    10 runs
 
Benchmark 2: uv-profiling run --no-dev python -c "print('hi')"
  Time (mean ± σ):     129.7 ms ±   2.5 ms    [User: 105.4 ms, System: 23.2 ms]
  Range (min … max):   126.0 ms … 136.1 ms    22 runs
 
Summary
  uv-profiling run --no-dev python -c "print('hi')" ran
    3.80 ± 0.09 times faster than uv run --no-dev python -c "print('hi')"
```

The profile after those change below. We still spend a large chunk in
toml parsing (both `uv.lock` and `pyproject.toml`), but it's not
excessive anymore.


![image](https://github.com/user-attachments/assets/6fe78510-7e25-48ee-8a6d-220ee98ad120)
2025-03-10 22:03:30 +01:00
Christian Sachs c57dd1a4a8
Allow overriding module name for uv build backend (#11884)
Thank you for uv, it has game-changer capabilities in the field of
Python package and environment maangement!

## Summary

This is a small PR adding the option `module-name`
(`tool.uv.build-backend.module-name`) to the uv build backend (
https://github.com/astral-sh/uv/issues/8779 ).

Currently, the uv build backend will assume that the module name matches
the (dash to underdash-transformed) package name. In some packaging
scenarios this is not the case, and currently there exists no
possibility to override it, which this PR addresses.

From the main issue ( https://github.com/astral-sh/uv/issues/8779 ) I
could not tell if there is any extensive roadmap or plans how to
implement more complex scenarios, hence this PR as a suggestion for a
small feature with a big impact for certain scenarios.

I am new to Rust, I hope the borrow/reference usage is correct.

## Test Plan

So far I tested this at an example, if desired I can look into extending
the tests.

Fixes #11428

---------

Co-authored-by: konstin <konstin@mailbox.org>
2025-03-07 15:20:00 +01:00
John Mumm 1ab1945dd9
Move `DependencyGroups` to uv-pypi-types so it can be imported there (#12037)
This PR is in support of #12005, where we need to import
`DependencyGroups` in the `uv-pypi-types` crate without a circular
dependency on `uv-workspace`.
2025-03-07 12:30:47 +01:00
Charlie Marsh d4a805544f
Allow users to set `package = true` on `tool.uv.sources` (#12014)
## Summary

In https://github.com/astral-sh/uv/issues/11998, a user is attempting to
vendor `pydantic-core`. But when they add `pydantic-core = { path =
"src/foo/vendor/pydantic-core" } `, we're installing it as a virtual
package, since `pydantic-core/pyproject.toml` contains `package =
false`.

This PR allows users to mark dependencies as "explicitly a package" or
"explicitly not a package" (i.e., virtual), as a workaround.

Closes https://github.com/astral-sh/uv/issues/11998.
2025-03-06 18:28:09 +00:00
konsti d712ff243e
Edition 2024 prep: Escape `r#gen` and remove redundant ref (#11922)
Three edition 2021 compatible sets of changes in preparation for the
edition 2025 split out from #11724.

In edition 2025, `gen` is a keyword, so we escape it as `r#gen`. `ref`
and `ref mut` are not allowed anymore for `&T` and `&mut T`, so we
remove them. `cargo fmt` now formats inside of macros, which the 2021
formatter doesn't undo.
2025-03-03 11:13:56 +00:00
konsti dc39d6622b
Fix non-directory in workspace on Windows (#11833)
Fixes #11793

On Windows, trying to read a file inside what is not a directory but
another file results in a not found error, while on Unix we get a not a
directory error. We check explicitly if something included in a
workspace glob is a non-directory to fix the behavior on Windows.
2025-02-28 13:40:19 +01:00
KATO So ad86005e9a
Warn when duplicate index names found in single file (#11824)
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:
- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
## Summary

This pull request introduces validation for unique index names in the
`tool.uv.index` field and adds corresponding tests to ensure the
functionality. The most important changes include adding a custom
deserializer function, updating the `ToolUv` struct to use the new
deserializer, and adding tests to verify the behavior.

Validation and deserialization:

*
[`crates/uv-workspace/src/pyproject.rs`](diffhunk://#diff-e12cd255985adfd45ab06f398cb420d2f543841ccbeea4175ccf827aa9215b9dR283-R311):
Added a custom deserializer function `deserialize_index_vec` to validate
that index names in the `tool.uv.index` field are unique.
*
[`crates/uv-workspace/src/pyproject.rs`](diffhunk://#diff-e12cd255985adfd45ab06f398cb420d2f543841ccbeea4175ccf827aa9215b9dR374):
Updated the `ToolUv` struct to use the `deserialize_index_vec` function
for the `index` field.

Testing:

*
[`crates/uv/tests/it/lock.rs`](diffhunk://#diff-82edd36151736f44055f699a34c8b19a63ffc4cf3c86bf5fb34d69f8ac88a957R15336):
Added a test `lock_repeat_named_index` to verify that duplicate index
names result in an error.
[[1]](diffhunk://#diff-82edd36151736f44055f699a34c8b19a63ffc4cf3c86bf5fb34d69f8ac88a957R15336)
[[2]](diffhunk://#diff-82edd36151736f44055f699a34c8b19a63ffc4cf3c86bf5fb34d69f8ac88a957R15360-R15402)
*
[`crates/uv/tests/it/lock.rs`](diffhunk://#diff-82edd36151736f44055f699a34c8b19a63ffc4cf3c86bf5fb34d69f8ac88a957R15360-R15402):
Added a test `lock_unique_named_index` to verify that unique index names
result in successful lock file generation.

Schema update:

*
[`uv.schema.json`](diffhunk://#diff-c669473b258a19ba6d3557d0369126773b68b27171989f265333a77bc5cb935bR205):
Updated the schema to set the default value of the `index` field to
`null`.

Fixes #11804

## Test Plan
### Steps to reproduce and verify the fix:

1. Clone the repository and checkout the feature branch
   ```bash
   git clone https://github.com/astral-sh/uv.git
   cd uv
   git checkout feature/warn-duplicate-index-names
   ```

2. Build the modified binary
   ```bash
   cargo build
   ```

3. Create a test project using the system installed uv
   ```bash
   uv init uv-test
   cd uv-test
   ```

4. Manually edit pyproject.toml to add duplicate index names
   ```toml
   [[tool.uv.index]]
   name = "alpha_b"
   url = "<omitted>"

   [[tool.uv.index]]
   name = "alpha_b"
   url = "<omitted>"
   ```

5. Try to add a package using the modified binary
   ```bash
   ../target/debug/uv add numpy
   ```

### Results
Before: use release binary
![スクリーンショット 2025-02-27 15 52
28](https://github.com/user-attachments/assets/2823a4b4-b3ba-40aa-aa41-e593d35c3f3b)

After: use self build binary
![スクリーンショット 2025-02-27 15 51
58](https://github.com/user-attachments/assets/9ac773a9-58cd-4d4b-8685-148bf6dc85fb)

Now when attempting to use a pyproject.toml with duplicate index names,
the modified binary correctly detects the issue and produces an error
message:
```
error: Failed to parse: `pyproject.toml`
  Caused by: TOML parse error at line 9, column 1
  |
9 | [[tool.uv.index]]
  | ^^^^^^^^^^^^^^^^^
duplicate index name `alpha_b`
```

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-02-27 21:33:57 +00:00
Charlie Marsh c37af945b3
Avoid using owned `String` in deserializers (#11764)
## Summary

This is the pattern I see in a variety of crates, and I believe this is
preferred if you don't _need_ an owned `String`, since you can avoid the
allocation. This could be pretty impactful for us?
2025-02-25 14:28:16 +00:00
Charlie Marsh 76c3caf24f
Avoid using owned `String` for package name constructors (#11768)
## Summary

Since we use `SmallString` internally, there's no benefit to passing an
owned string to the `PackageName` constructor (same goes for
`ExtraName`, etc.). I've kept them for now (maybe that will change in
the future, so it's useful to have clients passed own values if they
_can_), but removed a bunch of usages where we were casting from `&str`
to `String` needlessly to use the constructor.
2025-02-24 23:06:15 -08:00
Charlie Marsh 13cf4555c4
Remove unnecessary clones when adding package names (#11771)
## Summary

Really not important but looks like this was copied around at some
point.
2025-02-24 23:05:30 -08:00
samypr100 878497a014
Upgrade Rust toolchain to 1.85 (#11720)
## Summary

* Upgrade the rust toolchain to 1.85.0. This does not increase the MSRV.
* Update windows trampoline to 1.86 nightly beta (previously in 1.85
nightly beta).

## Test Plan

Existing tests
2025-02-23 16:52:34 +01:00
John Mumm b086437bff
Sort dependency group keys when adding new group (#11591)
This change keeps dependency group keys sorted when adding new ones. 

If earlier dependency group keys were not sorted, we just append the new
group key to avoid churn in `pyproject.toml`. See discussion on #11447.
I've added a new snapshot test to capture this case.

Closes #11447.
2025-02-18 19:12:50 +01:00
konsti 29c2be3e97
Eagerly reject unsupported Git schemes (#11514)
Initially, we were limiting Git schemes to HTTPS and SSH as only
supported schemes. We lost this validation in #3429. This incidentally
allowed file schemes, which apparently work with Git out of the box.

A caveat for this is that in tool.uv.sources, we parse the git field
always as URL. This caused a problem with #11425: repo = { git =
'c:\path\to\repo', rev = "xxxxx" } was parsed as a URL where c: is the
scheme, causing a bad error message down the line.

This PR:

* Puts Git URL validation back in place. It bans everything but HTTPS,
SSH, and file URLs. This could be a breaking change, if users were using
a git transport protocol were not aware of, even though never
intentionally supported.
* Allows file: URL in Git: This seems to be supported by Git and we were
supporting it albeit unintentionally, so it's reasonable to continue to
support it.
* It does not allow relative paths in the git field in tool.uv.sources.
Absolute file URLs are supported, whether we want relative file URLs for
Git too should be discussed separately.

Closes #3429: We reject the input with a proper error message, while
hinting the user towards file:. If there's still desire for relative
path support, we can keep it open.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-02-18 02:14:06 +00:00
Chao Ning 8c3a6b2155
Add `tool.uv.build-constraint-dependencies` to `pyproject.toml` (#11585)
## Summary

Resolves #6913. 

Add `tool.uv.build-constraint-dependencies` to pyproject.toml.
The changes are analogous to the constraint-dependencies feature
implemented in #5248.

Add documentation for `build-constraint-dependencies`

## Test Plan

Add tests for `uv lock`, `uv add`, `uv pip install` and `uv pip
compile`.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-02-17 20:58:36 -05:00
konsti 248da23f6d
Split uv-git and uv-git-types (#11448)
We want to build `uv-build` without depending on the network crates. In
preparation for that, we split uv-git into uv-git and uv-git-types,
where only uv-git depends on reqwest, so that uv-build can use
uv-git-types.
2025-02-17 10:37:55 +01:00
Charlie Marsh 172305abb6
Allow users to mark platforms as "required" for wheel coverage (#10067)
## Summary

This PR revives https://github.com/astral-sh/uv/pull/10017, which might
be viable now that we _don't_ enforce any platforms by default.

The basic idea here is that users can mark certain platforms as required
(empty, by default). When resolving, we ensure that the specified
platforms have wheel coverage, backtracking if not.

For example, to require that we include a version of PyTorch that
supports Intel macOS:

```toml
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["torch>1.13"]

[tool.uv]
required-platforms = [
    "sys_platform == 'darwin' and platform_machine == 'x86_64'"
]
```

Other than that, the forking is identical to past iterations of this PR.

This would give users a way to resolve the tail of issues in #9711, but
with manual opt-in to supporting specific platforms.
2025-02-14 15:11:18 -05:00
Charlie Marsh f001605505
Validate dependency groups even when `--frozen` is present (#11499)
## Summary

We now use the same strategy as for extras, validating against the
lockfile instead of the `pyproject.toml`.

Closes https://github.com/astral-sh/uv/issues/10882.
2025-02-14 09:54:28 -06:00
Charlie Marsh ceb22fcfe5
Support `--active` for PEP 723 script environments (#11433)
## Summary

See: https://github.com/astral-sh/uv/pull/11361#discussion_r1948851085
2025-02-13 13:40:21 -06:00
konsti 62b7e16f3c
Optional schemars dependency (#11449)
In preparation for `uv-build`, make schemars an optional dependency
consistently, so it will not be part of the `uv-build` dependency tree.
2025-02-12 18:20:19 +01:00
konsti 3e7ec1df05
Fix walkdir error message (#11310)
Fixes #11309
2025-02-07 10:24:05 +00:00
Zanie Blue 239f3d76b9
Allow the project `VIRTUAL_ENV` warning to be silenced with `--no-active` (#11251)
Follow-up to https://github.com/astral-sh/uv/pull/11189

Closes https://github.com/astral-sh/uv-pre-commit/issues/36
2025-02-05 19:44:46 +00:00
Zanie Blue 989b103171
Add support for respecting `VIRTUAL_ENV` in project commands via `--active` (#11189)
I think `UV_PROJECT_ENVIRONMENT` is too complicated for use-cases where
the user wants to sync to the active environment. I don't see a
compelling reason not to make opt-in easier. I see a lot of questions
about how to deal with this warning in the issue tracker, but it seems
painful to collect them here for posterity.

A notable behavior here — we'll treat this as equivalent to
`UV_PROJECT_ENVIRONMENT` so... if you point us to a valid virtual
environment that needs to be recreated for some reason (e.g., new Python
version request), we'll happily delete it and start over.
2025-02-05 10:12:19 -06:00
micolous 52870c587c
Fix incorrect error message when specifying `tool.uv.sources.(package).workspace` with other options (#11013)
## Summary

When a `pyproject.toml` `[tool.uv.sources.(package)]` section specifies
`workspace` and one or more of (`index`, `git`, `url`, `path`, `rev`,
`tag`, `branch`, `editable`), running `uv` to build or sync the package
gives the error:

```
cannot specify both `index` and `(parameter name)`
```

The error should actually say:

```
cannot specify both `workspace` and `(parameter name)`
```

## Test Plan

I ran `cargo test`, and all tests still passed.
2025-01-28 09:25:33 -05:00
Charlie Marsh a00f6f5d3d
Reject `--editable` flag on non-directory requirements (#10994)
## Summary

Closes https://github.com/astral-sh/uv/issues/10992.
2025-01-27 19:37:23 +00:00
Charlie Marsh 2df3f0e782
Reduce ambiguity in conflicting extras example (#10877)
## Summary

Closes https://github.com/astral-sh/uv/issues/10378.
2025-01-22 19:09:49 -05:00
Charlie Marsh 434706389b
Error when workspace contains conflicting Python requirements (#10841)
## Summary

If members define disjoint Python requirements, we should error. Right
now, it seems that it maps to unbounded and leads to weird behavior.

Closes https://github.com/astral-sh/uv/issues/10835.
2025-01-22 17:22:52 +00:00
Charlie Marsh 78639187e8
Remove the `FullCommit` variant from `GitReference` (#10803)
## Summary

It's not quite correct for this to be on `GitReference`. It's not a
variant that can be created by users, or by us.
2025-01-21 19:26:58 +00:00
Charlie Marsh 45911693c4
Remove short commit variant (#10795)
## Summary

This is never constructed.
2025-01-20 18:35:47 -05:00
Charlie Marsh c306e46e1d
Remove trailing commas before brackets (#10740) 2025-01-18 19:56:46 +00:00
Mathieu Kniewallner b46c6db317
docs: fix a few typos (#10675)
## Summary

Fixing a few typos found in the documentation and in comments.
2025-01-16 09:53:59 -05:00
Charlie Marsh 0617fd5da6
Omit dynamic versions from the lockfile (#10622)
## Summary

This PR modifies the lockfile to omit versions for source trees that use
`dynamic` versioning, thereby enabling projects to use dynamic
versioning with `uv.lock`.

Prior to this change, dynamic versioning was largely incompatible with
locking, especially for popular tools like `setuptools_scm` -- in that
case, every commit bumps the version, so every commit invalidates the
committed lockfile.

Closes https://github.com/astral-sh/uv/issues/7533.
2025-01-15 11:54:32 -05:00
bnorick 918ddef090
Fixes bug in `uv remove` when only comments exist (#10484)
## Summary

Fixes a bug when there are only comments in the dependencies section.

Basically, after one removes all dependencies, if there are remaining
comments then the value unwrapped here
c198e2233e/crates/uv-workspace/src/pyproject_mut.rs (L1309)
is never properly initialized.
It's initialized to `None`, here
c198e2233e/crates/uv-workspace/src/pyproject_mut.rs (L1256),
but doesn't get set to `Some(...)` until the first dependency here
c198e2233e/crates/uv-workspace/src/pyproject_mut.rs (L1276)
and since we remove them all... there are none.

## Test Plan
Manually induced bug with
```
[project]
name = "t1"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "duct>=0.6.4",
    "minilog>=2.3.1",
    # comment
]
```

Then running
```
$ RUST_LOG=trace RUST_BACKTRACE=full uv remove duct minilog
DEBUG uv 0.5.8
DEBUG Found project root: `/home/bnorick/dev/workspace/t1`
DEBUG No workspace root found, using project root
thread 'main' panicked at crates/uv-workspace/src/pyproject_mut.rs:1294:73:
called `Option::unwrap()` on a `None` value
stack backtrace:
   0:     0x5638d7bed6ba - <unknown>
   1:     0x5638d783760b - <unknown>
   2:     0x5638d7bae232 - <unknown>
   3:     0x5638d7bf0f07 - <unknown>
   4:     0x5638d7bf215c - <unknown>
   5:     0x5638d7bf1972 - <unknown>
   6:     0x5638d7bf1909 - <unknown>
   7:     0x5638d7bf18f4 - <unknown>
   8:     0x5638d75087d2 - <unknown>
   9:     0x5638d750896b - <unknown>
  10:     0x5638d7508d68 - <unknown>
  11:     0x5638d8dcf1bb - <unknown>
  12:     0x5638d76be271 - <unknown>
  13:     0x5638d75ef1f9 - <unknown>
  14:     0x5638d75fc3cd - <unknown>
  15:     0x5638d772d9de - <unknown>
  16:     0x5638d8476812 - <unknown>
  17:     0x5638d83e1894 - <unknown>
  18:     0x5638d84722d3 - <unknown>
  19:     0x5638d83e1372 - <unknown>
  20:     0x7f851cfc7d90 - <unknown>
  21:     0x7f851cfc7e40 - __libc_start_main
  22:     0x5638d758e992 - <unknown>
  23:                0x0 - <unknown>
```
2025-01-10 20:07:03 -05:00
Charlie Marsh 243d2f8d5d
Redact new index credentials in `uv add` (#10329)
## Summary

Closes https://github.com/astral-sh/uv/issues/10328.
2025-01-06 17:24:05 +00:00
Charlie Marsh bec8468183
Remove unnecessary prefixes (#10158) 2024-12-25 14:18:01 -05:00
Charlie Marsh f872b56124
Add a lock target abstraction (#10129)
## Summary

This PR introduces a `LockTarget`, which is peer to `InstallTarget` and
enables us to capture the common functionality necessary to support
locking.

For now, to minimize changes, only the `Workspace` target is
implemented. In a future PR, I'll add a `Script` target for both locking
and installing.
2024-12-24 19:26:31 -05:00
Charlie Marsh e09b1080f4
Store dependency groups separate from dependencies in lockfile (#10148)
## Summary

This is necessary for some future improvements to non-`[project]`
workspaces and PEP 723 scripts. It's not "breaking", but it will
invalidate lockfiles for non-`[project]` workspaces. I think that's
okay, since we consider those legacy right now, and they're really rare.
2024-12-24 17:32:29 -05:00
Mathieu Kniewallner b24fb774b1
docs: fix invalid syntax in some sources examples (#10127)
## Summary

TOML 1.0 doesn't support multi-line for inline tables, so those examples
are invalid.
2024-12-23 16:12:45 -05:00
Charlie Marsh 38a38fa8e2
Avoid erroring when subdirectories are provided in `uv add` (#10095)
## Summary

Closes https://github.com/astral-sh/uv/issues/10094.
2024-12-22 15:23:27 +00:00
Charlie Marsh 705b3da913
Preserve sort when deciding on requirement placement (#10078)
## Summary

We had the right logic for determining whether the list is already
sorted, but we forgot to apply the same logic when deciding where to
insert the requirement, which made the list _unsorted_ for future
operations.

Closes https://github.com/astral-sh/uv/issues/10076.
2024-12-21 09:43:43 -05:00
Charlie Marsh 48c9196f9e
Show a concise error message for missing version field (#9912)
## Summary

This now looks like:

```
error: Failed to parse: `pyproject.toml`
  Caused by: TOML parse error at line 1, column 1
  |
1 | [project]
  | ^^^^^^^^^
`pyproject.toml` is using the `[project]` table, but the required `project.version` field is neither set nor present in the `project.dynamic` list
```

Closes https://github.com/astral-sh/uv/issues/9910.
2024-12-15 10:27:43 -05:00
Zanie Blue ae25c2f4db
Upgrade minimum Rust version to 1.83 (#9815)
This reverts commit 6cc7a560f7 to reapply
#9511 since we've disabled ppc64le-musl per #9793
2024-12-11 10:06:19 -06:00
Charlie Marsh 4a21daff49
Don't drop comments between items in TOML tables (#9784)
## Summary

If you look at Ed's reply
[here](https://github.com/toml-rs/toml/issues/818#issuecomment-2532626305),
it sounds like we're being too heavy-handed in applying `.fmt()`. I
think I added this to handle an issue with inline tables whereby we were
inserting a space after a trailing comma? So now I'm just applying
`.fmt()` to inline tables, which don't allow comments between elements
anyway.

Closes https://github.com/astral-sh/uv/issues/9758.
2024-12-10 14:59:13 -05:00
Charlie Marsh 1ecdc1a31e
Model groups as a property of requirements (#9545)
## Summary

Today, our dependency group implementation is a little awkward... For
each package `P`, we check if `P` contains dependencies for each enabled
group, then add a dependency on `P` with the group enabled. There are a
few issues here:

1. It's sort of backwards... We add a dependency from the base package
`P` to `P` with the group enabled. Then `P` with the group enabled adds
a dependency on the base package.
2. We can't, e.g., enable different groups for different packages. (We
don't have a way for users to specify this on the CLI, but there's no
reason that it should be _impossible_ in the resolver.)
3. It's inconsistent with how extras work, which leads to confusing
differences in the resolver.

Instead, our internal requirement type can now include dependency
groups, which makes dependency groups look much, much more like extras
in the resolver.
2024-12-04 00:55:51 +00:00
Zanie Blue 6cc7a560f7
Revert "Upgrade to Rust 1.83 (#9511)" (#9617)
This reverts commit cf20673197 (#9511) due
to failure on powerpc64le in https://github.com/astral-sh/uv/pull/9612
2024-12-03 19:21:05 +00:00
Charlie Marsh 8126a5ed32
Make `MarkerTree` `Copy` (#9542)
## Summary

It's just a `usize`. It seems simpler and perhaps even more performant
(?) to make it `Copy`.
2024-11-30 14:07:07 -05:00
Charlie Marsh cf20673197
Upgrade to Rust 1.83 (#9511)
## Summary

A lot of good new lints, and most importantly, error stabilizations. I
tried to find a few usages of the new stabilizations, but I'm sure there
are more.

IIUC, this _does_ require bumping our MSRV.
2024-11-29 12:04:22 -05:00
Charlie Marsh 7169b2c427
Respect sources in overrides and constraints (#9455)
## Summary

We still only respect overrides and constraints in the workspace root --
which we may want to change -- but overrides and constraints are now
correctly lowered.

Closes https://github.com/astral-sh/uv/issues/8148.
2024-11-27 13:56:14 +00:00
Ed Morley 62e0ee7f67
Fix grammar in missing platform marker error message (#9240)
`s/a platform markers/a platform marker/`
2024-11-19 20:03:52 +00:00
Zanie Blue ca9aaf1c48
Reorganize the project concept documentation (#9121)
- Adds a collapsible section for the project concept
- Splits the project concept document into several child documents.
- Moves the workspace and dependencies documents to under the project
section
- Adds a mkdocs plugin for redirects, so links to the moved documents
still work

I attempted to make the minimum required changes to the contents of the
documents here. There is a lot of room for improvement on the content of
each new child document. For review purposes, I want to do that work
separately. I'd prefer if the review focused on this structure and idea
rather than the content of the files.

I expect to do this to other documentation pages that would otherwise be
very nested.

The project concept landing page and nav (collapsed by default) looks
like this now:

<img width="1507" alt="Screenshot 2024-11-14 at 11 28 45 AM"
src="https://github.com/user-attachments/assets/88288b09-8463-49d4-84ba-ee27144b62a5">
2024-11-19 13:52:12 -06:00
Charlie Marsh e4fc875afa
Allow conflicting extras in explicit index assignments (#9160)
## Summary

This PR enables something like the "final boss" of PyTorch setups --
explicit support for CPU vs. GPU-enabled variants via extras:

```toml
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.13.0"
dependencies = []

[project.optional-dependencies]
cpu = [
    "torch==2.5.1+cpu",
]
gpu = [
    "torch==2.5.1",
]

[tool.uv.sources]
torch = [
    { index = "torch-cpu", extra = "cpu" },
    { index = "torch-gpu", extra = "gpu" },
]

[[tool.uv.index]]
name = "torch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

[[tool.uv.index]]
name = "torch-gpu"
url = "https://download.pytorch.org/whl/cu124"
explicit = true

[tool.uv]
conflicts = [
    [
        { extra = "cpu" },
        { extra = "gpu" },
    ],
]
```

It builds atop the conflicting extras work to allow sources to be marked
as specific to a dedicated extra being enabled or disabled.

As part of this work, sources now have an `extra` field. If a source has
an `extra`, it means that the source is only applied to the requirement
when defined within that optional group. For example, `{ index =
"torch-cpu", extra = "cpu" }` above only applies to
`"torch==2.5.1+cpu"`.

The `extra` field does _not_ mean that the source is "enabled" when the
extra is activated. For example, this wouldn't work:

```toml
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.13.0"
dependencies = ["torch"]

[tool.uv.sources]
torch = [
    { index = "torch-cpu", extra = "cpu" },
    { index = "torch-gpu", extra = "gpu" },
]

[[tool.uv.index]]
name = "torch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

[[tool.uv.index]]
name = "torch-gpu"
url = "https://download.pytorch.org/whl/cu124"
explicit = true
```

In this case, the sources would effectively be ignored. Extras are
really confusing... but I think this is correct? We don't want enabling
or disabling extras to affect resolution information that's _outside_ of
the relevant optional group.
2024-11-19 01:06:25 +00:00
Charlie Marsh d08bfee718
Remove separate test files in favor of same-file `mod tests` (#9199)
## Summary

These were moved as part of a broader refactor to create a single
integration test module. That "single integration test module" did
indeed have a big impact on compile times, which is great! But we aren't
seeing any benefit from moving these tests into their own files (despite
the claim in [this blog
post](https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html),
I see the same compilation pattern regardless of where the tests are
located). Plus, we don't have many of these, and same-file tests is such
a strong Rust convention.
2024-11-18 20:11:46 +00:00
Charlie Marsh 5ba186628b
Avoid showing disjoint marker error with `true` (#9169)
## Summary

Ran into this in practice, and it's awkward:

![Screenshot 2024-11-16 at 12 19
25 PM](https://github.com/user-attachments/assets/1c5d296e-b6ea-4e28-83fc-0ae096dfe2b8)
2024-11-17 20:50:44 -05:00
Charlie Marsh 12266f8f81
Add a dedicated error for `include = "dev"` with `tool.uv.dev-dependencies` (#9173)
## Summary

This isn't really spec-compliant, so we already don't allow it -- this
just adds a better error message and an explicit test for it.
2024-11-17 13:22:04 -05:00
renovate[bot] 312ae12650
Update Rust crate thiserror to v2 (#9006) 2024-11-15 09:54:16 -06:00
Micha Reiser 7b4197bc0e
Detect nested workspace inside the current workspace and members with identical names (#9094)
## Summary

Align uv's workspace discovery with red knots (see
https://github.com/astral-sh/ruff/pull/14308#issuecomment-2474296308)

* Detect nested workspace inside the current workspace rather than
testing if the current workspace is a member of any outer workspace.
* Detect packages with identical names.

## Test Plan

I added two integration tests. I also back ported the tests to main to
verify that both these invalid workspaces aren't catched by uv today.
That makes this, technically, a breaking change but I would consider the
change a bug fix.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-11-15 04:03:00 +00:00
Andrew Gallant e310dcc7c1 doc: tweak docs a bit
We also update the docs for flags like `--extra` to note that they may
result in an error if they try to enable extras that are conflicting.
2024-11-14 08:02:46 -05:00
Andrew Gallant c68e0d624e uv: expose `conflicts` in `tool.uv` in `pyproject.toml` 2024-11-14 08:02:46 -05:00
Andrew Gallant bb78e00a87 *: update "conflicting groups" terminology everywhere else 2024-11-14 08:02:46 -05:00
Andrew Gallant 19a044d4db uv-pypi-types: rename "conflicting group" types to more generic "conflicts"
Since this is intended to support _both_ groups and extras, it doesn't
make sense to just name it for groups. And since there isn't really a
word that encapsulates both "extra" and "group," we just fall back to
the super general "conflicts."

We'll rename the variables and other things in the next commit.
2024-11-14 08:02:46 -05:00
Charlie Marsh 2e73f47453
Avoid duplicating first-entry comments in `uv add` (#9109)
## Summary

Closes https://github.com/astral-sh/uv/issues/9105.
2024-11-14 02:13:59 +00:00
Charlie Marsh b0e7476008
Sort by name, then specifiers in `uv add` (#9097)
## Summary

This PR ensures that `pylint>=3.2.6` followed by
`pylint-module-boundaries>=1.3.1` is considered sorted, despite the fact
that `>` is later in the alphabetic than `-`. By purely comparing
strings, they would _not_ be sorted; but by considering the name, then
the specifiers, they are.

Closes https://github.com/astral-sh/uv/issues/9076.
2024-11-13 15:47:57 -05:00
Andrew Gallant 15ef807c80
add support for specifying conflicting extras (#8976)
This PR adds support for conflicting extras. For example, consider
some optional dependencies like this:

```toml
[project.optional-dependencies]
project1 = ["numpy==1.26.3"]
project2 = ["numpy==1.26.4"]
```

These dependency specifications are not compatible with one another.
And if you ask uv to lock these, you'll get an unresolvable error.

With this PR, you can now add this to your `pyproject.toml` to get
around this:

```toml
[tool.uv]
conflicting-groups = [
    [
      { package = "project", extra = "project1" },
      { package = "project", extra = "project2" },
    ],
]
```

This will make the universal resolver create additional forks
internally that keep the dependencies from the `project1` and
`project2` extras separate. And we make all of this work by reporting
an error at **install** time if one tries to install with two or more
extras that have been declared as conflicting. (If we didn't do this,
it would be possible to try and install two different versions of the
same package into the same environment.)

This PR does *not* add support for conflicting **groups**, but it is
intended to add support in a follow-up PR.

Closes #6981

Fixes #8024

Ref #6729, Ref #6830

This should also hopefully unblock
https://github.com/dagster-io/dagster/pull/23814, but in my testing, I
did run into other problems (specifically, with `pywin`). But it does
resolve the problem with incompatible dependencies in two different
extras once you declare `test-airflow-1` and `test-airflow-2` as
conflicting for `dagster-airflow`.

NOTE: This PR doesn't make `conflicting-groups` public yet. And in a
follow-up PR, I plan to switch the name to `conflicts` instead of
`conflicting-groups`, since it will be able to accept conflicting extras
_and_ conflicting groups.
2024-11-13 09:52:28 -05:00
Charlie Marsh 769afa96a4
Avoid retraversing filesystem when testing exact glob matches (#9022)
## Summary

When testing for exact inclusion, we can just test the glob directly.
There's no need to re-traverse the filesystem to find it.
2024-11-11 12:54:35 -05:00
Zanie Blue 8ef5949294 Discover and respect `.python-version` files in parent directories (#6370)
Uses #6369 for test coverage.

Updates version file discovery to search up into parent directories.
Also refactors Python request determination to avoid duplicating the
user request / version file / workspace lookup logic in every command
(this supersedes the work started in
https://github.com/astral-sh/uv/pull/6372).

There is a bit of remaining work here, mostly around documentation.
There are some edge-cases where we don't use the refactored request
utility, like `uv build` — I'm not sure how I'm going to handle that yet
as it needs a separate root directory.
2024-11-07 14:29:54 -06:00
Zanie Blue b6c531f4dd Error when disallowed settings are defined in `uv.toml` (#8550)
These settings can only be defined in `pyproject.toml`, since they're
project-centric, and not _configuration_.

Closes https://github.com/astral-sh/uv/issues/8539.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Co-authored-by: konsti <konstin@mailbox.org>
2024-11-07 14:29:54 -06:00
Charlie Marsh d3e50a2376
Enable `--all-packages --frozen` in `uv sync` and `uv export` (#8760)
## Summary

This PR improves the interaction of `--frozen` such that we reduce the
dependency on the `pyproject.toml` and increase the dependency on the
`uv.lock`. Specifically, we now read the list of workspace members from
the `uv.lock` rather than the `pyproject.toml`, which means we don't
need to discover the member `pyproject.toml` files in order to perform a
`uv sync --frozen --all-packages`.
2024-11-02 02:48:55 +00:00
Charlie Marsh 3c9dd97fe9
Add support for `uv sync --all-packages` (#8739)
## Summary

This PR enables `uv sync --all-packages` to sync all packages in a
workspace. It removes a common use-case for the legacy non-`[project]`
packages that we're trying to move away from.

Closes https://github.com/astral-sh/uv/issues/8724.
2024-11-02 01:55:08 +00:00
Charlie Marsh 40b48267e5
Include member groups when locking workspace (#8736)
## Summary

It turns out that when locking, we were only taking the groups from the
root `pyproject.toml` into account, and ignoring groups that were only
defined in a workspace member.
2024-11-01 00:04:34 +00:00
Charlie Marsh dd0f696695
Allow `[dependency-groups]` in non-`[project]` projects (#8574)
## Summary

We already support `tool.uv.dev-dependencies` in the legacy
non-`[project]` projects. This adds equivalent support for
`[dependency-groups]`, e.g.:

```toml
[tool.uv.workspace]

[dependency-groups]
lint = ["ruff"]
```
2024-10-25 13:57:06 -05:00
Zanie Blue 8262e91e2f Update reference documentation for PEP 735 (#8567)
Updates the CLI and setting documentation to reflect the PEP 735
changes.
2024-10-25 13:27:37 -05:00
Charlie Marsh 07b6887c08 Add to `dependency-groups.dev` in `uv add --dev` (#8570)
## Summary

`uv add --dev` now updates the `dependency-groups.dev` section, rather
than `tool.uv.dev-dependencies` -- unless the dependency is already
present in `tool.uv.dev-dependencies`.

`uv remove --dev` now removes from both `dependency-groups.dev` and
`tool.uv.dev-dependencies`.

`--dev` and `--group dev` are now treated equivalently in `uv add` and
`uv remove`.
2024-10-25 13:27:37 -05:00
Charlie Marsh 291c4c496d Add support for `default-groups` (#8471)
This PR adds support for `tool.uv.default-groups`, which defaults to
`["dev"]` for backwards-compatibility. These represent the groups we
sync by default.
2024-10-25 13:27:37 -05:00
Charlie Marsh c7ccf88939 Error when --group includes non-existent groups (#8394)
## Summary

Part of https://github.com/astral-sh/uv/pull/8272.
2024-10-25 13:27:37 -05:00
Charlie Marsh 4d134a4ffe Error on duplicate PEP 735 dependency groups (#8390)
## Summary

Part of: https://github.com/astral-sh/uv/pull/8272.
2024-10-25 13:27:37 -05:00