From 11159379a564e2cbf05a0c546d7507d76a983e8a Mon Sep 17 00:00:00 2001 From: ManifoldFR <wilson.jallet@polytechnique.org> Date: Sun, 28 Apr 2024 23:01:49 +0200 Subject: [PATCH] Add deprecation call policy --- CMakeLists.txt | 1 + include/eigenpy/deprecation-policy.hpp | 62 ++++++++++++++++++++++ unittest/CMakeLists.txt | 3 ++ unittest/deprecation_policy.cpp | 24 +++++++++ unittest/python/test_deprecation_policy.py | 4 ++ 5 files changed, 94 insertions(+) create mode 100644 include/eigenpy/deprecation-policy.hpp create mode 100644 unittest/deprecation_policy.cpp create mode 100644 unittest/python/test_deprecation_policy.py diff --git a/CMakeLists.txt b/CMakeLists.txt index ec07537d..bcc8f989 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,6 +220,7 @@ set(${PROJECT_NAME}_HEADERS ${${PROJECT_NAME}_DECOMPOSITIONS_HEADERS} include/eigenpy/alignment.hpp include/eigenpy/computation-info.hpp + include/eigenpy/deprecation-policy.hpp include/eigenpy/eigenpy.hpp include/eigenpy/exception.hpp include/eigenpy/scalar-conversion.hpp diff --git a/include/eigenpy/deprecation-policy.hpp b/include/eigenpy/deprecation-policy.hpp new file mode 100644 index 00000000..c1635ea1 --- /dev/null +++ b/include/eigenpy/deprecation-policy.hpp @@ -0,0 +1,62 @@ +// +// Copyright (C) 2024 LAAS-CNRS, INRIA +// +#ifndef __eigenpy_deprecation_hpp__ +#define __eigenpy_deprecation_hpp__ + +#include "eigenpy/fwd.hpp" + +namespace eigenpy { + +enum class DeprecationType { DEPRECATION, FUTURE }; + +namespace detail { + +constexpr PyObject *deprecationTypeToPyObj(DeprecationType dep) { + switch (dep) { + case DeprecationType::DEPRECATION: + return PyExc_DeprecationWarning; + case DeprecationType::FUTURE: + return PyExc_FutureWarning; + } +} + +} // namespace detail + +constexpr char defaultDeprecationMessage[] = + "This function or attribute has been marked as deprecated, and will be " + "removed in the " + "future."; + +/// @brief A Boost.Python call policy which triggers a Python warning on +/// precall. +template <DeprecationType deprecation_type = DeprecationType::DEPRECATION, + class BasePolicy = bp::default_call_policies> +struct deprecation_warning_policy : BasePolicy { + using result_converter = typename BasePolicy::result_converter; + using argument_package = typename BasePolicy::argument_package; + + deprecation_warning_policy( + const std::string &warning_msg = defaultDeprecationMessage) + : BasePolicy(), m_what(warning_msg) {} + + const std::string what() const { return m_what; } + + const BasePolicy *derived() const { + return static_cast<const BasePolicy *>(this); + } + + template <class ArgPackage> + bool precall(const ArgPackage &args) const { + PyErr_WarnEx(detail::deprecationTypeToPyObj(deprecation_type), + m_what.c_str(), 1); + return derived()->precall(args); + } + + private: + const std::string m_what; +}; + +} // namespace eigenpy + +#endif // ifndef __eigenpy_deprecation_hpp__ diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 09b35a02..d0c216fb 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -37,6 +37,7 @@ endif() add_lib_unit_test(tensor) add_lib_unit_test(geometry) add_lib_unit_test(complex) +add_lib_unit_test(deprecation_policy) add_lib_unit_test(return_by_ref) add_lib_unit_test(include) if(NOT ${EIGEN3_VERSION} VERSION_LESS "3.2.0") @@ -104,6 +105,8 @@ add_python_lib_unit_test("py-matrix" "unittest/python/test_matrix.py") add_python_lib_unit_test("py-tensor" "unittest/python/test_tensor.py") add_python_lib_unit_test("py-geometry" "unittest/python/test_geometry.py") add_python_lib_unit_test("py-complex" "unittest/python/test_complex.py") +add_python_lib_unit_test("py-deprecation-policy" + "unittest/python/test_deprecation_policy.py") add_python_lib_unit_test("py-return-by-ref" "unittest/python/test_return_by_ref.py") add_python_lib_unit_test("py-eigen-ref" "unittest/python/test_eigen_ref.py") diff --git a/unittest/deprecation_policy.cpp b/unittest/deprecation_policy.cpp new file mode 100644 index 00000000..d06d4954 --- /dev/null +++ b/unittest/deprecation_policy.cpp @@ -0,0 +1,24 @@ +#include "eigenpy/eigenpy.hpp" +#include "eigenpy/deprecation-policy.hpp" + +#include <iostream> + +namespace bp = boost::python; +using eigenpy::DeprecationType; + +void some_deprecated_function() { + std::cout << "Calling this should produce a warning" << std::endl; +} + +void some_future_deprecated_function() { + std::cout + << "Calling this should produce a warning about a future deprecation" + << std::endl; +} + +BOOST_PYTHON_MODULE(deprecation_policy) { + bp::def("some_deprecated_function", some_deprecated_function, + eigenpy::deprecation_warning_policy<DeprecationType::DEPRECATION>()); + bp::def("some_future_deprecated_function", some_future_deprecated_function, + eigenpy::deprecation_warning_policy<DeprecationType::FUTURE>()); +} diff --git a/unittest/python/test_deprecation_policy.py b/unittest/python/test_deprecation_policy.py new file mode 100644 index 00000000..b47550c7 --- /dev/null +++ b/unittest/python/test_deprecation_policy.py @@ -0,0 +1,4 @@ +from deprecation_policy import some_deprecated_function, some_future_deprecated_function + +some_deprecated_function() +some_future_deprecated_function() -- GitLab