test_dist_info.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. """Test .dist-info style distributions."""
  2. import pathlib
  3. import re
  4. import shutil
  5. import subprocess
  6. import sys
  7. from functools import partial
  8. import pytest
  9. from setuptools.archive_util import unpack_archive
  10. from .textwrap import DALS
  11. read = partial(pathlib.Path.read_text, encoding="utf-8")
  12. class TestDistInfo:
  13. def test_invalid_version(self, tmp_path):
  14. """
  15. Supplying an invalid version crashes dist_info.
  16. """
  17. config = "[metadata]\nname=proj\nversion=42\n[egg_info]\ntag_build=invalid!!!\n"
  18. (tmp_path / "setup.cfg").write_text(config, encoding="utf-8")
  19. msg = re.compile("invalid version", re.MULTILINE | re.IGNORECASE)
  20. proc = run_command_inner("dist_info", cwd=tmp_path, check=False)
  21. assert proc.returncode
  22. assert msg.search(proc.stdout)
  23. assert not list(tmp_path.glob("*.dist-info"))
  24. def test_tag_arguments(self, tmp_path):
  25. config = """
  26. [metadata]
  27. name=proj
  28. version=42
  29. [egg_info]
  30. tag_date=1
  31. tag_build=.post
  32. """
  33. (tmp_path / "setup.cfg").write_text(config, encoding="utf-8")
  34. print(run_command("dist_info", "--no-date", cwd=tmp_path))
  35. dist_info = next(tmp_path.glob("*.dist-info"))
  36. assert dist_info.name.startswith("proj-42")
  37. shutil.rmtree(dist_info)
  38. print(run_command("dist_info", "--tag-build", ".a", cwd=tmp_path))
  39. dist_info = next(tmp_path.glob("*.dist-info"))
  40. assert dist_info.name.startswith("proj-42a")
  41. @pytest.mark.parametrize("keep_egg_info", (False, True))
  42. def test_output_dir(self, tmp_path, keep_egg_info):
  43. config = "[metadata]\nname=proj\nversion=42\n"
  44. (tmp_path / "setup.cfg").write_text(config, encoding="utf-8")
  45. out = tmp_path / "__out"
  46. out.mkdir()
  47. opts = ["--keep-egg-info"] if keep_egg_info else []
  48. run_command("dist_info", "--output-dir", out, *opts, cwd=tmp_path)
  49. assert len(list(out.glob("*.dist-info"))) == 1
  50. assert len(list(tmp_path.glob("*.dist-info"))) == 0
  51. expected_egg_info = int(keep_egg_info)
  52. assert len(list(out.glob("*.egg-info"))) == expected_egg_info
  53. assert len(list(tmp_path.glob("*.egg-info"))) == 0
  54. assert len(list(out.glob("*.__bkp__"))) == 0
  55. assert len(list(tmp_path.glob("*.__bkp__"))) == 0
  56. class TestWheelCompatibility:
  57. """Make sure the .dist-info directory produced with the ``dist_info`` command
  58. is the same as the one produced by ``bdist_wheel``.
  59. """
  60. SETUPCFG = DALS(
  61. """
  62. [metadata]
  63. name = {name}
  64. version = {version}
  65. [options]
  66. install_requires =
  67. foo>=12; sys_platform != "linux"
  68. [options.extras_require]
  69. test = pytest
  70. [options.entry_points]
  71. console_scripts =
  72. executable-name = my_package.module:function
  73. discover =
  74. myproj = my_package.other_module:function
  75. """
  76. )
  77. EGG_INFO_OPTS = [
  78. # Related: #3088 #2872
  79. ("", ""),
  80. (".post", "[egg_info]\ntag_build = post\n"),
  81. (".post", "[egg_info]\ntag_build = .post\n"),
  82. (".post", "[egg_info]\ntag_build = post\ntag_date = 1\n"),
  83. (".dev", "[egg_info]\ntag_build = .dev\n"),
  84. (".dev", "[egg_info]\ntag_build = .dev\ntag_date = 1\n"),
  85. ("a1", "[egg_info]\ntag_build = .a1\n"),
  86. ("+local", "[egg_info]\ntag_build = +local\n"),
  87. ]
  88. @pytest.mark.parametrize("name", "my-proj my_proj my.proj My.Proj".split())
  89. @pytest.mark.parametrize("version", ["0.42.13"])
  90. @pytest.mark.parametrize(("suffix", "cfg"), EGG_INFO_OPTS)
  91. def test_dist_info_is_the_same_as_in_wheel(
  92. self, name, version, tmp_path, suffix, cfg
  93. ):
  94. config = self.SETUPCFG.format(name=name, version=version) + cfg
  95. for i in "dir_wheel", "dir_dist":
  96. (tmp_path / i).mkdir()
  97. (tmp_path / i / "setup.cfg").write_text(config, encoding="utf-8")
  98. run_command("bdist_wheel", cwd=tmp_path / "dir_wheel")
  99. wheel = next(tmp_path.glob("dir_wheel/dist/*.whl"))
  100. unpack_archive(wheel, tmp_path / "unpack")
  101. wheel_dist_info = next(tmp_path.glob("unpack/*.dist-info"))
  102. run_command("dist_info", cwd=tmp_path / "dir_dist")
  103. dist_info = next(tmp_path.glob("dir_dist/*.dist-info"))
  104. assert dist_info.name == wheel_dist_info.name
  105. assert dist_info.name.startswith(f"my_proj-{version}{suffix}")
  106. for file in "METADATA", "entry_points.txt":
  107. assert read(dist_info / file) == read(wheel_dist_info / file)
  108. def run_command_inner(*cmd, **kwargs):
  109. opts = {
  110. "stderr": subprocess.STDOUT,
  111. "stdout": subprocess.PIPE,
  112. "text": True,
  113. "encoding": "utf-8",
  114. "check": True,
  115. **kwargs,
  116. }
  117. cmd = [sys.executable, "-c", "__import__('setuptools').setup()", *map(str, cmd)]
  118. return subprocess.run(cmd, **opts)
  119. def run_command(*args, **kwargs):
  120. return run_command_inner(*args, **kwargs).stdout