test_files.py
Go to the documentation of this file.
1 from __future__ import annotations
2 
3 import contextlib
4 import os
5 import string
6 import subprocess
7 import sys
8 import tarfile
9 import zipfile
10 
11 # These tests must be run explicitly
12 # They require CMake 3.15+ (--install)
13 
14 DIR = os.path.abspath(os.path.dirname(__file__))
15 MAIN_DIR = os.path.dirname(os.path.dirname(DIR))
16 
17 PKGCONFIG = """\
18 prefix=${{pcfiledir}}/../../
19 includedir=${{prefix}}/include
20 
21 Name: pybind11
22 Description: Seamless operability between C++11 and Python
23 Version: {VERSION}
24 Cflags: -I${{includedir}}
25 """
26 
27 
28 main_headers = {
29  "include/pybind11/attr.h",
30  "include/pybind11/buffer_info.h",
31  "include/pybind11/cast.h",
32  "include/pybind11/chrono.h",
33  "include/pybind11/common.h",
34  "include/pybind11/complex.h",
35  "include/pybind11/eigen.h",
36  "include/pybind11/embed.h",
37  "include/pybind11/eval.h",
38  "include/pybind11/functional.h",
39  "include/pybind11/gil.h",
40  "include/pybind11/gil_safe_call_once.h",
41  "include/pybind11/iostream.h",
42  "include/pybind11/numpy.h",
43  "include/pybind11/operators.h",
44  "include/pybind11/options.h",
45  "include/pybind11/pybind11.h",
46  "include/pybind11/pytypes.h",
47  "include/pybind11/stl.h",
48  "include/pybind11/stl_bind.h",
49  "include/pybind11/type_caster_pyobject_ptr.h",
50  "include/pybind11/typing.h",
51 }
52 
53 detail_headers = {
54  "include/pybind11/detail/class.h",
55  "include/pybind11/detail/common.h",
56  "include/pybind11/detail/cpp_conduit.h",
57  "include/pybind11/detail/descr.h",
58  "include/pybind11/detail/init.h",
59  "include/pybind11/detail/internals.h",
60  "include/pybind11/detail/type_caster_base.h",
61  "include/pybind11/detail/typeid.h",
62  "include/pybind11/detail/value_and_holder.h",
63  "include/pybind11/detail/exception_translation.h",
64 }
65 
66 eigen_headers = {
67  "include/pybind11/eigen/common.h",
68  "include/pybind11/eigen/matrix.h",
69  "include/pybind11/eigen/tensor.h",
70 }
71 
72 stl_headers = {
73  "include/pybind11/stl/filesystem.h",
74 }
75 
76 eigen_headers = {
77  "include/pybind11/eigen/common.h",
78  "include/pybind11/eigen/matrix.h",
79  "include/pybind11/eigen/tensor.h",
80 }
81 
82 stl_headers = {
83  "include/pybind11/stl/filesystem.h",
84 }
85 
86 cmake_files = {
87  "share/cmake/pybind11/FindPythonLibsNew.cmake",
88  "share/cmake/pybind11/pybind11Common.cmake",
89  "share/cmake/pybind11/pybind11Config.cmake",
90  "share/cmake/pybind11/pybind11ConfigVersion.cmake",
91  "share/cmake/pybind11/pybind11GuessPythonExtSuffix.cmake",
92  "share/cmake/pybind11/pybind11NewTools.cmake",
93  "share/cmake/pybind11/pybind11Targets.cmake",
94  "share/cmake/pybind11/pybind11Tools.cmake",
95 }
96 
97 pkgconfig_files = {
98  "share/pkgconfig/pybind11.pc",
99 }
100 
101 py_files = {
102  "__init__.py",
103  "__main__.py",
104  "_version.py",
105  "commands.py",
106  "py.typed",
107  "setup_helpers.py",
108 }
109 
110 headers = main_headers | detail_headers | eigen_headers | stl_headers
111 src_files = headers | cmake_files | pkgconfig_files
112 all_files = src_files | py_files
113 
114 
115 sdist_files = {
116  "pybind11",
117  "pybind11/include",
118  "pybind11/include/pybind11",
119  "pybind11/include/pybind11/detail",
120  "pybind11/include/pybind11/eigen",
121  "pybind11/include/pybind11/stl",
122  "pybind11/share",
123  "pybind11/share/cmake",
124  "pybind11/share/cmake/pybind11",
125  "pybind11/share/pkgconfig",
126  "pyproject.toml",
127  "setup.cfg",
128  "setup.py",
129  "LICENSE",
130  "MANIFEST.in",
131  "README.rst",
132  "PKG-INFO",
133  "SECURITY.md",
134 }
135 
136 local_sdist_files = {
137  ".egg-info",
138  ".egg-info/PKG-INFO",
139  ".egg-info/SOURCES.txt",
140  ".egg-info/dependency_links.txt",
141  ".egg-info/not-zip-safe",
142  ".egg-info/top_level.txt",
143 }
144 
145 
146 def read_tz_file(tar: tarfile.TarFile, name: str) -> bytes:
147  start = tar.getnames()[0] + "/"
148  inner_file = tar.extractfile(tar.getmember(f"{start}{name}"))
149  assert inner_file
150  with contextlib.closing(inner_file) as f:
151  return f.read()
152 
153 
154 def normalize_line_endings(value: bytes) -> bytes:
155  return value.replace(os.linesep.encode("utf-8"), b"\n")
156 
157 
158 def test_build_sdist(monkeypatch, tmpdir):
159  monkeypatch.chdir(MAIN_DIR)
160 
161  subprocess.run(
162  [sys.executable, "-m", "build", "--sdist", f"--outdir={tmpdir}"], check=True
163  )
164 
165  (sdist,) = tmpdir.visit("*.tar.gz")
166 
167  with tarfile.open(str(sdist), "r:gz") as tar:
168  start = tar.getnames()[0] + "/"
169  version = start[9:-1]
170  simpler = {n.split("/", 1)[-1] for n in tar.getnames()[1:]}
171 
172  setup_py = read_tz_file(tar, "setup.py")
173  pyproject_toml = read_tz_file(tar, "pyproject.toml")
174  pkgconfig = read_tz_file(tar, "pybind11/share/pkgconfig/pybind11.pc")
175  cmake_cfg = read_tz_file(
176  tar, "pybind11/share/cmake/pybind11/pybind11Config.cmake"
177  )
178 
179  assert (
180  'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")'
181  in cmake_cfg.decode("utf-8")
182  )
183 
184  files = {f"pybind11/{n}" for n in all_files}
185  files |= sdist_files
186  files |= {f"pybind11{n}" for n in local_sdist_files}
187  files.add("pybind11.egg-info/entry_points.txt")
188  files.add("pybind11.egg-info/requires.txt")
189  assert simpler == files
190 
191  with open(os.path.join(MAIN_DIR, "tools", "setup_main.py.in"), "rb") as f:
192  contents = (
193  string.Template(f.read().decode("utf-8"))
194  .substitute(version=version, extra_cmd="")
195  .encode("utf-8")
196  )
197  assert setup_py == contents
198 
199  with open(os.path.join(MAIN_DIR, "tools", "pyproject.toml"), "rb") as f:
200  contents = f.read()
201  assert pyproject_toml == contents
202 
203  simple_version = ".".join(version.split(".")[:3])
204  pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode("utf-8")
205  assert normalize_line_endings(pkgconfig) == pkgconfig_expected
206 
207 
208 def test_build_global_dist(monkeypatch, tmpdir):
209  monkeypatch.chdir(MAIN_DIR)
210  monkeypatch.setenv("PYBIND11_GLOBAL_SDIST", "1")
211  subprocess.run(
212  [sys.executable, "-m", "build", "--sdist", "--outdir", str(tmpdir)], check=True
213  )
214 
215  (sdist,) = tmpdir.visit("*.tar.gz")
216 
217  with tarfile.open(str(sdist), "r:gz") as tar:
218  start = tar.getnames()[0] + "/"
219  version = start[16:-1]
220  simpler = {n.split("/", 1)[-1] for n in tar.getnames()[1:]}
221 
222  setup_py = read_tz_file(tar, "setup.py")
223  pyproject_toml = read_tz_file(tar, "pyproject.toml")
224  pkgconfig = read_tz_file(tar, "pybind11/share/pkgconfig/pybind11.pc")
225  cmake_cfg = read_tz_file(
226  tar, "pybind11/share/cmake/pybind11/pybind11Config.cmake"
227  )
228 
229  assert (
230  'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")'
231  in cmake_cfg.decode("utf-8")
232  )
233 
234  files = {f"pybind11/{n}" for n in all_files}
235  files |= sdist_files
236  files |= {f"pybind11_global{n}" for n in local_sdist_files}
237  assert simpler == files
238 
239  with open(os.path.join(MAIN_DIR, "tools", "setup_global.py.in"), "rb") as f:
240  contents = (
241  string.Template(f.read().decode())
242  .substitute(version=version, extra_cmd="")
243  .encode("utf-8")
244  )
245  assert setup_py == contents
246 
247  with open(os.path.join(MAIN_DIR, "tools", "pyproject.toml"), "rb") as f:
248  contents = f.read()
249  assert pyproject_toml == contents
250 
251  simple_version = ".".join(version.split(".")[:3])
252  pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode("utf-8")
253  assert normalize_line_endings(pkgconfig) == pkgconfig_expected
254 
255 
256 def tests_build_wheel(monkeypatch, tmpdir):
257  monkeypatch.chdir(MAIN_DIR)
258 
259  subprocess.run(
260  [sys.executable, "-m", "pip", "wheel", ".", "-w", str(tmpdir)], check=True
261  )
262 
263  (wheel,) = tmpdir.visit("*.whl")
264 
265  files = {f"pybind11/{n}" for n in all_files}
266  files |= {
267  "dist-info/LICENSE",
268  "dist-info/METADATA",
269  "dist-info/RECORD",
270  "dist-info/WHEEL",
271  "dist-info/entry_points.txt",
272  "dist-info/top_level.txt",
273  }
274 
275  with zipfile.ZipFile(str(wheel)) as z:
276  names = z.namelist()
277 
278  trimmed = {n for n in names if "dist-info" not in n}
279  trimmed |= {f"dist-info/{n.split('/', 1)[-1]}" for n in names if "dist-info" in n}
280  assert files == trimmed
281 
282 
283 def tests_build_global_wheel(monkeypatch, tmpdir):
284  monkeypatch.chdir(MAIN_DIR)
285  monkeypatch.setenv("PYBIND11_GLOBAL_SDIST", "1")
286 
287  subprocess.run(
288  [sys.executable, "-m", "pip", "wheel", ".", "-w", str(tmpdir)], check=True
289  )
290 
291  (wheel,) = tmpdir.visit("*.whl")
292 
293  files = {f"data/data/{n}" for n in src_files}
294  files |= {f"data/headers/{n[8:]}" for n in headers}
295  files |= {
296  "dist-info/LICENSE",
297  "dist-info/METADATA",
298  "dist-info/WHEEL",
299  "dist-info/top_level.txt",
300  "dist-info/RECORD",
301  }
302 
303  with zipfile.ZipFile(str(wheel)) as z:
304  names = z.namelist()
305 
306  beginning = names[0].split("/", 1)[0].rsplit(".", 1)[0]
307  trimmed = {n[len(beginning) + 1 :] for n in names}
308 
309  assert files == trimmed
test_files.test_build_sdist
def test_build_sdist(monkeypatch, tmpdir)
Definition: test_files.py:158
encode
int encode(Index i, Index j)
Definition: indexed_view.cpp:45
test_files.tests_build_global_wheel
def tests_build_global_wheel(monkeypatch, tmpdir)
Definition: test_files.py:283
test_files.test_build_global_dist
def test_build_global_dist(monkeypatch, tmpdir)
Definition: test_files.py:208
test_files.tests_build_wheel
def tests_build_wheel(monkeypatch, tmpdir)
Definition: test_files.py:256
decode
IndexPair decode(Index ij)
Definition: indexed_view.cpp:49
str
Definition: pytypes.h:1560
test_files.normalize_line_endings
bytes normalize_line_endings(bytes value)
Definition: test_files.py:154
gtsam::split
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
Definition: graph-inl.h:245
len
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2448
test_files.read_tz_file
bytes read_tz_file(tarfile.TarFile tar, str name)
Definition: test_files.py:146


gtsam
Author(s):
autogenerated on Fri Mar 28 2025 03:06:28