1import email 2import zipfile 3 4import pytest 5 6from pdm.pep517 import api 7from tests.testutils import build_fixture_project, get_tarball_names, get_wheel_names 8 9 10def test_build_single_module(tmp_path): 11 with build_fixture_project("demo-module"): 12 wheel_name = api.build_wheel(tmp_path.as_posix()) 13 sdist_name = api.build_sdist(tmp_path.as_posix()) 14 assert api.get_requires_for_build_sdist() == [] 15 assert api.get_requires_for_build_wheel() == [] 16 assert sdist_name == "demo-module-0.1.0.tar.gz" 17 assert wheel_name == "demo_module-0.1.0-py3-none-any.whl" 18 tar_names = get_tarball_names(tmp_path / sdist_name) 19 for name in [ 20 "foo_module.py", 21 "bar_module.py", 22 "LICENSE", 23 "pyproject.toml", 24 "PKG-INFO", 25 "README.md", 26 ]: 27 assert f"demo-module-0.1.0/{name}" in tar_names 28 29 zip_names = get_wheel_names(tmp_path / wheel_name) 30 for name in ["foo_module.py", "bar_module.py"]: 31 assert name in zip_names 32 33 for name in ("pyproject.toml", "LICENSE"): 34 assert name not in zip_names 35 36 37def test_build_package(tmp_path): 38 with build_fixture_project("demo-package"): 39 wheel_name = api.build_wheel(tmp_path.as_posix()) 40 sdist_name = api.build_sdist(tmp_path.as_posix()) 41 assert sdist_name == "demo-package-0.1.0.tar.gz" 42 assert wheel_name == "demo_package-0.1.0-py2.py3-none-any.whl" 43 44 tar_names = get_tarball_names(tmp_path / sdist_name) 45 assert "demo-package-0.1.0/my_package/__init__.py" in tar_names 46 assert "demo-package-0.1.0/my_package/data.json" in tar_names 47 assert "demo-package-0.1.0/single_module.py" not in tar_names 48 assert "demo-package-0.1.0/data_out.json" in tar_names 49 50 zip_names = get_wheel_names(tmp_path / wheel_name) 51 assert "my_package/__init__.py" in zip_names 52 assert "my_package/data.json" in zip_names 53 assert "single_module.py" not in zip_names 54 assert "data_out.json" not in zip_names 55 56 57def test_build_src_package(tmp_path): 58 with build_fixture_project("demo-src-package"): 59 wheel_name = api.build_wheel(tmp_path.as_posix()) 60 sdist_name = api.build_sdist(tmp_path.as_posix()) 61 assert sdist_name == "demo-package-0.1.0.tar.gz" 62 assert wheel_name == "demo_package-0.1.0-py3-none-any.whl" 63 64 tar_names = get_tarball_names(tmp_path / sdist_name) 65 zip_names = get_wheel_names(tmp_path / wheel_name) 66 assert "demo-package-0.1.0/src/my_package/__init__.py" in tar_names 67 assert "demo-package-0.1.0/src/my_package/data.json" in tar_names 68 69 assert "my_package/__init__.py" in zip_names 70 assert "my_package/data.json" in zip_names 71 72 73def test_build_package_include(tmp_path): 74 with build_fixture_project("demo-package-include"): 75 wheel_name = api.build_wheel(tmp_path.as_posix()) 76 sdist_name = api.build_sdist(tmp_path.as_posix()) 77 assert sdist_name == "demo-package-0.1.0.tar.gz" 78 assert wheel_name == "demo_package-0.1.0-py3-none-any.whl" 79 80 tar_names = get_tarball_names(tmp_path / sdist_name) 81 zip_names = get_wheel_names(tmp_path / wheel_name) 82 83 assert "demo-package-0.1.0/my_package/__init__.py" in tar_names 84 assert "demo-package-0.1.0/my_package/data.json" not in tar_names 85 assert "demo-package-0.1.0/requirements.txt" in tar_names 86 assert "demo-package-0.1.0/data_out.json" in tar_names 87 88 assert "my_package/__init__.py" in zip_names 89 assert "my_package/data.json" not in zip_names 90 assert "requirements.txt" in zip_names 91 assert "data_out.json" in zip_names 92 93 94def test_namespace_package_by_include(tmp_path): 95 with build_fixture_project("demo-pep420-package"): 96 wheel_name = api.build_wheel(tmp_path.as_posix()) 97 sdist_name = api.build_sdist(tmp_path.as_posix()) 98 assert sdist_name == "demo-package-0.1.0.tar.gz" 99 assert wheel_name == "demo_package-0.1.0-py3-none-any.whl" 100 101 tar_names = get_tarball_names(tmp_path / sdist_name) 102 zip_names = get_wheel_names(tmp_path / wheel_name) 103 assert "demo-package-0.1.0/foo/my_package/__init__.py" in tar_names 104 assert "demo-package-0.1.0/foo/my_package/data.json" in tar_names 105 106 assert "foo/my_package/__init__.py" in zip_names 107 assert "foo/my_package/data.json" in zip_names 108 109 110def test_build_explicit_package_dir(tmp_path): 111 with build_fixture_project("demo-explicit-package-dir"): 112 wheel_name = api.build_wheel(tmp_path.as_posix()) 113 sdist_name = api.build_sdist(tmp_path.as_posix()) 114 assert sdist_name == "demo-package-0.1.0.tar.gz" 115 assert wheel_name == "demo_package-0.1.0-py3-none-any.whl" 116 117 tar_names = get_tarball_names(tmp_path / sdist_name) 118 zip_names = get_wheel_names(tmp_path / wheel_name) 119 assert "demo-package-0.1.0/foo/my_package/__init__.py" in tar_names 120 assert "demo-package-0.1.0/foo/my_package/data.json" in tar_names 121 122 assert "my_package/__init__.py" in zip_names 123 assert "my_package/data.json" in zip_names 124 125 126def test_prepare_metadata(tmp_path): 127 with build_fixture_project("demo-package"): 128 dist_info = api.prepare_metadata_for_build_wheel(tmp_path.as_posix()) 129 assert dist_info == "demo_package-0.1.0.dist-info" 130 for filename in ("WHEEL", "METADATA"): 131 assert (tmp_path / dist_info / filename).is_file() 132 133 134@pytest.mark.xfail 135def test_build_legacypackage(tmp_path): 136 with build_fixture_project("demo-legacy"): 137 wheel_name = api.build_wheel(tmp_path.as_posix()) 138 sdist_name = api.build_sdist(tmp_path.as_posix()) 139 assert sdist_name == "demo-legacy-0.1.0.tar.gz" 140 assert wheel_name == "demo_legacy-0.1.0-py3-none-any.whl" 141 142 tar_names = get_tarball_names(tmp_path / sdist_name) 143 assert "demo-legacy-0.1.0/my_package/__init__.py" in tar_names 144 assert "demo-legacy-0.1.0/my_package/data.json" in tar_names 145 assert "demo-legacy-0.1.0/single_module.py" not in tar_names 146 assert "demo-legacy-0.1.0/data_out.json" not in tar_names 147 148 zip_names = get_wheel_names(tmp_path / wheel_name) 149 assert "my_package/__init__.py" in zip_names 150 assert "my_package/data.json" in zip_names 151 assert "single_module.py" not in zip_names 152 assert "data_out.json" not in zip_names 153 154 155def test_build_package_with_modules_in_src(tmp_path): 156 with build_fixture_project("demo-src-pymodule"): 157 wheel_name = api.build_wheel(tmp_path.as_posix()) 158 sdist_name = api.build_sdist(tmp_path.as_posix()) 159 160 tar_names = get_tarball_names(tmp_path / sdist_name) 161 assert "demo-module-0.1.0/src/foo_module.py" in tar_names 162 163 zip_names = get_wheel_names(tmp_path / wheel_name) 164 assert "foo_module.py" in zip_names 165 166 167def test_build_with_cextension(tmp_path): 168 with build_fixture_project("demo-cextension"): 169 wheel_name = api.build_wheel(tmp_path.as_posix()) 170 sdist_name = api.build_sdist(tmp_path.as_posix()) 171 assert api.get_requires_for_build_sdist() == [] 172 assert api.get_requires_for_build_wheel() == ["setuptools>=40.8.0"] 173 174 zip_names = get_wheel_names(tmp_path / wheel_name) 175 assert "my_package/__init__.py" in zip_names 176 assert ( 177 "my_package/hellomodule.c" not in zip_names 178 ), "Not collect c files while building wheel" 179 180 tar_names = get_tarball_names(tmp_path / sdist_name) 181 assert "demo-package-0.1.0/my_package/__init__.py" in tar_names 182 assert ( 183 "demo-package-0.1.0/my_package/hellomodule.c" in tar_names 184 ), "Collect c files while building sdist" 185 assert not any( 186 path.startswith("build") for path in tar_names 187 ), 'Not collect c files in temporary directory "./build"' 188 189 190def test_build_with_cextension_in_src(tmp_path): 191 with build_fixture_project("demo-cextension-in-src"): 192 wheel_name = api.build_wheel(tmp_path.as_posix()) 193 sdist_name = api.build_sdist(tmp_path.as_posix()) 194 195 zip_names = get_wheel_names(tmp_path / wheel_name) 196 assert "my_package/__init__.py" in zip_names 197 assert ( 198 "my_package/hellomodule.c" not in zip_names 199 ), "Not collect c files while building wheel" 200 201 tar_names = get_tarball_names(tmp_path / sdist_name) 202 assert "demo-package-0.1.0/src/my_package/__init__.py" in tar_names 203 assert ( 204 "demo-package-0.1.0/src/my_package/hellomodule.c" in tar_names 205 ), "Collect c files while building sdist" 206 assert not any( 207 path.startswith("build") for path in tar_names 208 ), 'Not collect c files in temporary directory "./build"' 209 210 211def test_build_editable(tmp_path): 212 with build_fixture_project("demo-package") as project: 213 wheel_name = api.build_editable(tmp_path.as_posix()) 214 assert api.get_requires_for_build_editable() == [] 215 with zipfile.ZipFile(tmp_path / wheel_name) as zf: 216 namelist = zf.namelist() 217 assert "demo_package.pth" in namelist 218 assert "_demo_package.py" in namelist 219 220 metadata = email.message_from_bytes( 221 zf.read("demo_package-0.1.0.dist-info/METADATA") 222 ) 223 assert "editables" in metadata.get_all("Requires-Dist", []) 224 225 pth_content = zf.read("demo_package.pth").decode("utf-8").strip() 226 assert pth_content == "import _demo_package" 227 228 proxy_module = zf.read("_demo_package.py").decode("utf-8").strip() 229 assert proxy_module == ( 230 "from editables.redirector import RedirectingFinder as F\n" 231 "F.install()\n" 232 "F.map_module('my_package', {0!r})".format( 233 str((project / "my_package" / "__init__.py").resolve()) 234 ) 235 ) 236 237 238def test_build_editable_src(tmp_path): 239 with build_fixture_project("demo-src-package-include") as project: 240 wheel_name = api.build_editable(tmp_path.as_posix()) 241 242 with zipfile.ZipFile(tmp_path / wheel_name) as zf: 243 namelist = zf.namelist() 244 assert "demo_package.pth" in namelist 245 assert "_demo_package.py" in namelist 246 assert "my_package/data.json" not in namelist 247 assert "data_out.json" in namelist 248 249 pth_content = zf.read("demo_package.pth").decode("utf-8").strip() 250 assert pth_content == "import _demo_package" 251 252 proxy_module = zf.read("_demo_package.py").decode("utf-8").strip() 253 assert proxy_module == ( 254 "from editables.redirector import RedirectingFinder as F\n" 255 "F.install()\n" 256 "F.map_module('my_package', {0!r})".format( 257 str((project / "sub" / "my_package" / "__init__.py").resolve()) 258 ) 259 ) 260 261 262def test_build_editable_pep420(tmp_path): 263 with build_fixture_project("demo-pep420-package") as project: 264 wheel_name = api.build_editable(tmp_path.as_posix()) 265 266 with zipfile.ZipFile(tmp_path / wheel_name) as zf: 267 namelist = zf.namelist() 268 assert "demo_package.pth" in namelist 269 assert "_demo_package.py" not in namelist 270 271 metadata = email.message_from_bytes( 272 zf.read("demo_package-0.1.0.dist-info/METADATA") 273 ) 274 assert "editables" not in metadata.get_all("Requires-Dist", []) 275 276 pth_content = zf.read("demo_package.pth").decode("utf-8").strip() 277 assert pth_content == str(project.resolve()) 278