Source code for caikit.core.toolkit.compatibility

# Copyright The Caikit Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# Standard
import importlib
import sys

# First Party
import alog

# Local
from ..exceptions import error_handler

log = alog.use_channel("COMPATIBILITY")
error = error_handler.get(log)


[docs] def unsupported_platforms(platforms): """This decorator can be used to raise NotImplementedError if it's run on a given platform. Otherwise it runs as normal. For guidance on different permissible values of platforms, see: https://docs.python.org/3/library/sys.html#sys.platform Args: platforms (List | Tuple | str): Platforms on which this capability is not implemented. """ error.type_check("<COR48137162E>", list, tuple, str, platforms=platforms) if not isinstance(platforms, str): error.type_check_all("<COR92928316E>", str, platforms=platforms) def decorator(func): def wrapper(*args, **kwargs): if ( isinstance(platforms, str) and sys.platform == platforms ) or sys.platform in platforms: error( "<COR12233351E>", NotImplementedError( "Operation [{}] has not been implemented for platform [{}]".format( func.__name__, sys.platform ) ), ) return func(*args, **kwargs) return wrapper return decorator
[docs] def is_importable_on_platform(module, package, exc_type, platforms, platform_hint): """Some modules have trouble on specific operating systems. This function takes a module and package from which we want to import, and an exception type to look out for on a given problem. If the exception is raised, we warn the platform hint. NOTE: This function does set any properties on your package. You should use this function to check if something is importable, then you should import it. This will only run the package initialization one time, because this function will add your module into the loaded packages if it's successful, but doing things this way prevents your package from having a bunch of undesirable attributes and keeps it cleaner than other approaches. It also ensures that the import stack trace doesn't look abnormally handled if we raise on other platforms. Args: module (str): Module that we want to import. package (str): Package from which we want to import the module. exc_type (Exception): Exception that we want to warn a hint for if we hit it on import for a given platform. platforms (str): Platform on which we expect potential bad import from for this module. platform_hint (str): Hint to warn if we hit the exception type on the provided platform. """ error.type_check( "<COR48442162E>", str, module=module, package=package, platform_hint=platform_hint, ) error.type_check("<COR62245359E>", list, tuple, str, platforms=platforms) if not isinstance(platforms, str): error.type_check_all("<COR86935489E>", str, platforms=platforms) # If this is not a platform that needs special handling, just return True if ( isinstance(platforms, str) and sys.platform != platforms ) or sys.platform not in platforms: return True # We are running on a platform that has potential issues for this module. # If we succeed on import, return True. If we throw the known exception type, # catch it and log the hint, then return False. This is non-fatal. try: log.debug( "Determining if module {} is importable on platform {}".format( module, platforms ) ) importlib.import_module(module, package) return True except exc_type as e: log.warning( "Module [{}] from package [{}] failed to import on platform [{}]" " with error [{}] and will not be available.\nHINT: {}".format( module, package, platforms, str(e), platform_hint ) ) return False