From 1a2cb4d37d46aa5fd087eb6e682d5523819e3b76 Mon Sep 17 00:00:00 2001 From: Dominique Lasserre Date: Tue, 11 Feb 2025 21:01:45 +0100 Subject: [PATCH] Fix Python 3.13: classmethod + property unsupported (#448) * Use own classproperty (don't inherit from property). * Config generation: Rename pathlib._local to pathlib --- scripts/generate_config_md.py | 2 +- src/akkudoktoreos/config/config.py | 7 ++++--- src/akkudoktoreos/core/decorators.py | 17 +++++++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/scripts/generate_config_md.py b/scripts/generate_config_md.py index 226dfa0..ba0910f 100755 --- a/scripts/generate_config_md.py +++ b/scripts/generate_config_md.py @@ -86,7 +86,7 @@ def get_default_value(field_info: Union[FieldInfo, ComputedFieldInfo], regular_f def get_type_name(field_type: type) -> str: - type_name = str(field_type).replace("typing.", "") + type_name = str(field_type).replace("typing.", "").replace("pathlib._local", "pathlib") if type_name.startswith(" Path: """Compute the default config file path.""" return cls.package_root_path.joinpath("data/default.config.json") - @classmethod @classproperty def package_root_path(cls) -> Path: """Compute the package root path.""" diff --git a/src/akkudoktoreos/core/decorators.py b/src/akkudoktoreos/core/decorators.py index 7811a9c..55120d8 100644 --- a/src/akkudoktoreos/core/decorators.py +++ b/src/akkudoktoreos/core/decorators.py @@ -1,3 +1,4 @@ +from collections.abc import Callable from typing import Any, Optional from akkudoktoreos.core.logging import get_logger @@ -5,13 +6,14 @@ from akkudoktoreos.core.logging import get_logger logger = get_logger(__name__) -class classproperty(property): +class classproperty: """A decorator to define a read-only property at the class level. - This class extends the built-in `property` to allow a method to be accessed - as a property on the class itself, rather than an instance. This is useful - when you want a property-like syntax for methods that depend on the class - rather than any instance of the class. + This class replaces the built-in `property` which is no longer available in + combination with @classmethod since Python 3.13 to allow a method to be + accessed as a property on the class itself, rather than an instance. This + is useful when you want a property-like syntax for methods that depend on + the class rather than any instance of the class. Example: class MyClass: @@ -28,13 +30,16 @@ class classproperty(property): decorated method on the class. Parameters: - fget (Callable[[type], Any]): A method that takes the class as an + fget (Callable[[Any], Any]): A method that takes the class as an argument and returns a value. Raises: AssertionError: If `fget` is not defined when `__get__` is called. """ + def __init__(self, fget: Callable[[Any], Any]) -> None: + self.fget = fget + def __get__(self, _: Any, owner_cls: Optional[type[Any]] = None) -> Any: if owner_cls is None: return self