Funcy

A fancy and practical collection of functional programming tools for Python, from collection walking to control-flow decorators.

Library
PyPI
v2.0
3,510stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
54/100Fair
Development Activity48
Maintenance4
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture82
Code Quality80
Innovation80
Learning Curve75

Funcy is a pure-Python, zero-dependency toolkit of functional utilities inspired by Clojure and Underscore. It covers three broad areas: collection operations (merge, walk, select, group_by, flatten and their type-preserving variants across dicts, sets, lists and iterators), function composition and currying (partial, curry, compose, complement, all_fn), and control-flow decorators that turn common patterns like retrying, rate-limiting, memoizing, and suppressing exceptions into single-line annotations.

The library is organized as a set of focused, single-purpose modules (colls, funcs, seqs, decorators, flow, objects, debug, strings, tree, calc, primitives, types, funcolls) that are re-exported through a flat top-level namespace, so from funcy import whatever_you_need works without knowing which submodule it lives in. It has no runtime dependencies, supports Python 3.4 through 3.13 plus PyPy3, and has been actively maintained since 2012 with a large surface area documented via a dedicated cheatsheet and Sphinx docs site.

What You Get

  • Type-preserving collection operations — merge, walk, select, and group_by work identically across dicts, sets, lists, tuples, and even strings, always returning the same type they were given
  • A @decorator helper that turns a plain function into a proper decorator (with functools.wraps semantics) in one line, instead of hand-rolling wrapper boilerplate
  • Ready-made control-flow decorators — @retry, @limit_error_rate, @ignore, @once, and print_durations/print_exits for debugging without adding logging calls everywhere
  • Function tools for point-free style — partial, rpartial, curry, rcurry, compose, complement, and all_fn/any_fn for building predicates from smaller pieces
  • Nested-structure helpers — get_in, set_in, update_in, del_in, and has_path for reading and writing deep dict/list paths without manual traversal
  • Zero runtime dependencies and broad interpreter support (CPython 3.4-3.13, PyPy3), keeping it safe to add to any project without pulling in a dependency tree

Common Use Cases

  • Merging and transforming configuration dicts or API response payloads without writing custom merge logic for each shape
  • Wrapping unreliable I/O calls (HTTP requests, external services) with @retry and @limit_error_rate instead of writing bespoke try/except loops
  • Building small composable predicates for filtering and validation with complement, all_fn, and the select/lwhere family
  • Reading and writing deeply nested JSON-like structures (e.g. app config, GraphQL responses) via get_in/set_in without manual key-chasing
  • Writing custom decorators quickly with @decorator instead of hand-writing functools.wraps boilerplate for every new decorator

Under The Hood

Architecture Funcy is organized as a flat set of single-concern modules — colls.py, funcs.py, seqs.py, decorators.py, flow.py, objects.py, debug.py, strings.py, tree.py, calc.py, primitives.py, types.py, and funcolls.py — each declaring its own __all__ and getting re-exported through funcy/__init__.py, which concatenates every module’s __all__ into one flat public namespace via lcat(sys.modules['funcy.' + m].__all__ for m in modules). There are almost no classes; the core abstraction is the Call object used by the @decorator helper in decorators.py, which wraps a function invocation so decorator authors can inspect call._func/call._args and invoke call() when ready. Collection operations in colls.py use a _factory() dispatcher keyed on type(coll) (with special-casing for defaultdict, dict views, and iterators) so that operations like walk and merge can stay generic across dicts, sets, lists, and strings while preserving the caller’s original type.

Tech Stack The library has zero runtime dependencies — everything is built on the Python standard library (itertools, collections.abc, functools, contextlib, inspect, operator). Packaging uses a plain setuptools setup.py with the version read from a standalone VERSION file. Documentation is built with Sphinx (docs/ directory, published to Read the Docs) and includes a dedicated cheatsheet page. CI runs on GitHub Actions with a version matrix covering CPython 3.5 through 3.13 plus PyPy3, alongside a separate flake8 lint job and a docs-build job with -W (warnings as errors).

Code Quality Every module has a dedicated test file (test_colls.py, test_funcs.py, test_decorators.py, etc.) plus a test_interface.py that checks the public API surface, and separate py38_decorators.py/py38_funcs.py files isolate syntax that requires newer Python versions. flake8 is enforced in CI against both the library and the test suite. The code has no type hints and relies on flake8 rather than mypy for static checking, but naming is consistent and terse throughout (l-prefixed variants like lmap/lfilter for list-returning versions of lazy iterator functions is a clear, deliberate convention).

API Design The library’s defining trait is ergonomic, guessable naming: l-prefixed functions return lists instead of iterators, r-prefixed functions flip the first-argument convention (rpartial, rcurry), and one-word verbs (walk, select, join, merge) read naturally at call sites. The @decorator helper is the most distinctive piece — it lets you write a decorator as a single function taking a call object instead of writing nested def wrapper(*args, **kwargs) boilerplate, and it automatically supports both @deco and @deco(arg=val) call styles based on the wrapped function’s signature.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search