Compare commits
No commits in common. "def2634f217eeb0d6c3552ac153d1de4c43e8908" and "305f193f93b1d905132288fcec13335d1bef6d9d" have entirely different histories.
def2634f21
...
305f193f93
12 changed files with 104 additions and 87 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -29,6 +29,3 @@ aliases/*/src
|
||||||
docs/_build
|
docs/_build
|
||||||
docs/_static
|
docs/_static
|
||||||
docs/templates
|
docs/templates
|
||||||
|
|
||||||
# changes during CD/CI
|
|
||||||
aliases/*/pyproject.toml
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.9.0
|
|
||||||
|
|
||||||
+ Fix to make experimental `Waiter` usable
|
|
||||||
+ Suspend `glue()` release indefinitely
|
|
||||||
+ Add `yesno()`
|
|
||||||
+ Document validators
|
|
||||||
|
|
||||||
## 0.8.2 and 0.7.9
|
## 0.8.2 and 0.7.9
|
||||||
|
|
||||||
+ `.color`: fix `chalk` not behaving as expected
|
+ `.color`: fix `chalk` not behaving as expected
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ Please note that you probably already have those dependencies, if you just use t
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
Read the [documentation](https://suou.readthedocs.io/).
|
...
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
Just a heads up: SUOU was made to support Sakuragasaki46 (me)'s own selfish, egoistic needs. Not certainly to provide a service to the public.
|
Just a heads up: SUOU was made to support Sakuragasaki46 (me)'s own selfish, egoistic needs. Not to provide a service to the public.
|
||||||
|
|
||||||
As a consequence, 'add this add that' stuff is best-effort.
|
As a consequence, 'add this add that' stuff is best-effort.
|
||||||
|
|
||||||
|
|
|
||||||
87
aliases/sakuragasaki46_suou/pyproject.toml
Normal file
87
aliases/sakuragasaki46_suou/pyproject.toml
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
[project]
|
||||||
|
name = "sakuragasaki46_suou"
|
||||||
|
description = "casual utility library for coding QoL"
|
||||||
|
authors = [
|
||||||
|
{ name = "Sakuragasaki46" }
|
||||||
|
]
|
||||||
|
dynamic = [ "version" ]
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
"suou==0.8.1",
|
||||||
|
"itsdangerous",
|
||||||
|
"toml",
|
||||||
|
"pydantic",
|
||||||
|
"setuptools>=78.0.0",
|
||||||
|
"uvloop; os_name=='posix'"
|
||||||
|
]
|
||||||
|
# - further devdependencies below - #
|
||||||
|
|
||||||
|
# - publishing -
|
||||||
|
classifiers = [
|
||||||
|
"Development Status :: 2 - Pre-Alpha",
|
||||||
|
|
||||||
|
# actively supported Pythons
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Programming Language :: Python :: 3.12",
|
||||||
|
"Programming Language :: Python :: 3.13",
|
||||||
|
"Programming Language :: Python :: 3.14"
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Repository = "https://nekode.yusur.moe/yusur/suou"
|
||||||
|
Documentation = "https://suou.readthedocs.io"
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
# the below are all dev dependencies (and probably already installed)
|
||||||
|
sqlalchemy = [
|
||||||
|
"SQLAlchemy[asyncio]>=2.0.0",
|
||||||
|
"flask-sqlalchemy"
|
||||||
|
]
|
||||||
|
flask = [
|
||||||
|
"Flask>=2.0.0",
|
||||||
|
"Flask-RestX"
|
||||||
|
]
|
||||||
|
flask_sqlalchemy = [
|
||||||
|
"sakuragasaki46_suou[sqlalchemy]",
|
||||||
|
"sakuragasaki46_suou[flask]"
|
||||||
|
]
|
||||||
|
peewee = [
|
||||||
|
## HEADS UP! peewee has setup.py, may slow down installation
|
||||||
|
"peewee>=3.0.0"
|
||||||
|
]
|
||||||
|
markdown = [
|
||||||
|
"markdown>=3.0.0"
|
||||||
|
]
|
||||||
|
quart = [
|
||||||
|
"Quart",
|
||||||
|
"Quart-Schema",
|
||||||
|
"starlette>=0.47.2"
|
||||||
|
]
|
||||||
|
sass = [
|
||||||
|
## HEADS UP!! libsass carries a C extension + uses setup.py
|
||||||
|
"libsass"
|
||||||
|
]
|
||||||
|
|
||||||
|
full = [
|
||||||
|
"sakuragasaki46_suou[sqlalchemy]",
|
||||||
|
"sakuragasaki46_suou[flask]",
|
||||||
|
"sakuragasaki46_suou[quart]",
|
||||||
|
"sakuragasaki46_suou[peewee]",
|
||||||
|
"sakuragasaki46_suou[markdown]",
|
||||||
|
"sakuragasaki46_suou[sass]"
|
||||||
|
]
|
||||||
|
|
||||||
|
docs = [
|
||||||
|
"sphinx>=2.1",
|
||||||
|
"myst_parser",
|
||||||
|
"sphinx_rtd_theme"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = { attr = "suou.__version__" }
|
||||||
|
|
@ -15,5 +15,4 @@ ease programmer's QoL and write shorter and cleaner code that works.
|
||||||
|
|
||||||
sqlalchemy
|
sqlalchemy
|
||||||
iding
|
iding
|
||||||
validators
|
|
||||||
api
|
api
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
validators
|
|
||||||
==================
|
|
||||||
|
|
||||||
.. currentmodule:: suou.validators
|
|
||||||
|
|
||||||
Validators for use in frameworks such as Pydantic or Marshmallow.
|
|
||||||
|
|
||||||
.. autofunction:: matches
|
|
||||||
|
|
||||||
.. autofunction:: not_greater_than
|
|
||||||
|
|
||||||
.. autofunction:: not_less_than
|
|
||||||
|
|
||||||
.. autofunction:: yesno
|
|
||||||
|
|
@ -32,12 +32,12 @@ from .signing import UserSigner
|
||||||
from .snowflake import Snowflake, SnowflakeGen
|
from .snowflake import Snowflake, SnowflakeGen
|
||||||
from .lex import symbol_table, lex, ilex
|
from .lex import symbol_table, lex, ilex
|
||||||
from .strtools import PrefixIdentifier
|
from .strtools import PrefixIdentifier
|
||||||
from .validators import matches, not_less_than, not_greater_than, yesno
|
from .validators import matches
|
||||||
from .redact import redact_url_password
|
from .redact import redact_url_password
|
||||||
from .http import WantsContentType
|
from .http import WantsContentType
|
||||||
from .color import chalk, WebColor
|
from .color import chalk, WebColor
|
||||||
|
|
||||||
__version__ = "0.9.0"
|
__version__ = "0.8.2"
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',
|
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',
|
||||||
|
|
@ -51,10 +51,9 @@ __all__ = (
|
||||||
'cb32decode', 'chalk', 'count_ones', 'dei_args', 'deprecated',
|
'cb32decode', 'chalk', 'count_ones', 'dei_args', 'deprecated',
|
||||||
'future', 'ilex', 'join_bits',
|
'future', 'ilex', 'join_bits',
|
||||||
'jsonencode', 'kwargs_prefix', 'lex', 'ltuple', 'makelist', 'mask_shift',
|
'jsonencode', 'kwargs_prefix', 'lex', 'ltuple', 'makelist', 'mask_shift',
|
||||||
'matches', 'mod_ceil', 'mod_floor', 'must_be', 'none_pass', 'not_implemented',
|
'matches', 'mod_ceil', 'mod_floor', 'none_pass', 'not_implemented',
|
||||||
'not_less_than', 'not_greater_than',
|
|
||||||
'redact_url_password', 'rtuple', 'split_bits', 'ssv_list', 'symbol_table',
|
'redact_url_password', 'rtuple', 'split_bits', 'ssv_list', 'symbol_table',
|
||||||
'timed_cache', 'twocolon_list', 'want_bytes', 'want_datetime', 'want_isodate',
|
'timed_cache', 'twocolon_list', 'want_bytes', 'want_datetime', 'want_isodate',
|
||||||
'want_str', 'want_timestamp', 'want_urlsafe', 'want_urlsafe_bytes', 'yesno',
|
'want_str', 'want_timestamp', 'want_urlsafe', 'want_urlsafe_bytes',
|
||||||
'z85encode', 'z85decode'
|
'z85encode', 'z85decode'
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
from suou.functools import not_implemented
|
||||||
from suou.luck import lucky
|
from suou.luck import lucky
|
||||||
from suou.validators import not_greater_than
|
from suou.validators import not_greater_than
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ from suou.classtools import MISSING
|
||||||
from suou.functools import future
|
from suou.functools import future
|
||||||
|
|
||||||
|
|
||||||
@future()
|
@future(version="0.9.0")
|
||||||
class FakeModule(ModuleType):
|
class FakeModule(ModuleType):
|
||||||
"""
|
"""
|
||||||
Fake module used in @glue() in case of import error
|
Fake module used in @glue() in case of import error
|
||||||
|
|
@ -34,12 +34,12 @@ class FakeModule(ModuleType):
|
||||||
raise AttributeError(f'Module {self.__name__} not found; this feature is not available ({self._exc})') from self._exc
|
raise AttributeError(f'Module {self.__name__} not found; this feature is not available ({self._exc})') from self._exc
|
||||||
|
|
||||||
|
|
||||||
@future()
|
@future(version = "0.9.0")
|
||||||
def glue(*modules):
|
def glue(*modules):
|
||||||
"""
|
"""
|
||||||
Helper for "glue" code -- it imports the given modules and passes them as keyword arguments to the wrapped functions.
|
Helper for "glue" code -- it imports the given modules and passes them as keyword arguments to the wrapped functions.
|
||||||
|
|
||||||
EXPERIMENTAL
|
NEW 0.9.0
|
||||||
"""
|
"""
|
||||||
module_dict = dict()
|
module_dict = dict()
|
||||||
imports_succeeded = True
|
imports_succeeded = True
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,6 @@ import re
|
||||||
|
|
||||||
from typing import Any, Iterable, TypeVar
|
from typing import Any, Iterable, TypeVar
|
||||||
|
|
||||||
from suou.classtools import MISSING
|
|
||||||
|
|
||||||
from .functools import future
|
|
||||||
|
|
||||||
_T = TypeVar('_T')
|
_T = TypeVar('_T')
|
||||||
|
|
||||||
def matches(regex: str | int, /, length: int = 0, *, flags=0):
|
def matches(regex: str | int, /, length: int = 0, *, flags=0):
|
||||||
|
|
@ -59,13 +55,5 @@ def not_less_than(y):
|
||||||
"""
|
"""
|
||||||
return lambda x: x >= y
|
return lambda x: x >= y
|
||||||
|
|
||||||
def yesno(x: str) -> bool:
|
__all__ = ('matches', 'not_greater_than')
|
||||||
"""
|
|
||||||
Returns False if x.lower() is in '0', '', 'no', 'n', 'false' or 'off'.
|
|
||||||
|
|
||||||
*New in 0.9.0*
|
|
||||||
"""
|
|
||||||
return x not in (None, MISSING) and x.lower() not in ('', '0', 'off', 'n', 'no', 'false', 'f')
|
|
||||||
|
|
||||||
__all__ = ('matches', 'must_be', 'not_greater_than', 'not_less_than', 'yesno')
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from typing import Callable
|
|
||||||
import warnings
|
import warnings
|
||||||
from starlette.applications import Starlette
|
from starlette.applications import Starlette
|
||||||
from starlette.responses import JSONResponse, PlainTextResponse, Response
|
from starlette.responses import JSONResponse, PlainTextResponse, Response
|
||||||
|
|
@ -28,22 +27,15 @@ from suou.functools import future
|
||||||
|
|
||||||
@future()
|
@future()
|
||||||
class Waiter():
|
class Waiter():
|
||||||
_cached_app: Callable | None = None
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.routes: list[Route] = []
|
self.routes: list[Route] = []
|
||||||
self.production = False
|
self.production = False
|
||||||
|
|
||||||
async def __call__(self, *args):
|
|
||||||
return await self._build_app()(*args)
|
|
||||||
|
|
||||||
def _build_app(self) -> Starlette:
|
def _build_app(self) -> Starlette:
|
||||||
if not self._cached_app:
|
return Starlette(
|
||||||
self._cached_app = Starlette(
|
|
||||||
debug = not self.production,
|
debug = not self.production,
|
||||||
routes= self.routes
|
routes= self.routes
|
||||||
)
|
)
|
||||||
return self._cached_app
|
|
||||||
|
|
||||||
def get(self, endpoint: str, *a, **k):
|
def get(self, endpoint: str, *a, **k):
|
||||||
return self._route('GET', endpoint, *a, **k)
|
return self._route('GET', endpoint, *a, **k)
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
from suou.validators import yesno
|
|
||||||
|
|
||||||
class TestValidators(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
...
|
|
||||||
def tearDown(self):
|
|
||||||
...
|
|
||||||
def test_yesno(self):
|
|
||||||
self.assertFalse(yesno('false'))
|
|
||||||
self.assertFalse(yesno('FALSe'))
|
|
||||||
self.assertTrue(yesno('fasle'))
|
|
||||||
self.assertTrue(yesno('falso'))
|
|
||||||
self.assertTrue(yesno('zero'))
|
|
||||||
self.assertTrue(yesno('true'))
|
|
||||||
self.assertFalse(yesno('0'))
|
|
||||||
self.assertTrue(yesno('00'))
|
|
||||||
self.assertTrue(yesno('.'))
|
|
||||||
self.assertTrue(yesno('2'))
|
|
||||||
self.assertTrue(yesno('o'))
|
|
||||||
self.assertFalse(yesno('oFF'))
|
|
||||||
self.assertFalse(yesno('no'))
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue