Source code for zserio.cppbind
"""
The module provides helper for importing of optimized C++ classes.
"""
import importlib
import os
import typing
ZSERIO_PYTHON_IMPLEMENTATION_ENV = "ZSERIO_PYTHON_IMPLEMENTATION"
ZSERIO_CPP_MODULE = "zserio_cpp"
[docs]def import_cpp_class(cppname: str, *, exception_class=None) -> typing.Optional[typing.Type[typing.Any]]:
"""
Tries to import optimized C++ implementation of the given python class if 'ZSERIO_PYTHON_IMPLEMENTATION'
environment variable is either unset or set to 'cpp'.
Depending on the content of the 'ZSERIO_PYTHON_IMPLEMENTATION' environment variable,
it either fails when no C++ implementation is available ('cpp') or ignores missing implementation
and just return the original python class (None) or even does not try to load the C++ implementation if
the variable is set to anyhing else (e.g. 'python').
:param pyclass: Pure python class implemenation for which the C++ optimized version should be loaded.
:param cppname: Name of optimized C++ class in case that it differs from the pyclass name.
:param exception_class: Exception to raise in case of an error.
:returns: Requested implemenation of the given pyclass.
:raises PythonRuntimeException: When the requested implementation is not available.
"""
if exception_class is None:
# we need to break cyclic import from zserio.exception
# pylint: disable-next=cyclic-import,import-outside-toplevel
from zserio.exception import PythonRuntimeException
exception_class = PythonRuntimeException
impl = os.getenv(ZSERIO_PYTHON_IMPLEMENTATION_ENV)
if not impl in [None, "python", "cpp", "c++"]:
raise exception_class(f"Zserio Python runtime implementation '{impl}' is not available!")
if impl != "python":
try:
return getattr(importlib.import_module(ZSERIO_CPP_MODULE), cppname)
except (ImportError, AttributeError) as err:
if impl in ["cpp", "c++"]:
message = f"Zserio C++ implementation of '{cppname}' is not available!"
raise exception_class(message) from err
return None