diff options
author | myrtle <gatecat@ds0.me> | 2022-09-15 09:06:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-15 09:06:35 +0200 |
commit | 3983d4fe53e2c609a5c76510aff8e998a4c22285 (patch) | |
tree | 1c4a543f661dd1b281aecf4660388491702fa8d8 /3rdparty/pybind11/setup.py | |
parent | f1349e114f3a16ccd002e8513339e18f5be4d31b (diff) | |
parent | a72f898ff4c4237424c468044a6db9d6953b541e (diff) | |
download | nextpnr-3983d4fe53e2c609a5c76510aff8e998a4c22285.tar.gz nextpnr-3983d4fe53e2c609a5c76510aff8e998a4c22285.tar.bz2 nextpnr-3983d4fe53e2c609a5c76510aff8e998a4c22285.zip |
Merge pull request #1024 from YosysHQ/gatecat/pybind11-bump
3rdparty: Bump vendored pybind11 version for py3.11 support
Diffstat (limited to '3rdparty/pybind11/setup.py')
-rw-r--r-- | 3rdparty/pybind11/setup.py | 121 |
1 files changed, 78 insertions, 43 deletions
diff --git a/3rdparty/pybind11/setup.py b/3rdparty/pybind11/setup.py index 3a032798..68573519 100644 --- a/3rdparty/pybind11/setup.py +++ b/3rdparty/pybind11/setup.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +#!/usr/bin/env python3 # Setup script for PyPI; use CMakeFile.txt to build extension modules @@ -10,87 +9,110 @@ import shutil import string import subprocess import sys -import tempfile +from pathlib import Path +from tempfile import TemporaryDirectory +from typing import Dict, Iterator, List, Union import setuptools.command.sdist -DIR = os.path.abspath(os.path.dirname(__file__)) +DIR = Path(__file__).parent.absolute() VERSION_REGEX = re.compile( r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE ) +VERSION_FILE = Path("pybind11/_version.py") +COMMON_FILE = Path("include/pybind11/detail/common.h") + + +def build_expected_version_hex(matches: Dict[str, str]) -> str: + patch_level_serial = matches["PATCH"] + serial = None + major = int(matches["MAJOR"]) + minor = int(matches["MINOR"]) + flds = patch_level_serial.split(".") + if flds: + patch = int(flds[0]) + if len(flds) == 1: + level = "0" + serial = 0 + elif len(flds) == 2: + level_serial = flds[1] + for level in ("a", "b", "c", "dev"): + if level_serial.startswith(level): + serial = int(level_serial[len(level) :]) + break + if serial is None: + msg = f'Invalid PYBIND11_VERSION_PATCH: "{patch_level_serial}"' + raise RuntimeError(msg) + version_hex_str = f"{major:02x}{minor:02x}{patch:02x}{level[:1]}{serial:x}" + return f"0x{version_hex_str.upper()}" + # PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers # files, and the sys.prefix files (CMake and headers). global_sdist = os.environ.get("PYBIND11_GLOBAL_SDIST", False) -setup_py = "tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in" +setup_py = Path( + "tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in" +) extra_cmd = 'cmdclass["sdist"] = SDist\n' to_src = ( - ("pyproject.toml", "tools/pyproject.toml"), - ("setup.py", setup_py), + (Path("pyproject.toml"), Path("tools/pyproject.toml")), + (Path("setup.py"), setup_py), ) + # Read the listed version -with open("pybind11/_version.py") as f: - code = compile(f.read(), "pybind11/_version.py", "exec") -loc = {} +loc: Dict[str, str] = {} +code = compile(VERSION_FILE.read_text(encoding="utf-8"), "pybind11/_version.py", "exec") exec(code, loc) version = loc["__version__"] # Verify that the version matches the one in C++ -with open("include/pybind11/detail/common.h") as f: - matches = dict(VERSION_REGEX.findall(f.read())) +matches = dict(VERSION_REGEX.findall(COMMON_FILE.read_text(encoding="utf8"))) cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches) if version != cpp_version: - msg = "Python version {} does not match C++ version {}!".format( - version, cpp_version - ) + msg = f"Python version {version} does not match C++ version {cpp_version}!" + raise RuntimeError(msg) + +version_hex = matches.get("HEX", "MISSING") +exp_version_hex = build_expected_version_hex(matches) +if version_hex != exp_version_hex: + msg = f"PYBIND11_VERSION_HEX {version_hex} does not match expected value {exp_version_hex}!" raise RuntimeError(msg) -def get_and_replace(filename, binary=False, **opts): - with open(filename, "rb" if binary else "r") as f: - contents = f.read() - # Replacement has to be done on text in Python 3 (both work in Python 2) +# TODO: use literals & overload (typing extensions or Python 3.8) +def get_and_replace( + filename: Path, binary: bool = False, **opts: str +) -> Union[bytes, str]: if binary: + contents = filename.read_bytes() return string.Template(contents.decode()).substitute(opts).encode() - else: - return string.Template(contents).substitute(opts) + + return string.Template(filename.read_text()).substitute(opts) # Use our input files instead when making the SDist (and anything that depends # on it, like a wheel) -class SDist(setuptools.command.sdist.sdist): - def make_release_tree(self, base_dir, files): - setuptools.command.sdist.sdist.make_release_tree(self, base_dir, files) +class SDist(setuptools.command.sdist.sdist): # type: ignore[misc] + def make_release_tree(self, base_dir: str, files: List[str]) -> None: + super().make_release_tree(base_dir, files) for to, src in to_src: txt = get_and_replace(src, binary=True, version=version, extra_cmd="") - dest = os.path.join(base_dir, to) + dest = Path(base_dir) / to # This is normally linked, so unlink before writing! - os.unlink(dest) - with open(dest, "wb") as f: - f.write(txt) - - -# Backport from Python 3 -@contextlib.contextmanager -def TemporaryDirectory(): # noqa: N802 - "Prepare a temporary directory, cleanup when done" - try: - tmpdir = tempfile.mkdtemp() - yield tmpdir - finally: - shutil.rmtree(tmpdir) + dest.unlink() + dest.write_bytes(txt) # type: ignore[arg-type] # Remove the CMake install directory when done @contextlib.contextmanager -def remove_output(*sources): +def remove_output(*sources: str) -> Iterator[None]: try: yield finally: @@ -105,10 +127,23 @@ with remove_output("pybind11/include", "pybind11/share"): "-DCMAKE_INSTALL_PREFIX=pybind11", "-DBUILD_TESTING=OFF", "-DPYBIND11_NOPYTHON=ON", + "-Dprefix_for_pc_file=${pcfiledir}/../../", ] - cmake_opts = dict(cwd=DIR, stdout=sys.stdout, stderr=sys.stderr) - subprocess.check_call(cmd, **cmake_opts) - subprocess.check_call(["cmake", "--install", tmpdir], **cmake_opts) + if "CMAKE_ARGS" in os.environ: + fcommand = [ + c + for c in os.environ["CMAKE_ARGS"].split() + if "DCMAKE_INSTALL_PREFIX" not in c + ] + cmd += fcommand + subprocess.run(cmd, check=True, cwd=DIR, stdout=sys.stdout, stderr=sys.stderr) + subprocess.run( + ["cmake", "--install", tmpdir], + check=True, + cwd=DIR, + stdout=sys.stdout, + stderr=sys.stderr, + ) txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd) code = compile(txt, setup_py, "exec") |