add @future

This commit is contained in:
Yusur 2025-09-19 17:22:00 +02:00
parent f07d691004
commit e7726328d3
3 changed files with 45 additions and 23 deletions

View file

@ -5,9 +5,10 @@
+ Add RNG/random selection overloads such as `luck()`, `rng_overload()`
+ Add 7 new throwable exceptions
+ Add color utilities: `chalk` module
+ Add `.terminal` module, to ease TUI development.
+ `calendar`: add `parse_time()`.
+ Add validator `not_greater_than()`.
+ Add `.terminal` module, to ease TUI development
+ `calendar`: add `parse_time()`
+ Add validator `not_greater_than()`
+ Add `@future()` decorator
## 0.6.1

View file

@ -24,7 +24,7 @@ from .calendar import want_datetime, want_isodate, want_timestamp, age_and_days
from .configparse import MissingConfigError, MissingConfigWarning, ConfigOptions, ConfigParserConfigSource, ConfigSource, DictConfigSource, ConfigValue, EnvConfigSource
from .collections import TimedDict
from .dei import dei_args
from .functools import deprecated, not_implemented, timed_cache, none_pass, alru_cache
from .functools import deprecated, not_implemented, timed_cache, none_pass, alru_cache, future
from .classtools import Wanted, Incomplete
from .itertools import makelist, kwargs_prefix, ltuple, rtuple, additem, addattr
from .i18n import I18n, JsonI18n, TomlI18n
@ -47,7 +47,8 @@ __all__ = (
'StringCase', 'TimedDict', 'TomlI18n', 'UserSigner', 'Wanted', 'WantsContentType',
'addattr', 'additem', 'age_and_days', 'alru_cache', 'b2048decode', 'b2048encode',
'b32ldecode', 'b32lencode', 'b64encode', 'b64decode', 'cb32encode',
'cb32decode', 'chalk', 'count_ones', 'dei_args', 'deprecated', 'ilex', 'join_bits',
'cb32decode', 'chalk', 'count_ones', 'dei_args', 'deprecated',
'future', 'ilex', 'join_bits',
'jsonencode', 'kwargs_prefix', 'lex', 'ltuple', 'makelist', 'mask_shift',
'matches', 'mod_ceil', 'mod_floor', 'none_pass', 'not_implemented',
'redact_url_password', 'rtuple', 'split_bits', 'ssv_list', 'symbol_table',

View file

@ -28,37 +28,43 @@ from suou.itertools import hashed_list
_T = TypeVar('_T')
_U = TypeVar('_U')
def _suou_deprecated(message: str, /, *, category=DeprecationWarning, stacklevel: int = 1) -> Callable[[Callable[_T, _U]], Callable[_T, _U]]:
"""
Backport of PEP 702 for Python <=3.12.
The stack_level stuff is used by warnings.warn() btw
"""
def decorator(func: Callable[_T, _U]) -> Callable[_T, _U]:
@wraps(func)
def wrapper(*a, **ka):
if category is not None:
warnings.warn(message, category, stacklevel=stacklevel)
return func(*a, **ka)
func.__deprecated__ = True
wrapper.__deprecated__ = True
return wrapper
return decorator
try:
from warnings import deprecated
except ImportError:
# Python <=3.12 does not implement warnings.deprecated
def deprecated(message: str, /, *, category=DeprecationWarning, stacklevel: int = 1) -> Callable[[Callable[_T, _U]], Callable[_T, _U]]:
"""
Backport of PEP 702 for Python <=3.12.
The stack_level stuff is not reimplemented on purpose because
too obscure for the average programmer.
"""
def decorator(func: Callable[_T, _U]) -> Callable[_T, _U]:
@wraps(func)
def wrapper(*a, **ka):
if category is not None:
warnings.warn(message, category, stacklevel=stacklevel)
return func(*a, **ka)
func.__deprecated__ = True
wrapper.__deprecated__ = True
return wrapper
return decorator
deprecated = _suou_deprecated
## this syntactic sugar for deprecated() is ... deprecated, which is ironic.
## Needed move because VSCode seems to not sense deprecated_alias()es as deprecated.
@deprecated('use deprecated(message)(func) instead')
def deprecated_alias(func: Callable, /, message='use .{name}() instead', *, category=DeprecationWarning) -> Callable:
def deprecated_alias(func: Callable[_T, _U], /, message='use .{name}() instead', *, category=DeprecationWarning) -> Callable[_T, _U]:
"""
Syntactic sugar helper for renaming functions.
DEPRECATED use deprecated(message)(func) instead
"""
return deprecated(message.format(name=func.__name__), category=category)(func)
@deprecated(message.format(name=func.__name__), category=category)
@wraps(func)
def deprecated_wrapper(*a, **k) -> _U:
return func(*a, **k)
return deprecated_wrapper
def not_implemented(msg: Callable | str | None = None):
"""
@ -74,6 +80,20 @@ def not_implemented(msg: Callable | str | None = None):
return decorator(msg)
return decorator
def future(message: str | None = None):
"""
Describes experimental or future API's introduced as bug fixes (including as backports)
but not yet intended for general use (mostly to keep semver consistent).
NEW 0.7.0
"""
def decorator(func: Callable[_T, _U]) -> Callable[_T, _U]:
@wraps(func)
def wrapper(*a, **k) -> _U:
warnings.warn(message or f'{func.__name__}() is intended for a future release and not intended for use right now', FutureWarning)
return func(*a, **k)
return wrapper
return decorator
def flat_args(args: Iterable, kwds: Mapping, typed,
kwd_mark = (object(),),