18DIR = os.path.abspath(os.path.dirname(__file__))
19VERSION_REGEX = re.compile(
20 r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE
25 patch_level_serial = matches[
"PATCH"]
28 major = int(matches[
"MAJOR"])
29 minor = int(matches[
"MINOR"])
30 flds = patch_level_serial.split(
".")
38 level_serial = flds[1]
39 for level
in (
"a",
"b",
"c",
"dev"):
40 if level_serial.startswith(level):
41 serial = int(level_serial[
len(level) :])
46 msg =
'Invalid PYBIND11_VERSION_PATCH: "{}"'.format(patch_level_serial)
47 raise RuntimeError(msg)
50 +
"{:02x}{:02x}{:02x}{}{:x}".format(
51 major, minor, patch, level[:1], serial
59global_sdist = os.environ.get(
"PYBIND11_GLOBAL_SDIST",
False)
61setup_py =
"tools/setup_global.py.in" if global_sdist
else "tools/setup_main.py.in"
62extra_cmd =
'cmdclass["sdist"] = SDist\n'
65 (
"pyproject.toml",
"tools/pyproject.toml"),
66 (
"setup.py", setup_py),
70with open(
"pybind11/_version.py")
as f:
71 code = compile(f.read(),
"pybind11/_version.py",
"exec")
74version = loc[
"__version__"]
77with io.open(
"include/pybind11/detail/common.h", encoding=
"utf8")
as f:
78 matches =
dict(VERSION_REGEX.findall(f.read()))
79cpp_version =
"{MAJOR}.{MINOR}.{PATCH}".format(**matches)
80if version != cpp_version:
81 msg =
"Python version {} does not match C++ version {}!".format(
84 raise RuntimeError(msg)
86version_hex = matches.get(
"HEX",
"MISSING")
88if version_hex != expected_version_hex:
89 msg =
"PYBIND11_VERSION_HEX {} does not match expected value {}!".format(
93 raise RuntimeError(msg)
97 with open(filename,
"rb" if binary
else "r")
as f:
101 return string.Template(contents.decode()).substitute(opts).encode()
103 return string.Template(contents).substitute(opts)
108class SDist(setuptools.command.sdist.sdist):
110 setuptools.command.sdist.sdist.make_release_tree(self, base_dir, files)
112 for to, src
in to_src:
115 dest = os.path.join(base_dir, to)
119 with open(dest,
"wb")
as f:
124@contextlib.contextmanager
125def TemporaryDirectory():
126 "Prepare a temporary directory, cleanup when done"
128 tmpdir = tempfile.mkdtemp()
131 shutil.rmtree(tmpdir)
135@contextlib.contextmanager
146 with TemporaryDirectory()
as tmpdir:
147 cmd = [
"cmake",
"-S",
".",
"-B", tmpdir] + [
148 "-DCMAKE_INSTALL_PREFIX=pybind11",
149 "-DBUILD_TESTING=OFF",
150 "-DPYBIND11_NOPYTHON=ON",
152 if "CMAKE_ARGS" in os.environ:
155 for c
in os.environ[
"CMAKE_ARGS"].split()
156 if "DCMAKE_INSTALL_PREFIX" not in c
159 cmake_opts =
dict(cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)
160 subprocess.check_call(cmd, **cmake_opts)
161 subprocess.check_call([
"cmake",
"--install", tmpdir], **cmake_opts)
164 code = compile(txt, setup_py,
"exec")
165 exec(code, {
"SDist": SDist})
def make_release_tree(self, base_dir, files)
size_t len(handle h)
Get the length of a Python object.
def remove_output(*sources)
def get_and_replace(filename, binary=False, **opts)
def build_expected_version_hex(matches)
void exec(const str &expr, object global=globals(), object local=object())