| name | func-args |
| description | Guide for using the func_args Python library (>=1.0.2) — sentinel-based function argument handling with REQ/OPT markers and enhanced dataclasses. Use when writing API wrappers, parameter validation, or dataclass-based config objects. |
func_args Library Usage Guide
func_args is a lightweight, zero-dependency Python library (requires Python >=3.10) that provides sentinel values for enhanced function argument handling. Install with pip install func_args.
All public API is imported from func_args.api:
from func_args.api import (
REQ,
OPT,
check_required,
remove_optional,
prepare_kwargs,
BaseModel,
BaseFrozenModel,
ParamError,
T_KWARGS,
T_OPT_KWARGS,
)
Core Concept
REQ and OPT are singleton sentinel values used as default parameter values:
REQ — marks a parameter as required. If the caller doesn't provide it, validation raises ParamError.
OPT — marks a parameter as optional. It is automatically stripped from the final kwargs dict, so unprovided optional params never reach the downstream API.
Use identity checks (is), never equality (==):
if value is REQ: ...
if value is OPT: ...
Use Case 1: Wrapping Third-Party APIs
The primary use case. Create a better interface around an existing function you cannot modify:
from func_args.api import REQ, OPT, prepare_kwargs
def s3_put_object(Bucket, Key, Body, Metadata=None, Tags=None):
...
def put_object(
Bucket: str = REQ,
Key: str = REQ,
Body: bytes = REQ,
Metadata: dict | None = OPT,
Tags: dict | None = OPT,
):
if Metadata is OPT:
Metadata = {"creator": "admin"}
kwargs = dict(
Bucket=Bucket, Key=Key, Body=Body,
Metadata=Metadata, Tags=Tags,
)
return s3_put_object(**prepare_kwargs(**kwargs))
put_object(Bucket="b", Key="k", Body=b"data")
put_object(Bucket="b", Key="k", Body=b"data", Tags={})
put_object(Bucket="b", Key="k")
Use Case 2: Individual Utilities
Use check_required and remove_optional separately when you need finer control:
from func_args.api import REQ, OPT, check_required, remove_optional
def create_user(username=REQ, email=REQ, nickname=OPT, role="user"):
check_required(username=username, email=email)
return remove_optional(
username=username, email=email,
nickname=nickname, role=role,
)
create_user(username="alice", email="a@b.com")
create_user(username="bob", email="b@b.com", nickname="Bobby")
Use Case 3: Enhanced Dataclasses
BaseModel and BaseFrozenModel are dataclass mixins that:
- Bypass field ordering restrictions — OPT/REQ fields can appear in any order (standard dataclasses require non-default fields before default fields).
- Validate REQ fields on init — Raises
ParamError immediately if a REQ field is missing.
- Provide
to_dict() and to_kwargs() — Convert to dict with or without OPT values.
import dataclasses
from func_args.api import BaseModel, REQ, OPT
@dataclasses.dataclass
class DeployConfig(BaseModel):
region: str = dataclasses.field(default=OPT)
env: str = dataclasses.field(default="prod")
app_name: str = dataclasses.field(default=REQ)
tags: list = dataclasses.field(default_factory=list)
config = DeployConfig(app_name="my-service")
config.to_dict()
config.to_kwargs()
DeployConfig()
Frozen Dataclass with Computed Fields
import dataclasses
from func_args.api import BaseFrozenModel, REQ, OPT
@dataclasses.dataclass(frozen=True)
class Document(BaseFrozenModel):
title: str = dataclasses.field(default=REQ)
author: str = dataclasses.field(default=OPT)
slug: str = dataclasses.field(init=False)
def __post_init__(self):
super().__post_init__()
object.__setattr__(self, "slug", self.title.lower().replace(" ", "-"))
doc = Document(title="API Guide")
doc.to_kwargs()
Splitting kwargs with _split_req_opt
kwargs = {"app_name": "svc", "region": "us-east-1", "env": "staging", "tags": ["v2"]}
req, opt = DeployConfig._split_req_opt(kwargs)
API Quick Reference
| Symbol | Description |
|---|
REQ | Sentinel for required parameters |
OPT | Sentinel for optional parameters (auto-removed) |
check_required(**kw) -> None | Raises ParamError if any value is REQ |
remove_optional(**kw) -> dict | Returns new dict with OPT values removed |
prepare_kwargs(**kw) -> dict | check_required + remove_optional in one pass |
BaseModel | Mutable dataclass mixin (use with @dataclasses.dataclass) |
BaseFrozenModel | Frozen dataclass mixin (use with @dataclasses.dataclass(frozen=True)) |
ParamError | Exception for missing required parameters |
Key Rules
- Always use
is for sentinel checks, never ==.
- All three functions take
**kwargs, not a dict: prepare_kwargs(**my_dict), not prepare_kwargs(my_dict).
- Dataclass fields use
dataclasses.field(default=REQ), not bare REQ as default (bare defaults work but field() is the canonical pattern).
- Import from
func_args.api for the public API surface.
to_kwargs() excludes OPT values, to_dict() includes them.