add addattr()

This commit is contained in:
Yusur 2025-07-11 09:58:08 +02:00
parent d9690ea3a5
commit 4a2e8d3343
2 changed files with 28 additions and 6 deletions

View file

@ -2,15 +2,17 @@
## 0.4.0 ## 0.4.0
+ Added `ValueProperty`, abstract superclass for `ConfigProperty`. + Added `ValueProperty`, abstract superclass for `ConfigProperty`
+ Changed the behavior of `makelist()`: now it can also decorate a callable, converting its return type to a list
+ Added `addattr()`
## 0.3.6 ## 0.3.6
- Fixed `ConfigValue` behavior with multiple sources. It used to iterate through all the sources, possibly overwriting; now, iteration stops at first non-missing value. - Fixed `ConfigValue` behavior with multiple sources. It used to iterate through all the sources, possibly overwriting; now, iteration stops at first non-missing value
## 0.3.5 ## 0.3.5
- Fixed cb32 handling. Now leading zeros in SIQ's are stripped, and `.from_cb32()` was implemented. - Fixed cb32 handling. Now leading zeros in SIQ's are stripped, and `.from_cb32()` was implemented
## 0.3.4 ## 0.3.4

View file

@ -14,20 +14,28 @@ This software is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
''' '''
from functools import wraps
from typing import Any, Iterable, MutableMapping, TypeVar from typing import Any, Iterable, MutableMapping, TypeVar
import warnings import warnings
from suou.classtools import MISSING
_T = TypeVar('_T') _T = TypeVar('_T')
def makelist(l: Any) -> list: def makelist(l: Any, *, wrap: bool = True) -> list:
''' '''
Make a list out of an iterable or a single value. Make a list out of an iterable or a single value.
NEW 0.4.0: Now supports a callable: can be used to decorate generators and turn them into lists.
Pass wrap=False to return instead the unwrapped function in a list.
''' '''
if callable(l) and wrap:
return wraps(l)(lambda *a, **k: makelist(l(*a, **k), wrap=False))
if isinstance(l, (str, bytes, bytearray)): if isinstance(l, (str, bytes, bytearray)):
return [l] return [l]
elif isinstance(l, Iterable): elif isinstance(l, Iterable):
return list(l) return list(l)
elif l in (None, NotImplemented, Ellipsis): elif l in (None, NotImplemented, Ellipsis, MISSING):
return [] return []
else: else:
return [l] return [l]
@ -83,6 +91,18 @@ def additem(obj: MutableMapping, /, name: str = None):
return func return func
return decorator return decorator
def addattr(obj: Any, /, name: str = None):
"""
Same as additem() but setting as attribute instead.
"""
def decorator(func):
key = name or func.__name__
if hasattr(obj, key):
warnings.warn(f'object does already have attribute {key!r}')
setattr(obj, key, func)
return func
return decorator
__all__ = ('makelist', 'kwargs_prefix', 'ltuple', 'rtuple', 'additem')
__all__ = ('makelist', 'kwargs_prefix', 'ltuple', 'rtuple', 'additem', 'addattr')