oct
Loading...
Searching...
No Matches
compat.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# oct/core/compat.py
4
5"""
6Purpose
7-------
8Provide a version-compatibility check between OCT and the ``oc_diagnostics``
9runtime package.
10
11Responsibilities
12----------------
13- Define the supported ``oc_diagnostics`` version range.
14- Query the installed ``oc_diagnostics`` version via ``importlib.metadata``.
15- Return a human-readable warning or info string when the installed version
16 is out of range or absent; return ``None`` when compatible.
17
18Diagnostics
19-----------
20Domain: OCT-CORE
21Levels:
22 L2 - lifecycle
23 L3 - semantic details
24 L4 - deep tracing
25
26Contracts
27---------
28- Must not import ``oc_diagnostics`` directly; ``_dbg`` arrives through
29 the fail-soft ``oct.core.diagnostics`` shim, and the installed version
30 is read from metadata rather than by importing the package.
31- Must not require the ``packaging`` library; uses tuple-based comparison.
32- Must be safe to call when ``oc_diagnostics`` is not installed.
33
34Dependencies
35------------
36- oct.core.diagnostics (_dbg structured logger)
37"""
38
39from __future__ import annotations
40from oct.core.diagnostics import _dbg
41
42_OC_DIAGNOSTICS_COMPAT = {"min": "2.0.0", "max": "3.0.0"}
43
44
45def _parse_version_tuple(v: str) -> tuple[int, ...]:
46 """Convert a dotted version string to a tuple of ints for comparison."""
47 parts: list[int] = []
48 for segment in v.split("."):
49 digits = ""
50 for ch in segment:
51 if ch.isdigit():
52 digits += ch
53 else:
54 break
55 parts.append(int(digits) if digits else 0)
56 return tuple(parts)
57
58
59def check_oc_diagnostics_compat() -> str | None:
60 """
61 Check whether the installed ``oc_diagnostics`` version is within the
62 supported range.
63
64 Returns
65 -------
66 str or None
67 A warning/info message if out of range or not installed.
68 ``None`` if the version is compatible.
69 """
70 func = "check_oc_diagnostics_compat"
71 _dbg("OCT-CORE", func, "checking the installed oc_diagnostics version", 3)
72 try:
73 from importlib.metadata import version as _pkg_version
74 installed = _pkg_version("oc_diagnostics")
75 except Exception:
76 return (
77 "Info: oc_diagnostics is not installed. "
78 "Projects created by OCT require oc_diagnostics at runtime."
79 )
80
81 try:
82 v = _parse_version_tuple(installed)
83 v_min = _parse_version_tuple(_OC_DIAGNOSTICS_COMPAT["min"])
84 v_max = _parse_version_tuple(_OC_DIAGNOSTICS_COMPAT["max"])
85 except (ValueError, TypeError):
86 return f"Warning: Could not parse oc_diagnostics version '{installed}'."
87
88 if v < v_min:
89 return (
90 f"Warning: oc_diagnostics {installed} is below the minimum "
91 f"supported version ({_OC_DIAGNOSTICS_COMPAT['min']}). "
92 f"Consider upgrading."
93 )
94
95 if v >= v_max:
96 return (
97 f"Warning: oc_diagnostics {installed} is at or above the maximum "
98 f"tested version ({_OC_DIAGNOSTICS_COMPAT['max']}). "
99 f"OCT may need an update."
100 )
101
102 return None
tuple[int,...] _parse_version_tuple(str v)
Definition compat.py:45
str|None check_oc_diagnostics_compat()
Definition compat.py:59