@@ -380,6 +380,17 @@ def test_pinned_older_tag_still_runs_installer(
380380 assert "Upgrading specify-cli 0.7.6 → v0.7.5 via uv tool:" in out
381381 assert mock_run .call_count == 2
382382
383+ def test_pinned_rc_tag_uses_canonical_version_equality_for_noop (
384+ self , uv_tool_argv0 , clean_environ
385+ ):
386+ with patch ("specify_cli.shutil.which" , return_value = "/usr/bin/uv" ), patch (
387+ "specify_cli._get_installed_version" , return_value = "1.0.0rc1"
388+ ):
389+ result = runner .invoke (app , ["self" , "upgrade" , "--tag" , "v1.0.0-rc1" ])
390+
391+ assert result .exit_code == 0
392+ assert "Already on requested release: v1.0.0-rc1" in strip_ansi (result .output )
393+
383394
384395class TestDryRun_UvTool :
385396 """--dry-run preview path + --dry-run combined with --tag."""
@@ -1120,6 +1131,26 @@ def test_verify_nonzero_exit_is_not_treated_as_success(
11201131 assert "Verification failed" in out
11211132 assert "(unknown) (expected v0.7.6)" in out
11221133
1134+ def test_verify_accepts_pep440_equivalent_rc_version (
1135+ self ,
1136+ uv_tool_argv0 ,
1137+ clean_environ ,
1138+ ):
1139+ with patch ("specify_cli.urllib.request.urlopen" ) as mock_urlopen , patch (
1140+ "specify_cli.shutil.which" , return_value = "/usr/bin/uv"
1141+ ), patch ("specify_cli.subprocess.run" ) as mock_run , patch (
1142+ "specify_cli._get_installed_version" , return_value = "0.9.0"
1143+ ):
1144+ mock_urlopen .return_value = _mock_urlopen_response ({"tag_name" : "v9.9.9" })
1145+ mock_run .side_effect = [
1146+ _completed_process (0 ),
1147+ _completed_process (0 , stdout = "specify 1.0.0rc1\n " ),
1148+ ]
1149+ result = runner .invoke (app , ["self" , "upgrade" , "--tag" , "v1.0.0-rc1" ])
1150+
1151+ assert result .exit_code == 0
1152+ assert "Upgraded specify-cli: 0.9.0 → 1.0.0rc1" in strip_ansi (result .output )
1153+
11231154 def test_verify_uses_current_entrypoint_when_not_on_path (
11241155 self ,
11251156 uv_tool_argv0 ,
0 commit comments