Fix Python 3.13: classmethod + property unsupported (#448)

* Use own classproperty (don't inherit from property).
 * Config generation: Rename pathlib._local to pathlib
This commit is contained in:
Dominique Lasserre 2025-02-11 21:01:45 +01:00 committed by GitHub
parent d05b161e24
commit 1a2cb4d37d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 16 additions and 10 deletions

View File

@ -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("<class"):
type_name = field_type.__name__
return type_name

View File

@ -167,7 +167,10 @@ class SettingsEOS(BaseSettings):
utils: Optional[UtilsCommonSettings] = None
model_config = SettingsConfigDict(
env_nested_delimiter="__", nested_model_default_partial_update=True, env_prefix="EOS_"
env_nested_delimiter="__",
nested_model_default_partial_update=True,
env_prefix="EOS_",
ignored_types=(classproperty,),
)
@ -314,13 +317,11 @@ class ConfigEOS(SingletonMixin, SettingsEOSDefaults):
setting_sources.append(default_settings)
return tuple(setting_sources)
@classmethod
@classproperty
def config_default_file_path(cls) -> 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."""

View File

@ -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