Coverage for src\pqlattice\settings.py: 58%

40 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2026-01-10 12:32 +0100

1import contextlib 

2from collections.abc import Generator 

3from typing import Literal 

4 

5from ._backends._fast import FastBackend 

6from ._backends._native import NativeBackend 

7from ._backends._protocol import BackendInterface 

8 

9BackendName = Literal["native", "fast"] 

10 

11 

12class _Settings: 

13 def __init__(self) -> None: 

14 self._active_backend_name: BackendName = "native" 

15 self._native_backend = NativeBackend() 

16 self._fast_backend: FastBackend | None = None 

17 

18 @property 

19 def backend_name(self) -> BackendName: 

20 return self._active_backend_name 

21 

22 @property 

23 def backend(self) -> BackendInterface: 

24 if self.backend_name == "native": 

25 return self._native_backend 

26 elif self.backend_name == "fast": 

27 if self._fast_backend is None: 

28 self._fast_backend = FastBackend() 

29 return self._fast_backend 

30 

31 raise RuntimeError(f"No backend {self.backend_name}") 

32 

33 def set_backend(self, name: BackendName) -> None: 

34 self._active_backend_name = name 

35 

36 

37_config = _Settings() 

38 

39 

40def get_backend_name() -> BackendName: 

41 return _config.backend_name 

42 

43 

44def get_backend() -> BackendInterface: 

45 return _config.backend 

46 

47 

48def set_backend(name: BackendName) -> None: 

49 _config.set_backend(name) 

50 

51 

52@contextlib.contextmanager 

53def backend(name: BackendName) -> Generator[None, None, None]: 

54 """ 

55 Context manager to temporarily switch the backend. 

56 

57 Usage: 

58 with pq.settings.backend("fpylll"): 

59 pq.lattice.lll(B) 

60 """ 

61 previous = _config.backend_name 

62 try: 

63 set_backend(name) 

64 yield 

65 finally: 

66 set_backend(previous)