Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 78 additions & 11 deletions ooodev/utils/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,31 +243,38 @@ def get_reg_mods_path(cls) -> str:

@overload
@classmethod
def get_reg_item_prop(cls, item: str) -> str: ...
def get_reg_item_prop(cls, item: str) -> str:
...

@overload
@classmethod
def get_reg_item_prop(cls, item: str, prop: str) -> str: ...
def get_reg_item_prop(cls, item: str, prop: str) -> str:
...

@overload
@classmethod
def get_reg_item_prop(cls, item: str, prop: str, node: str) -> str: ...
def get_reg_item_prop(cls, item: str, prop: str, node: str) -> str:
...

@overload
@classmethod
def get_reg_item_prop(cls, item: str, *, kind: Info.RegPropKind) -> str: ...
def get_reg_item_prop(cls, item: str, *, kind: Info.RegPropKind) -> str:
...

@overload
@classmethod
def get_reg_item_prop(cls, item: str, *, kind: Info.RegPropKind, idx: int) -> str: ...
def get_reg_item_prop(cls, item: str, *, kind: Info.RegPropKind, idx: int) -> str:
...

@overload
@classmethod
def get_reg_item_prop(cls, item: str, prop: str, *, idx: int) -> str: ...
def get_reg_item_prop(cls, item: str, prop: str, *, idx: int) -> str:
...

@overload
@classmethod
def get_reg_item_prop(cls, item: str, prop: str, node: str, kind: Info.RegPropKind) -> str: ...
def get_reg_item_prop(cls, item: str, prop: str, node: str, kind: Info.RegPropKind) -> str:
...

@classmethod
def get_reg_item_prop(
Expand Down Expand Up @@ -2461,19 +2468,23 @@ def __delitem__(self, _item: int | str | DrawPage | XDrawPage) -> None:
# region is_type_enum_multi()
@overload
@staticmethod
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: Enum) -> bool: ...
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: Enum) -> bool:
...

@overload
@staticmethod
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: str) -> bool: ...
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: str) -> bool:
...

@overload
@staticmethod
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: Enum, arg_name: str) -> bool: ...
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: Enum, arg_name: str) -> bool:
...

@overload
@staticmethod
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: str, arg_name: str) -> bool: ...
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: str, arg_name: str) -> bool:
...

@staticmethod
def is_type_enum_multi(alt_type: str, enum_type: Type[Enum], enum_val: Enum | str, arg_name: str = "") -> bool:
Expand Down Expand Up @@ -2722,6 +2733,62 @@ def version_info(cls) -> Tuple[int, ...]:
cls._version_info = tuple(int(s) for s in cls.version.split("."))
return cls._version_info

@classproperty
def version_info(cls) -> Tuple[int, ...]:
"""
Gets the running LibreOffice version.

|lo_unsafe|

Returns:
tuple: version as tuple such as ``(7, 3, 4, 2)``

Note:
This property only works after Office is Loaded.
"""

try:
return cls._version_info
except AttributeError:
cls._version_info = Info.parse_version_string_to_int_tuple(cls.version)
return cls._version_info

@staticmethod
def parse_version_string_to_int_tuple(version_string: str) -> tuple[int, ...]:
"""
Parses a version string (e.g., "2025.0.1.alpha1") into a tuple of integers.
The string is split by '.', and any non-integer parts are ignored.

Args:
version_string: The string to parse.

Returns:
A tuple of integers representing the version parts.
Example: "2025.0.1.alpha1" -> (2025, 0, 1)
"1.2.3" -> (1, 2, 3)
"5.0beta" -> (5, 0)
"abc" -> ()

Raises:
TypeError: If the input is not a string.

.. versionadded:: 0.53.4
"""
if not isinstance(version_string, str):
raise TypeError("Input must be a string.")

parts = version_string.split(".")
int_parts = []
for part in parts:
try:
# Attempt to convert the part to an integer
int_parts.append(int(part))
except ValueError:
# If conversion fails (e.g., "alpha1", "beta"),
# stop processing further parts and break the loop.
break
return tuple(int_parts)


def _del_cache_attrs(source: object, e: EventArgs) -> None:
# clears Write Attributes that are dynamically created
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "ooo-dev-tools"
version = "0.53.3"
version = "0.53.4"

description = "LibreOffice Developer Tools"
license = "Apache Software License"
Expand Down
28 changes: 28 additions & 0 deletions tests/test_info/test_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,31 @@ def test_parese_language_code_error() -> None:
_ = Info.parse_language_code("en_GB")
with pytest.raises(ValueError):
_ = Info.parse_language_code("-GB")


def test_parse_version_string_to_int_tuple() -> None:
from ooodev.utils.info import Info

# Test valid version strings
assert Info.parse_version_string_to_int_tuple("2025.0.1.alpha1") == (2025, 0, 1)
assert Info.parse_version_string_to_int_tuple("1.2.3") == (1, 2, 3)
assert Info.parse_version_string_to_int_tuple("5.0beta") == (5,)
assert Info.parse_version_string_to_int_tuple("10.20.30.40") == (10, 20, 30, 40)

# Test invalid version strings
assert Info.parse_version_string_to_int_tuple("abc") == ()
assert Info.parse_version_string_to_int_tuple("") == ()

# Test mixed valid and invalid parts
assert Info.parse_version_string_to_int_tuple("1.2.alpha.3") == (1, 2)
assert Info.parse_version_string_to_int_tuple("1..3") == (1,)

# Test edge cases
assert Info.parse_version_string_to_int_tuple("0") == (0,)
assert Info.parse_version_string_to_int_tuple("0.0.0") == (0, 0, 0)

# Test input type validation
with pytest.raises(TypeError):
Info.parse_version_string_to_int_tuple(12345) # Not a string
with pytest.raises(TypeError):
Info.parse_version_string_to_int_tuple(None) # Not a string
Loading