switch to jiff from chrono (#6205)

This PR migrates uv's use of `chrono` to `jiff`.

I did most of this work a while back as one of my tests to ensure Jiff
could actually be used in a real world project. I decided to revive
this because I noticed that `reqwest-retry` dropped its Chrono
dependency,
which is I believe the only other thing requiring Chrono in uv.
(Although, we use a fork of `reqwest-middleware` at present, and that
hasn't been updated to latest upstream yet. I wasn't quite sure of the
process we have for that.)

In course of doing this, I actually made two changes to uv:

First is that the lock file now writes an RFC 3339 timestamp for
`exclude-newer`. Previously, we were using Chrono's `Display`
implementation for this which is a non-standard but "human readable"
format. I think the right thing to do here is an RFC 3339 timestamp.

Second is that, in addition to an RFC 3339 timestamp, `--exclude-newer`
used to accept a "UTC date." But this PR changes it to a "local date."
That is, a date in the user's system configured time zone. I think
this makes more sense than a UTC date, but one alternative is to drop
support for a date and just rely on an RFC 3339 timestamp. The main
motivation here is that automatically assuming UTC is often somewhat
confusing, since just writing an unqualified date like `2024-08-19` is
often assumed to be interpreted relative to the writer's "local" time.
This commit is contained in:
Andrew Gallant 2024-08-19 10:36:00 -07:00 committed by Zanie Blue
parent c8f27a3978
commit 33480d61eb
38 changed files with 285 additions and 213 deletions

39
Cargo.lock generated
View file

@ -388,12 +388,12 @@ name = "bench"
version = "0.0.0"
dependencies = [
"anyhow",
"chrono",
"codspeed-criterion-compat",
"criterion",
"distribution-filename",
"distribution-types",
"install-wheel-rs",
"jiff",
"pep440_rs",
"pep508_rs",
"platform-tags",
@ -656,10 +656,8 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-targets 0.52.6",
]
@ -1105,6 +1103,7 @@ dependencies = [
"distribution-filename",
"fs-err",
"itertools 0.13.0",
"jiff",
"pep440_rs",
"pep508_rs",
"platform-tags",
@ -1926,6 +1925,32 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jiff"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94fda28c0e0f7e5ac1e40c34a06393ae6ecf4c9ce6b6421a2217a32680bb8038"
dependencies = [
"jiff-tzdb-platform",
"serde",
"windows-sys 0.59.0",
]
[[package]]
name = "jiff-tzdb"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05fac328b3df1c0f18a3c2ab6cb7e06e4e549f366017d796e3e66b6d6889abe6"
[[package]]
name = "jiff-tzdb-platform"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8da387d5feaf355954c2c122c194d6df9c57d865125a67984bb453db5336940"
dependencies = [
"jiff-tzdb",
]
[[package]]
name = "jobserver"
version = "0.1.32"
@ -2829,10 +2854,10 @@ name = "pypi-types"
version = "0.0.1"
dependencies = [
"anyhow",
"chrono",
"distribution-filename",
"indexmap",
"itertools 0.13.0",
"jiff",
"mailparse",
"pep440_rs",
"pep508_rs",
@ -4472,7 +4497,6 @@ dependencies = [
"base64 0.22.1",
"byteorder",
"cache-key",
"chrono",
"clap",
"distribution-types",
"filetime",
@ -4486,6 +4510,7 @@ dependencies = [
"insta",
"install-wheel-rs",
"itertools 0.13.0",
"jiff",
"miette",
"mimalloc",
"owo-colors",
@ -4648,7 +4673,6 @@ dependencies = [
"async_http_range_reader",
"async_zip",
"cache-key",
"chrono",
"distribution-filename",
"distribution-types",
"fs-err",
@ -4661,6 +4685,7 @@ dependencies = [
"insta",
"install-wheel-rs",
"itertools 0.13.0",
"jiff",
"pep440_rs",
"pep508_rs",
"platform-tags",
@ -5052,7 +5077,6 @@ version = "0.0.1"
dependencies = [
"anyhow",
"cache-key",
"chrono",
"clap",
"dashmap",
"derivative",
@ -5064,6 +5088,7 @@ dependencies = [
"insta",
"install-wheel-rs",
"itertools 0.13.0",
"jiff",
"once-map",
"owo-colors",
"pep440_rs",

View file

@ -70,7 +70,6 @@ base64 = { version = "0.22.0" }
boxcar = { version = "0.2.5" }
cachedir = { version = "0.3.1" }
cargo-util = { version = "0.2.8" }
chrono = { version = "0.4.31" }
clap = { version = "4.5.9" }
clap_complete_command = { version = "0.6.0" }
configparser = { version = "3.0.4" }
@ -98,6 +97,7 @@ indexmap = { version = "2.2.5" }
indicatif = { version = "0.17.7" }
indoc = { version = "2.0.4" }
itertools = { version = "0.13.0" }
jiff = { version = "0.1.6", features = ["serde"] }
junction = { version = "1.0.0" }
mailparse = { version = "0.15.0" }
md-5 = { version = "0.10.6" }

View file

@ -491,7 +491,8 @@ cases, but may lose fidelity for complex package and platform combinations._
uv supports an `--exclude-newer` option to limit resolution to distributions published before a
specific date, allowing reproduction of installations regardless of new package releases. The date
may be specified as an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamp (e.g.,
`2006-12-02T02:07:43Z`) or UTC date in the same format (e.g., `2006-12-02`).
`2006-12-02T02:07:43Z`) or a local date in the same format (e.g., `2006-12-02`) in your system's
configured time zone.
Note the package index must support the `upload-time` field as specified in
[`PEP 700`](https://peps.python.org/pep-0700/). If the field is not present for a given

View file

@ -46,9 +46,9 @@ uv-resolver = { workspace = true }
uv-types = { workspace = true }
anyhow = { workspace = true }
chrono = { workspace = true }
codspeed-criterion-compat = { version = "2.6.0", default-features = false, optional = true }
criterion = { version = "0.5.1", default-features = false, features = ["async_tokio"] }
jiff = { workspace = true }
tokio = { workspace = true }
[features]

View file

@ -82,7 +82,6 @@ mod resolver {
use std::sync::LazyLock;
use anyhow::Result;
use chrono::NaiveDate;
use distribution_types::IndexLocations;
use install_wheel_rs::linker::LinkMode;
@ -144,11 +143,10 @@ mod resolver {
let concurrency = Concurrency::default();
let config_settings = ConfigSettings::default();
let exclude_newer = Some(
NaiveDate::from_ymd_opt(2024, 8, 8)
jiff::civil::date(2024, 8, 8)
.to_zoned(jiff::tz::TimeZone::UTC)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap()
.and_utc()
.timestamp()
.into(),
);
let flat_index = FlatIndex::default();

View file

@ -26,6 +26,7 @@ uv-normalize = { workspace = true }
anyhow = { workspace = true }
fs-err = { workspace = true }
itertools = { workspace = true }
jiff = { workspace = true }
rkyv = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }

View file

@ -3,6 +3,7 @@ use std::fmt::{self, Display, Formatter};
use std::path::PathBuf;
use std::str::FromStr;
use jiff::Timestamp;
use serde::{Deserialize, Serialize};
use url::Url;
@ -31,7 +32,7 @@ pub struct File {
pub hashes: Vec<HashDigest>,
pub requires_python: Option<VersionSpecifiers>,
pub size: Option<u64>,
// N.B. We don't use a chrono DateTime<Utc> here because it's a little
// N.B. We don't use a Jiff timestamp here because it's a little
// annoying to do so with rkyv. Since we only use this field for doing
// comparisons in testing, we just store it as a UTC timestamp in
// milliseconds.
@ -57,7 +58,7 @@ impl File {
.transpose()
.map_err(|err| FileConversionError::RequiresPython(err.line().clone(), err))?,
size: file.size,
upload_time_utc_ms: file.upload_time.map(|dt| dt.timestamp_millis()),
upload_time_utc_ms: file.upload_time.map(Timestamp::as_millisecond),
url: match Url::parse(&file.url) {
Ok(url) => FileLocation::AbsoluteUrl(url.into()),
Err(_) => FileLocation::RelativeUrl(base.to_string(), file.url),

View file

@ -20,9 +20,9 @@ uv-fs = { workspace = true, features = ["serde"] }
uv-git = { workspace = true }
uv-normalize = { workspace = true }
chrono = { workspace = true, features = ["serde"] }
indexmap = { workspace = true, features = ["serde"] }
itertools = { workspace = true }
jiff = { workspace = true, features = ["serde"] }
mailparse = { workspace = true }
regex = { workspace = true }
rkyv = { workspace = true }

View file

@ -1,6 +1,6 @@
use std::str::FromStr;
use chrono::{DateTime, Utc};
use jiff::Timestamp;
use serde::{Deserialize, Deserializer, Serialize};
use pep440_rs::{VersionSpecifiers, VersionSpecifiersParseError};
@ -51,7 +51,7 @@ pub struct File {
#[serde(default, deserialize_with = "deserialize_version_specifiers_lenient")]
pub requires_python: Option<Result<VersionSpecifiers, VersionSpecifiersParseError>>,
pub size: Option<u64>,
pub upload_time: Option<DateTime<Utc>>,
pub upload_time: Option<Timestamp>,
pub url: String,
pub yanked: Option<Yanked>,
}

View file

@ -2009,8 +2009,8 @@ pub struct VenvArgs {
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// format (e.g., `2006-12-02`).
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same
/// format (e.g., `2006-12-02`) in your system's configured time zone.
#[arg(long, env = "UV_EXCLUDE_NEWER")]
pub exclude_newer: Option<ExcludeNewer>,
@ -3314,8 +3314,8 @@ pub struct InstallerArgs {
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// format (e.g., `2006-12-02`).
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same
/// format (e.g., `2006-12-02`) in your system's configured time zone.
#[arg(long, env = "UV_EXCLUDE_NEWER", help_heading = "Resolver options")]
pub exclude_newer: Option<ExcludeNewer>,
@ -3488,8 +3488,8 @@ pub struct ResolverArgs {
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// format (e.g., `2006-12-02`).
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same
/// format (e.g., `2006-12-02`) in your system's configured time zone.
#[arg(long, env = "UV_EXCLUDE_NEWER", help_heading = "Resolver options")]
pub exclude_newer: Option<ExcludeNewer>,
@ -3660,8 +3660,8 @@ pub struct ResolverInstallerArgs {
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// format (e.g., `2006-12-02`).
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same
/// format (e.g., `2006-12-02`) in your system's configured time zone.
#[arg(long, env = "UV_EXCLUDE_NEWER", help_heading = "Resolver options")]
pub exclude_newer: Option<ExcludeNewer>,

View file

@ -27,12 +27,12 @@ anyhow = { workspace = true }
async-trait = { workspace = true }
async_http_range_reader = { workspace = true }
async_zip = { workspace = true, features = ["tokio"] }
chrono = { workspace = true }
fs-err = { workspace = true, features = ["tokio"] }
futures = { workspace = true }
html-escape = { workspace = true }
http = { workspace = true }
itertools = { workspace = true }
jiff = { workspace = true }
reqwest = { workspace = true }
reqwest-middleware = { workspace = true }
reqwest-retry = { workspace = true }

View file

@ -1363,13 +1363,13 @@ fn unix_timestamp(time: SystemTime) -> u64 {
}
fn rfc2822_to_unix_timestamp(s: &str) -> Option<u64> {
rfc2822_to_datetime(s).and_then(|dt| u64::try_from(dt.timestamp()).ok())
rfc2822_to_datetime(s).and_then(|timestamp| u64::try_from(timestamp.as_second()).ok())
}
fn rfc2822_to_datetime(s: &str) -> Option<chrono::DateTime<chrono::Utc>> {
chrono::DateTime::parse_from_rfc2822(s)
fn rfc2822_to_datetime(s: &str) -> Option<jiff::Timestamp> {
jiff::fmt::rfc2822::DateTimeParser::new()
.parse_timestamp(s)
.ok()
.map(|dt| dt.to_utc())
}
fn unix_timestamp_to_header(seconds: u64) -> Option<HeaderValue> {
@ -1377,11 +1377,19 @@ fn unix_timestamp_to_header(seconds: u64) -> Option<HeaderValue> {
}
fn unix_timestamp_to_rfc2822(seconds: u64) -> Option<String> {
unix_timestamp_to_datetime(seconds).map(|dt| dt.to_rfc2822())
use jiff::fmt::rfc2822::DateTimePrinter;
unix_timestamp_to_datetime(seconds).and_then(|timestamp| {
let mut buf = String::new();
DateTimePrinter::new()
.print_timestamp(&timestamp, &mut buf)
.ok()?;
Some(buf)
})
}
fn unix_timestamp_to_datetime(seconds: u64) -> Option<chrono::DateTime<chrono::Utc>> {
chrono::DateTime::from_timestamp(i64::try_from(seconds).ok()?, 0)
fn unix_timestamp_to_datetime(seconds: u64) -> Option<jiff::Timestamp> {
jiff::Timestamp::from_second(i64::try_from(seconds).ok()?).ok()
}
fn parse_seconds(value: &[u8]) -> Option<u64> {

View file

@ -36,7 +36,6 @@ uv-warnings = { workspace = true }
uv-workspace = { workspace = true }
anyhow = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["derive"], optional = true }
dashmap = { workspace = true }
derivative = { workspace = true }
@ -44,6 +43,7 @@ either = { workspace = true }
futures = { workspace = true }
indexmap = { workspace = true }
itertools = { workspace = true }
jiff = { workspace = true, features = ["serde"] }
owo-colors = { workspace = true }
petgraph = { workspace = true }
pubgrub = { workspace = true }

View file

@ -1,21 +1,21 @@
use std::str::FromStr;
use chrono::{DateTime, Days, NaiveDate, NaiveTime, Utc};
use jiff::{tz::TimeZone, Timestamp, ToSpan};
/// A timestamp that excludes files newer than it.
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct ExcludeNewer(DateTime<Utc>);
pub struct ExcludeNewer(Timestamp);
impl ExcludeNewer {
/// Returns the timestamp in milliseconds.
pub fn timestamp_millis(&self) -> i64 {
self.0.timestamp_millis()
self.0.as_millisecond()
}
}
impl From<DateTime<Utc>> for ExcludeNewer {
fn from(datetime: DateTime<Utc>) -> Self {
Self(datetime)
impl From<Timestamp> for ExcludeNewer {
fn from(timestamp: Timestamp) -> Self {
Self(timestamp)
}
}
@ -24,25 +24,38 @@ impl FromStr for ExcludeNewer {
/// Parse an [`ExcludeNewer`] from a string.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same
/// format (e.g., `2006-12-02`).
fn from_str(input: &str) -> Result<Self, Self::Err> {
let date_err = match NaiveDate::from_str(input) {
Ok(date) => {
// Midnight that day is 00:00:00 the next day
return Ok(Self(
(date + Days::new(1)).and_time(NaiveTime::MIN).and_utc(),
));
}
Err(err) => err,
};
let datetime_err = match DateTime::parse_from_rfc3339(input) {
Ok(datetime) => return Ok(Self(datetime.with_timezone(&Utc))),
Err(err) => err,
};
Err(format!(
"`{input}` is neither a valid date ({date_err}) nor a valid datetime ({datetime_err})"
))
// NOTE(burntsushi): Previously, when using Chrono, we tried
// to parse as a date first, then a timestamp, and if both
// failed, we combined both of the errors into one message.
// But in Jiff, if an RFC 3339 timestamp could be parsed, then
// it must necessarily be the case that a date can also be
// parsed. So we can collapse the error cases here. That is,
// if we fail to parse a timestamp and a date, then it should
// be sufficient to just report the error from parsing the date.
// If someone tried to write a timestamp but committed an error
// in the non-date portion, the date parsing below will still
// report a holistic error that will make sense to the user.
// (I added a snapshot test for that case.)
if let Ok(timestamp) = input.parse::<Timestamp>() {
return Ok(Self(timestamp));
}
let date = input
.parse::<jiff::civil::Date>()
.map_err(|err| format!("`{input}` could not be parsed as a valid date: {err}"))?;
let timestamp = date
.checked_add(1.day())
.and_then(|date| date.to_zoned(TimeZone::system()))
.map(|zdt| zdt.timestamp())
.map_err(|err| {
format!(
"`{input}` parsed to date `{date}`, but could not \
be converted to a timestamp: {err}",
)
})?;
Ok(Self(timestamp))
}
}
@ -68,7 +81,7 @@ impl schemars::JsonSchema for ExcludeNewer {
..schemars::schema::StringValidation::default()
})),
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some("Exclude distributions uploaded after the given timestamp.\n\nAccepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).".to_string()),
description: Some("Exclude distributions uploaded after the given timestamp.\n\nAccepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`).".to_string()),
..schemars::schema::Metadata::default()
})),
..schemars::schema::SchemaObject::default()

View file

@ -383,7 +383,8 @@ pub struct ResolverInstallerOptions {
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g.,
/// `2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).
/// `2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`) in your
/// system's configured time zone.
#[option(
default = "None",
value_type = "str",
@ -978,7 +979,8 @@ pub struct PipOptions {
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g.,
/// `2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).
/// `2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`) in your
/// system's configured time zone.
#[option(
default = "None",
value_type = "str",

View file

@ -47,7 +47,6 @@ uv-workspace = { workspace = true }
anstream = { workspace = true }
anyhow = { workspace = true }
axoupdater = { workspace = true, features = ["github_releases", "tokio"], optional = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["derive", "string", "wrap_help"] }
flate2 = { workspace = true, default-features = false }
fs-err = { workspace = true, features = ["tokio"] }
@ -56,6 +55,7 @@ indexmap = { workspace = true }
indicatif = { workspace = true }
indoc = { workspace = true }
itertools = { workspace = true }
jiff = { workspace = true }
miette = { workspace = true, features = ["fancy"] }
owo-colors = { workspace = true }
rayon = { workspace = true }

View file

@ -3,7 +3,7 @@ use std::str::FromStr;
use anstream::ColorChoice;
use anyhow::Context;
use chrono::Utc;
use jiff::Timestamp;
use owo_colors::OwoColorize;
use tracing::{Event, Subscriber};
#[cfg(feature = "tracing-durations-export")]
@ -54,9 +54,9 @@ where
if self.display_timestamp {
if ansi {
write!(writer, "{} ", Utc::now().dimmed())?;
write!(writer, "{} ", Timestamp::now().dimmed())?;
} else {
write!(writer, "{} ", Utc::now())?;
write!(writer, "{} ", Timestamp::now())?;
}
}

View file

@ -214,7 +214,7 @@ fn root_package_splits_transitive_too() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "a"
@ -409,7 +409,7 @@ fn root_package_splits_other_dependencies_too() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "a"
@ -570,7 +570,7 @@ fn branching_between_registry_and_direct_url() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "a"
@ -655,7 +655,7 @@ fn branching_urls_of_different_sources_disjoint() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "a"
@ -778,7 +778,7 @@ fn dont_pre_visit_url_packages() -> Result<()> {
requires-python = ">=3.11, <3.13"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "a"

View file

@ -71,7 +71,7 @@ fn add_registry() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -229,7 +229,7 @@ fn add_git() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -361,7 +361,7 @@ fn add_git_private_source() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -460,7 +460,7 @@ fn add_git_private_raw() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -639,7 +639,7 @@ fn add_git_raw() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -861,7 +861,7 @@ fn add_unnamed() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -959,7 +959,7 @@ fn add_remove_dev() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -1081,7 +1081,7 @@ fn add_remove_dev() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -1168,7 +1168,7 @@ fn add_remove_optional() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -1289,7 +1289,7 @@ fn add_remove_optional() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -1415,7 +1415,7 @@ fn add_remove_workspace() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -1498,7 +1498,7 @@ fn add_remove_workspace() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -1615,7 +1615,7 @@ fn add_workspace_editable() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -1821,7 +1821,7 @@ fn update() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "certifi"
@ -2326,7 +2326,7 @@ fn add_no_clean() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -2462,7 +2462,7 @@ fn remove_registry() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -3082,7 +3082,7 @@ fn add_lower_bound_optional() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -3294,7 +3294,7 @@ fn add_virtual() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"

View file

@ -52,7 +52,7 @@ fn lock_wheel_registry() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -267,7 +267,7 @@ fn lock_sdist_git() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -364,7 +364,7 @@ fn lock_sdist_git() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -422,7 +422,7 @@ fn lock_sdist_git() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -480,7 +480,7 @@ fn lock_sdist_git() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -542,7 +542,7 @@ fn lock_sdist_git_subdirectory() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "example-pkg-a"
@ -629,7 +629,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -694,7 +694,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -748,7 +748,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -802,7 +802,7 @@ fn lock_sdist_git_pep508() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -863,7 +863,7 @@ fn lock_wheel_url() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -1010,7 +1010,7 @@ fn lock_sdist_url() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -1146,7 +1146,7 @@ fn lock_project_extra() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -1411,7 +1411,7 @@ fn lock_dependency_extra() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "blinker"
@ -1616,7 +1616,7 @@ fn lock_conditional_dependency_extra() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "certifi"
@ -1898,7 +1898,7 @@ fn lock_dependency_non_existent_extra() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "blinker"
@ -2082,7 +2082,7 @@ fn lock_upgrade_log() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -2165,7 +2165,7 @@ fn lock_upgrade_log() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "markupsafe"
@ -2257,7 +2257,7 @@ fn lock_upgrade_log_multi_version() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "markupsafe"
@ -2340,7 +2340,7 @@ fn lock_upgrade_log_multi_version() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "markupsafe"
@ -2414,7 +2414,7 @@ fn lock_preference() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -2474,7 +2474,7 @@ fn lock_preference() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -2521,7 +2521,7 @@ fn lock_preference() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -2575,7 +2575,7 @@ fn lock_git_sha() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -2626,7 +2626,7 @@ fn lock_git_sha() -> Result<()> {
----- stderr -----
warning: `uv lock` is experimental and may change without warning
Resolved 2 packages in [TIME]
"###);
"###);
let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
@ -2641,7 +2641,7 @@ fn lock_git_sha() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -2740,7 +2740,7 @@ fn lock_requires_python() -> Result<()> {
requires-python = ">=3.7"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "attrs"
@ -2892,7 +2892,7 @@ fn lock_requires_python() -> Result<()> {
requires-python = ">=3.7.9"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "attrs"
@ -3034,7 +3034,7 @@ fn lock_requires_python() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "attrs"
@ -3178,7 +3178,7 @@ fn lock_requires_python_wheels() -> Result<()> {
requires-python = "==3.12.*"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "frozenlist"
@ -3263,7 +3263,7 @@ fn lock_requires_python_wheels() -> Result<()> {
requires-python = "==3.11.*"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "frozenlist"
@ -3373,7 +3373,7 @@ fn lock_requires_python_star() -> Result<()> {
requires-python = "==3.11.*"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "attrs"
@ -3497,7 +3497,7 @@ fn lock_requires_python_pre() -> Result<()> {
requires-python = ">=3.11"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "attrs"
@ -3620,7 +3620,7 @@ fn lock_requires_python_unbounded() -> Result<()> {
requires-python = "<=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -3718,7 +3718,7 @@ fn lock_python_version_marker_complement() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "attrs"
@ -3824,7 +3824,7 @@ fn lock_dev() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -3942,7 +3942,7 @@ fn lock_conditional_unconditional() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -4021,7 +4021,7 @@ fn lock_multiple_markers() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -4140,7 +4140,7 @@ fn lock_relative_and_absolute_paths() -> Result<()> {
requires-python = ">=3.11, <3.13"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "a"
@ -4222,7 +4222,7 @@ fn lock_cycles() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "argparse"
@ -4427,7 +4427,7 @@ fn lock_new_extras() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "certifi"
@ -4552,7 +4552,7 @@ fn lock_new_extras() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "certifi"
@ -4799,7 +4799,7 @@ fn lock_resolution_mode() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -4882,7 +4882,7 @@ fn lock_resolution_mode() -> Result<()> {
[options]
resolution-mode = "lowest-direct"
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -5047,7 +5047,7 @@ fn lock_same_version_multiple_urls() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -5264,7 +5264,7 @@ fn lock_exclusion() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "child"
@ -5383,7 +5383,7 @@ fn lock_dev_transitive() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -5506,7 +5506,7 @@ fn lock_redact_https() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "foo"
@ -5657,7 +5657,7 @@ fn lock_redact_git() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "foo"
@ -5746,7 +5746,7 @@ fn lock_relative_index() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "foo"
@ -5854,7 +5854,7 @@ fn lock_no_sources() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -5928,7 +5928,7 @@ fn lock_no_sources() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -6013,7 +6013,7 @@ fn lock_migrate() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[distribution-term-we-dont-know]]
name = "anyio"
@ -6081,7 +6081,7 @@ fn lock_migrate() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -6181,7 +6181,7 @@ fn lock_upgrade_package() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -6278,7 +6278,7 @@ fn lock_upgrade_package() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -6363,7 +6363,7 @@ fn lock_upgrade_package() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -6528,7 +6528,7 @@ fn lock_find_links_local_wheel() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -6620,7 +6620,7 @@ fn lock_find_links_local_sdist() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -6711,7 +6711,7 @@ fn lock_find_links_http_wheel() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "packaging"
@ -6805,7 +6805,7 @@ fn lock_find_links_http_sdist() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "packaging"
@ -7021,7 +7021,7 @@ fn lock_sources_url() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -7160,7 +7160,7 @@ fn lock_sources_archive() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -7314,7 +7314,7 @@ fn lock_sources_source_tree() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -7447,7 +7447,7 @@ fn lock_editable() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -7530,7 +7530,7 @@ fn lock_editable() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -7691,7 +7691,7 @@ fn lock_mixed_extras() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -7887,7 +7887,7 @@ fn lock_transitive_extra() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -8083,7 +8083,7 @@ fn lock_mismatched_versions() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -8204,7 +8204,7 @@ fn lock_change_index() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -8251,7 +8251,7 @@ fn lock_change_index() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -8347,7 +8347,7 @@ fn lock_remove_member() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -8472,7 +8472,7 @@ fn lock_remove_member() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -8530,7 +8530,7 @@ fn lock_add_member() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
@ -8641,7 +8641,7 @@ fn lock_add_member() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -8745,7 +8745,7 @@ fn lock_redundant_add_member() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -8852,7 +8852,7 @@ fn lock_redundant_add_member() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -8944,7 +8944,7 @@ fn lock_new_constraints() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -9053,7 +9053,7 @@ fn lock_new_constraints() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
constraints = [{ name = "anyio", specifier = "<4.3" }]
@ -9154,7 +9154,7 @@ fn lock_remove_member_virtual() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [
@ -9263,7 +9263,7 @@ fn lock_remove_member_virtual() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
"###
);
});
@ -9310,7 +9310,7 @@ fn lock_rename_project() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -9393,7 +9393,7 @@ fn lock_rename_project() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
@ -9445,7 +9445,7 @@ fn lock_missing_metadata() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -9496,7 +9496,7 @@ fn lock_missing_metadata() -> Result<()> {
----- stderr -----
warning: `uv lock` is experimental and may change without warning
Resolved 4 packages in [TIME]
"###);
"###);
let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
@ -9509,7 +9509,7 @@ fn lock_missing_metadata() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -9597,7 +9597,7 @@ fn lock_reorder() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"
@ -9750,7 +9750,7 @@ fn lock_narrowed_python_version() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "dependency"
@ -9854,7 +9854,7 @@ fn lock_exclude_unnecessary_python_forks() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"

View file

@ -2559,7 +2559,27 @@ fn compile_exclude_newer() -> Result<()> {
----- stdout -----
----- stderr -----
error: invalid value '2022-04-04+02:00' for '--exclude-newer <EXCLUDE_NEWER>': `2022-04-04+02:00` is neither a valid date (trailing input) nor a valid datetime (input contains invalid characters)
error: invalid value '2022-04-04+02:00' for '--exclude-newer <EXCLUDE_NEWER>': `2022-04-04+02:00` could not be parsed as a valid date: parsed value '2022-04-04', but unparsed input "+02:00" remains (expected no unparsed input)
For more information, try '--help'.
"###
);
// Check the error message for the case of
// an invalid timestamp that still has a
// valid date.
uv_snapshot!(context
.pip_compile()
.env_remove("UV_EXCLUDE_NEWER")
.arg("requirements.in")
.arg("--exclude-newer")
.arg("2022-04-04T26:00:00+00"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: invalid value '2022-04-04T26:00:00+00' for '--exclude-newer <EXCLUDE_NEWER>': `2022-04-04T26:00:00+00` could not be parsed as a valid date: failed to parse hour in time "26:00:00+00": hour is not valid: parameter 'hour' with value 26 is not in the required range of 0..=23
For more information, try '--help'.
"###

View file

@ -10,7 +10,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2024-08-08 00:00:00 UTC"
exclude-newer = "2024-08-08T00:00:00Z"
[[package]]
name = "aiohappyeyeballs"

View file

@ -10,7 +10,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2024-08-08 00:00:00 UTC"
exclude-newer = "2024-08-08T00:00:00Z"
[[package]]
name = "annotated-types"

View file

@ -6,7 +6,7 @@ version = 1
requires-python = ">=3.12.[X]"
[options]
exclude-newer = "2024-08-08 00:00:00 UTC"
exclude-newer = "2024-08-08T00:00:00Z"
[[package]]
name = "acme"

View file

@ -6,7 +6,7 @@ version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-08-08 00:00:00 UTC"
exclude-newer = "2024-08-08T00:00:00Z"
[[package]]
name = "anyio"

View file

@ -23,7 +23,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2024-08-08 00:00:00 UTC"
exclude-newer = "2024-08-08T00:00:00Z"
[[package]]
name = "absl-py"

View file

@ -12,7 +12,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2024-08-08 00:00:00 UTC"
exclude-newer = "2024-08-08T00:00:00Z"
[[package]]
name = "alabaster"

View file

@ -12,7 +12,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "importlib-metadata"

View file

@ -6,7 +6,7 @@ version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"

View file

@ -6,7 +6,7 @@ version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"

View file

@ -6,7 +6,7 @@ version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "anyio"

View file

@ -740,7 +740,7 @@ fn sync_relative_wheel() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "ok"

View file

@ -429,7 +429,7 @@ fn jax_instability() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "importlib-metadata"
@ -566,7 +566,7 @@ fn jax_instability() -> Result<()> {
]
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "importlib-metadata"

View file

@ -1086,7 +1086,7 @@ fn workspace_inherit_sources() -> Result<()> {
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
exclude-newer = "2024-03-25T00:00:00Z"
[manifest]
members = [

View file

@ -263,7 +263,8 @@ unconditionally when using overrides — it does not matter if the marker evalua
uv supports an `--exclude-newer` option to limit resolution to distributions published before a
specific date, allowing reproduction of installations regardless of new package releases. The date
may be specified as an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamp (e.g.,
`2006-12-02T02:07:43Z`) or UTC date in the same format (e.g., `2006-12-02`).
`2006-12-02T02:07:43Z`) or a local date in the same format (e.g., `2006-12-02`) in your system's
configured time zone.
Note the package index must support the `upload-time` field as specified in
[`PEP 700`](https://peps.python.org/pep-0700/). If the field is not present for a given

View file

@ -100,7 +100,7 @@ uv run [OPTIONS] <COMMAND>
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name.</p>
@ -513,7 +513,7 @@ uv add [OPTIONS] <PACKAGES|--requirements <REQUIREMENTS>>
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Extras to enable for the dependency.</p>
@ -797,7 +797,7 @@ uv remove [OPTIONS] <PACKAGES>...
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -1049,7 +1049,7 @@ uv sync [OPTIONS]
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name.</p>
@ -1299,7 +1299,7 @@ uv lock [OPTIONS]
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -1526,7 +1526,7 @@ uv tree [OPTIONS]
<p>[default: 255]</p>
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -1855,7 +1855,7 @@ uv tool run [OPTIONS] [COMMAND]
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -2097,7 +2097,7 @@ uv tool install [OPTIONS] <PACKAGE>
</dd><dt><code>--editable</code>, <code>-e</code></dt><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -2339,7 +2339,7 @@ uv tool upgrade [OPTIONS] <NAME>
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -3625,7 +3625,7 @@ uv pip compile [OPTIONS] <SRC_FILE>...
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name; may be provided more than once.</p>
@ -3974,7 +3974,7 @@ uv pip sync [OPTIONS] <SRC_FILE>...
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
@ -4269,7 +4269,7 @@ uv pip install [OPTIONS] <PACKAGE|--requirement <REQUIREMENT>|--editable <EDITAB
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name; may be provided more than once.</p>
@ -5238,7 +5238,7 @@ uv venv [OPTIONS] [NAME]
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and UTC dates in the same format (e.g., <code>2006-12-02</code>).</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>

View file

@ -149,7 +149,8 @@ unsatisfiable branches in the solution space.
Limit candidate packages to those that were uploaded prior to the given date.
Accepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g.,
`2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).
`2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`) in your
system's configured time zone.
**Default value**: `None`
@ -1385,7 +1386,8 @@ be correct.
Limit candidate packages to those that were uploaded prior to the given date.
Accepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g.,
`2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).
`2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`) in your
system's configured time zone.
**Default value**: `None`

6
uv.schema.json generated
View file

@ -59,7 +59,7 @@
}
},
"exclude-newer": {
"description": "Limit candidate packages to those that were uploaded prior to the given date.\n\nAccepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).",
"description": "Limit candidate packages to those that were uploaded prior to the given date.\n\nAccepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`) in your system's configured time zone.",
"anyOf": [
{
"$ref": "#/definitions/ExcludeNewer"
@ -414,7 +414,7 @@
}
},
"ExcludeNewer": {
"description": "Exclude distributions uploaded after the given timestamp.\n\nAccepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).",
"description": "Exclude distributions uploaded after the given timestamp.\n\nAccepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`).",
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2}))?$"
},
@ -641,7 +641,7 @@
]
},
"exclude-newer": {
"description": "Limit candidate packages to those that were uploaded prior to the given date.\n\nAccepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same format (e.g., `2006-12-02`).",
"description": "Limit candidate packages to those that were uploaded prior to the given date.\n\nAccepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g., `2006-12-02T02:07:43Z`) and local dates in the same format (e.g., `2006-12-02`) in your system's configured time zone.",
"anyOf": [
{
"$ref": "#/definitions/ExcludeNewer"