23
.gitea/workflows/build.yaml
Normal file
23
.gitea/workflows/build.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: woryzen
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.12'
|
||||||
|
cache: 'pip'
|
||||||
|
- name: Execute build
|
||||||
|
env:
|
||||||
|
TWINE_REPOSITORY_URL: ${{ vars.PYPI_REGISTRY_URL }}
|
||||||
|
TWINE_USERNAME: ${{ vars.PUBLISHER_USERNAME }}
|
||||||
|
TWINE_PASSWORD: ${{ secrets.PUBLISHER_TOKEN }}
|
||||||
|
run: |
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python -m build
|
||||||
|
python -m twine upload --repository gitea dist/*{.whl,rag.gz}
|
35
pyproject.toml
Normal file
35
pyproject.toml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.0"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "pwo"
|
||||||
|
version = "0.0.1"
|
||||||
|
authors = [
|
||||||
|
{ name="Walter Oggioni", email="oggioni.walter@gmail.com" },
|
||||||
|
]
|
||||||
|
description = "Python language utilities"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
classifiers = [
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
'typing_extensions==4.7.1'
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
"Homepage" = "https://gitea.woggioni.net/woggioni/pwo"
|
||||||
|
"Bug Tracker" = "https://gitea.woggioni.net/woggioni/pwo/issues"
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
python_version = "3.12"
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
show_error_codes = true
|
||||||
|
no_implicit_optional = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unused_ignores = true
|
||||||
|
exclude = ["scripts", "docs", "test"]
|
||||||
|
strict = true
|
288
requirements.txt
Normal file
288
requirements.txt
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
alabaster==0.7.16
|
||||||
|
annotated-types==0.7.0
|
||||||
|
anyio==4.4.0
|
||||||
|
appdirs==1.4.4
|
||||||
|
apsw==3.45.2.0
|
||||||
|
argcomplete==3.1.3.dev0+g140fa51.d20240618
|
||||||
|
argon2-cffi==23.1.0
|
||||||
|
argon2-cffi-bindings==21.2.0
|
||||||
|
asciidoc==10.2.0
|
||||||
|
astroid==3.2.2
|
||||||
|
asttokens==2.4.1
|
||||||
|
async-lru==2.0.4
|
||||||
|
async-timeout==4.0.3
|
||||||
|
attrs==23.2.1.dev0
|
||||||
|
Authlib==1.2.1
|
||||||
|
autocommand==2.2.2
|
||||||
|
Babel==2.14.0
|
||||||
|
bcrypt==4.1.3
|
||||||
|
beautifulsoup4==4.12.3
|
||||||
|
black==24.4.2
|
||||||
|
bleach==6.1.0
|
||||||
|
botocore==1.34.106
|
||||||
|
bottle==0.12.25
|
||||||
|
breezy==3.3.7
|
||||||
|
Brlapi==0.8.5
|
||||||
|
Brotli==1.1.0
|
||||||
|
brotlicffi==1.1.0.0
|
||||||
|
btrfsutil==6.9
|
||||||
|
build==1.2.1
|
||||||
|
CacheControl==0.14.0
|
||||||
|
certifi==2024.6.2
|
||||||
|
cffi==1.16.0
|
||||||
|
chardet==5.2.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
colorama==0.4.6
|
||||||
|
comm==0.2.2
|
||||||
|
commonmark==0.9.1
|
||||||
|
configobj==5.0.8
|
||||||
|
construct==2.10.70
|
||||||
|
contourpy==1.2.1
|
||||||
|
coverage==7.5.1
|
||||||
|
cryptography==42.0.6
|
||||||
|
css-parser==1.0.10
|
||||||
|
cssselect==1.2.0
|
||||||
|
cycler==0.12.1
|
||||||
|
Cython==3.0.10
|
||||||
|
dbus-python==1.3.2
|
||||||
|
decorator==5.1.1
|
||||||
|
defusedxml==0.7.1
|
||||||
|
dill==0.3.8
|
||||||
|
distlib==0.3.8
|
||||||
|
distro==1.9.0
|
||||||
|
dnspython==2.6.1
|
||||||
|
docker==7.1.0
|
||||||
|
docutils==0.21.2
|
||||||
|
dulwich==0.22.1
|
||||||
|
executing==2.0.0
|
||||||
|
fastbencode==0.2
|
||||||
|
fastjsonschema==2.20.0
|
||||||
|
faust-cchardet==2.1.19
|
||||||
|
feedparser==6.0.11
|
||||||
|
fido2==1.1.3
|
||||||
|
filelock==3.13.3
|
||||||
|
fonttools==4.53.0
|
||||||
|
future==1.0.0
|
||||||
|
gbinder-python==1.1.2
|
||||||
|
gevent==24.2.1
|
||||||
|
Glances==4.0.8
|
||||||
|
gpg==1.23.2
|
||||||
|
greenlet==3.0.3
|
||||||
|
h11==0.14.0
|
||||||
|
html2text==2020.1.16
|
||||||
|
html5-parser==0.4.12
|
||||||
|
html5lib==1.1
|
||||||
|
httpcore==1.0.5
|
||||||
|
httpx==0.27.0
|
||||||
|
idna==3.6
|
||||||
|
ifaddr==0.2.0
|
||||||
|
imagesize==1.4.1
|
||||||
|
importlib_metadata==5.1.0
|
||||||
|
inflate64==1.0.0
|
||||||
|
inflect==7.2.1
|
||||||
|
installer==0.7.0
|
||||||
|
ipykernel==6.29.4
|
||||||
|
ipython==8.25.0
|
||||||
|
isort==5.13.2
|
||||||
|
jaraco.classes==3.4.0
|
||||||
|
jaraco.context==4.3.0
|
||||||
|
jaraco.functools==4.0.1
|
||||||
|
jaraco.text==3.12.1
|
||||||
|
jedi==0.19.1
|
||||||
|
jeepney==0.8.0
|
||||||
|
Jinja2==3.1.4
|
||||||
|
jmespath==1.0.1
|
||||||
|
json5==0.9.25
|
||||||
|
jsonschema==4.22.0
|
||||||
|
jsonschema-specifications==2023.12.1
|
||||||
|
jupyter-events==0.10.0
|
||||||
|
jupyter_client==8.6.2
|
||||||
|
jupyter_core==5.7.2
|
||||||
|
jupyter_server==2.14.1
|
||||||
|
jupyterlab==4.2.2
|
||||||
|
jupyterlab_pygments==0.3.0
|
||||||
|
jupyterlab_server==2.27.2
|
||||||
|
keyring==25.2.1
|
||||||
|
kiwisolver==1.4.5
|
||||||
|
lazy-object-proxy==1.10.0
|
||||||
|
lensfun==0.3.4
|
||||||
|
libfdt==1.7.0
|
||||||
|
lit==17.0.6.dev0
|
||||||
|
louis==3.30.0
|
||||||
|
lxml==5.2.2
|
||||||
|
lxml_html_clean==0.1.1
|
||||||
|
Mako==1.3.5.dev0
|
||||||
|
Markdown==3.6
|
||||||
|
markdown-it-py==3.0.0
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
matplotlib==3.8.3
|
||||||
|
matplotlib-inline==0.1.7
|
||||||
|
mccabe==0.7.0
|
||||||
|
mdurl==0.1.2
|
||||||
|
mechanize==0.4.10
|
||||||
|
merge3==0.0.15
|
||||||
|
meson==1.4.1
|
||||||
|
mistune==3.0.2
|
||||||
|
more-itertools==10.2.0
|
||||||
|
msgpack==1.0.5
|
||||||
|
multivolumefile==0.2.3
|
||||||
|
mutagen==1.47.0
|
||||||
|
mypy_extensions==1.0.0
|
||||||
|
nbclient==0.10.0
|
||||||
|
nbconvert==7.16.4
|
||||||
|
nbformat==5.10.4
|
||||||
|
nest_asyncio==1.6.0
|
||||||
|
netifaces==0.11.0
|
||||||
|
netsnmp-python==1.0a1
|
||||||
|
nftables==0.1
|
||||||
|
nose==1.3.7
|
||||||
|
notebook==7.2.1
|
||||||
|
notebook_shim==0.2.4
|
||||||
|
nspektr==0.5.0
|
||||||
|
numpy==1.26.4
|
||||||
|
ordered-set==4.1.0
|
||||||
|
orjson==3.10.5
|
||||||
|
overrides==7.7.0
|
||||||
|
packaging==24.0
|
||||||
|
pandocfilters==1.5.1
|
||||||
|
paramiko==3.4.0
|
||||||
|
parso==0.8.4
|
||||||
|
pathspec==0.12.1
|
||||||
|
patiencediff==0.2.15
|
||||||
|
pbr==6.0.0
|
||||||
|
pdftotext==2.2.2
|
||||||
|
pefile==2023.2.7
|
||||||
|
pexpect==4.9.0
|
||||||
|
pickleshare==0.7.5
|
||||||
|
pillow==10.3.0
|
||||||
|
pipx==1.6.0
|
||||||
|
platformdirs==4.2.0
|
||||||
|
ply==3.11
|
||||||
|
prometheus_client==0.20.0
|
||||||
|
prompt_toolkit==3.0.47
|
||||||
|
psutil==5.9.8
|
||||||
|
ptyprocess==0.7.0
|
||||||
|
pure_eval==0.2.2
|
||||||
|
pwquality==1.4.5
|
||||||
|
py7zr==0.21.0
|
||||||
|
pyalpm==0.10.6
|
||||||
|
pyasn1==0.5.1
|
||||||
|
pybcj==1.0.2
|
||||||
|
pycairo==1.26.0
|
||||||
|
pychm==0.8.6
|
||||||
|
pycodestyle==2.11.1
|
||||||
|
pycparser==2.22
|
||||||
|
pycryptodome==3.20.0
|
||||||
|
pycryptodomex==3.20.0
|
||||||
|
pycurl==7.45.2
|
||||||
|
pydantic==2.7.4
|
||||||
|
pydantic_core==2.18.4
|
||||||
|
pyflakes==3.2.0
|
||||||
|
Pygments==2.17.2
|
||||||
|
PyGObject==3.48.2
|
||||||
|
PyKCS11==1.5.16
|
||||||
|
pykeepass==4.0.7
|
||||||
|
pylint==3.2.3
|
||||||
|
PyNaCl==1.5.0
|
||||||
|
pyOpenSSL==24.1.0
|
||||||
|
pyotp==2.9.0
|
||||||
|
pyparsing==3.1.2
|
||||||
|
pyppmd==1.1.0
|
||||||
|
pyproject_hooks==1.1.0
|
||||||
|
PyQt5==5.15.10
|
||||||
|
PyQt5_sip==12.13.0
|
||||||
|
PyQt6==6.7.0
|
||||||
|
PyQt6-WebEngine==6.7.0
|
||||||
|
PyQt6_sip==13.6.0
|
||||||
|
PyQtWebEngine==5.15.6
|
||||||
|
pyrsistent==0.19.3
|
||||||
|
pyscard==2.0.8
|
||||||
|
PySocks==1.7.1
|
||||||
|
pystache==0.6.5
|
||||||
|
python-dateutil==2.9.0
|
||||||
|
python-json-logger==2.0.7
|
||||||
|
python-xlib==0.33
|
||||||
|
python-yubico==1.3.3
|
||||||
|
pytz==2024.1
|
||||||
|
pyusb==1.2.1
|
||||||
|
pyxdg==0.28
|
||||||
|
PyYAML==6.0.1
|
||||||
|
pyzmq==25.1.2
|
||||||
|
pyzstd==0.16.0
|
||||||
|
qrtools==2.1
|
||||||
|
referencing==0.35.1
|
||||||
|
Reflector==2023.6.28.0.36.1
|
||||||
|
regex==2024.5.15
|
||||||
|
requests==2.32.3
|
||||||
|
resolvelib==1.0.1
|
||||||
|
retrying==1.3.4
|
||||||
|
rich==13.7.1
|
||||||
|
rpds-py==0.18.1
|
||||||
|
rsa==4.9
|
||||||
|
ruamel.yaml==0.18.6
|
||||||
|
ruamel.yaml.clib==0.2.8
|
||||||
|
s3transfer==0.10.1
|
||||||
|
SecretStorage==3.3.3
|
||||||
|
Send2Trash==1.8.2
|
||||||
|
setproctitle==1.3.3
|
||||||
|
setuptools==69.0.3
|
||||||
|
setuptools-scm==8.1.0
|
||||||
|
sgmllib3k==1.0.0
|
||||||
|
simplejson==3.19.2
|
||||||
|
six==1.16.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
snowballstemmer==2.2.0
|
||||||
|
soupsieve==2.5
|
||||||
|
speedtest-cli==2.1.3
|
||||||
|
Sphinx==7.3.7
|
||||||
|
sphinx_rtd_theme==1.3.0
|
||||||
|
sphinxcontrib-applehelp==1.0.8
|
||||||
|
sphinxcontrib-devhelp==1.0.6
|
||||||
|
sphinxcontrib-htmlhelp==2.0.5
|
||||||
|
sphinxcontrib-jquery==4.1
|
||||||
|
sphinxcontrib-jsmath==1.0.1
|
||||||
|
sphinxcontrib-qthelp==1.0.7
|
||||||
|
sphinxcontrib-serializinghtml==1.1.10
|
||||||
|
stack_data==0.6.3
|
||||||
|
TBB==0.2
|
||||||
|
tenacity==8.3.0
|
||||||
|
texttable==1.7.0
|
||||||
|
tinycss2==1.3.0
|
||||||
|
toml==0.10.2
|
||||||
|
tomli==2.0.1
|
||||||
|
tomlkit==0.12.5
|
||||||
|
torbrowser-launcher==0.3.7
|
||||||
|
tornado==6.4
|
||||||
|
tqdm==4.66.2
|
||||||
|
traitlets==5.14.3
|
||||||
|
trove-classifiers==2024.5.23
|
||||||
|
typeguard==4.3.0
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
tzlocal==5.2
|
||||||
|
uc-micro-py==1.0.3
|
||||||
|
ufw==0.36.2
|
||||||
|
ujson==5.10.0
|
||||||
|
unrardll==0.1.7
|
||||||
|
urllib3==1.26.18
|
||||||
|
userpath==1.9.2
|
||||||
|
validate==5.0.8
|
||||||
|
validate-pyproject==0.16
|
||||||
|
validators==0.20.0
|
||||||
|
vdf==3.4
|
||||||
|
wcwidth==0.2.13
|
||||||
|
webencodings==0.5.1
|
||||||
|
websocket-client==1.8.0
|
||||||
|
websockets==12.0
|
||||||
|
wheel==0.43.0
|
||||||
|
wrapt==1.16.0
|
||||||
|
xxhash==3.4.1
|
||||||
|
yt-dlp==2024.5.27
|
||||||
|
yubikey-manager==5.4.0
|
||||||
|
zeroconf==0.63.0
|
||||||
|
zipfile-deflate64==0.2.0
|
||||||
|
zipp==3.18.1
|
||||||
|
zope.event==5.0
|
||||||
|
zope.interface==6.3
|
||||||
|
zstandard==0.22.0
|
||||||
|
zxcvbn==4.4.28
|
75
src/pwo/maybe.py
Normal file
75
src/pwo/maybe.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from typing import TypeVar, Generic, Optional, Callable, Any
|
||||||
|
|
||||||
|
T = TypeVar('T')
|
||||||
|
U = TypeVar('U')
|
||||||
|
|
||||||
|
|
||||||
|
class Maybe(Generic[T]):
|
||||||
|
|
||||||
|
def __init__(self, value: Optional[T] = None):
|
||||||
|
self._value: Optional[T] = value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def of(obj: T) -> Maybe[T]:
|
||||||
|
return Maybe(obj)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def of_nullable(obj: Optional[T]) -> Maybe[T]:
|
||||||
|
return Maybe(obj)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def empty() -> Maybe[U]:
|
||||||
|
return _empty
|
||||||
|
|
||||||
|
@property
|
||||||
|
def value(self) -> T:
|
||||||
|
value = self._value
|
||||||
|
if not value:
|
||||||
|
raise ValueError('Empty Maybe')
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_present(self) -> bool:
|
||||||
|
return self._value is not None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_empty(self) -> bool:
|
||||||
|
return not self.is_present
|
||||||
|
|
||||||
|
def map(self, transformer: Callable[[T], U]) -> Maybe[U]:
|
||||||
|
result: Maybe[U]
|
||||||
|
if self.is_present:
|
||||||
|
result = Maybe(transformer(self.value))
|
||||||
|
else:
|
||||||
|
result = Maybe.empty()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def filter(self, predicate: Callable[[T], bool]) -> Maybe[T]:
|
||||||
|
return self if self.is_present and predicate(self.value) else Maybe.empty()
|
||||||
|
|
||||||
|
def flat_map(self, transformer: Callable[[T], Maybe[U]]) -> Maybe[U]:
|
||||||
|
return transformer(self.value) if self.is_present else Maybe.empty()
|
||||||
|
|
||||||
|
def or_else(self, alt: T) -> T:
|
||||||
|
return self.value if self.is_present else alt
|
||||||
|
|
||||||
|
def or_none(self) -> Optional[T]:
|
||||||
|
return self.value if self.is_present else None
|
||||||
|
|
||||||
|
def or_else_throw(self, supplier: Callable[[], Exception]) -> T:
|
||||||
|
if self.is_present:
|
||||||
|
return self.value
|
||||||
|
else:
|
||||||
|
raise supplier()
|
||||||
|
|
||||||
|
def or_else_get(self, supplier: Callable[[], T]) -> Maybe[T]:
|
||||||
|
return self if self.is_present else Maybe.of_nullable(supplier())
|
||||||
|
|
||||||
|
def if_present(self, callback: Callable[[T], U]) -> None:
|
||||||
|
if self.is_present:
|
||||||
|
callback(self.value)
|
||||||
|
|
||||||
|
|
||||||
|
_empty: Maybe[Any] = Maybe(None)
|
Reference in New Issue
Block a user