diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 8c5884e3a9..4e7480495e 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(example_scripts) add_subdirectory(tests) -set(PYEXEC_FILES __init__.py function_class.py gnucash_business.py gnucash_core.py app_utils.py) +set(PYEXEC_FILES __init__.py function_class.py gnucash_business.py gnucash_core.py app_utils.py deprecation.py) set(SWIG_FILES ${CMAKE_CURRENT_SOURCE_DIR}/gnucash_core.i ${CMAKE_CURRENT_SOURCE_DIR}/time64.i) set(GNUCASH_CORE_C_INCLUDES diff --git a/bindings/python/__init__.py b/bindings/python/__init__.py index 16b72fba9d..8b3e0b6870 100644 --- a/bindings/python/__init__.py +++ b/bindings/python/__init__.py @@ -5,6 +5,7 @@ # >>> from gnucash.gnucash_core import thingy from gnucash.gnucash_core import * from . import app_utils +from . import deprecation ## @file # @brief helper file for the importing of gnucash # @author Mark Jenkins, ParIT Worker Co-operative diff --git a/bindings/python/deprecation.py b/bindings/python/deprecation.py new file mode 100644 index 0000000000..81d4cdc362 --- /dev/null +++ b/bindings/python/deprecation.py @@ -0,0 +1,68 @@ +# deprecation.py - gnucash submodule with deprecation related content +# +# contains decorator methods dealing with deprecated methods and +# deprecation related convenience methods +# +# @brief gnucash submodule with deprecation related content +# @author Christoph Holtermann +# @ingroup python_bindings + +from functools import wraps + +# use of is_new, force_new and ignore_lock is deprecated, use mode instead +# the following decorators enable backward compatibility for the deprecation period +def deprecated_args_session(ignore_lock_or_mode=None, is_new=None, + force_new=None, mode=None, ignore_lock=None): + + # check for usage of deprecated arguments (ignore_lock, is_new, force_new) + deprecated_args = (ignore_lock, is_new, force_new) + deprecated_keyword_use = deprecated_args.count(None) != len(deprecated_args) + if deprecated_keyword_use: + # deprecated arguments have been used by keyword or more than three args have been used which is only possible with the deprecated args + deprecation = True + else: + deprecation = False + # __init__ could have been called without keywords like __init__(book_uri, True) where True aims at ignore_lock + # which ist not distinguishable from __init__(book, SessionOpenMode.SESSION_NORMAL_OPEN) + # so if mode has not been set by keyword use the 3rd argument + if mode is None: + mode = ignore_lock_or_mode + + if deprecation: + # if any(item in ("is_new", "ignore_lock", "force_new") for item in kwargs): + import warnings + warnings.warn( + "Use of ignore_lock, is_new or force_new arguments is deprecated. Use mode argument instead. Have a look at gnucash.SessionOpenMode.", + category=DeprecationWarning, + stacklevel=3 + ) + + # if not provided calculate mode from deprecated args + if mode is None: + from gnucash.gnucash_core import SessionOpenMode + ignore_lock = False if ignore_lock is None else ignore_lock + is_new = False if is_new is None else is_new + force_new = False if force_new is None else force_new + mode = SessionOpenMode((ignore_lock << 2) + (is_new << 1) + force_new) + + return mode + +def deprecated_args_session_init(original_function): + """decorator for Session.__init__() to provide backward compatibility for deprecated use of ignore_lock, is_new and force_new""" + @wraps(original_function) + def new_function(self, book_uri=None, ignore_lock_or_mode=None, is_new=None, + force_new=None, instance=None, mode=None, ignore_lock=None): + + mode = deprecated_args_session(ignore_lock_or_mode, is_new, force_new, mode, ignore_lock) + return(original_function(self, book_uri=book_uri, mode=mode, instance=instance)) + return new_function + +def deprecated_args_session_begin(original_function): + """decorator for Session.begin() to provide backward compatibility for deprecated use of ignore_lock, is_new and force_new""" + @wraps(original_function) + def new_function(self, new_uri=None, ignore_lock_or_mode=None, is_new=None, + force_new=None, mode=None, ignore_lock=None): + mode = deprecated_args_session(ignore_lock_or_mode, is_new, force_new, mode, ignore_lock) + return(original_function(self, new_uri=new_uri, mode=mode)) + return new_function +