better-py
Functional programming patterns for Python - pragmatic, type-safe, and developer-friendly.
✨ Features
Monads & Functional Types
Maybe[T]- Handle optional values safelyResult<T, E>- Explicit error handlingEither<L, R>- Two-value alternativesValidation<T, E>- Accumulate validation errors- And more:
Try,IO,Reader,Writer,State,Task, etc.
Functional Collections
MappableList[T]- List with functional operationsImmutableDict[K, V]- Safe immutable dictionariesLazySequence[T]- Lazy evaluation sequencesBidirectionalMap[K, V]- Two-way lookups
Function Utilities
curry(f)- Incremental argument applicationcompose(f, g)- Function compositionpipe(value, f, g)- Left-to-right pipelinespartial(f, ...)- Fix function arguments
OOP-First Design
- Protocol-based (like
collections.abc) - Generic types with full type hints
- Method chaining and fluent APIs
- Modern Python patterns (dataclasses, protocols, etc.)
🚀 Quick Start
from better_py import Maybe, Result, pipe
# Maybe: Safe optional handling
user = Maybe.from_value(get_user(id))
name = user.map(lambda u: u.name).unwrap_or_else(lambda: "Guest")
# Result: Explicit error handling
def divide(a: int, b: int) -> Result[float, str]:
if b == 0:
return Result.error("Division by zero")
return Result.ok(a / b)
result = divide(10, 2)
if result.is_ok():
print(f"Result: {result.unwrap()}")
else:
print(f"Error: {result.unwrap_error()}")
# Pipe: Data pipelines
result = pipe(
data,
validate,
transform,
save
)
📦 Installation
# Install from PyPI
pip install better-py
# Or with uv (recommended)
uv pip install better-py
Requirements: Python 3.11+
📚 Documentation
💡 Why better-py?
Pragmatic FP
Not academic functional programming - practical patterns that make software development easier.
Type-Safe
Full type hints with mypy strict mode. Catch errors before runtime.
OOP-First
Everything is an object. Operations are functional. Works naturally with Python.
Developer-Friendly
Clear error messages, helpful APIs, extensive documentation.
🎯 Use Cases
# REST API error handling
from better_py import Result
async def get_user(id: int) -> Result[User, Error]:
user = await db.fetch_user(id)
if not user:
return Result.error(Error("User not found"))
return Result.ok(user)
# Data validation
from better_py import Validation
email_validated = Validation.validate(email, EmailValidator())
password_validated = Validation.validate(password, PasswordValidator())
user_validation = email_validated.and_then(password_validated)
if user_validation.is_valid():
create_user(email, password)
# Data processing pipeline
from better_py import pipe
result = pipe(
raw_data,
clean,
validate,
transform,
load_to_db
)
🏗️ Project Status
Current Version: 0.1.0 (Alpha)
What's Working:
- ✅ Documentation framework
- ✅ CI/CD pipeline
- ✅ Type system design
In Development:
- 🔄 Core protocols (Mappable, Reducible, etc.)
- 🔄 Monad implementations
- 🔄 Functional collections
- 🔄 Function utilities
Planned:
- 📋 More monads (Writer, State, etc.)
- 📋 Performance benchmarks
- 📋 Integration examples (FastAPI, SQLAlchemy, etc.)
See Issues for detailed roadmap.
🤝 Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
Quick start:
# Clone repository
git clone https://github.com/nesalia-inc/better-py.git
cd better-py
# Install with uv
uv venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
uv sync --all-extras
# Run tests
uv run pytest
# Run checks
uv run ruff check .
uv run mypy better_py
📄 License
MIT License - see LICENSE for details.
🙏 Acknowledgments
Inspired by:
📮 Contact
- GitHub: nesalia-inc/better-py
- Issues: GitHub Issues
Made with ❤️ by nesalia-inc
Metadata
Release files for better-py-fp 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| better_py_fp-0.2.0.tar.gz | 34.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| better_py_fp-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.1 kB
Release files / better_py_fp-0.2.0.tar.gz
| Download URL | better_py_fp-0.2.0.tar.gz |
|---|---|
| Size | 34.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8337c8c3519e4d41a945a6e2924859de9da2cfa47934cd28e381f1acb8697147
|
|
BLAKE2b-256 checksum How to use checksums |
df0ad141de663d5a9a88670ed895d362131884d6a864dd06b0170ce8d235e740
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"43","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / better_py_fp-0.2.0-py3-none-any.whl
| Download URL | better_py_fp-0.2.0-py3-none-any.whl |
|---|---|
| Size | 51.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f7edb5310c44a5988c6e236471710c0af51e8becc16c0e395b6828d361670130
|
|
BLAKE2b-256 checksum How to use checksums |
1fd253fe8737717f83796e15f5813bed921391fc37dbf79924695463f3995243
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"43","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|