11"""Tests for detect_native.py sdist configure tool."""
22
33import io
4- import json
54import os
65import sys
76import tarfile
109
1110from uv .private .sdist_configure .detect_native import detect
1211
13- try :
14- import tomllib
15- HAS_TOMLLIB = True
16- except ModuleNotFoundError :
17- HAS_TOMLLIB = False
18-
19-
20- class _Skip (Exception ):
21- """Raised to skip a test."""
22-
23-
24- def requires_tomllib (fn ):
25- """Skip test if tomllib is not available (Python < 3.11)."""
26- def wrapper ():
27- if not HAS_TOMLLIB :
28- raise _Skip ("requires Python >= 3.11 (tomllib)" )
29- return fn ()
30- wrapper .__name__ = fn .__name__
31- return wrapper
32-
3312
3413def _make_tar_gz (members ):
3514 """Create a .tar.gz archive in a temp file from a dict of {name: content}.
@@ -142,7 +121,6 @@ def test_rust():
142121# --- pyproject.toml parsing ---
143122
144123
145- @requires_tomllib
146124def test_pyproject_build_requires ():
147125 pyproject = """\
148126 [build-system]
@@ -160,6 +138,25 @@ def test_pyproject_build_requires():
160138 assert "cython" in result ["build_requires" ]
161139
162140
141+ def test_pyproject_degrades_without_tomllib ():
142+ """On a pre-3.11 interpreter, pyproject parsing is skipped with a warning
143+ while the rest of the tool (native detection etc.) keeps working."""
144+ from uv .private .sdist_configure import detect_native
145+ archive = _make_tar_gz ({
146+ "pkg-1.0/" : None ,
147+ "pkg-1.0/pyproject.toml" : '[build-system]\n requires = ["cython"]\n ' ,
148+ "pkg-1.0/pkg/fast.pyx" : "# cython source" ,
149+ })
150+ saved = detect_native .tomllib
151+ detect_native .tomllib = None
152+ try :
153+ result = detect (archive , {})
154+ finally :
155+ detect_native .tomllib = saved
156+ assert result ["build_requires" ] == []
157+ assert result ["is_native" ] is True
158+
159+
163160# --- setup.cfg parsing ---
164161
165162
@@ -195,7 +192,6 @@ def test_legacy_setup_py_infers_setuptools():
195192 assert "wheel" in result ["build_requires" ]
196193
197194
198- @requires_tomllib
199195def test_pyproject_does_not_infer_setuptools ():
200196 """A package with pyproject.toml should NOT get implicit setuptools."""
201197 archive = _make_tar_gz ({
@@ -215,7 +211,6 @@ def test_pyproject_does_not_infer_setuptools():
215211# --- extra_deps resolution ---
216212
217213
218- @requires_tomllib
219214def test_extra_deps_resolved_from_available ():
220215 """Declared build deps that exist in available_deps become extra_deps."""
221216 pyproject = """\
@@ -240,7 +235,6 @@ def test_extra_deps_resolved_from_available():
240235 assert "cython" in result ["extra_deps" ]
241236
242237
243- @requires_tomllib
244238def test_extra_deps_excludes_already_provided ():
245239 """Deps already in the explicit deps list are not reported as extra."""
246240 pyproject = """\
@@ -266,7 +260,6 @@ def test_extra_deps_excludes_already_provided():
266260 assert "cython" in result ["extra_deps" ]
267261
268262
269- @requires_tomllib
270263def test_extra_deps_unresolvable_not_included ():
271264 """Deps not in available_deps are silently omitted from extra_deps."""
272265 pyproject = """\
@@ -324,7 +317,6 @@ def test_zip_archive():
324317 assert "pkg-1.0/pkg/ext.c" in result ["native_files" ]
325318
326319
327- @requires_tomllib
328320def test_zip_archive_with_pyproject ():
329321 archive = _make_zip ({
330322 "pkg-1.0/pkg/__init__.py" : "" ,
@@ -342,7 +334,6 @@ def test_zip_archive_with_pyproject():
342334# --- Config files at root (no top-level directory) ---
343335
344336
345- @requires_tomllib
346337def test_flat_archive ():
347338 """Some archives don't have a top-level directory prefix."""
348339 archive = _make_tar_gz ({
@@ -757,22 +748,18 @@ def test_setup_cfg_and_setup_py_merged():
757748
758749if __name__ == "__main__" :
759750 failures = []
760- skipped = []
761751 test_fns = [v for k , v in sorted (globals ().items ()) if k .startswith ("test_" ) and callable (v )]
762752 for fn in test_fns :
763753 try :
764754 fn ()
765755 print (f" PASS { fn .__name__ } " )
766- except _Skip as e :
767- print (f" SKIP { fn .__name__ } : { e } " )
768- skipped .append (fn .__name__ )
769756 except Exception as e :
770757 print (f" FAIL { fn .__name__ } : { e } " )
771758 failures .append (fn .__name__ )
772759
773760 total = len (test_fns )
774- passed = total - len (failures ) - len ( skipped )
775- print (f"\n { passed } passed, { len (skipped ) } skipped, { len ( failures )} failed (of { total } )" )
761+ passed = total - len (failures )
762+ print (f"\n { passed } passed, { len (failures )} failed (of { total } )" )
776763 if failures :
777764 print (f"Failures: { ', ' .join (failures )} " )
778765 sys .exit (1 )
0 commit comments