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
This is obviously mostly vibe-coded and perhaps better suited to static analysis anyhow. I'm using it as an exercise and any actual utility is just a bonus
Super-quick Start
Requires: Python 3.10 to 3.13
Install through pip:
pip install pure-function-decorators
from pure_function_decorators import forbid_globals
@forbid_globals()
def bad(x):
return x + CONST
CONST = 10
bad(1) # Raises NameError
import datetime
from pure_function_decorators import enforce_deterministic
@enforce_deterministic
def bad():
return datetime.datetime.now().microsecond
print(bad())
print(bad()) # raises ValueError
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 see in-place mutations.- By default, the decorator raises when a mutation is detected
- it can instead log warnings with
warn_only=True.
enforce_deterministicensures that the decorated function consistently returns the same result for the same parameters.forbid_globalsprevents a function from reading or mutating module-level state by sandboxing its globals.check_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:
- 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 allowlisted 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.
Side Effects
A side effect is any interaction with outside state other than computing and returning a value.
Canonical side effects and impurity sources:
State mutation: modifying globals, nonlocals, class/static attributes, singletons, caches, or the objects passed in as arguments (in-place changes).
I/O: printing/logging, reading/writing files, networking, databases, stdin/stdout/stderr, GUI operations.
Process/system effects: spawning threads/processes, signals, timers, sleeping, exiting the process.
Nondeterministic sources: reading clocks (now, time), random/URNGs (random, secrets, uuid4, os.urandom), environment variables, current working directory, locale.
Hidden global dependencies: reading mutable module state or configuration not provided as explicit parameters.
Observable control effects: raising exceptions or relying on exceptions for normal control can be considered effects in stricter definitions; total purity disallows them, weaker purity allows deterministic exceptions for invalid inputs.
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.3.tar.gz.
File metadata
- Download URL: pure_function_decorators-0.1.3.tar.gz
- Upload date:
- Size: 58.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd16240f4daee334b50ccadb6f4313b1883f07d0b14cfb17d81e4f974cb56918
|
|
| MD5 |
f63add68464616dcd68522d213a4bf5c
|
|
| BLAKE2b-256 |
2d6ad7d37eacda2ecf76559debadc2a659162cbb2508fc9d2a1a2525a45b0bd2
|
File details
Details for the file pure_function_decorators-0.1.3-py3-none-any.whl.
File metadata
- Download URL: pure_function_decorators-0.1.3-py3-none-any.whl
- Upload date:
- Size: 14.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60e7cdf0c6fc5fb37904e4c67da147e6b52ba28eda3ef60f03bba5ceabf6bfa1
|
|
| MD5 |
ff7503a194e342fe91324d65f08124a8
|
|
| BLAKE2b-256 |
1606add19284f8c5d1bd3137321d9303814f13081b141e0bfd8d2748ef822356
|