Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PyOV] Added deprecation function #12540

Merged
19 changes: 19 additions & 0 deletions src/bindings/python/src/openvino/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

adrianboguszewski marked this conversation as resolved.
Show resolved Hide resolved
import os
import sys
from functools import wraps
from typing import Callable, Any


def add_openvino_libs_to_path() -> None:
Expand All @@ -28,3 +30,20 @@ def add_openvino_libs_to_path() -> None:
# On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH.
if (3, 8) <= sys.version_info:
os.add_dll_directory(os.path.abspath(lib_path))


def deprecated(version: str = "", message: str = "") -> Callable[..., Any]:
p-wysocki marked this conversation as resolved.
Show resolved Hide resolved
"""Prints deprecation warning "{function_name} is deprecated and will be removed in version {version}. {message}" and runs the function.

:param version: The version in which the code will be removed.
:param message: A message explaining why the function is deprecated and/or what to use instead.
"""
def decorator(wrapped: Callable[..., Any]) -> Callable[..., Any]:
@wraps(wrapped)
def wrapper(*args: Any, **kwargs: Any) -> Callable[..., Any]:
# it must be imported here; otherwise, there are errors with no loaded DLL for Windows
from openvino.pyopenvino.util import deprecation_warning
adrianboguszewski marked this conversation as resolved.
Show resolved Hide resolved
deprecation_warning(wrapped.__name__, version, message)
return wrapped(*args, **kwargs)
return wrapper
return decorator
24 changes: 10 additions & 14 deletions src/bindings/python/src/pyopenvino/graph/passes/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
#include "openvino/pass/manager.hpp"

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <utility>

#include "openvino/pass/constant_folding.hpp"
#include "openvino/pass/pass.hpp"
#include "openvino/pass/serialize.hpp"
#include "openvino/pass/validate.hpp"
#include "pyopenvino/graph/passes/manager.hpp"
#include "pyopenvino/utils/utils.hpp"

namespace py = pybind11;

Expand Down Expand Up @@ -69,10 +68,9 @@ void regclass_passes_Manager(py::module m) {
manager.def(
"register_pass",
[](ov::pass::Manager& self, const std::string& pass_name) -> void {
PyErr_WarnEx(PyExc_DeprecationWarning,
"register_pass with this arguments is deprecated! "
"Please use register_pass(ConstantFolding()) instead.",
1);
Common::utils::deprecation_warning("register_pass(pass_name)",
"",
"Please use register_pass(ConstantFolding()) instead.");
jiwaszki marked this conversation as resolved.
Show resolved Hide resolved
if (pass_name == "ConstantFolding") {
self.register_pass<ov::pass::ConstantFolding>();
}
Expand All @@ -93,10 +91,9 @@ void regclass_passes_Manager(py::module m) {
const std::string& pass_name,
const FilePaths& file_paths,
const std::string& version) -> void {
PyErr_WarnEx(PyExc_DeprecationWarning,
"register_pass with this arguments is deprecated! "
"Please use register_pass(Serialize(xml, bin, version)) instead.",
1);
Common::utils::deprecation_warning("register_pass(pass_name, output_files, version)",
"",
"Please use register_pass(Serialize(xml, bin, version)) instead.");
if (pass_name == "Serialize") {
self.register_pass<ov::pass::Serialize>(file_paths.first,
file_paths.second,
Expand Down Expand Up @@ -139,10 +136,9 @@ void regclass_passes_Manager(py::module m) {
const std::string& xml_path,
const std::string& bin_path,
const std::string& version) -> void {
PyErr_WarnEx(PyExc_DeprecationWarning,
"register_pass with this arguments is deprecated! "
"Please use register_pass(Serialize(xml, bin, version)) instead.",
1);
Common::utils::deprecation_warning("register_pass(pass_name, xml_path, bin_path, version",
"",
"Please use register_pass(Serialize(xml, bin, version)) instead.");
if (pass_name == "Serialize") {
self.register_pass<ov::pass::Serialize>(xml_path, bin_path, convert_to_version(version));
}
Expand Down
17 changes: 17 additions & 0 deletions src/bindings/python/src/pyopenvino/graph/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "openvino/core/graph_util.hpp"
#include "openvino/core/validation_util.hpp"
#include "openvino/pass/manager.hpp"
#include "pyopenvino/utils/utils.hpp"

namespace py = pybind11;

Expand Down Expand Up @@ -70,4 +71,20 @@ void regmodule_graph_util(py::module m) {
py::arg("target"),
py::arg("replacement"),
py::arg("outputs_order"));

mod.def(
"deprecation_warning",
[](const std::string& function_name, const std::string& version, const std::string& message) {
Common::utils::deprecation_warning(function_name, version, message);
},
py::arg("function_name"),
py::arg("version") = "",
py::arg("message") = "",
R"(
Prints deprecation warning "{function_name} is deprecated and will be removed in version {version}. {message}".

:param function_name: The name of the deprecated function.
:param version: The version in which the code will be removed.
:param message: A message explaining why the function is deprecated.
)");
}
12 changes: 12 additions & 0 deletions src/bindings/python/src/pyopenvino/utils/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,17 @@ std::string convert_path_to_string(const py::object& path) {
"Examples:\n(1) '/home/user/models/model.onnx'\n(2) Path('/home/user/models/model/model.onnx')";
throw ov::Exception(str.str());
}

void deprecation_warning(const std::string& function_name, const std::string& version, const std::string& message) {
std::stringstream ss;
ss << function_name << " is deprecated";
if (!version.empty()) {
ss << " and will be removed in version " << version;
}
if (!message.empty()) {
ss << ". " << message;
}
PyErr_WarnEx(PyExc_DeprecationWarning, ss.str().data(), 2);
}
}; // namespace utils
}; // namespace Common
2 changes: 2 additions & 0 deletions src/bindings/python/src/pyopenvino/utils/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ namespace utils {
std::map<std::string, ov::Any> properties_to_any_map(const std::map<std::string, py::object>& properties);

std::string convert_path_to_string(const py::object& path);

void deprecation_warning(const std::string& function_name, const std::string& version = std::string(), const std::string& message = std::string());
adrianboguszewski marked this conversation as resolved.
Show resolved Hide resolved
}; // namespace utils
}; // namespace Common

Expand Down
13 changes: 13 additions & 0 deletions src/bindings/python/tests/test_graph/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import numpy as np
import openvino.runtime as ov
import pytest
from openvino.pyopenvino.util import deprecation_warning
from openvino.runtime import Shape


Expand All @@ -27,3 +29,14 @@ def test_get_constant_from_source_failed():
folded_const = ov.utils.get_constant_from_source(reshape.input(1).get_source_output())

assert folded_const is None


def test_deprecation_warning():
with pytest.warns(DeprecationWarning, match="function1 is deprecated"):
deprecation_warning("function1")
with pytest.warns(DeprecationWarning, match="function2 is deprecated and will be removed in version 2025.4"):
deprecation_warning("function2", "2025.4")
with pytest.warns(DeprecationWarning, match="function3 is deprecated. Use another function instead"):
deprecation_warning("function3", message="Use another function instead")
with pytest.warns(DeprecationWarning, match="function4 is deprecated and will be removed in version 2025.4. Use another function instead"):
deprecation_warning("function4", version="2025.4", message="Use another function instead")
36 changes: 33 additions & 3 deletions src/bindings/python/tests/test_utils/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
# Copyright (C) 2018-2022 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

from typing import Tuple, Union, List

import numpy as np
import openvino
import openvino.runtime.opset8 as ops
import pytest
from openvino.runtime import Model, Core, Shape, Type
from openvino.runtime.op import Parameter
import openvino.runtime.opset8 as ops
from typing import Tuple, Union, List
import numpy as np
from openvino.utils import deprecated


def get_test_model():
Expand Down Expand Up @@ -49,3 +52,30 @@ def generate_add_model() -> openvino.pyopenvino.Model:
param2 = ops.parameter(Shape([2, 1]), dtype=np.float32, name="data2")
add = ops.add(param1, param2)
return Model(add, [param1, param2], "TestFunction")


def test_deprecation_decorator():
@deprecated()
def deprecated_function1(param1, param2=None):
pass

@deprecated(version="2025.4")
def deprecated_function2(param1=None):
pass

@deprecated(message="Use another function instead")
def deprecated_function3():
pass

@deprecated(version="2025.4", message="Use another function instead")
def deprecated_function4():
pass

with pytest.warns(DeprecationWarning, match="deprecated_function1 is deprecated"):
deprecated_function1("param1")
with pytest.warns(DeprecationWarning, match="deprecated_function2 is deprecated and will be removed in version 2025.4"):
deprecated_function2(param1=1)
with pytest.warns(DeprecationWarning, match="deprecated_function3 is deprecated. Use another function instead"):
deprecated_function3()
with pytest.warns(DeprecationWarning, match="deprecated_function4 is deprecated and will be removed in version 2025.4. Use another function instead"):
deprecated_function4()