Skip to content

How it works

  • Importing wishful installs a MagicFinder at the front of sys.meta_path.
  • Imports under wishful.static.* and wishful.dynamic.* get routed to MagicLoader.
  • Internal modules (wishful.core, wishful.config, …) bypass the hook to avoid recursion.

discover() looks around the call site:

  • Parses the import to know which symbols are wanted.
  • Scrapes nearby code/comments (radius configurable via WISHFUL_CONTEXT_RADIUS or wishful.set_context_radius).
  • Pulls registered type schemas and output bindings from @wishful.type.

That bundle becomes prompt seasoning for the LLM.

  • Static: check cache → use if present; otherwise generate once and write to .wishful/<module>.py.
  • Dynamic: always regenerate (runtime-context-aware), and also write a snapshot under .wishful/_dynamic/.
  • Safety gate: validate_code blocks dangerous imports/calls unless allow_unsafe=True.
  • Missing symbols? Static loader regenerates with the expanded symbol set. Dynamic loader proxies __getattr__ and call-time regeneration.
  • wishful.settings is stored on builtins so it survives module reloads (handy for tests).
  • install_finder() is idempotent: if a finder from wishful.core.finder is already present, it won’t stack duplicates.
  • MagicLoader resolves generate_module_code each call, so monkeypatches work even after reloads.
  • wishful.static.foo.wishful/foo.py
  • wishful.dynamic.foo.wishful/foo.py (same cache file) plus dynamic snapshot .wishful/_dynamic/foo.py
  • CLI helpers (wishful inspect/clear/regen) and Python helpers (inspect_cache, clear_cache, regenerate) manage these paths.

That’s the core loop. Everything else (CLI, types, logging) builds on this.

wishful.explore() is a smarter way to populate the cache:

  • Generates multiple implementations of a function
  • Tests each one against your criteria
  • Benchmarks them (optional) to find the fastest
  • Caches the winner to .wishful/ like a regular import
# Generate 5 variants, test each, cache the winner
parser = wishful.explore(
"wishful.static.text.extract_emails",
variants=5,
test=lambda fn: fn("test@example.com") == ["test@example.com"]
)
# Future imports use the proven winner
from wishful.static.text import extract_emails # ← No re-exploration

Uses async internally (litellm.acompletion()) for responsive UI with a beautiful Rich progress display. See Explore for the full tour.

For knobs you can turn, see Configuration.