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 RNG/random selection overloads such as `luck()`, `rng_overload()`
+ Add 7 new throwable exceptions + Add 7 new throwable exceptions
+ Add color utilities: `chalk` module + Add color utilities: `chalk` object and `WebColor()`
+ Add `.terminal` module, to ease TUI development + Add `.terminal` module, to ease TUI development
+ `calendar`: add `parse_time()` + `calendar`: add `parse_time()`
+ Add validator `not_greater_than()` + Add validators `not_greater_than()`, `not_less_than()`
+ Add `@future()` decorator + 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 ## 0.6.1

View file

@ -1,6 +1,6 @@
# SIS Unified Object Underarmor # 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: It provides utilities such as:
* [SIQ](https://yusur.moe/protocols/siq.html) * [SIQ](https://yusur.moe/protocols/siq.html)

View file

@ -37,7 +37,7 @@ from .redact import redact_url_password
from .http import WantsContentType from .http import WantsContentType
from .color import chalk from .color import chalk
__version__ = "0.7.0-dev37" __version__ = "0.7.0-dev38"
__all__ = ( __all__ = (
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue', '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 from functools import lru_cache
@ -75,5 +77,56 @@ class Chalk:
return self._wrap(self.FAINT, self.END_BOLD) return self._wrap(self.FAINT, self.END_BOLD)
## TODO make it lazy? ## TODO make it lazy / an instance variable?
chalk = Chalk() 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. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
""" """
from functools import wraps
from typing import Callable, Generic, Iterable, TypeVar from typing import Callable, Generic, Iterable, TypeVar
import random import random
from suou.exceptions import BadLuckError from suou.exceptions import BadLuckError
@ -34,7 +35,7 @@ def lucky(validators: Iterable[Callable[[_U], bool]] = ()):
NEW 0.7.0 NEW 0.7.0
""" """
def decorator(func: Callable[_T, _U]): def decorator(func: Callable[..., _U]):
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs) -> _U: def wrapper(*args, **kwargs) -> _U:
try: try:
@ -56,7 +57,7 @@ def lucky(validators: Iterable[Callable[[_U], bool]] = ()):
class RngCallable(Callable, Generic[_T, _U]): class RngCallable(Callable, Generic[_T, _U]):
""" """
Overloaded ... randomly chosen callable. Overloaded ...randomly chosen callable.
UNTESTED UNTESTED
@ -86,13 +87,13 @@ class RngCallable(Callable, Generic[_T, _U]):
choice -= w 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 Decorate the first function with @rng_overload and the weight= parameter
(default 1, must be an integer) to create a "RNG" overloaded callable. (default 1, must be an integer) to create a "RNG" overloaded callable.
Each call chooses randomly one candidate (weight is taken in consideration) Each call chooses randomly one candidate (weight is taken in consideration),
, calls it, and returns the result. calls it, and returns the result.
UNTESTED UNTESTED

View file

@ -49,5 +49,11 @@ def not_greater_than(y):
""" """
return lambda x: x <= 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') __all__ = ('matches', 'not_greater_than')