wrap/pybind11/setup.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 # Setup script for PyPI; use CMakeFile.txt to build extension modules
5 
6 import contextlib
7 import os
8 import re
9 import shutil
10 import string
11 import subprocess
12 import sys
13 import tempfile
14 
15 import setuptools.command.sdist
16 
17 DIR = os.path.abspath(os.path.dirname(__file__))
18 VERSION_REGEX = re.compile(
19  r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE
20 )
21 
22 # PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers
23 # files, and the sys.prefix files (CMake and headers).
24 
25 global_sdist = os.environ.get("PYBIND11_GLOBAL_SDIST", False)
26 
27 setup_py = "tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in"
28 extra_cmd = 'cmdclass["sdist"] = SDist\n'
29 
30 to_src = (
31  ("pyproject.toml", "tools/pyproject.toml"),
32  ("setup.py", setup_py),
33 )
34 
35 # Read the listed version
36 with open("pybind11/_version.py") as f:
37  code = compile(f.read(), "pybind11/_version.py", "exec")
38  loc = {}
39  exec(code, loc)
40  version = loc["__version__"]
41 
42 # Verify that the version matches the one in C++
43 with open("include/pybind11/detail/common.h") as f:
44  matches = dict(VERSION_REGEX.findall(f.read()))
45 cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches)
46 if version != cpp_version:
47  msg = "Python version {} does not match C++ version {}!".format(
48  version, cpp_version
49  )
50  raise RuntimeError(msg)
51 
52 
53 def get_and_replace(filename, binary=False, **opts):
54  with open(filename, "rb" if binary else "r") as f:
55  contents = f.read()
56  # Replacement has to be done on text in Python 3 (both work in Python 2)
57  if binary:
58  return string.Template(contents.decode()).substitute(opts).encode()
59  else:
60  return string.Template(contents).substitute(opts)
61 
62 
63 # Use our input files instead when making the SDist (and anything that depends
64 # on it, like a wheel)
65 class SDist(setuptools.command.sdist.sdist):
66  def make_release_tree(self, base_dir, files):
67  setuptools.command.sdist.sdist.make_release_tree(self, base_dir, files)
68 
69  for to, src in to_src:
70  txt = get_and_replace(src, binary=True, version=version, extra_cmd="")
71 
72  dest = os.path.join(base_dir, to)
73 
74  # This is normally linked, so unlink before writing!
75  os.unlink(dest)
76  with open(dest, "wb") as f:
77  f.write(txt)
78 
79 
80 # Backport from Python 3
81 @contextlib.contextmanager
82 def TemporaryDirectory(): # noqa: N802
83  "Prepare a temporary directory, cleanup when done"
84  try:
85  tmpdir = tempfile.mkdtemp()
86  yield tmpdir
87  finally:
88  shutil.rmtree(tmpdir)
89 
90 
91 # Remove the CMake install directory when done
92 @contextlib.contextmanager
93 def remove_output(*sources):
94  try:
95  yield
96  finally:
97  for src in sources:
98  shutil.rmtree(src)
99 
100 
101 with remove_output("pybind11/include", "pybind11/share"):
102  # Generate the files if they are not present.
103  with TemporaryDirectory() as tmpdir:
104  cmd = ["cmake", "-S", ".", "-B", tmpdir] + [
105  "-DCMAKE_INSTALL_PREFIX=pybind11",
106  "-DBUILD_TESTING=OFF",
107  "-DPYBIND11_NOPYTHON=ON",
108  ]
109  cmake_opts = dict(cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)
110  subprocess.check_call(cmd, **cmake_opts)
111  subprocess.check_call(["cmake", "--install", tmpdir], **cmake_opts)
112 
113  txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)
114  code = compile(txt, setup_py, "exec")
115  exec(code, {"SDist": SDist})
def remove_output(sources)
def make_release_tree(self, base_dir, files)
def get_and_replace(filename, binary=False, opts)
Definition: pytypes.h:1255
def TemporaryDirectory()
void exec(str expr, object global=globals(), object local=object())
Definition: eval.h:60


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:44:01