File size: 1,692 Bytes
1bfc3f0
7c09a0c
 
 
 
 
1bfc3f0
7c09a0c
 
1bfc3f0
7c09a0c
1bfc3f0
 
 
 
 
 
 
7c09a0c
 
 
 
 
 
 
1bfc3f0
 
 
 
 
7c09a0c
 
 
 
1bfc3f0
 
7c09a0c
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
"""Dispatch AC2 numerical work to the optional C++ runtime."""

from __future__ import annotations

import os

__all__ = ["native", "have_native", "require_native", "resolve_backend", "native_kernel"]

try:  # pragma: no cover - exercised by whichever branch the build state picks
    from . import _native as native
except ImportError:  # pragma: no cover
    try:
        from actioncodec2.core.backends.actioncodec2 import _native as native
    except ImportError:
        try:
            from actioncodec2_kernels import _native as native
        except ImportError:
            native = None


def have_native() -> bool:
    """True when the compiled kernels are importable and not disabled."""
    return native is not None and not os.environ.get("ACTIONCODEC2_NO_NATIVE")


def native_kernel(name: str):
    """Resolve an optional kernel, honoring the Python reference override."""
    return getattr(native, name, None) if have_native() else None


def require_native():
    """Return the native module or explain how to get one."""
    if not have_native():
        raise RuntimeError(
            "the actioncodec2 native extension is not available; run "
            "'python setup.py build_ext --inplace' from the repository root or "
            "select backend='python'"
        )
    return native


def resolve_backend(backend: str) -> str:
    """Turn ``'auto'`` into a concrete backend name."""
    if backend not in {"auto", "native", "python"}:
        raise ValueError("backend must be 'auto', 'native' or 'python'")
    if backend == "auto":
        return "native" if have_native() else "python"
    if backend == "native":
        require_native()
    return backend