initial commit
All checks were successful
CI / build (push) Successful in 12s

This commit is contained in:
2024-06-22 08:13:48 +08:00
commit 514962d9e3
4 changed files with 167 additions and 0 deletions

View 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:
cache: 'pip'
- name: Execute build
env:
TWINE_REPOSITORY_URL: ${{ vars.PYPI_REGISTRY_URL }}
TWINE_USERNAME: ${{ vars.PUBLISHER_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PUBLISHER_TOKEN }}
run: |
python -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m build
.venv/bin/python -m twine upload --repository gitea dist/*{.whl,tar.gz}

35
pyproject.toml Normal file
View 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

34
requirements.txt Normal file
View File

@@ -0,0 +1,34 @@
build==1.2.1
certifi==2024.6.2
cffi==1.16.0
charset-normalizer==3.3.2
cryptography==42.0.8
docutils==0.21.2
idna==3.7
importlib_metadata==7.2.0
jaraco.classes==3.4.0
jaraco.context==5.3.0
jaraco.functools==4.0.1
jeepney==0.8.0
keyring==25.2.1
markdown-it-py==3.0.0
mdurl==0.1.2
more-itertools==10.3.0
mypy==1.10.0
mypy-extensions==1.0.0
nh3==0.2.17
packaging==24.1
pkginfo==1.11.1
pycparser==2.22
Pygments==2.18.0
pyproject_hooks==1.1.0
readme_renderer==43.0
requests==2.32.3
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==13.7.1
SecretStorage==3.3.3
twine==5.1.0
typing_extensions==4.12.2
urllib3==2.2.2
zipp==3.19.2

75
src/pwo/maybe.py Normal file
View 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)