Skip to main content

An extensive drop-in argument validator.

Project description

typekeeper

Overview

typekeeper is a lightweight Python library that injects comprehensive runtime validation into your functions with a single decorator. It automatically:

  • Verifies that arguments conform to their type annotations (including nested generics).
  • Warns when default values don’t match annotations or use mutable defaults.
  • Enforces numeric ranges and sequence-length constraints via an easy spec string.
  • Captures both the function definition and call site in all warnings for precise diagnostics.

Simply decorate your function with @print_param_info(...) to gain these safeguards during development, without changing your function signature.

Features

  • Type validation: Recursively checks simple and generic types (List[int], Dict[str, float], Optional[...], Union[...], Callable, etc.).
  • Default‐value checks: Detects mismatches between annotated types and default values, plus the classic mutable‐default gotcha.
  • Range & length specs: Specify numeric or length constraints in one string (e.g. "x=1-5; tags=2-4").
  • Context‐aware warnings: All warnings include file paths and line numbers of both the decorator and the call site.
  • Global control: Enable or disable checks at runtime with set_arg_checks() or temporarily within suspended_arg_checks().
  • Recursive _validate() Invocation: Recursively calls _validate() on variable if defined. Gives metadata of location of object in recursion path which fails _validate().

Installation

pip install typekeeper

Configuration

Global Toggle

Argument checks are controlled by an internal flag; direct access is not required. Use the provided APIs:

  • set_arg_checks(enabled: bool): Turn all checks on or off globally.
  • suspended_arg_checks(): Context manager to disable checks within a with block.

API Reference

print_param_info

def print_param_info(*, lengths: Optional[str] = None, ignore_defaults: bool = False) -> Callable
  • lengths: Optional specification string for constraining numeric values or sequence lengths. It uses a semicolon-separated list of parameter specifications in the form:
    name=token1,token2,...
    
    where each token is either:
    • A single number N, enforcing an exact value (for numeric arguments) or exact length (for sequences).
    • A range min-max, enforcing inclusive bounds (both endpoints inclusive). For example:
    lengths="x=1,3-5; y=2"
    
    enforces:
    • x must be either exactly 1 or between 3 and 5.
    • y must be exactly 2.
      If omitted, no range or length constraints are applied.
  • ignore_defaults: Skip warnings for mutable default arguments if set to True.

set_arg_checks

def set_arg_checks(enabled: bool) -> None

Globally enable or disable all argument validation.

suspended_arg_checks

@contextmanager
def suspended_arg_checks() -> None

Temporarily suspend argument checks within a with block.

Examples

# Example 1: Basic type‐and‐default validation
from typekeeper import validate_args

@validate_args()
def greet(name: str, times: int = 1):
    return " ".join([name] * times)

# Valid call:
greet("Alice")         # → "Alice"
# Invalid call (wrong type):
greet(42)              
#  UserWarning: Arg 'name' mismatches <class 'str'>; expected <class 'str'>, got <class 'int'>
# Example 2: Numeric‐range and length‐range constraints
from typekeeper import validate_args

@validate_args(lengths="x=1-3; data=2-4")
def process(x: int, data: list[int]):
    return data * x

# Valid:
process(2, [10, 20, 30])   
# Invalid x:
process(0, [1, 2])         
#  UserWarning: Param 'x'=0 not in ranges [(1.0, 3.0)]
# Invalid data length:
process(2, [1])            
#  UserWarning: Length of 'data'=1 not in ranges [(2.0, 4.0)]
# Example 3: Mutable‐default detection
from typekeeper import validate_args

@validate_args(ignore_defaults=False)
def append_item(items: list[int] = []):
    items.append(1)
    return items

# Decoration‐time warning:
#  UserWarning: Mutable default for 'items' in '<function append_item>' : []
# Example 4: Custom _validate() on nested items
from typekeeper import validate_args

class Thing:
    def __init__(self, v: int):
        self.v = v
    def _validate(self) -> bool:
        return self.v >= 0

@validate_args()
def handle(things: list[Thing]):
    return [t.v for t in things]

# Call with one bad element:
handle([Thing(1), Thing(-5), Thing(3)])
#  UserWarning: Parameter 'things' failed at [1] in 'handle'; offending value: Thing(v=-5)

Contributing

Contributions are welcome! To contribute:

  1. Fork the repository.
  2. Create a feature branch.
  3. Submit a pull request.

License

MIT License

Author

Parth Mittal
Email: parth@privatepanda.co

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typekeeper-0.0.1.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typekeeper-0.0.1-py3-none-any.whl (7.1 kB view details)

Uploaded Python 3

File details

Details for the file typekeeper-0.0.1.tar.gz.

File metadata

  • Download URL: typekeeper-0.0.1.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for typekeeper-0.0.1.tar.gz
Algorithm Hash digest
SHA256 f1f69d1a1a1d48744dc30790abd8f749b336b9bbfa229792e725ca4d10d9872b
MD5 0d6fb2b7ad3832a1126687b63cb89f03
BLAKE2b-256 dec9bb1d31c910a1e9deee53144c88d07978352a23cddcc5f9af373359f44bff

See more details on using hashes here.

File details

Details for the file typekeeper-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: typekeeper-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for typekeeper-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 63b8aaeb84aa2bebfc92dd1eb5f4364833c558cc7f7156c412a093ee90ae40ad
MD5 ad4543d960c747b2bf97b04dedfd59e8
BLAKE2b-256 f120c9f77bba220e551bbb7aac4009607cda2cb404c30d6635eb85a747b1458f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page