11import os
22import pathlib
3+ import tempfile
4+
5+ import pytest
36
47from rsconnect .pyproject import (
8+ detect_python_version_requirement ,
9+ get_python_version_requirement_parser ,
510 lookup_metadata_file ,
611 parse_pyproject_python_requires ,
7- parse_setupcfg_python_requires ,
812 parse_pyversion_python_requires ,
9- get_python_version_requirement_parser ,
10- detect_python_version_requirement ,
13+ parse_setupcfg_python_requires ,
14+ InvalidVersionConstraintError ,
1115)
1216
13- import pytest
14-
1517HERE = os .path .dirname (__file__ )
1618PROJECTS_DIRECTORY = os .path .abspath (os .path .join (HERE , "testdata" , "python-project" ))
1719
@@ -117,7 +119,7 @@ def test_setupcfg_python_requires(project_dir, expected):
117119@pytest .mark .parametrize (
118120 "project_dir, expected" ,
119121 [
120- (os .path .join (PROJECTS_DIRECTORY , "using_pyversion" ), ">=3.8, <3.12" ),
122+ (os .path .join (PROJECTS_DIRECTORY , "using_pyversion" ), ">=3.8,<3.12" ),
121123 ],
122124 ids = ["option-exists" ],
123125)
@@ -139,6 +141,60 @@ def test_detect_python_version_requirement():
139141 version requirement is used.
140142 """
141143 project_dir = os .path .join (PROJECTS_DIRECTORY , "allofthem" )
142- assert detect_python_version_requirement (project_dir ) == ">=3.8, <3.12"
144+ assert detect_python_version_requirement (project_dir ) == ">=3.8,<3.12"
143145
144146 assert detect_python_version_requirement (os .path .join (PROJECTS_DIRECTORY , "empty" )) is None
147+
148+
149+ @pytest .mark .parametrize ( # type: ignore
150+ ["content" , "expected" ],
151+ [
152+ ("3.8" , "~=3.8" ),
153+ ("3.8.0" , "~=3.8" ),
154+ ("3.8.0b1" , InvalidVersionConstraintError ("pre-release versions are not supported: 3.8.0b1" )),
155+ ("3.8.0rc1" , InvalidVersionConstraintError ("pre-release versions are not supported: 3.8.0rc1" )),
156+ ("3.8.0a1" , InvalidVersionConstraintError ("pre-release versions are not supported: 3.8.0a1" )),
157+ ("3.8.*" , "==3.8.*" ),
158+ ("3.*" , "==3.*" ),
159+ ("*" , InvalidVersionConstraintError ("Invalid python version: *" )),
160+ # This is not perfect, but the added regex complexity doesn't seem worth it.
161+ ("invalid" , InvalidVersionConstraintError ("pre-release versions are not supported: invalid" )),
162+ ("[email protected] " , InvalidVersionConstraintError ("python specific implementations are not supported: [email protected] " )), 163+ (
164+ "cpython-3.12.3-macos-aarch64-none" ,
165+ InvalidVersionConstraintError (
166+ "python specific implementations are not supported: cpython-3.12.3-macos-aarch64-none"
167+ ),
168+ ),
169+ (
170+ "/usr/bin/python3.8" ,
171+ InvalidVersionConstraintError ("python specific implementations are not supported: /usr/bin/python3.8" ),
172+ ),
173+ (">=3.8,<3.10" , ">=3.8,<3.10" ),
174+ (">=3.8, <*" , ValueError ("Invalid python version: <*" )),
175+ ],
176+ )
177+ def test_python_version_file_adapt (content , expected ):
178+ """Test that the python version is correctly converted to a PEP440 format.
179+
180+ Connect expects a PEP440 format, but the .python-version file can contain
181+ plain version numbers and other formats.
182+
183+ We should convert them to the constraints that connect expects.
184+ """
185+ with tempfile .TemporaryDirectory () as tmpdir :
186+ versionfile = pathlib .Path (tmpdir ) / ".python-version"
187+ with open (versionfile , "w" ) as tmpfile :
188+ tmpfile .write (content )
189+
190+ try :
191+ if isinstance (expected , Exception ):
192+ with pytest .raises (expected .__class__ ) as excinfo :
193+ parse_pyversion_python_requires (versionfile )
194+ assert str (excinfo .value ) == expected .args [0 ]
195+ assert detect_python_version_requirement (tmpdir ) is None
196+ else :
197+ assert parse_pyversion_python_requires (versionfile ) == expected
198+ assert detect_python_version_requirement (tmpdir ) == expected
199+ finally :
200+ os .remove (tmpfile .name )
0 commit comments