How to hide incomplete mock features with a Python feature toggle

A simple decorator-based feature toggle that returns a placeholder when a mock feature is disabled, so incomplete code can ship safely.

Easy Python 3.9+ Aug 9, 2026 Production deployment patterns 12 views 0 copies

Python code

39 lines
Python 3.9+
import functools


class FeatureToggle:
    def __init__(self, enabled=False):
        self.enabled = enabled

    def feature(self, func=None):
        """Decorator to conditionally enable a feature."""
        if func is None:
            return self.feature

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            if not self.enabled:
                print(f"Feature '{func.__name__}' is disabled. Returning placeholder.")
                return None
            return func(*args, **kwargs)

        return wrapper


def demo():
    # Create toggle, initially disabled
    toggle = FeatureToggle(enabled=False)

    @toggle.feature
    def incomplete_mock():
        return "Mock data"

    print("First call (disabled):", incomplete_mock())

    # Enable the toggle
    toggle.enabled = True
    print("Second call (enabled):", incomplete_mock())


if __name__ == "__main__":
    demo()

Output

stdout
First call (disabled): Feature 'incomplete_mock' is disabled. Returning placeholder.
None
Second call (enabled): Mock data

How it works

The FeatureToggle.feature decorator wraps a function and checks the enabled attribute at call time. When disabled, the wrapper prints a message and returns None instead of executing the real function. The @functools.wraps call preserves the original function's metadata like __name__, which keeps debugging and tooling working. Because you can flip toggle.enabled anytime, the same decorated function behaves differently without touching its implementation, making it ideal for gradual rollout.

Common mistakes

  • Forgetting `@functools.wraps`, which breaks the function's name and docstring in tracebacks
  • Keeping the toggle enabled by default in production, so the feature ships before it's ready
  • Returning None without logging — makes it hard to know why output is missing
  • Applying the decorator without parentheses (`@toggle.feature` vs `@toggle.feature()`), which changes how arguments are passed

Variations

  1. Read the enabled state from an environment variable or config file instead of a hardcoded attribute
  2. Use a context manager or function-based toggle to switch features dynamically per request

Real-world use cases

  • Shipping a stubbed-out analytics module to production while real instrumentation is still in development.
  • Disabling experimental API endpoints in a live service until they pass load testing and QA.
  • Hiding unfinished UI components behind a toggle so the frontend can deploy independently of the backend.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Production deployment patterns

Related tutorials and quizzes for this topic.