smithery.ai

apply-decorator-wrap

For cross-cutting concerns: add behavior without modifying functions, caching, timing, logging, validation wrappers.

First seen Mar 28, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 2,335 B
  • docs SUMMARY.md 144 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

apply-decorator-wrap

When to Use

  • Adding caching/memoization
  • Timing function execution
  • Logging function calls
  • Input validation
  • Retry logic
  • Any cross-cutting concern

When NOT to Use

  • Behavior is specific to one function
  • Would obscure function's purpose
  • Simple inline code is clearer

The Pattern

Decorators wrap functions to add behavior before, after, or around the original.

def timing(func):
    """Decorator to time function execution."""
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print(f"{func.__name__} took {elapsed:.3f}s")
        return result
    return wrapper

@timing
def slow_function():
    time.sleep(1)
    return "done"

# Equivalent to: slow_function = timing(slow_function)

Example (from pytudes)

# Memoization decorator (ngrams.py)
def memo(f):
    """Memoize function f."""
    table = {}

    def fmemo(*args):
        if args not in table:
            table[args] = f(*args)
        return table[args]

    fmemo.memo = table  # Expose cache
    return fmemo

@memo
def segment(text):
    """Optimal word segmentation."""
    if not text:
        return []
    candidates = ([first] + segment(rest)
                  for first, rest in splits(text))
    return max(candidates, key=word_prob)

# Using functools for cleaner decorators
from functools import cache, lru_cache, wraps

@cache  # Built-in memoization
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

@lru_cache(maxsize=1000)  # Limited cache size
def expensive_lookup(key):
    ...

# Reusable decorator with parameter
cache = lru_cache(None)  # Alias for unlimited cache

@cache
def expressions(numbers):
    ...

@cache
def segment(text):
    ...

Key Principles

  1. Wrapper preserves signature: Use @functools.wraps
  2. Return wrapper: Decorator returns the wrapped function
  3. Expose internals: Attach cache/state as attribute
  4. Stack decorators: Multiple decorators apply bottom-up
  5. Decorator factories: @lru_cache(n) returns decorator