add not_lesser_than(), WebColor(), annotations and documentation changes

This commit is contained in:
Yusur 2025-09-23 12:52:11 +02:00
parent 17cab8e257
commit 25697ee958
6 changed files with 71 additions and 11 deletions

View file

@ -4,11 +4,11 @@
+ Add RNG/random selection overloads such as `luck()`, `rng_overload()`
+ Add 7 new throwable exceptions
+ Add color utilities: `chalk` module
+ Add color utilities: `chalk` object and `WebColor()`
+ Add `.terminal` module, to ease TUI development
+ `calendar`: add `parse_time()`
+ Add validator `not_greater_than()`
+ Add `@future()` decorator
+ Add validators `not_greater_than()`, `not_less_than()`
+ Add `@future()` decorator: it signals features not yet intended to be public, for instance, backported as a part of a bug fix.
## 0.6.1

View file

@ -1,6 +1,6 @@
# SIS Unified Object Underarmor
Good morning, my brother! Welcome **SUOU** (**S**IS **U**nified **O**bject **U**nderarmor), the Python library which makes API development faster for developing API's, database schemas and stuff in Python.
Good morning, my brother! Welcome **SUOU** (**S**IS **U**nified **O**bject **U**nderarmor), the Python library which speeds up and makes it pleasing to develop API, database schemas and stuff in Python.
It provides utilities such as:
* [SIQ](https://yusur.moe/protocols/siq.html)

View file

@ -37,7 +37,7 @@ from .redact import redact_url_password
from .http import WantsContentType
from .color import chalk
__version__ = "0.7.0-dev37"
__version__ = "0.7.0-dev38"
__all__ = (
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',

View file

@ -17,7 +17,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
from __future__ import annotations
from collections import namedtuple
from functools import lru_cache
@ -75,5 +77,56 @@ class Chalk:
return self._wrap(self.FAINT, self.END_BOLD)
## TODO make it lazy?
## TODO make it lazy / an instance variable?
chalk = Chalk()
## Utilities for web colors
class WebColor(namedtuple('_WebColor', 'red green blue')):
"""
Representation of a color in the TrueColor space (aka rgb).
Useful for theming.
"""
def lighten(self, *, factor = .75):
"""
Return a whitened shade of the color.
Factor stands between 0 and 1: 0 = total white, 1 = no change. Default is .75
"""
return WebColor(
255 - int((255 - self.red) * factor),
255 - int((255 - self.green) * factor),
255 - int((255 - self.blue) * factor),
)
def darken(self, *, factor = .75):
"""
Return a darkened shade of the color.
Factor stands between 0 and 1: 0 = total black, 1 = no change. Default is .75
"""
return WebColor(
int(self.red * factor),
int(self.green * factor),
int(self.blue * factor)
)
def greyen(self, *, factor = .75):
"""
Return a desaturated shade of the color.
Factor stands between 0 and 1: 0 = gray, 1 = no change. Default is .75
"""
return self.darken(factor=factor) + self.lighten(factor=factor)
def blend_with(self, other: WebColor):
"""
Mix two colors, returning the average.
"""
return WebColor (
(self.red + other.red) // 2,
(self.green + other.green) // 2,
(self.blue + other.blue) // 2
)
__add__ = blend_with
def __str__(self):
return f"rgb({self.red}, {self.green}, {self.blue})"

View file

@ -16,6 +16,7 @@ This software is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
from functools import wraps
from typing import Callable, Generic, Iterable, TypeVar
import random
from suou.exceptions import BadLuckError
@ -34,7 +35,7 @@ def lucky(validators: Iterable[Callable[[_U], bool]] = ()):
NEW 0.7.0
"""
def decorator(func: Callable[_T, _U]):
def decorator(func: Callable[..., _U]):
@wraps(func)
def wrapper(*args, **kwargs) -> _U:
try:
@ -86,13 +87,13 @@ class RngCallable(Callable, Generic[_T, _U]):
choice -= w
def rng_overload(prev_func: RngCallable[_T, _U] | int | None, /, *, weight: int = 1) -> RngCallable[_T, _U]:
def rng_overload(prev_func: RngCallable[..., _U] | int | None, /, *, weight: int = 1) -> RngCallable[..., _U]:
"""
Decorate the first function with @rng_overload and the weight= parameter
(default 1, must be an integer) to create a "RNG" overloaded callable.
Each call chooses randomly one candidate (weight is taken in consideration)
, calls it, and returns the result.
Each call chooses randomly one candidate (weight is taken in consideration),
calls it, and returns the result.
UNTESTED

View file

@ -49,5 +49,11 @@ def not_greater_than(y):
"""
return lambda x: x <= y
def not_less_than(y):
"""
Return a function that returns True if X is not less than (i.e. greater than or equal to) the given value.
"""
return lambda x: x >= y
__all__ = ('matches', 'not_greater_than')