coremltools 中的 pybind11 升级实战指南:从 v2.0 到 v2.12 的破坏性变更与迁移清单
AI 应用机器学习模型优化【免费下载链接】coremltoolsCore ML tools contain supporting tools for Core ML model conversion, editing, and validation.项目地址https://gitcode.com/gh_mirrors/co/coremltools点击查看免费下载导读pybind11 是 coremltools 项目 C 与 Python 之间最重要的桥梁它被用于编译libmilstoragepython.so读写 Core ML 权重 blob、libmodelpackage.so管理 .mlpackage 模型包以及 macOS 上的libcoremlpython.so封装 Core ML framework。当这些扩展模块跟随 pybind11 主版本升级时若干 API 与构建系统行为会发生破坏性变更。本文以仓库内 deps/pybind11/docs/upgrade.rst 为骨架系统梳理 pybind11 从 v2.0 到 v2.12 每个版本面向用户的变更弃用 API、替换方案、CMake 行为、符号可见性、类型语义并对照当前仓库 deps/pybind11 中捆绑的 2.13.1 源码与 milstoragepython/MilStoragePython.cpp、modelpackage/src/ModelPackagePython.cpp、coremlpython/CoreMLPython.mm 等真实绑定代码帮助你完成一次可验证、可落地的升级。读完本文你将能逐版本识别哪些写法已经弃用、知道每个弃用 API 的标准替换写法、理解 CMake 侧必须调整的选项并能照葫芦画瓢改造现有的 pybind11 绑定代码。一、为什么升级指南值得单独阅读pybind11 的 changelog 简要罗列了新特性、改进与 bug 修复而 upgrade.rst 只聚焦其中直接冲击你升级体验的子集并且讲得更深弃用 API 及其替换方案、构建系统变更、代码现代化以及其他实用信息。本文即按该文档的版本顺序v2.12 → v2.0展开并在每一节补充当前仓库内的源码佐证。在进入各版本之前先看看本仓库当前捆绑的 pybind11 版本与使用现状作为后续对照的基线捆绑版本deps/pybind11/include/pybind11/detail/common.h中PYBIND11_VERSION_MAJOR 2、PYBIND11_VERSION_MINOR 13、PYBIND11_VERSION_PATCH 1即pybind11 2.13.1同时 deps/pybind11/docs/changelog.rst 记载 2.13.1 于 2024 年 6 月 26 日发布。绑定入口milstoragepython/MilStoragePython.cpp 与 modelpackage/src/ModelPackagePython.cpp 仍然使用旧式PYBIND11_PLUGIN(name)宏 py::module m(...)return m.ptr()的写法其中MilStoragePython.cpp明确以py::module_local()注册_BlobStorageWriter/_BlobStorageReader并在注释中说明这是为了避免 coremltools 与 coremltools-internal 两个扩展模块之间的类型冲突——这正对应下文 v2.2 引入的 module-local 机制。另一侧coremlpython/CoreMLPython.mm 已经使用py::module_带下划线后缀的新命名与py::module_::import(...)反向导入coremltools.models.compute_plan、coremltools.models.model等 Python 模块对应下文 v2.6 的改名与 v2.9 的py::module_::import(types).attr(SimpleNamespace)模式。构建系统顶层 CMakeLists.txt 仍在使用find_package(PythonInterp)/find_package(PythonLibs)这正是下文 v2.11 与 v2.6 明确提示正在被弃用、未来将移除的旧机制仓库同时以CMAKE_CXX_STANDARD 17设置标准对应 v2.6 起推荐的CMAKE_CXX_STANDARDnumber方式。二、v2.12NumPy 2.x 支持与迁移要点从 pybind11 2.12.0 开始NumPy 支持升级到了 2.x 系列参见 changelog。两个直接相关的内部变化dtype.flags()现在返回uint64dtype.alignment()返回ssize_t在 NumPy 2.x 中itemsize()可能返回一个超出普通整型范围的值需要用相应宽度的有符号类型接收。早已弃用的 NumPy 函数PyArray_GetArrayParamsFromObject在 2.x 中已不可用。由于这些 NumPy 侧的变化升级到 NumPy 2 时可能遇到困难官方提供了一份 NumPy 2 迁移指南供参考。一个更直接的例子是NumPy 2 中默认整数类型int_以及uint现在是ssize_t而非long这会影响 64 位 Windows 平台上的对齐与隐式转换。只支持 NumPy 1.x 的临时开关如果暂时只打算支持 NumPy 1.x 并受上述两个内部变化困扰可以定义PYBIND11_NUMPY_1_ONLY来关闭新的 NumPy 2 支持。需要注意该宏必须在所有 pybind11 编译单元中保持一致地定义否则可能引发 ODR单一定义规则违规——这一点在 deps/pybind11/include/pybind11/detail/common.h 中通过PYBIND11_INTERNAL_NUMPY_1_ONLY_DETECTED标记机制加以检测该选项未来会被移除官方强烈建议尽快适配代码而不是长期依赖它。从仓库证据看本仓库捆绑的 deps/pybind11/include/pybind11/numpy.h 中大量出现#ifdef PYBIND11_NUMPY_1_ONLY分支例如第 183-188 行会在运行期检测到 NumPy 2 时抛出ImportError提示此扩展以 PYBIND11_NUMPY_1_ONLY 编译需要重新构建印证了该开关的完整实现路径。另外本仓库的coremlpython模块通过 coremlpython/CoreMLPythonArray.h 直接引入pybind11/numpy.hmilstoragepython则通过 milstoragepython/MilStorage.cpp 大量使用py::array_tT承载 int4/uint8/fp16/float 等权重数据——这些 numpy 数组接口正是 v2.12 NumPy 2 支持波及的核心区域升级时建议先用dtype.flags()类型、ssize_t相关断言与py::ssize_t显式转换参见 deps/pybind11/tests/test_numpy_array.cpp 中大量py::ssize_t用法做一轮自查。三、v2.11CMake 最低版本与 Python 查找机制的前瞻pybind11 的 CMake 最低版本要求提升到3.5未来版本可能进一步提升到 3.15 左右。需要注意 CMake3.27 正在移除早已弃用的FindPythonInterp支持如果你把 3.27 设为最低或最高支持版本时尤为明显。为应对这一趋势强烈建议在 CMake 3.15 上改用FindPython或设置PYBIND11_FINDPYTHON否则 pybind11 会在FindPythonInterp不可用时自动切换到FindPython。这一条与本仓库直接相关顶层 CMakeLists.txt 目前仍在使用find_package(PythonInterp)与find_package(PythonLibs)定位 Python 解释器与库并在 CMakeLists.txt 打印PYTHON_EXECUTABLE、PYTHON_VERSION_STRING、PYTHON_INCLUDE_DIRS。按照 v2.11 升级指南的提示这些旧机制在 pybind11 侧已被FindPython取代未来迁移时应将上述两行替换为find_package(Python COMPONENTS Interpreter Development)并改用Python::Python、Python::Module等新式目标。四、v2.9两个小而重要的 API 替换py::make_simple_namespace被替换任何近期新增的py::make_simple_namespace用法都应改为py::module_::import(types).attr(SimpleNamespace)。即先导入 Python 内置types模块再取SimpleNamespace属性使用。_缩写升级为const_name自定义类型转换器type caster中原本用_表示编译期常量字符串现在可以用更可读的const_name替代旧_快捷方式仍被保留除非它正被当作宏使用例如 gettext 场景。仓库佐证deps/pybind11/include/pybind11/cast.h 中PYBIND11_TYPE_CASTER已全面采用const_name(...)如const_namestd::is_integralT::value(int, float)、const_name(None)等说明本捆绑版本已完整落地该 APIdeps/pybind11/tests/test_pytypes.cpp 中也有py::module_::import(types).attr(SimpleNamespace)的测试佐证。五、v2.7py::str语义收紧字符串类型判断的重要行为变更v2.7 之前py::str可以持有PyUnicodeObject或PyBytesObjectpy::isinstancestr()对py::str和py::bytes都返回true。v2.7 起py::str只持有PyUnicodeObjectpy::isinstancestr()只对py::str返回true。为帮助用户平滑过渡pybind11 提供了PYBIND11_STR_LEGACY_PERMISSIVE宏作为逃生舱可以恢复旧行为——但该宏会在未来版本中移除。其语义在 deps/pybind11/include/pybind11/detail/common.h 中有完整注释DEFINED 时py::str可持有两种对象且isinstancestr对二者为真UNDEFINED 时只允许 Unicode仅 Python 2 下strcaster 会隐式把 bytes 解码为 Unicode。文档预计用户会遇到两类常见修复误用py::str代替py::bytes这类错误通常被旧行为掩盖修复很简单——把py::str改成py::bytes。依赖py::isinstancestr(obj)对py::bytes返回true多数场景下只需追加|| py::isinstancebytes(obj)但如果py::isinstanceT出现在模板中修复会更复杂需要仔细审查并定制修改。仓库里与本条相关的实践coremlpython的 CoreMLPython.mm 与 coremlpython/CoreMLPythonUtils.mm 中py::bytes、py::str均有实际使用升级时可按上述两条规则逐一核对字节串相关的桥接路径。六、v2.6命名、宏、构造语义与 CMake 的一揽子变更v2.6 是升级指南中体量最大的版本之一逐条对照如下。6.1 OVERLOAD → OVERRIDE 系列宏PYBIND11_OVERLOAD*宏和get_overload函数应替换为PYBIND11_OVERRIDE*与get_override。未来旧宏可能被正式弃用并移除。当前 deps/pybind11/include/pybind11/pybind11.h 已完整提供PYBIND11_OVERRIDE_IMPL、PYBIND11_OVERRIDE_NAME、PYBIND11_OVERRIDE_PURE_NAME、PYBIND11_OVERRIDE等新宏。6.2py::module改名为py::module_py::module已改名为py::module_但保留了向后兼容的 typedef。改名原因C20 语言规则不允许未限定的module出现在逻辑行开头限定用法如py::module不受影响typedef 会一直保留到 C 语言规则再次变化为止。仓库对照coremlpython/CoreMLPython.h第 58 行namespace py pybind11;、coremlpython/CoreMLPython.mm 使用py::module_与py::module_::import已采用新命名而 milstoragepython/MilStoragePython.cpp 与 modelpackage/src/ModelPackagePython.cpp 仍写py::module m(...)依赖兼容 typedef——这正是升级指南所说的过渡形态。6.3 模块构造与初始化语义收紧py::module_的公开构造函数已被弃用应改用PYBIND11_MODULE或module_::create_extension_module。子类忘记调用__init__现在会抛出错误此前不正确但未检查请补上__init__调用。向子类例如从py::object转py::bytes做非法转换时现在抛出py::type_error请改为合法转换。6.4 类型工具与 dunder 方法未文档化的h.get_type()已弃用替换为py::type::of(h)。枚举现在预定义了__str__方法若要覆盖它最简单的方式是在定义__str__时加上新的py::prepend()标签。如果定义了__eq__而未定义__hash____hash__现在会被置为None与 CPython 行为一致若希望类可哈希应补上__hash__可使用新的py::hash快捷方式。6.5 数组构造与工具迁移py::array的构造函数现在统一使用有符号整数作为尺寸以保证一致性某些系统上可能产生编译器警告应显式转换为py::ssize_t而不是std::size_t。本仓库捆绑版本的大量内部代码也统一使用py::ssize_t参见 deps/pybind11/tests/test_numpy_array.cpp。tools/clang子模块与tools/mkdoc.py已迁移到独立的pybind11-mkdoc包原使用者请通过 pip 从新位置安装使用。PyPI 上的pybind11包不再填充 wheel 的 headers 插槽如果你依赖该插槽获取头文件需要通过pip install pybind11[global]请求globalextra。绝大多数用户不受影响因为python -m pybind11 --includes与pybind11.get_include()报告的pybind11/include位置仍然正确自 2.5 起未变。6.6 CMake 支持变更v2.6 起生效PYBIND11_CPP_STANDARDplatform-flag已弃用请改用CMAKE_CXX_STANDARDnumber或任何其他合法的 CMake CXX/CUDA 标准选择方式如target_compile_features。本仓库已在 CMakeLists.txt 使用set(CMAKE_CXX_STANDARD 17)符合新方式。若未显式请求标准pybind11 目标将按编译器默认标准编译不低于 C11而不再强制 C14依赖旧行为的项目请显式set(CMAKE_CXX_STANDARD 14 CACHE STRING )。直接使用pybind11::module时应始终配合至少set(CMAKE_CXX_VISIBILITY_PRESET hidden)或等价设置——旧版曾尝试手动强制该编译选项但在部分编译器或 CUDA 下并不正确。pybind11_add_module的SYSTEM参数已弃用且不再生效链接行为现在与其他导入库在 config 与 submodule 模式下保持一致默认按SYSTEM库对待。若未设置PYTHON_EXECUTABLE虚拟环境venv、virtualenv、conda的优先级高于标准搜索与新版 FindPython 模式类似。CMAKE_INTERPROCEDURAL_OPTIMIZATION若被设置会被pybind11_add_module直接尊重而不再需要链接pybind11::lto/pybind11::thin_lto。在 pybind11 之前先执行find_package(Python COMPONENTS Interpreter Development)会让 pybind11 改用新版 Python 机制而非自研搜索后者基于打补丁的经典FindPythonInterp/FindPythonLibs未来这可能成为默认建议使用较新的 CMake3.15 或 3.18.2。结合上文 v2.11 一节本仓库的 CMakeLists.txt 正是等待迁移的旧式调用方。七、v2.5头文件随 Python 包分发Python 包现在把头文件作为数据放进包自身同时也放进 headers wheel 插槽。pybind11 --includes与pybind11.get_include()报告的始终是新位置无论 pybind11 如何安装都正确这使得旧的user参数失去意义。如果你还没有使用这两个入口获取头文件位置建议切换到包内位置。八、v2.2模块入口、构造函数、符号可见性与绑定本地化8.1PYBIND11_PLUGIN弃用PYBIND11_MODULE成为首选PYBIND11_MODULE现在是创建模块入口点的首选方式旧宏会发出编译期弃用警告。旧新写法对照来自原文档代码块// old PYBIND11_PLUGIN(example) { py::module m(example, documentation string); m.def(add, [](int a, int b) { return a b; }); return m.ptr(); } // new PYBIND11_MODULE(example, m) { m.doc() documentation string; // optional m.def(add, [](int a, int b) { return a b; }); }仓库佐证捆绑头文件 deps/pybind11/include/pybind11/detail/common.h 中PYBIND11_PLUGIN宏本身带有PYBIND11_DEPRECATED(PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE)属性而 milstoragepython/MilStoragePython.cpp 与 modelpackage/src/ModelPackagePython.cpp 目前仍使用旧式PYBIND11_PLUGIN(...)包装只是通过 CMakeLists.txt 的 clang 诊断抑制处理了-Wdeprecated-declarations。按照升级指南这两处是仓库中最典型的待迁移代码应改写为PYBIND11_MODULE(libmilstoragepython, m)/PYBIND11_MODULE(libmodelpackage, m)形式把return m.ptr();删除并把模块变量声明改为宏参数。8.2 自定义构造函数与 pickle从 placement-new 到py::init/py::pickle旧的 placement-new 自定义构造函数已被弃用新方案使用py::init()与工厂函数显著提升类型安全。placement-new 可能被意外地用不兼容类型调用没有任何编译器错误或警告或者在 Python 侧__init__调用不当的情况下重复初始化同一对象新式自定义构造函数可以避免这些错误详见 deps/pybind11/docs/advanced/classes.rst 的 custom constructors 章节。// old -- deprecated (runtime warning shown only in debug mode) py::classFoo(m, Foo) .def(__init__, [](Foo self, ...) { new (self) Foo(...); // uses placement-new }); // new py::classFoo(m, Foo) .def(py::init([](...) { // Note: no self argument return new Foo(...); // return by raw pointer // or: return std::make_uniqueFoo(...); // return by holder // or: return Foo(...); // return by value (move constructor) }));与此对应py::pickle()现在是设置与获取对象状态的推荐方式详见 deps/pybind11/docs/advanced/classes.rst 的 pickling 章节// old -- deprecated (runtime warning shown only in debug mode) py::classFoo(m, Foo) ... .def(__getstate__, [](const Foo self) { return py::make_tuple(self.value1(), self.value2(), ...); }) .def(__setstate__, [](Foo self, py::tuple t) { new (self) Foo(t[0].caststd::string(), ...); }); // new py::classFoo(m, Foo) ... .def(py::pickle( [](const Foo self) { // __getstate__ return py::make_tuple(self.value1(), self.value2(), ...); // unchanged }, [](py::tuple t) { // __setstate__, note: no self argument return new Foo(t[0].caststd::string(), ...); // or: return std::make_uniqueFoo(...); // return by holder // or: return Foo(...); // return by value (move constructor) } ));两种迁移的弃用警告都出现在模块初始化import时而非函数调用时且只在 debug 模式编译时可见。示例警告文本pybind11-bound class mymodule.Foo is using an old-style placement-new __init__ which has been deprecated. See the upgrade guide in pybind11s docs.8.3 隐藏符号可见性的更严格强制pybind11 现在更严格地强制模块的隐藏符号可见性命名空间级pybind11命名空间内部所有符号都被声明为 hidden——这在 deps/pybind11/include/pybind11/detail/common.h 中实现PYBIND11_NAMESPACE pybind11 __attribute__((visibility(hidden)))。它对用户基本透明但确保两点用不同 pybind11 版本编译的模块互不冲突py::module_local绑定等新特性能按预期工作。编译选项级Linux/macOS 上自动加入-fvisibilityhidden仅针对扩展模块不针对嵌入解释器场景。它同样作用于用户绑定代码pybind11命名空间之外好处是最小化模块间符号冲突例如两个无关模块静态链接了同一第三方库的不同 ABI 版本时符号冲突几乎必然且结果不可预测在 Linux/macOS 上产出更小的二进制与strip工具配合。pybind11 的 CMake 与 Python 构建系统会自动设置该标志其他构建系统需手动添加。pybind11_add_module此前只在 release 模式设置该标志现在无条件应用debug 模式也不例外且不能再通过NO_EXTRAS选项关闭pybind11::module目标现在也把该标志加入其 interfacepybind11::embed目标保持不变。对pybind11::module目标而言这是最显著的变化如果此前依赖默认可见性例如 Python 模块同时充当带依赖方的共享库你需要手动导出符号跨平台库的推荐做法或把共享库拆出来让 Python 模块像其他依赖方一样链接它。临时恢复默认可见性的 CMake 写法如下不推荐长期使用target_link_libraries(mymodule PRIVATE pybind11::module) add_library(restore_default_visibility INTERFACE) target_compile_options(restore_default_visibility INTERFACE -fvisibilitydefault) target_link_libraries(mymodule PRIVATE restore_default_visibility)仓库佐证顶层 CMakeLists.txt 在非 Debug 构建下对libmilstoragepython.so与libmodelpackage.so执行strip -x正是文档所述隐藏可见性 strip 得到更小二进制的组合实践而 CMakeLists.txt 为 macOS 的coremlpython目标显式使用-Wl,-exported_symbols_list导出符号清单文件 coremlpython/exported_symbols_osx.ver即为手动导出符号的典型方案。8.4 本地 STL 容器绑定module-local早期 pybind11 只能全局绑定类型——所有模块哪怕互不相关都能访问同一批导出类型若两个模块导出同一个 C 类型就会冲突这对std::vectorint这类极常见类型尤其麻烦。module_local机制就是为解决此问题而引入的完整用法见 deps/pybind11/docs/advanced/classes.rst 的 module-local class bindings 章节。py::class_仍默认全局绑定因为这类类型通常跨模块唯一但为避免不透明类型冲突py::bind_vector与py::bind_map在元素满足以下任一条件时会把 STL 容器绑定为py::module_local元素是内建类型int、float等、未用py::class_绑定、或本身已绑定为py::module_local。例如该变更允许多个模块各自绑定std::vectorint而不冲突详见 deps/pybind11/docs/advanced/cast/stl.rst 的 stl_bind 章节。升级到该版本时若存在多个模块依赖同一 STL 容器的单个全局绑定请注意所有模块仍可接受外来的py::module_local类型Python→C 方向不受限本地性只影响 C→Python 方向。如果多个模块都需要这种能力只能二选一给所有需要它的模块各自拷贝一份相同的 STL 绑定用py::module_local(false)把该绑定恢复为全局状态。后者是快捷的临时方案但长期来看为规避第三方模块冲突最好把所有常见类型绑定都本地化。仓库佐证milstoragepython/MilStoragePython.cpp 中注册_BlobStorageWriter/_BlobStorageReader时明确传入py::module_local()注释写明因为同一个 MilStoragePythonWriter 类在两个扩展模块中都有 pybind 绑定需要 module_local 以避免 coremltools 与 coremltools-internal 的冲突——这正是 v2.2 该特性的生产级应用实例。8.5 负步幅buffer 与 numpy 数组接口改有符号整数对 Python buffer 对象与 numpy 数组的负步幅支持要求py::buffer_info与py::array接口中的整数类型从无符号改为有符号。开启编译器警告时升级后可能看到新的转换警告用static_cast显式转换即可消除。8.6 若干py::objectAPI 弃用按指针比较py::object实例请改用obj1.is(obj2)等价于 Python 的obj1 is obj2。此前用operatorobj1 obj2语义容易混淆现已弃用以便未来替换为真正的富比较。对继承自py::object的类borrowed与stolen原本是受保护的构造标签现在应直接使用类型borrowed_t{}与stolen_t{}。8.7 更严格的编译期错误检查部分错误检查从运行期移到编译期当T未直接以py::class_T注册时例如std::shared_ptrint、std::shared_ptrstd::vectorT不再支持其std::shared_ptrT的自动转换绑定此类参数的函数现在直接报编译期错误而不是等到运行期失败。py::init...()构造函数定义更严格会阻止可能引发意外行为的绑定struct Example { Example(int ); }; py::class_Example(m, Example) .def(py::initint ()); // OK, exact match // .def(py::initint()); // compile-time error, mismatch注意非const左值引用不能绑定到右值但接受const T 的构造函数仍可以用py::initT()注册因为const左值引用可以绑定右值。九、v2.1编译器门槛与 metaclass 简化9.1 编译器最低版本改为编译期强制编译器最低要求同样适用于 v2.0但从 v2.1 起检查显式化——编译器不达标会直接编译期报错GCC 4.8clang 3.3appleclang 5.0MSVC 2015u3Intel C 15.09.2 静态属性不再需要py::metaclass绑定含静态属性的类现在默认可用零参数版py::metaclass()已弃用。新增的单参数py::metaclass(python_type)用于少数需要自定义元类以覆盖 pybind11 默认行为的场景// old -- emits a deprecation warning py::class_Foo(m, Foo, py::metaclass()) .def_property_readonly_static(foo, ...); // new -- static properties work without the attribute py::class_Foo(m, Foo) .def_property_readonly_static(foo, ...); // new -- advanced feature, override pybind11s default metaclass py::class_Bar(m, Bar, py::metaclass(custom_python_type)) ...十、v2.0py::class_的破坏性变更与旧 API 清理这些变更旨在让 pybind11 的类型定义面向未来支持 PyPy 的cpyext机制并提升效率。10.1py::class_的三项破坏性变更buffer 协议类型必须显式标注通过 buffer 协议提供访问的类型必须在py::class_构造函数参数中加上py::buffer_protocol()标注py::class_Matrix(Matrix, py::buffer_protocol()) .def(py::init...()) .def_buffer(...);静态属性需要py::metaclass()含静态属性如def_readwrite_static()的类必须带上py::metaclass()属性。注意该要求在 v2.1 中已被移除若从 1.x 升级建议直接跳到 v2.1 或更新版本。trampoline 类语法重构用于在 Python 中覆盖虚方法的 trampoline 类改用了全新实例化机制语法随之变化// old v1.x syntax py::class_TrampolineClass(MyClass) .aliasMyClass() ... // new v2.x syntax py::class_MyClass, TrampolineClass(MyClass) ...重要的是原始类与 trampoline 类现在都作为py::class_模板参数给出alias..()调用被移除。新机制在 Python 不覆盖底层 C 类任何函数时零开销。类类型必须是py::class_的第一个模板参数trampoline 可与其他参数以任意顺序混合见下节。10.2py::baseT()弃用py::baseT()已被弃用改为把T作为py::class_的模板参数新语法还支持多继承。导出类型必须是py::class_Class, ...模板的第一个参数其余参数基类、holder、trampoline顺序无关// old v1.x py::class_Derived(Derived, py::baseBase()); // new v2.x py::class_Derived, Base(Derived); // new -- multiple inheritance py::class_Derived, Base1, Base2(Derived); // new -- apart from Derived the argument order can be arbitrary py::class_Derived, Base1, Holder, Base2, Trampoline(Derived);10.3std::shared_ptr开箱支持相关 type caster 现已内建不再需要声明形如PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptrT)的宏继续写也不会报错或警告但已完全冗余。仓库佐证modelpackage/src/ModelPackagePython.cpp 中py::class_MPL::ModelPackageItemInfo, std::shared_ptrMPL::ModelPackageItemInfo(...)正是把 holder 直接作为模板参数的新式写法。10.4 若干py::objectAPI 弃用对照表以下旧式调用都会产生弃用警告旧语法新语法obj.call(args...)obj(args...)obj.str()py::str(obj)auto l py::list(obj); l.check()py::isinstancepy::list(obj)py::object(ptr, true)py::reinterpret_borrowpy::object(ptr)py::object(ptr, false)py::reinterpret_stealpy::object(ptr)if (obj.attr(foo))if (py::hasattr(obj, foo))if (obj[bar])if (obj.contains(bar))十一、升级实操建议对照本仓库的迁移清单综合以上各版本把指南落到 coremltools 仓库本身可以得到一份可直接照做的检查清单模块入口v2.2/v2.6将 milstoragepython/MilStoragePython.cpp 与 modelpackage/src/ModelPackagePython.cpp 中的PYBIND11_PLUGINpy::modulereturn m.ptr()改写为PYBIND11_MODULE(name, m)形式并把py::module写全为py::module_对应 CMakeLists.txt 与 modelpackage/src/ModelPackagePython.cpp 中的-Wdeprecated-declarations抑制即可移除。模块本地化v2.2MilStoragePython.cpp已正确使用py::module_local()无需改动ModelPackagePython.cpp中的std::shared_ptrholder 写法已符合 v2.0 新语法。构建系统v2.6/v2.11将 CMakeLists.txt 的find_package(PythonInterp)/find_package(PythonLibs)迁移为find_package(Python COMPONENTS Interpreter Development)避免未来 CMake 3.27 移除旧模块后失效继续沿用CMAKE_CXX_STANDARD当前为 17而非已弃用的PYBIND11_CPP_STANDARD。NumPy 边界v2.12对 milstoragepython/MilStorage.cpp 与 coremlpython/CoreMLPythonArray.h 涉及的py::array_tT接口做一次ssize_t类型审计确认升级 NumPy 2 后无itemsize/strides隐式转换告警。符号可见性v2.2macOS 上 CMakeLists.txt 已通过导出符号清单控制coremlpython的符号迁移后的milstoragepython、modelpackage若复用pybind11::module目标需注意其 interface 已默认携带-fvisibilityhidden必要时按 8.3 节方案手动导出符号。最后升级前请以 deps/pybind11/tests 中的对应测试如test_numpy_array.cpp、test_pytypes.cpp、test_stl_binders.cpp为行为基准跑一遍自身绑定代码的回归测试pybind11 的弃用警告在 debug 编译下于模块 import 时即会打印可作为迁移进度的可视化检查器。赞分享AI 应用机器学习模型优化【免费下载链接】coremltoolsCore ML tools contain supporting tools for Core ML model conversion, editing, and validation.项目地址https://gitcode.com/gh_mirrors/co/coremltools点击查看免费下载相关推荐pybind11 升级指南从 v2.0 到 v3.0 的迁移路线、破坏性变更与实战要点pybind11 升级指南从 v2.0 到 v3.0 的迁移路线、破坏性变更与实战要点 本文是 pybind11 官方 docs/upgrade.rst ht开发工具CodeIgniter 4.2.2 升级指南从 4.2.1 升级的破坏性变更与迁移清单CodeIgniter 4.2.2 升级指南从 4.2.1 升级的破坏性变更与迁移清单 本篇升级指南以 CodeIgniter4 官方文档 upgrade_4后端Web框架GUN 版本演进与迁移实战指南从 0.3 到 0.2020 的 API 变迁、破坏性变更与升级清单GUN 版本演进与迁移实战指南从 0.3 到 0.2020 的 API 变迁、破坏性变更与升级清单 本文以 GUN 官方 CHANGELOG 为骨架梳理 G数据库图数据库后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考