Source code for schrodinger.application.matsci.codeutils
"""
Module for utilities related to code maintenance
Copyright Schrodinger, LLC. All rights reserved.
"""
import importlib
import warnings
import decorator
MATSCI_MODULE_BASE = 'schrodinger.application.matsci.'
[docs]def check_moved_variables(var_name, moved_variables):
"""
Check if the target variable has been moved, and if yes, post a warning
about it and return the variable in the new module
Raises AttributeError if a moved variable isn't found.
:param str var_name: Name of the target variable
:param tuple moved_variables: Tuple of tuples. Each inner tuple has a
format of (module, remove_release, variables), where `module` is the
new module name, `remove_release` is the release in which the link will
stop working, and `variables` are the set of variables that were moved
:raise AttributeError: If `var_name` is not a moved variable
:rtype: Any
:return: The moved variable
"""
for new_module_name, remove_release, variables in moved_variables:
if var_name not in variables:
continue
# The variable was moved. Show a warning and return the new variable.
if not new_module_name.startswith('schrodinger'):
# Convert to full path
new_module_name = MATSCI_MODULE_BASE + new_module_name
msg = (
f"'{var_name}' has been moved to the '{new_module_name}' module. The"
f" old usage will stop functioning in {remove_release} release.")
warnings.warn(msg, FutureWarning, stacklevel=3)
new_module = importlib.import_module(new_module_name)
return getattr(new_module, var_name)
raise AttributeError
[docs]@decorator.decorator
def deprecate(func, to_remove_in=None, replacement=None, *args, **kwargs):
"""
Post a warning about the function being deprecated
:param callable func: The function that is deprecated
:param str to_remove_in: The release in which the function will be removed
:param callable replacement: The function to call instead
"""
def name(x):
# qualname includes the method's class too
return f"{x.__module__}.{x.__qualname__}"
msg = (f"{name(func)} is deprecated and will be "
f"removed in {to_remove_in} release. ")
if replacement:
msg += f'Please use {name(replacement)} instead.'
warnings.warn(msg, FutureWarning, stacklevel=3)
return func(*args, **kwargs)