Merge branch 'master' into sh_merge_master

This commit is contained in:
Ralf W. Grosse-Kunstleve 2023-06-27 15:11:06 -07:00
commit 3a5d27e1f0
10 changed files with 81 additions and 42 deletions

View File

@ -37,6 +37,7 @@ jobs:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- 'pypy-3.7'
- 'pypy-3.8'
- 'pypy-3.9'
@ -75,6 +76,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
allow-prereleases: true
- name: Setup Boost (Linux)
# Can't use boost + define _
@ -457,16 +459,16 @@ jobs:
fail-fast: false
matrix:
include:
- { gcc: 7, std: 11, container_suffix: "" }
- { gcc: 7, std: 17, container_suffix: "" }
- { gcc: 8, std: 14, container_suffix: "" }
- { gcc: 8, std: 17, container_suffix: "" }
- { gcc: 10, std: 17, container_suffix: "-bullseye" }
- { gcc: 11, std: 20, container_suffix: "" }
- { gcc: 12, std: 20, container_suffix: "" }
- { gcc: 7, std: 11 }
- { gcc: 7, std: 17 }
- { gcc: 8, std: 14 }
- { gcc: 8, std: 17 }
- { gcc: 10, std: 17 }
- { gcc: 11, std: 20 }
- { gcc: 12, std: 20 }
name: "🐍 3 • GCC ${{ matrix.gcc }} • C++${{ matrix.std }}• x64"
container: "gcc:${{ matrix.gcc }}${{ matrix.container_suffix }}"
container: "gcc:${{ matrix.gcc }}"
steps:
- uses: actions/checkout@v3

View File

@ -54,6 +54,7 @@ repos:
- markdown-it-py<3 # Drop this together with dropping Python 3.7 support.
- nox
- rich
- types-setuptools
# CMake formatting
- repo: https://github.com/cheshirekow/cmake-format-precommit

View File

@ -509,8 +509,8 @@ protected:
rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;
capsule rec_capsule(unique_rec.release(),
detail::get_function_record_capsule_name(),
[](void *ptr) { destruct((detail::function_record *) ptr); });
rec_capsule.set_name(detail::get_function_record_capsule_name());
guarded_strdup.release();
object scope_module;

View File

@ -1925,28 +1925,13 @@ public:
}
}
/// Capsule name is nullptr.
capsule(const void *value, void (*destructor)(void *)) {
m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {
// guard if destructor called while err indicator is set
error_scope error_guard;
auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
if (destructor == nullptr && PyErr_Occurred()) {
throw error_already_set();
}
const char *name = get_name_in_error_scope(o);
void *ptr = PyCapsule_GetPointer(o, name);
if (ptr == nullptr) {
throw error_already_set();
initialize_with_void_ptr_destructor(value, nullptr, destructor);
}
if (destructor != nullptr) {
destructor(ptr);
}
});
if (!m_ptr || PyCapsule_SetContext(m_ptr, reinterpret_cast<void *>(destructor)) != 0) {
throw error_already_set();
}
capsule(const void *value, const char *name, void (*destructor)(void *)) {
initialize_with_void_ptr_destructor(value, name, destructor);
}
explicit capsule(void (*destructor)()) {
@ -2014,6 +1999,32 @@ private:
return name;
}
void initialize_with_void_ptr_destructor(const void *value,
const char *name,
void (*destructor)(void *)) {
m_ptr = PyCapsule_New(const_cast<void *>(value), name, [](PyObject *o) {
// guard if destructor called while err indicator is set
error_scope error_guard;
auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
if (destructor == nullptr && PyErr_Occurred()) {
throw error_already_set();
}
const char *name = get_name_in_error_scope(o);
void *ptr = PyCapsule_GetPointer(o, name);
if (ptr == nullptr) {
throw error_already_set();
}
if (destructor != nullptr) {
destructor(ptr);
}
});
if (!m_ptr || PyCapsule_SetContext(m_ptr, reinterpret_cast<void *>(destructor)) != 0) {
throw error_already_set();
}
}
};
class tuple : public object {

View File

@ -66,8 +66,8 @@ try:
from setuptools import Extension as _Extension
from setuptools.command.build_ext import build_ext as _build_ext
except ImportError:
from distutils.command.build_ext import build_ext as _build_ext
from distutils.extension import Extension as _Extension
from distutils.command.build_ext import build_ext as _build_ext # type: ignore[assignment]
from distutils.extension import Extension as _Extension # type: ignore[assignment]
import distutils.ccompiler
import distutils.errors
@ -84,7 +84,7 @@ STD_TMPL = "/std:c++{}" if WIN else "-std=c++{}"
# directory into your path if it sits beside your setup.py.
class Pybind11Extension(_Extension): # type: ignore[misc]
class Pybind11Extension(_Extension):
"""
Build a C++11+ Extension module with pybind11. This automatically adds the
recommended flags when you init the extension and assumes C++ sources - you
@ -266,7 +266,7 @@ def auto_cpp_level(compiler: Any) -> Union[str, int]:
raise RuntimeError(msg)
class build_ext(_build_ext): # type: ignore[misc] # noqa: N801
class build_ext(_build_ext): # noqa: N801
"""
Customized build_ext that allows an auto-search for the highest supported
C++ level for Pybind11Extension. This is only needed for the auto-search

View File

@ -2,6 +2,7 @@
requires = ["setuptools>=42", "cmake>=3.18", "ninja"]
build-backend = "setuptools.build_meta"
[tool.check-manifest]
ignore = [
"tests/**",
@ -15,6 +16,7 @@ ignore = [
"noxfile.py",
]
[tool.mypy]
files = ["pybind11"]
python_version = "3.6"
@ -24,7 +26,7 @@ enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true
[[tool.mypy.overrides]]
module = ["ghapi.*", "setuptools.*"]
module = ["ghapi.*"]
ignore_missing_imports = true
@ -55,10 +57,11 @@ messages_control.disable = [
"unused-argument", # covered by Ruff ARG
]
[tool.ruff]
select = [
"E", "F", "W", # flake8
"B", "B904", # flake8-bugbear
"B", # flake8-bugbear
"I", # isort
"N", # pep8-naming
"ARG", # flake8-unused-arguments
@ -84,7 +87,6 @@ ignore = [
"SIM118", # iter(x) is not always the same as iter(x.keys())
]
target-version = "py37"
typing-modules = ["scikit_build_core._compat.typing"]
src = ["src"]
unfixable = ["T20"]
exclude = []

View File

@ -20,6 +20,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
License :: OSI Approved :: BSD License
Programming Language :: Python :: Implementation :: PyPy
Programming Language :: Python :: Implementation :: CPython

View File

@ -96,7 +96,7 @@ def get_and_replace(
# Use our input files instead when making the SDist (and anything that depends
# on it, like a wheel)
class SDist(setuptools.command.sdist.sdist): # type: ignore[misc]
class SDist(setuptools.command.sdist.sdist):
def make_release_tree(self, base_dir: str, files: List[str]) -> None:
super().make_release_tree(base_dir, files)

View File

@ -260,6 +260,15 @@ TEST_SUBMODULE(pytypes, m) {
});
});
m.def("return_capsule_with_destructor_3", []() {
py::print("creating capsule");
auto cap = py::capsule((void *) 1233, "oname", [](void *ptr) {
py::print("destructing capsule: {}"_s.format((size_t) ptr));
});
py::print("original name: {}"_s.format(cap.name()));
return cap;
});
m.def("return_renamed_capsule_with_destructor_2", []() {
py::print("creating capsule");
auto cap = py::capsule((void *) 1234, [](void *ptr) {

View File

@ -319,6 +319,19 @@ def test_capsule(capture):
"""
)
with capture:
a = m.return_capsule_with_destructor_3()
del a
pytest.gc_collect()
assert (
capture.unordered
== """
creating capsule
destructing capsule: 1233
original name: oname
"""
)
with capture:
a = m.return_renamed_capsule_with_destructor_2()
del a