Skip to content

Commit 1d9201b

Browse files
committed
Warning only when (major, minor) versions differ
Signed-off-by: Vlad Gheorghiu <[email protected]>
1 parent 3be2109 commit 1d9201b

File tree

2 files changed

+83
-42
lines changed

2 files changed

+83
-42
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Pre-release
22

33
- Added type checking and automatic linting/formatting, https://github.com/open-quantum-safe/liboqs-python/pull/97
4+
- Added a utility function for de-structuring version strings in `oqs.py`
5+
- `version(version_str: str) -> tuple[str, str, str]:` - Returns a tuple
6+
containing the
7+
(major, minor, patch) versions
8+
- A warning is issued only if the liboqs-python version's major and minor
9+
numbers differ from those of liboqs, ignoring the patch version
410

511
# Version 0.12.0 - January 15, 2025
612

oqs/oqs.py

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,6 @@
3535
logger.addHandler(logging.StreamHandler(stdout))
3636

3737

38-
def oqs_python_version() -> Union[str, None]:
39-
"""liboqs-python version string."""
40-
try:
41-
result = importlib.metadata.version("liboqs-python")
42-
except importlib.metadata.PackageNotFoundError:
43-
warnings.warn("Please install liboqs-python using pip install", stacklevel=2)
44-
return None
45-
return result
46-
47-
48-
# liboqs-python tries to automatically install and load this liboqs version in
49-
# case no other version is found
50-
OQS_VERSION = oqs_python_version()
51-
52-
53-
def _countdown(seconds: int) -> None:
54-
while seconds > 0:
55-
logger.info("Installing in %s seconds...", seconds)
56-
stdout.flush()
57-
seconds -= 1
58-
time.sleep(1)
59-
60-
6138
def _load_shared_obj(
6239
name: str,
6340
additional_searching_paths: Union[Sequence[Path], None] = None,
@@ -100,6 +77,14 @@ def _load_shared_obj(
10077
raise RuntimeError(msg)
10178

10279

80+
def _countdown(seconds: int) -> None:
81+
while seconds > 0:
82+
logger.info("Installing in %s seconds...", seconds)
83+
stdout.flush()
84+
seconds -= 1
85+
time.sleep(1)
86+
87+
10388
def _install_liboqs(
10489
target_directory: Path,
10590
oqs_version_to_install: Union[str, None] = None,
@@ -188,7 +173,9 @@ def _load_liboqs() -> ct.CDLL:
188173
assert liboqs # noqa: S101
189174
except RuntimeError:
190175
# We don't have liboqs, so we try to install it automatically
191-
_install_liboqs(target_directory=oqs_install_dir, oqs_version_to_install=OQS_VERSION)
176+
_install_liboqs(
177+
target_directory=oqs_install_dir, oqs_version_to_install=OQS_VERSION
178+
)
192179
# Try loading it again
193180
try:
194181
liboqs = _load_shared_obj(
@@ -206,11 +193,6 @@ def _load_liboqs() -> ct.CDLL:
206193
_liboqs = _load_liboqs()
207194

208195

209-
# Expected return value from native OQS functions
210-
OQS_SUCCESS: Final[int] = 0
211-
OQS_ERROR: Final[int] = -1
212-
213-
214196
def native() -> ct.CDLL:
215197
"""Handle to native liboqs handler."""
216198
return _liboqs
@@ -220,19 +202,58 @@ def native() -> ct.CDLL:
220202
native().OQS_init()
221203

222204

205+
def oqs_python_version() -> Union[str, None]:
206+
"""liboqs-python version string."""
207+
try:
208+
result = importlib.metadata.version("liboqs-python")
209+
except importlib.metadata.PackageNotFoundError:
210+
warnings.warn("Please install liboqs-python using pip install", stacklevel=2)
211+
return None
212+
return result
213+
214+
223215
def oqs_version() -> str:
224216
"""`liboqs` version string."""
225217
native().OQS_version.restype = ct.c_char_p
226218
return ct.c_char_p(native().OQS_version()).value.decode("UTF-8") # type: ignore[union-attr]
227219

228220

229-
# Warn the user if the liboqs version differs from liboqs-python version
230-
if oqs_version() != oqs_python_version():
231-
warnings.warn(
232-
f"liboqs version {oqs_version()} differs from liboqs-python version "
233-
f"{oqs_python_version()}",
234-
stacklevel=2,
221+
def version(version_str: str) -> tuple[str, str, str]:
222+
parts = version_str.split(".")
223+
224+
major = parts[0] if len(parts) > 0 else ""
225+
minor = parts[1] if len(parts) > 1 else ""
226+
patch = parts[2] if len(parts) > 2 else ""
227+
228+
return major, minor, patch
229+
230+
231+
oqs_ver = oqs_version()
232+
oqs_ver_major, oqs_ver_minor, oqs_ver_patch = version(oqs_ver)
233+
234+
oqs_python_ver = oqs_python_version()
235+
if oqs_python_ver:
236+
oqs_python_ver_major, oqs_python_ver_minor, oqs_python_ver_patch = version(
237+
oqs_python_ver
235238
)
239+
# Warn the user if the liboqs version differs from liboqs-python version
240+
if not (
241+
oqs_ver_major == oqs_python_ver_major and oqs_ver_minor == oqs_python_ver_minor
242+
):
243+
warnings.warn(
244+
f"liboqs version (major, minor) {oqs_version()} differs from liboqs-python version "
245+
f"{oqs_python_version()}",
246+
stacklevel=2,
247+
)
248+
249+
250+
# liboqs-python tries to automatically install and load this liboqs version in
251+
# case no other version is found
252+
OQS_VERSION = oqs_python_version()
253+
254+
# Expected return value from native OQS functions
255+
OQS_SUCCESS: Final[int] = 0
256+
OQS_ERROR: Final[int] = -1
236257

237258

238259
class MechanismNotSupportedError(Exception):
@@ -281,7 +302,9 @@ class KeyEncapsulation(ct.Structure):
281302
("decaps_cb", ct.c_void_p),
282303
]
283304

284-
def __init__(self, alg_name: str, secret_key: Union[int, bytes, None] = None) -> None:
305+
def __init__(
306+
self, alg_name: str, secret_key: Union[int, bytes, None] = None
307+
) -> None:
285308
"""
286309
Create new KeyEncapsulation with the given algorithm.
287310
@@ -435,9 +458,15 @@ def is_kem_enabled(alg_name: str) -> bool:
435458
return native().OQS_KEM_alg_is_enabled(ct.create_string_buffer(alg_name.encode()))
436459

437460

438-
_KEM_alg_ids = [native().OQS_KEM_alg_identifier(i) for i in range(native().OQS_KEM_alg_count())]
439-
_supported_KEMs: tuple[str, ...] = tuple([i.decode() for i in _KEM_alg_ids]) # noqa: N816
440-
_enabled_KEMs: tuple[str, ...] = tuple([i for i in _supported_KEMs if is_kem_enabled(i)]) # noqa: N816
461+
_KEM_alg_ids = [
462+
native().OQS_KEM_alg_identifier(i) for i in range(native().OQS_KEM_alg_count())
463+
]
464+
_supported_KEMs: tuple[str, ...] = tuple(
465+
[i.decode() for i in _KEM_alg_ids]
466+
) # noqa: N816
467+
_enabled_KEMs: tuple[str, ...] = tuple(
468+
[i for i in _supported_KEMs if is_kem_enabled(i)]
469+
) # noqa: N816
441470

442471

443472
def get_enabled_kem_mechanisms() -> tuple[str, ...]:
@@ -478,7 +507,9 @@ class Signature(ct.Structure):
478507
("verify_cb", ct.c_void_p),
479508
]
480509

481-
def __init__(self, alg_name: str, secret_key: Union[int, bytes, None] = None) -> None:
510+
def __init__(
511+
self, alg_name: str, secret_key: Union[int, bytes, None] = None
512+
) -> None:
482513
"""
483514
Create new Signature with the given algorithm.
484515
@@ -723,9 +754,13 @@ def is_sig_enabled(alg_name: str) -> bool:
723754
return native().OQS_SIG_alg_is_enabled(ct.create_string_buffer(alg_name.encode()))
724755

725756

726-
_sig_alg_ids = [native().OQS_SIG_alg_identifier(i) for i in range(native().OQS_SIG_alg_count())]
757+
_sig_alg_ids = [
758+
native().OQS_SIG_alg_identifier(i) for i in range(native().OQS_SIG_alg_count())
759+
]
727760
_supported_sigs: tuple[str, ...] = tuple([i.decode() for i in _sig_alg_ids])
728-
_enabled_sigs: tuple[str, ...] = tuple([i for i in _supported_sigs if is_sig_enabled(i)])
761+
_enabled_sigs: tuple[str, ...] = tuple(
762+
[i for i in _supported_sigs if is_sig_enabled(i)]
763+
)
729764

730765

731766
def get_enabled_sig_mechanisms() -> tuple[str, ...]:

0 commit comments

Comments
 (0)