Try to enforce various types of function purity in Python
Project description
pure-function-decorators
Decorators to try to enforce various types of function purity in Python
Mostly vibe-coded, though I hope to whittle down any issues
Super-quick Start
Requires: Python 3.10 to 3.13
Install through pip:
pip install pure-function-decorators
from pure_function_decorators import (
enforce_deterministic,
forbid_globals,
forbid_side_effects,
immutable_arguments,
)
@forbid_globals()
def bad(x):
return x + CONST
CONST = 10
bad(1) # Raises NameError
Documentation
The complete documentation can be found at the pure-function-decorators home page
Features
Existing decorators
immutable_argumentsdeep-copies inputs before invoking the wrapped callable so callers never observe in-place mutations. By default the decorator raises when a mutation is detected, and it can instead log warnings withwarn_only=True.enforce_deterministicreruns a function and compares its results so you can gate functions that rely on deterministic behavior.forbid_globalsprevents a function from reading or mutating module-level state by sandboxing its globals. Passcheck_names=Trueto also fail decoration when bytecode references globals outside the allow-list, or setsandbox=Falseto keep only the bytecode-based validation.forbid_side_effectsinstruments builtin operations that commonly mutate process state (e.g. file writes, subprocess launches) to surface accidental side effects.
Future purity checks to explore
The current decorators focus on globals, determinism, and structural immutability. Additional checks that build on the same inspection hooks could include:
- Non-deterministic source guards — wrap time-, randomness-, and UUID-related modules (
time,datetime,random,uuid,secrets) to ensure a supposedly pure function does not sample entropy or wall-clock timestamps. - Environment isolation — raise when a function touches environment variables, current working directory, or other process-wide configuration through
os.environ,os.chdir, or similar APIs. - I/O safelists — expand the
forbid_side_effectsstrategy with dedicated helpers that specifically deny file, socket, or HTTP operations unless a pure-safe allowlist is provided. - Mutable default detection — detect functions whose default arguments or closed-over state are mutable so callers do not accidentally share state across invocations.
- Dependency purity enforcement — verify that functions only call other decorated or safelisted pure functions by walking the bytecode or AST.
These ideas could live alongside the existing decorators as optional opt-in guards so projects can combine them to match their definition of purity.
Frequently asked questions
Can these decorators be enabled globally, like perl's strict pragma?
No. Python does not provide a hook that automatically wraps every function that is imported or defined after a module loads. The decorators in this project operate by returning a new callable, so each target function (or method) has to be wrapped explicitly. You can build your own helpers that iterate over a module or class and decorate selected callables, but the library cannot apply itself universally without the caller opting in on a per-function basis.
What about leaning on the descriptor protocol to auto-wrap methods?
Descriptors only help when attribute access goes through a class that you control, and Python already turns functions defined on a class into descriptors that bind methods at lookup time. Swapping in a custom descriptor still requires you to opt in for each attribute you expose, and it cannot cover free functions or methods defined on classes outside your control. You could build a metaclass or __setattr__ hook that decorates attributes as they are assigned, but that still imposes an explicit opt-in boundary (the metaclass or base class) rather than letting a library blanket the entire interpreter.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pure_function_decorators-0.1.2.tar.gz.
File metadata
- Download URL: pure_function_decorators-0.1.2.tar.gz
- Upload date:
- Size: 58.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb3701e3e29892ecfe9eff91d5bcbf2872822a11175e3bc868e6f25c04bc9016
|
|
| MD5 |
3611217d9bc64c38791df693e25e6fcf
|
|
| BLAKE2b-256 |
f2bf81fa18b9f2972951dfb36eb740ad00c73ec6711a5722f4750c534dadf8de
|
File details
Details for the file pure_function_decorators-0.1.2-py3-none-any.whl.
File metadata
- Download URL: pure_function_decorators-0.1.2-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
077a775c5b04c63088814da56fe1f4ceffa76ae0ec1a9081d6275264ebeb089c
|
|
| MD5 |
940ed96721105f01fbb8a5b8c6579ee8
|
|
| BLAKE2b-256 |
0fc8fed89845bc85b5da495ae0de3b430a3a5bd5818df7f912a839c615d53d0f
|