@@ -18,7 +18,6 @@ class TestParseUnparseable:
1818 [
1919 "" ,
2020 "latest" ,
21- "R4.3.3-python3.11.15" ,
2221 "v1.2.3" ,
2322 "not a version" ,
2423 "1" , # only one release component
@@ -59,6 +58,10 @@ class TestParseRoundtrip:
5958 ("2026.4.0-rc.1" , (2026 , 4 , 0 ), "rc.1" , None ),
6059 # Edge: build only.
6160 ("2026.4.0+abc" , (2026 , 4 , 0 ), None , "abc" ),
61+ # Dep-prefixed: single and compound matrix versions.
62+ ("R4.3.3" , (4 , 3 , 3 ), None , None ),
63+ ("python3.13.14" , (3 , 13 , 14 ), None , None ),
64+ ("R4.3.3-python3.11.15" , (4 , 3 , 3 ), None , None ),
6265 ],
6366 )
6467 def test_parses_and_roundtrips (self , value , release , prerelease , build , caplog ):
@@ -185,3 +188,26 @@ def mock_iv(name: str, *, is_matrix: bool = False) -> MagicMock:
185188 # (Python's sort is stable). Parseable entries follow in ascending order.
186189 assert names [:2 ] == ["R4.3.3-python3.11.15" , "garbage" ]
187190 assert names [2 :] == ["2026.04.0" , "2026.04.1" , "2026.05.0-dev+62-g1ca9367735" ]
191+
192+
193+ class TestDepVersions :
194+ @pytest .mark .parametrize (
195+ "value,expected" ,
196+ [
197+ ("R4.3.3" , (("R" , (4 , 3 , 3 )),)),
198+ ("python3.13.14" , (("python" , (3 , 13 , 14 )),)),
199+ ("R4.3.3-python3.11.15" , (("R" , (4 , 3 , 3 )), ("python" , (3 , 11 , 15 )))),
200+ ("R4.3-python3.11-quarto1.4" , (("R" , (4 , 3 )), ("python" , (3 , 11 )), ("quarto" , (1 , 4 )))),
201+ ],
202+ )
203+ def test_dep_versions_populated (self , value , expected , caplog ):
204+ caplog .set_level (logging .WARNING )
205+ parsed = ParsedVersion .parse (value )
206+ assert parsed is not None
207+ assert parsed .dep_versions == expected
208+ assert not [r for r in caplog .records if r .levelno >= logging .WARNING ]
209+
210+ def test_pure_calver_has_no_dep_versions (self ):
211+ parsed = ParsedVersion .parse ("2026.04.0-dev+92" )
212+ assert parsed is not None
213+ assert parsed .dep_versions is None
0 commit comments