mirror of
https://github.com/pybind/pybind11.git
synced 2025-01-31 07:10:30 +00:00
Merge branch 'master' into sh_merge_master
This commit is contained in:
commit
6df86934c2
16
.github/workflows/ci_sh_def.yml.patch
vendored
16
.github/workflows/ci_sh_def.yml.patch
vendored
@ -1,5 +1,5 @@
|
||||
--- ci.yml 2022-07-21 06:53:22.850154382 -0700
|
||||
+++ ci_sh_def.yml 2022-07-21 06:54:29.947056986 -0700
|
||||
--- ci.yml 2022-08-21 19:29:32.986391968 -0700
|
||||
+++ ci_sh_def.yml 2022-08-21 19:31:47.618458226 -0700
|
||||
@@ -1,4 +1,16 @@
|
||||
-name: CI
|
||||
+# PLEASE KEEP THIS GROUP OF FILES IN SYNC AT ALL TIMES:
|
||||
@ -154,8 +154,8 @@
|
||||
- name: Configure C++11
|
||||
# LTO leads to many undefined reference like
|
||||
# `pybind11::detail::function_call::function_call(pybind11::detail::function_call&&)
|
||||
- run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=11 -DDOWNLOAD_CATCH=ON -S . -B build
|
||||
+ run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=11 -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT" -S . -B build
|
||||
- run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=11 -DCMAKE_VERBOSE_MAKEFILE=ON -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON -S . -B build
|
||||
+ run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=11 -DCMAKE_VERBOSE_MAKEFILE=ON -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT" -S . -B build
|
||||
|
||||
- name: Build C++11
|
||||
run: cmake --build build -j 2
|
||||
@ -163,8 +163,8 @@
|
||||
run: git clean -fdx
|
||||
|
||||
- name: Configure C++14
|
||||
- run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=14 -DDOWNLOAD_CATCH=ON -S . -B build2
|
||||
+ run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=14 -DDOWNLOAD_CATCH=O -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT" -S . -B build2
|
||||
- run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=14 -DCMAKE_VERBOSE_MAKEFILE=ON -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON -S . -B build2
|
||||
+ run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=14 -DCMAKE_VERBOSE_MAKEFILE=ON -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT" -S . -B build2
|
||||
|
||||
- name: Build C++14
|
||||
run: cmake --build build2 -j 2
|
||||
@ -172,8 +172,8 @@
|
||||
run: git clean -fdx
|
||||
|
||||
- name: Configure C++17
|
||||
- run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=17 -DDOWNLOAD_CATCH=ON -S . -B build3
|
||||
+ run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=17 -DDOWNLOAD_CATCH=O -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT" -S . -B build3
|
||||
- run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=17 -DCMAKE_VERBOSE_MAKEFILE=ON -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON -S . -B build3
|
||||
+ run: cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=17 -DCMAKE_VERBOSE_MAKEFILE=ON -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT" -S . -B build3
|
||||
|
||||
- name: Build C++17
|
||||
run: cmake --build build3 -j 2
|
||||
|
@ -12,6 +12,9 @@
|
||||
#
|
||||
# See https://github.com/pre-commit/pre-commit
|
||||
|
||||
# third-party content
|
||||
exclude: ^tools/JoinPaths.cmake$
|
||||
|
||||
repos:
|
||||
# Standard hooks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
@ -93,7 +96,7 @@ repos:
|
||||
|
||||
# Automatically remove noqa that are not used
|
||||
- repo: https://github.com/asottile/yesqa
|
||||
rev: "v1.3.0"
|
||||
rev: "v1.4.0"
|
||||
hooks:
|
||||
- id: yesqa
|
||||
additional_dependencies: &flake8_dependencies
|
||||
@ -102,7 +105,7 @@ repos:
|
||||
|
||||
# Flake8 also supports pre-commit natively (same author)
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: "5.0.2"
|
||||
rev: "5.0.4"
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: ^(docs/.*|tools/.*|ubench/.*)$
|
||||
|
@ -205,6 +205,9 @@ else()
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
|
||||
# https://github.com/jtojnar/cmake-snips/#concatenating-paths-when-building-pkg-config-files
|
||||
# TODO: cmake 3.20 adds the cmake_path() function, which obsoletes this snippet
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/JoinPaths.cmake")
|
||||
|
||||
# Relative directory setting
|
||||
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
|
||||
@ -269,6 +272,16 @@ if(PYBIND11_INSTALL)
|
||||
NAMESPACE "pybind11::"
|
||||
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
||||
|
||||
# pkg-config support
|
||||
if(NOT prefix_for_pc_file)
|
||||
set(prefix_for_pc_file "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11.pc.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
|
||||
|
||||
# Uninstall target
|
||||
if(PYBIND11_MASTER_PROJECT)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
|
||||
|
@ -504,31 +504,6 @@ inline PyObject *make_object_base_type(PyTypeObject *metaclass) {
|
||||
return (PyObject *) heap_type;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Support for `d = instance.__dict__`.
|
||||
extern "C" inline PyObject *pybind11_get_dict(PyObject *self, void *) {
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
if (!dict) {
|
||||
dict = PyDict_New();
|
||||
}
|
||||
Py_XINCREF(dict);
|
||||
return dict;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Support for `instance.__dict__ = dict()`.
|
||||
extern "C" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) {
|
||||
if (!PyDict_Check(new_dict)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__dict__ must be set to a dictionary, not a '%.200s'",
|
||||
get_fully_qualified_tp_name(Py_TYPE(new_dict)).c_str());
|
||||
return -1;
|
||||
}
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
Py_INCREF(new_dict);
|
||||
Py_CLEAR(dict);
|
||||
dict = new_dict;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.
|
||||
extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
@ -560,9 +535,17 @@ inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
|
||||
type->tp_traverse = pybind11_traverse;
|
||||
type->tp_clear = pybind11_clear;
|
||||
|
||||
static PyGetSetDef getset[] = {
|
||||
{const_cast<char *>("__dict__"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr}};
|
||||
static PyGetSetDef getset[] = {{
|
||||
#if PY_VERSION_HEX < 0x03070000
|
||||
const_cast<char *>("__dict__"),
|
||||
#else
|
||||
"__dict__",
|
||||
#endif
|
||||
PyObject_GenericGetDict,
|
||||
PyObject_GenericSetDict,
|
||||
nullptr,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr}};
|
||||
type->tp_getset = getset;
|
||||
}
|
||||
|
||||
|
@ -150,6 +150,8 @@ inline void initialize_interpreter(bool init_signal_handlers = true,
|
||||
#else
|
||||
PyConfig config;
|
||||
PyConfig_InitIsolatedConfig(&config);
|
||||
config.isolated = 0;
|
||||
config.use_environment = 1;
|
||||
config.install_signal_handlers = init_signal_handlers ? 1 : 0;
|
||||
|
||||
PyStatus status = PyConfig_SetBytesArgv(&config, argc, const_cast<char *const *>(argv));
|
||||
|
@ -45,7 +45,7 @@ using forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,
|
||||
/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically
|
||||
/// used for forwarding a container's elements.
|
||||
template <typename T, typename U>
|
||||
forwarded_type<T, U> forward_like(U &&u) {
|
||||
constexpr forwarded_type<T, U> forward_like(U &&u) {
|
||||
return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ struct set_caster {
|
||||
pybind11::set s;
|
||||
for (auto &&value : src) {
|
||||
auto value_ = reinterpret_steal<object>(
|
||||
key_conv::cast(forward_like<T>(value), policy, parent));
|
||||
key_conv::cast(detail::forward_like<T>(value), policy, parent));
|
||||
if (!value_ || !s.add(std::move(value_))) {
|
||||
return handle();
|
||||
}
|
||||
@ -122,9 +122,9 @@ struct map_caster {
|
||||
}
|
||||
for (auto &&kv : src) {
|
||||
auto key = reinterpret_steal<object>(
|
||||
key_conv::cast(forward_like<T>(kv.first), policy_key, parent));
|
||||
key_conv::cast(detail::forward_like<T>(kv.first), policy_key, parent));
|
||||
auto value = reinterpret_steal<object>(
|
||||
value_conv::cast(forward_like<T>(kv.second), policy_value, parent));
|
||||
value_conv::cast(detail::forward_like<T>(kv.second), policy_value, parent));
|
||||
if (!key || !value) {
|
||||
return handle();
|
||||
}
|
||||
@ -178,7 +178,7 @@ public:
|
||||
ssize_t index = 0;
|
||||
for (auto &&value : src) {
|
||||
auto value_ = reinterpret_steal<object>(
|
||||
value_conv::cast(forward_like<T>(value), policy, parent));
|
||||
value_conv::cast(detail::forward_like<T>(value), policy, parent));
|
||||
if (!value_) {
|
||||
return handle();
|
||||
}
|
||||
@ -242,7 +242,7 @@ public:
|
||||
ssize_t index = 0;
|
||||
for (auto &&value : src) {
|
||||
auto value_ = reinterpret_steal<object>(
|
||||
value_conv::cast(forward_like<T>(value), policy, parent));
|
||||
value_conv::cast(detail::forward_like<T>(value), policy, parent));
|
||||
if (!value_) {
|
||||
return handle();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ def lint(session: nox.Session) -> None:
|
||||
Lint the codebase (except for clang-format/tidy).
|
||||
"""
|
||||
session.install("pre-commit")
|
||||
session.run("pre-commit", "run", "-a")
|
||||
session.run("pre-commit", "run", "-a", *session.posargs)
|
||||
|
||||
|
||||
@nox.session(python=PYTHON_VERSIONS)
|
||||
@ -58,7 +58,7 @@ def tests_packaging(session: nox.Session) -> None:
|
||||
"""
|
||||
|
||||
session.install("-r", "tests/requirements.txt", "--prefer-binary")
|
||||
session.run("pytest", "tests/extra_python_package")
|
||||
session.run("pytest", "tests/extra_python_package", *session.posargs)
|
||||
|
||||
|
||||
@nox.session(reuse_venv=True)
|
||||
|
@ -6,11 +6,12 @@ if sys.version_info < (3, 6):
|
||||
|
||||
|
||||
from ._version import __version__, version_info
|
||||
from .commands import get_cmake_dir, get_include
|
||||
from .commands import get_cmake_dir, get_include, get_pkgconfig_dir
|
||||
|
||||
__all__ = (
|
||||
"version_info",
|
||||
"__version__",
|
||||
"get_include",
|
||||
"get_cmake_dir",
|
||||
"get_pkgconfig_dir",
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ import argparse
|
||||
import sys
|
||||
import sysconfig
|
||||
|
||||
from .commands import get_cmake_dir, get_include
|
||||
from .commands import get_cmake_dir, get_include, get_pkgconfig_dir
|
||||
|
||||
|
||||
def print_includes() -> None:
|
||||
@ -36,6 +36,11 @@ def main() -> None:
|
||||
action="store_true",
|
||||
help="Print the CMake module directory, ideal for setting -Dpybind11_ROOT in CMake.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--pkgconfigdir",
|
||||
action="store_true",
|
||||
help="Print the pkgconfig directory, ideal for setting $PKG_CONFIG_PATH.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
if not sys.argv[1:]:
|
||||
parser.print_help()
|
||||
@ -43,6 +48,8 @@ def main() -> None:
|
||||
print_includes()
|
||||
if args.cmakedir:
|
||||
print(get_cmake_dir())
|
||||
if args.pkgconfigdir:
|
||||
print(get_pkgconfig_dir())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -23,3 +23,15 @@ def get_cmake_dir() -> str:
|
||||
|
||||
msg = "pybind11 not installed, installation required to access the CMake files"
|
||||
raise ImportError(msg)
|
||||
|
||||
|
||||
def get_pkgconfig_dir() -> str:
|
||||
"""
|
||||
Return the path to the pybind11 pkgconfig directory.
|
||||
"""
|
||||
pkgconfig_installed_path = os.path.join(DIR, "share", "pkgconfig")
|
||||
if os.path.exists(pkgconfig_installed_path):
|
||||
return pkgconfig_installed_path
|
||||
|
||||
msg = "pybind11 not installed, installation required to access the pkgconfig files"
|
||||
raise ImportError(msg)
|
||||
|
1
setup.py
1
setup.py
@ -127,6 +127,7 @@ with remove_output("pybind11/include", "pybind11/share"):
|
||||
"-DCMAKE_INSTALL_PREFIX=pybind11",
|
||||
"-DBUILD_TESTING=OFF",
|
||||
"-DPYBIND11_NOPYTHON=ON",
|
||||
"-Dprefix_for_pc_file=${pcfiledir}/../../",
|
||||
]
|
||||
if "CMAKE_ARGS" in os.environ:
|
||||
fcommand = [
|
||||
|
@ -12,6 +12,16 @@ import zipfile
|
||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
MAIN_DIR = os.path.dirname(os.path.dirname(DIR))
|
||||
|
||||
PKGCONFIG = """\
|
||||
prefix=${{pcfiledir}}/../../
|
||||
includedir=${{prefix}}/include
|
||||
|
||||
Name: pybind11
|
||||
Description: Seamless operability between C++11 and Python
|
||||
Version: {VERSION}
|
||||
Cflags: -I${{includedir}}
|
||||
"""
|
||||
|
||||
|
||||
main_headers = {
|
||||
"include/pybind11/attr.h",
|
||||
@ -66,6 +76,10 @@ cmake_files = {
|
||||
"share/cmake/pybind11/pybind11Tools.cmake",
|
||||
}
|
||||
|
||||
pkgconfig_files = {
|
||||
"share/pkgconfig/pybind11.pc",
|
||||
}
|
||||
|
||||
py_files = {
|
||||
"__init__.py",
|
||||
"__main__.py",
|
||||
@ -76,7 +90,7 @@ py_files = {
|
||||
}
|
||||
|
||||
headers = main_headers | detail_headers | stl_headers
|
||||
src_files = headers | cmake_files
|
||||
src_files = headers | cmake_files | pkgconfig_files
|
||||
all_files = src_files | py_files
|
||||
|
||||
|
||||
@ -89,6 +103,7 @@ sdist_files = {
|
||||
"pybind11/share",
|
||||
"pybind11/share/cmake",
|
||||
"pybind11/share/cmake/pybind11",
|
||||
"pybind11/share/pkgconfig",
|
||||
"pyproject.toml",
|
||||
"setup.cfg",
|
||||
"setup.py",
|
||||
@ -109,22 +124,25 @@ local_sdist_files = {
|
||||
}
|
||||
|
||||
|
||||
def read_tz_file(tar: tarfile.TarFile, name: str) -> bytes:
|
||||
start = tar.getnames()[0] + "/"
|
||||
inner_file = tar.extractfile(tar.getmember(f"{start}{name}"))
|
||||
assert inner_file
|
||||
with contextlib.closing(inner_file) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def normalize_line_endings(value: bytes) -> bytes:
|
||||
return value.replace(os.linesep.encode("utf-8"), b"\n")
|
||||
|
||||
|
||||
def test_build_sdist(monkeypatch, tmpdir):
|
||||
|
||||
monkeypatch.chdir(MAIN_DIR)
|
||||
|
||||
out = subprocess.check_output(
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
"build",
|
||||
"--sdist",
|
||||
"--outdir",
|
||||
str(tmpdir),
|
||||
]
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "build", "--sdist", f"--outdir={tmpdir}"], check=True
|
||||
)
|
||||
if hasattr(out, "decode"):
|
||||
out = out.decode()
|
||||
|
||||
(sdist,) = tmpdir.visit("*.tar.gz")
|
||||
|
||||
@ -133,25 +151,17 @@ def test_build_sdist(monkeypatch, tmpdir):
|
||||
version = start[9:-1]
|
||||
simpler = {n.split("/", 1)[-1] for n in tar.getnames()[1:]}
|
||||
|
||||
with contextlib.closing(
|
||||
tar.extractfile(tar.getmember(start + "setup.py"))
|
||||
) as f:
|
||||
setup_py = f.read()
|
||||
setup_py = read_tz_file(tar, "setup.py")
|
||||
pyproject_toml = read_tz_file(tar, "pyproject.toml")
|
||||
pkgconfig = read_tz_file(tar, "pybind11/share/pkgconfig/pybind11.pc")
|
||||
cmake_cfg = read_tz_file(
|
||||
tar, "pybind11/share/cmake/pybind11/pybind11Config.cmake"
|
||||
)
|
||||
|
||||
with contextlib.closing(
|
||||
tar.extractfile(tar.getmember(start + "pyproject.toml"))
|
||||
) as f:
|
||||
pyproject_toml = f.read()
|
||||
|
||||
with contextlib.closing(
|
||||
tar.extractfile(
|
||||
tar.getmember(
|
||||
start + "pybind11/share/cmake/pybind11/pybind11Config.cmake"
|
||||
)
|
||||
)
|
||||
) as f:
|
||||
contents = f.read().decode("utf8")
|
||||
assert 'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")' in contents
|
||||
assert (
|
||||
'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")'
|
||||
in cmake_cfg.decode("utf-8")
|
||||
)
|
||||
|
||||
files = {f"pybind11/{n}" for n in all_files}
|
||||
files |= sdist_files
|
||||
@ -162,9 +172,9 @@ def test_build_sdist(monkeypatch, tmpdir):
|
||||
|
||||
with open(os.path.join(MAIN_DIR, "tools", "setup_main.py.in"), "rb") as f:
|
||||
contents = (
|
||||
string.Template(f.read().decode())
|
||||
string.Template(f.read().decode("utf-8"))
|
||||
.substitute(version=version, extra_cmd="")
|
||||
.encode()
|
||||
.encode("utf-8")
|
||||
)
|
||||
assert setup_py == contents
|
||||
|
||||
@ -172,25 +182,19 @@ def test_build_sdist(monkeypatch, tmpdir):
|
||||
contents = f.read()
|
||||
assert pyproject_toml == contents
|
||||
|
||||
simple_version = ".".join(version.split(".")[:3])
|
||||
pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode("utf-8")
|
||||
assert normalize_line_endings(pkgconfig) == pkgconfig_expected
|
||||
|
||||
|
||||
def test_build_global_dist(monkeypatch, tmpdir):
|
||||
|
||||
monkeypatch.chdir(MAIN_DIR)
|
||||
monkeypatch.setenv("PYBIND11_GLOBAL_SDIST", "1")
|
||||
out = subprocess.check_output(
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
"build",
|
||||
"--sdist",
|
||||
"--outdir",
|
||||
str(tmpdir),
|
||||
]
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "build", "--sdist", "--outdir", str(tmpdir)], check=True
|
||||
)
|
||||
|
||||
if hasattr(out, "decode"):
|
||||
out = out.decode()
|
||||
|
||||
(sdist,) = tmpdir.visit("*.tar.gz")
|
||||
|
||||
with tarfile.open(str(sdist), "r:gz") as tar:
|
||||
@ -198,15 +202,17 @@ def test_build_global_dist(monkeypatch, tmpdir):
|
||||
version = start[16:-1]
|
||||
simpler = {n.split("/", 1)[-1] for n in tar.getnames()[1:]}
|
||||
|
||||
with contextlib.closing(
|
||||
tar.extractfile(tar.getmember(start + "setup.py"))
|
||||
) as f:
|
||||
setup_py = f.read()
|
||||
setup_py = read_tz_file(tar, "setup.py")
|
||||
pyproject_toml = read_tz_file(tar, "pyproject.toml")
|
||||
pkgconfig = read_tz_file(tar, "pybind11/share/pkgconfig/pybind11.pc")
|
||||
cmake_cfg = read_tz_file(
|
||||
tar, "pybind11/share/cmake/pybind11/pybind11Config.cmake"
|
||||
)
|
||||
|
||||
with contextlib.closing(
|
||||
tar.extractfile(tar.getmember(start + "pyproject.toml"))
|
||||
) as f:
|
||||
pyproject_toml = f.read()
|
||||
assert (
|
||||
'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")'
|
||||
in cmake_cfg.decode("utf-8")
|
||||
)
|
||||
|
||||
files = {f"pybind11/{n}" for n in all_files}
|
||||
files |= sdist_files
|
||||
@ -217,7 +223,7 @@ def test_build_global_dist(monkeypatch, tmpdir):
|
||||
contents = (
|
||||
string.Template(f.read().decode())
|
||||
.substitute(version=version, extra_cmd="")
|
||||
.encode()
|
||||
.encode("utf-8")
|
||||
)
|
||||
assert setup_py == contents
|
||||
|
||||
@ -225,12 +231,16 @@ def test_build_global_dist(monkeypatch, tmpdir):
|
||||
contents = f.read()
|
||||
assert pyproject_toml == contents
|
||||
|
||||
simple_version = ".".join(version.split(".")[:3])
|
||||
pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode("utf-8")
|
||||
assert normalize_line_endings(pkgconfig) == pkgconfig_expected
|
||||
|
||||
|
||||
def tests_build_wheel(monkeypatch, tmpdir):
|
||||
monkeypatch.chdir(MAIN_DIR)
|
||||
|
||||
subprocess.check_output(
|
||||
[sys.executable, "-m", "pip", "wheel", ".", "-w", str(tmpdir)]
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "pip", "wheel", ".", "-w", str(tmpdir)], check=True
|
||||
)
|
||||
|
||||
(wheel,) = tmpdir.visit("*.whl")
|
||||
@ -257,8 +267,8 @@ def tests_build_global_wheel(monkeypatch, tmpdir):
|
||||
monkeypatch.chdir(MAIN_DIR)
|
||||
monkeypatch.setenv("PYBIND11_GLOBAL_SDIST", "1")
|
||||
|
||||
subprocess.check_output(
|
||||
[sys.executable, "-m", "pip", "wheel", ".", "-w", str(tmpdir)]
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "pip", "wheel", ".", "-w", str(tmpdir)], check=True
|
||||
)
|
||||
|
||||
(wheel,) = tmpdir.visit("*.whl")
|
||||
|
@ -20,7 +20,25 @@
|
||||
namespace py = pybind11;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Setup for TEST_CASE in test_interpreter.cpp, tagging on a large random number:
|
||||
std::string updated_pythonpath("pybind11_test_embed_PYTHONPATH_2099743835476552");
|
||||
const char *preexisting_pythonpath = getenv("PYTHONPATH");
|
||||
if (preexisting_pythonpath != nullptr) {
|
||||
#if defined(_WIN32)
|
||||
updated_pythonpath += ';';
|
||||
#else
|
||||
updated_pythonpath += ':';
|
||||
#endif
|
||||
updated_pythonpath += preexisting_pythonpath;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
_putenv_s("PYTHONPATH", updated_pythonpath.c_str());
|
||||
#else
|
||||
setenv("PYTHONPATH", updated_pythonpath.c_str(), /*replace=*/1);
|
||||
#endif
|
||||
|
||||
py::scoped_interpreter guard{};
|
||||
|
||||
auto result = Catch::Session().run(argc, argv);
|
||||
|
||||
return result < 0xff ? result : 0xff;
|
||||
|
@ -75,6 +75,13 @@ PYBIND11_EMBEDDED_MODULE(throw_error_already_set, ) {
|
||||
d["missing"].cast<py::object>();
|
||||
}
|
||||
|
||||
TEST_CASE("PYTHONPATH is used to update sys.path") {
|
||||
// The setup for this TEST_CASE is in catch.cpp!
|
||||
auto sys_path = py::str(py::module_::import("sys").attr("path")).cast<std::string>();
|
||||
REQUIRE_THAT(sys_path,
|
||||
Catch::Matchers::Contains("pybind11_test_embed_PYTHONPATH_2099743835476552"));
|
||||
}
|
||||
|
||||
TEST_CASE("Pass classes and data between modules defined in C++ and Python") {
|
||||
auto module_ = py::module_::import("test_interpreter");
|
||||
REQUIRE(py::hasattr(module_, "DerivedWidget"));
|
||||
|
@ -109,6 +109,11 @@ TEST_SUBMODULE(pytypes, m) {
|
||||
m.def("get_iterator", [] { return py::iterator(); });
|
||||
// test_iterable
|
||||
m.def("get_iterable", [] { return py::iterable(); });
|
||||
m.def("get_frozenset_from_iterable",
|
||||
[](const py::iterable &iter) { return py::frozenset(iter); });
|
||||
m.def("get_list_from_iterable", [](const py::iterable &iter) { return py::list(iter); });
|
||||
m.def("get_set_from_iterable", [](const py::iterable &iter) { return py::set(iter); });
|
||||
m.def("get_tuple_from_iterable", [](const py::iterable &iter) { return py::tuple(iter); });
|
||||
// test_float
|
||||
m.def("get_float", [] { return py::float_(0.0f); });
|
||||
// test_list
|
||||
|
@ -26,6 +26,22 @@ def test_iterator(doc):
|
||||
assert doc(m.get_iterator) == "get_iterator() -> Iterator"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"pytype, from_iter_func",
|
||||
[
|
||||
(frozenset, m.get_frozenset_from_iterable),
|
||||
(list, m.get_list_from_iterable),
|
||||
(set, m.get_set_from_iterable),
|
||||
(tuple, m.get_tuple_from_iterable),
|
||||
],
|
||||
)
|
||||
def test_from_iterable(pytype, from_iter_func):
|
||||
my_iter = iter(range(10))
|
||||
s = from_iter_func(my_iter)
|
||||
assert type(s) == pytype
|
||||
assert s == pytype(range(10))
|
||||
|
||||
|
||||
def test_iterable(doc):
|
||||
assert doc(m.get_iterable) == "get_iterable() -> Iterable"
|
||||
|
||||
|
23
tools/JoinPaths.cmake
Normal file
23
tools/JoinPaths.cmake
Normal file
@ -0,0 +1,23 @@
|
||||
# This module provides function for joining paths
|
||||
# known from most languages
|
||||
#
|
||||
# SPDX-License-Identifier: (MIT OR CC0-1.0)
|
||||
# Copyright 2020 Jan Tojnar
|
||||
# https://github.com/jtojnar/cmake-snips
|
||||
#
|
||||
# Modelled after Python’s os.path.join
|
||||
# https://docs.python.org/3.7/library/os.path.html#os.path.join
|
||||
# Windows not supported
|
||||
function(join_paths joined_path first_path_segment)
|
||||
set(temp_path "${first_path_segment}")
|
||||
foreach(current_segment IN LISTS ARGN)
|
||||
if(NOT ("${current_segment}" STREQUAL ""))
|
||||
if(IS_ABSOLUTE "${current_segment}")
|
||||
set(temp_path "${current_segment}")
|
||||
else()
|
||||
set(temp_path "${temp_path}/${current_segment}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(${joined_path} "${temp_path}" PARENT_SCOPE)
|
||||
endfunction()
|
7
tools/pybind11.pc.in
Normal file
7
tools/pybind11.pc.in
Normal file
@ -0,0 +1,7 @@
|
||||
prefix=@prefix_for_pc_file@
|
||||
includedir=@includedir_for_pc_file@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: Seamless operability between C++11 and Python
|
||||
Version: @PROJECT_VERSION@
|
||||
Cflags: -I${includedir}
|
@ -233,7 +233,9 @@ function(pybind11_add_module target_name)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
||||
# Use case-insensitive comparison to match the result of $<CONFIG:cfgs>
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
|
||||
if(NOT MSVC AND NOT ${uppercase_CMAKE_BUILD_TYPE} MATCHES DEBUG|RELWITHDEBINFO)
|
||||
# Strip unnecessary sections of the binary on Linux/macOS
|
||||
pybind11_strip(${target_name})
|
||||
endif()
|
||||
|
@ -115,6 +115,7 @@ if(PYTHON_IS_DEBUG)
|
||||
PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
|
||||
endif()
|
||||
|
||||
# The <3.11 code here does not support release/debug builds at the same time, like on vcpkg
|
||||
if(CMAKE_VERSION VERSION_LESS 3.11)
|
||||
set_property(
|
||||
TARGET pybind11::module
|
||||
@ -130,16 +131,19 @@ if(CMAKE_VERSION VERSION_LESS 3.11)
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
||||
else()
|
||||
# The IMPORTED INTERFACE library here is to ensure that "debug" and "release" get processed outside
|
||||
# of a generator expression - https://gitlab.kitware.com/cmake/cmake/-/issues/18424, as they are
|
||||
# target_link_library keywords rather than real libraries.
|
||||
add_library(pybind11::_ClassicPythonLibraries IMPORTED INTERFACE)
|
||||
target_link_libraries(pybind11::_ClassicPythonLibraries INTERFACE ${PYTHON_LIBRARIES})
|
||||
target_link_libraries(
|
||||
pybind11::module
|
||||
INTERFACE
|
||||
pybind11::python_link_helper
|
||||
"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>"
|
||||
)
|
||||
"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:pybind11::_ClassicPythonLibraries>")
|
||||
|
||||
target_link_libraries(pybind11::embed INTERFACE pybind11::pybind11
|
||||
$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
||||
|
||||
pybind11::_ClassicPythonLibraries)
|
||||
endif()
|
||||
|
||||
function(pybind11_extension name)
|
||||
@ -208,7 +212,9 @@ function(pybind11_add_module target_name)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
||||
# Use case-insensitive comparison to match the result of $<CONFIG:cfgs>
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
|
||||
if(NOT MSVC AND NOT ${uppercase_CMAKE_BUILD_TYPE} MATCHES DEBUG|RELWITHDEBINFO)
|
||||
pybind11_strip(${target_name})
|
||||
endif()
|
||||
|
||||
|
@ -29,6 +29,7 @@ main_headers = glob.glob("pybind11/include/pybind11/*.h")
|
||||
detail_headers = glob.glob("pybind11/include/pybind11/detail/*.h")
|
||||
stl_headers = glob.glob("pybind11/include/pybind11/stl/*.h")
|
||||
cmake_files = glob.glob("pybind11/share/cmake/pybind11/*.cmake")
|
||||
pkgconfig_files = glob.glob("pybind11/share/pkgconfig/*.pc")
|
||||
headers = main_headers + detail_headers + stl_headers
|
||||
|
||||
cmdclass = {"install_headers": InstallHeadersNested}
|
||||
@ -51,6 +52,7 @@ setup(
|
||||
headers=headers,
|
||||
data_files=[
|
||||
(base + "share/cmake/pybind11", cmake_files),
|
||||
(base + "share/pkgconfig", pkgconfig_files),
|
||||
(base + "include/pybind11", main_headers),
|
||||
(base + "include/pybind11/detail", detail_headers),
|
||||
(base + "include/pybind11/stl", stl_headers),
|
||||
|
@ -17,6 +17,7 @@ setup(
|
||||
"pybind11.include.pybind11.detail",
|
||||
"pybind11.include.pybind11.stl",
|
||||
"pybind11.share.cmake.pybind11",
|
||||
"pybind11.share.pkgconfig",
|
||||
],
|
||||
package_data={
|
||||
"pybind11": ["py.typed"],
|
||||
@ -24,6 +25,7 @@ setup(
|
||||
"pybind11.include.pybind11.detail": ["*.h"],
|
||||
"pybind11.include.pybind11.stl": ["*.h"],
|
||||
"pybind11.share.cmake.pybind11": ["*.cmake"],
|
||||
"pybind11.share.pkgconfig": ["*.pc"],
|
||||
},
|
||||
extras_require={
|
||||
"global": ["pybind11_global==$version"]
|
||||
|
Loading…
Reference in New Issue
Block a user