Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/src/zserio/cppbind.py: 100%

20 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-12-05 10:43 +0000

1""" 

2The module provides helper for importing of optimized C++ classes. 

3""" 

4 

5import importlib 

6import os 

7import typing 

8 

9ZSERIO_PYTHON_IMPLEMENTATION_ENV = "ZSERIO_PYTHON_IMPLEMENTATION" 

10ZSERIO_CPP_MODULE = "zserio_cpp" 

11 

12 

13def import_cpp_class(cppname: str, *, exception_class=None) -> typing.Optional[typing.Type[typing.Any]]: 

14 """ 

15 Tries to import optimized C++ implementation of the given python class if 'ZSERIO_PYTHON_IMPLEMENTATION' 

16 environment variable is either unset or set to 'cpp'. 

17 

18 Depending on the content of the 'ZSERIO_PYTHON_IMPLEMENTATION' environment variable, 

19 it either fails when no C++ implementation is available ('cpp') or ignores missing implementation 

20 and just return the original python class (None) or even does not try to load the C++ implementation if 

21 the variable is set to anyhing else (e.g. 'python'). 

22 

23 :param pyclass: Pure python class implemenation for which the C++ optimized version should be loaded. 

24 :param cppname: Name of optimized C++ class in case that it differs from the pyclass name. 

25 :param exception_class: Exception to raise in case of an error. 

26 :returns: Requested implemenation of the given pyclass. 

27 :raises PythonRuntimeException: When the requested implementation is not available. 

28 """ 

29 

30 if exception_class is None: 

31 # we need to break cyclic import from zserio.exception 

32 # pylint: disable-next=cyclic-import,import-outside-toplevel 

33 from zserio.exception import PythonRuntimeException 

34 

35 exception_class = PythonRuntimeException 

36 

37 impl = os.getenv(ZSERIO_PYTHON_IMPLEMENTATION_ENV) 

38 if not impl in [None, "python", "cpp", "c++"]: 

39 raise exception_class(f"Zserio Python runtime implementation '{impl}' is not available!") 

40 

41 if impl != "python": 

42 try: 

43 return getattr(importlib.import_module(ZSERIO_CPP_MODULE), cppname) 

44 except (ImportError, AttributeError) as err: 

45 if impl in ["cpp", "c++"]: 

46 message = f"Zserio C++ implementation of '{cppname}' is not available!" 

47 raise exception_class(message) from err 

48 return None