@@ -17750,3 +17750,125 @@ fn lock_transitive_git() -> Result<()> {
17750
17750
17751
17751
Ok(())
17752
17752
}
17753
+
17754
+ /// Lock a package that's excluded from the parent workspace, but depends on that parent.
17755
+ #[test]
17756
+ fn lock_dynamic_version() -> Result<()> {
17757
+ let context = TestContext::new("3.12");
17758
+
17759
+ let pyproject_toml = context.temp_dir.child("pyproject.toml");
17760
+ pyproject_toml.write_str(
17761
+ r#"
17762
+ [project]
17763
+ name = "project"
17764
+ requires-python = ">=3.12"
17765
+ dynamic = ["version"]
17766
+
17767
+ [build-system]
17768
+ requires = ["setuptools"]
17769
+ build-backend = "setuptools.build_meta"
17770
+
17771
+ [tool.uv]
17772
+ cache-keys = [{ file = "pyproject.toml" }, { file = "src/project/__init__.py" }]
17773
+
17774
+ [tool.setuptools.dynamic]
17775
+ version = { attr = "project.__version__" }
17776
+
17777
+ [tool.setuptools]
17778
+ package-dir = { "" = "src" }
17779
+
17780
+ [tool.setuptools.packages.find]
17781
+ where = ["src"]
17782
+ "#,
17783
+ )?;
17784
+
17785
+ context
17786
+ .temp_dir
17787
+ .child("src")
17788
+ .child("project")
17789
+ .child("__init__.py")
17790
+ .write_str("__version__ = '0.1.0'")?;
17791
+
17792
+ uv_snapshot!(context.filters(), context.lock(), @r###"
17793
+ success: true
17794
+ exit_code: 0
17795
+ ----- stdout -----
17796
+
17797
+ ----- stderr -----
17798
+ Resolved 1 package in [TIME]
17799
+ "###);
17800
+
17801
+ let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
17802
+
17803
+ insta::with_settings!({
17804
+ filters => context.filters(),
17805
+ }, {
17806
+ assert_snapshot!(
17807
+ lock, @r###"
17808
+ version = 1
17809
+ requires-python = ">=3.12"
17810
+
17811
+ [options]
17812
+ exclude-newer = "2024-03-25T00:00:00Z"
17813
+
17814
+ [[package]]
17815
+ name = "project"
17816
+ version = "0.1.0"
17817
+ source = { editable = "." }
17818
+ "###
17819
+ );
17820
+ });
17821
+
17822
+ // Bump the version.
17823
+ context
17824
+ .temp_dir
17825
+ .child("src")
17826
+ .child("project")
17827
+ .child("__init__.py")
17828
+ .write_str("__version__ = '0.1.1'")?;
17829
+
17830
+ // Re-run with `--locked`.
17831
+ uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
17832
+ success: false
17833
+ exit_code: 2
17834
+ ----- stdout -----
17835
+
17836
+ ----- stderr -----
17837
+ Resolved 1 package in [TIME]
17838
+ error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.
17839
+ "###);
17840
+
17841
+ // Re-lock.
17842
+ uv_snapshot!(context.filters(), context.lock(), @r###"
17843
+ success: true
17844
+ exit_code: 0
17845
+ ----- stdout -----
17846
+
17847
+ ----- stderr -----
17848
+ Resolved 1 package in [TIME]
17849
+ Updated project v0.1.0 -> v0.1.1
17850
+ "###);
17851
+
17852
+ let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();
17853
+
17854
+ insta::with_settings!({
17855
+ filters => context.filters(),
17856
+ }, {
17857
+ assert_snapshot!(
17858
+ lock, @r###"
17859
+ version = 1
17860
+ requires-python = ">=3.12"
17861
+
17862
+ [options]
17863
+ exclude-newer = "2024-03-25T00:00:00Z"
17864
+
17865
+ [[package]]
17866
+ name = "project"
17867
+ version = "0.1.1"
17868
+ source = { editable = "." }
17869
+ "###
17870
+ );
17871
+ });
17872
+
17873
+ Ok(())
17874
+ }
0 commit comments