@@ -5506,76 +5506,206 @@ fn add_git_to_script() -> Result<()> {
5506
5506
Ok ( ( ) )
5507
5507
}
5508
5508
5509
- /// Revert changes to a `pyproject.toml` the `add` fails.
5509
+ /// Revert changes to the `pyproject.toml` and `uv.lock` when the `add` operation fails.
5510
5510
#[ test]
5511
5511
fn fail_to_add_revert_project ( ) -> Result < ( ) > {
5512
5512
let context = TestContext :: new ( "3.12" ) ;
5513
5513
5514
- let pyproject_toml = context. temp_dir . child ( "pyproject.toml" ) ;
5515
- pyproject_toml. write_str ( indoc ! { r#"
5514
+ context
5515
+ . temp_dir
5516
+ . child ( "pyproject.toml" )
5517
+ . write_str ( indoc ! { r#"
5516
5518
[project]
5517
- name = "project "
5519
+ name = "parent "
5518
5520
version = "0.1.0"
5519
5521
requires-python = ">=3.12"
5520
5522
dependencies = []
5523
+ "# } ) ?;
5524
+
5525
+ // Add a dependency on a package that declares static metadata (so can always resolve), but
5526
+ // can't be installed.
5527
+ let pyproject_toml = context. temp_dir . child ( "child/pyproject.toml" ) ;
5528
+ pyproject_toml. write_str ( indoc ! { r#"
5529
+ [project]
5530
+ name = "child"
5531
+ version = "0.1.0"
5532
+ requires-python = ">=3.12"
5533
+ dependencies = ["iniconfig"]
5521
5534
5522
5535
[build-system]
5523
5536
requires = ["setuptools>=42"]
5524
5537
build-backend = "setuptools.build_meta"
5525
5538
"# } ) ?;
5539
+ context
5540
+ . temp_dir
5541
+ . child ( "src" )
5542
+ . child ( "child" )
5543
+ . child ( "__init__.py" )
5544
+ . touch ( ) ?;
5545
+ context
5546
+ . temp_dir
5547
+ . child ( "child" )
5548
+ . child ( "setup.py" )
5549
+ . write_str ( "1/0" ) ?;
5526
5550
5527
- // Adding `pytorch==1.0.2` should produce an error
5528
5551
let filters = std:: iter:: once ( ( r"exit code: 1" , "exit status: 1" ) )
5529
5552
. chain ( context. filters ( ) )
5530
5553
. collect :: < Vec < _ > > ( ) ;
5531
- uv_snapshot ! ( filters, context. add( ) . arg( "pytorch==1.0.2 " ) , @r###"
5554
+ uv_snapshot ! ( filters, context. add( ) . arg( "./child " ) , @r###"
5532
5555
success: false
5533
5556
exit_code: 2
5534
5557
----- stdout -----
5535
5558
5536
5559
----- stderr -----
5537
- Resolved 2 packages in [TIME]
5560
+ Resolved 3 packages in [TIME]
5538
5561
error: Failed to prepare distributions
5539
- Caused by: Failed to download and build `pytorch==1.0.2 `
5540
- Caused by: Build backend failed to build wheel through `build_wheel` (exit status: 1)
5562
+ Caused by: Failed to build `child @ file://[TEMP_DIR]/child `
5563
+ Caused by: Build backend failed to determine requirements with `build_wheel() ` (exit status: 1)
5541
5564
5542
5565
[stderr]
5543
5566
Traceback (most recent call last):
5544
- File "<string>", line 11 , in <module>
5545
- File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 410 , in build_wheel
5546
- return self._build_with_temp_dir(
5547
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
5548
- File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 395 , in _build_with_temp_dir
5567
+ File "<string>", line 14 , in <module>
5568
+ File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 325 , in get_requires_for_build_wheel
5569
+ return self._get_build_requires(config_settings, requirements=['wheel'])
5570
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5571
+ File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 295 , in _get_build_requires
5549
5572
self.run_setup()
5550
- File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 487, in run_setup
5551
- super().run_setup(setup_script=setup_script)
5552
5573
File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 311, in run_setup
5553
5574
exec(code, locals())
5554
- File "<string>", line 15, in <module>
5555
- Exception: You tried to install "pytorch". The package named for PyTorch is "torch"
5556
-
5575
+ File "<string>", line 1, in <module>
5576
+ ZeroDivisionError: division by zero
5557
5577
"### ) ;
5558
5578
5559
- let pyproject_toml = context. read ( "pyproject.toml" ) ;
5579
+ let pyproject_toml = fs_err :: read_to_string ( context. temp_dir . join ( "pyproject.toml" ) ) ? ;
5560
5580
5561
5581
insta:: with_settings!( {
5562
5582
filters => context. filters( ) ,
5563
5583
} , {
5564
5584
assert_snapshot!(
5565
5585
pyproject_toml, @r###"
5566
5586
[project]
5567
- name = "project"
5587
+ name = "parent"
5588
+ version = "0.1.0"
5589
+ requires-python = ">=3.12"
5590
+ dependencies = []
5591
+ "###
5592
+ ) ;
5593
+ } ) ;
5594
+
5595
+ // The lockfile should not exist, even though resolution succeeded.
5596
+ assert ! ( !context. temp_dir. join( "uv.lock" ) . exists( ) ) ;
5597
+
5598
+ Ok ( ( ) )
5599
+ }
5600
+
5601
+ /// Revert changes to the `pyproject.toml` and `uv.lock` when the `add` operation fails.
5602
+ ///
5603
+ /// In this case, the project has an existing lockfile.
5604
+ #[ test]
5605
+ fn fail_to_edit_revert_project ( ) -> Result < ( ) > {
5606
+ let context = TestContext :: new ( "3.12" ) ;
5607
+
5608
+ context
5609
+ . temp_dir
5610
+ . child ( "pyproject.toml" )
5611
+ . write_str ( indoc ! { r#"
5612
+ [project]
5613
+ name = "parent"
5568
5614
version = "0.1.0"
5569
5615
requires-python = ">=3.12"
5570
5616
dependencies = []
5617
+ "# } ) ?;
5618
+
5619
+ uv_snapshot ! ( context. filters( ) , context. add( ) . arg( "iniconfig" ) , @r###"
5620
+ success: true
5621
+ exit_code: 0
5622
+ ----- stdout -----
5623
+
5624
+ ----- stderr -----
5625
+ Resolved 2 packages in [TIME]
5626
+ Prepared 1 package in [TIME]
5627
+ Installed 1 package in [TIME]
5628
+ + iniconfig==2.0.0
5629
+ "### ) ;
5630
+
5631
+ let before = fs_err:: read_to_string ( context. temp_dir . join ( "uv.lock" ) ) ?;
5632
+
5633
+ // Add a dependency on a package that declares static metadata (so can always resolve), but
5634
+ // can't be installed.
5635
+ let pyproject_toml = context. temp_dir . child ( "child/pyproject.toml" ) ;
5636
+ pyproject_toml. write_str ( indoc ! { r#"
5637
+ [project]
5638
+ name = "child"
5639
+ version = "0.1.0"
5640
+ requires-python = ">=3.12"
5641
+ dependencies = ["iniconfig"]
5571
5642
5572
5643
[build-system]
5573
5644
requires = ["setuptools>=42"]
5574
5645
build-backend = "setuptools.build_meta"
5646
+ "# } ) ?;
5647
+ context
5648
+ . temp_dir
5649
+ . child ( "src" )
5650
+ . child ( "child" )
5651
+ . child ( "__init__.py" )
5652
+ . touch ( ) ?;
5653
+ context
5654
+ . temp_dir
5655
+ . child ( "child" )
5656
+ . child ( "setup.py" )
5657
+ . write_str ( "1/0" ) ?;
5658
+
5659
+ let filters = std:: iter:: once ( ( r"exit code: 1" , "exit status: 1" ) )
5660
+ . chain ( context. filters ( ) )
5661
+ . collect :: < Vec < _ > > ( ) ;
5662
+ uv_snapshot ! ( filters, context. add( ) . arg( "./child" ) , @r###"
5663
+ success: false
5664
+ exit_code: 2
5665
+ ----- stdout -----
5666
+
5667
+ ----- stderr -----
5668
+ Resolved 3 packages in [TIME]
5669
+ error: Failed to prepare distributions
5670
+ Caused by: Failed to build `child @ file://[TEMP_DIR]/child`
5671
+ Caused by: Build backend failed to determine requirements with `build_wheel()` (exit status: 1)
5672
+
5673
+ [stderr]
5674
+ Traceback (most recent call last):
5675
+ File "<string>", line 14, in <module>
5676
+ File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 325, in get_requires_for_build_wheel
5677
+ return self._get_build_requires(config_settings, requirements=['wheel'])
5678
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5679
+ File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 295, in _get_build_requires
5680
+ self.run_setup()
5681
+ File "[CACHE_DIR]/builds-v0/[TMP]/build_meta.py", line 311, in run_setup
5682
+ exec(code, locals())
5683
+ File "<string>", line 1, in <module>
5684
+ ZeroDivisionError: division by zero
5685
+ "### ) ;
5686
+
5687
+ let pyproject_toml = fs_err:: read_to_string ( context. temp_dir . join ( "pyproject.toml" ) ) ?;
5688
+
5689
+ insta:: with_settings!( {
5690
+ filters => context. filters( ) ,
5691
+ } , {
5692
+ assert_snapshot!(
5693
+ pyproject_toml, @r###"
5694
+ [project]
5695
+ name = "parent"
5696
+ version = "0.1.0"
5697
+ requires-python = ">=3.12"
5698
+ dependencies = [
5699
+ "iniconfig>=2.0.0",
5700
+ ]
5575
5701
"###
5576
5702
) ;
5577
5703
} ) ;
5578
5704
5705
+ // The lockfile should exist, but be unchanged.
5706
+ let after = fs_err:: read_to_string ( context. temp_dir . join ( "uv.lock" ) ) ?;
5707
+ assert_eq ! ( before, after) ;
5708
+
5579
5709
Ok ( ( ) )
5580
5710
}
5581
5711
0 commit comments