Core Data Structures Defined in thefuck/types.py: Command, Rule, and CorrectedCommand Explained

The thefuck/types.py module defines three fundamental classes—Command, Rule, and CorrectedCommand—that form the complete pipeline for parsing failed shell commands, matching correction rules, and executing fixes in the nvbn/thefuck repository.

Understanding these core data structures is essential for anyone extending or debugging the popular command-line correction tool. The thefuck/types.py file serves as the central schema for how raw shell input transforms into executable corrections through a strictly typed object hierarchy.

Overview of thefuck/types.py Core Data Structures

The module implements an immutable data flow architecture comprising three primary types:

  • Command – Encapsulates the original failed command, its shell output, and parsed script components.
  • Rule – Defines matching logic and correction generation for specific error patterns.
  • CorrectedCommand – Represents a candidate fix with execution priority and optional side effects.

These objects interact in a strict pipeline: Command instances are parsed from raw input, tested against available Rule objects, and produce CorrectedCommand candidates for user selection.

The Command Class: Representing Failed Shell Commands

The Command class in thefuck/types.py serves as the primary input container for the correction pipeline. It captures both the literal command string and its execution context.

Key Attributes and Methods

  • script – The raw command string as typed by the user.
  • output – The stderr/stdout captured from the failed command execution.
  • script_parts – A lazily-evaluated list of the command split into tokens (e.g., ['git', 'commit']).
  • update(script) – Returns a new Command instance with an modified script while preserving output.
  • from_raw_script(raw_script) – Factory method that constructs a Command from a list of script parts, automatically joining them and fetching output via shell execution.

Creating a Command Instance

from thefuck.types import Command

# Simulate a failed command typed as: git commit

raw = ['git', 'commit']
cmd = Command.from_raw_script(raw)

print(cmd)                # → Command(script=git commit, output=…)

print(cmd.script_parts)   # → ['git', 'commit']

The from_raw_script method relies on utilities in thefuck/utils.py (specifically format_raw_script) and shell-specific helpers in thefuck/shells/*.py to handle quoting and history integration.

The Rule Class: Encapsulating Correction Logic

The Rule class defines the matching and correction strategy for specific error patterns. Each rule file in thefuck/rules/*.py effectively instantiates this class.

Rule Properties and Matching

  • name – Identifier derived from the rule filename.
  • match(command) – Function that returns True if the rule applies to the given Command.
  • get_new_command(command) – Function that generates the corrected command string(s).
  • enabled_by_default – Boolean controlling whether the rule loads automatically.
  • side_effect(old_cmd, new_cmd) – Optional function executed after running the correction (e.g., updating history).
  • priority – Integer determining suggestion order (higher values appear first).
  • requires_output – Boolean indicating whether the rule needs command output to match.

The class provides validation methods:

  • is_enabled – Checks against thefuck.conf.settings to determine if the rule is active.
  • is_match(command) – Validates that requires_output is satisfied before calling the custom match function.

Generating Corrected Commands

from pathlib import Path
from thefuck.types import Rule
from thefuck.conf import settings, load_source

# Load a rule file from thefuck/rules/git_add.py

rule_path = Path('thefuck/rules/git_add.py')
rule = Rule.from_path(rule_path)

if rule.is_enabled and rule.is_match(cmd):
    print('Rule matches!')   # → Rule matches!

When a rule matches, get_corrected_commands(command) yields CorrectedCommand instances by calling get_new_command and packaging the results with the rule's side_effect and priority values.

The CorrectedCommand Class: Executing Fixes

The CorrectedCommand class represents a candidate fix ready for execution. It bridges the gap between rule logic and shell integration.

Running Corrected Commands

  • script – The corrected command string to execute.
  • side_effect – Optional callable executed after running the command (passed from the parent Rule).
  • priority – Sorting key for ranking multiple suggestions.
  • run(old_cmd) – Executes the correction by printing the script to stdout (for shell alias capture) and triggering side effects.
  • _get_script() – Internal method that consults thefuck.conf.settings to determine if the command should be repeated on failure or added to history.

# Generate corrected commands from a matching rule

for corrected in rule.get_corrected_commands(cmd):
    print(corrected)          # → CorrectedCommand(script=git add ., …)

# Execute the first suggestion

suggestion = next(rule.get_corrected_commands(cmd))
suggestion.run(cmd)   # Outputs the corrected command for the shell alias to execute

The run method interacts with shell-specific modules in thefuck/shells/*.py to handle history appending and command repetition logic based on user configuration in thefuck/conf.py.

The Correction Pipeline: How the Types Work Together

The three core data structures form a strict processing pipeline implemented across the codebase:

  1. Parse – Command.from_raw_script() in thefuck/types.py receives raw input from the shell alias and constructs a Command instance, using thefuck/utils.py for formatting and thefuck/shells/*.py for execution context.

  2. Match – The system iterates over all loaded Rule objects (defined in thefuck/rules/*.py), calling rule.is_match(command) which checks requires_output constraints before executing the rule's custom match function.

  3. Generate – For each matching rule, rule.get_corrected_commands(command) yields CorrectedCommand instances, packaging the output of get_new_command with the rule's priority and side_effect attributes.

  4. Execute – The selected CorrectedCommand runs via corrected_cmd.run(original_cmd), printing the fixed script to stdout for the shell alias to capture and optionally triggering side effects like history updates through thefuck/conf.settings.

Summary

  • Command – Encapsulates the original failed shell command, its output, and parsed script parts via from_raw_script() and lazy script_parts evaluation.
  • Rule – Defines correction logic through match and get_new_command functions, with metadata like priority, side_effect, and requires_output controlling execution flow.
  • CorrectedCommand – Represents executable fixes generated by rules, providing run() for shell integration and side-effect handling.
  • Pipeline – These types form a strict chain: Command parsing → Rule matching → CorrectedCommand generation → execution via thefuck/shells/*.py integration.

Frequently Asked Questions

What is the purpose of the Command class in thefuck/types.py?

The Command class serves as the input container for the correction pipeline, capturing both the literal command string and its execution output. It provides from_raw_script() for constructing instances from shell input and script_parts for tokenized access to command arguments, enabling rules to analyze what was typed and what went wrong.

How does the Rule class determine if a correction should be applied?

The Rule class uses the is_match() method, which first validates that requires_output constraints are satisfied (checking if the command produced output), then executes the rule's custom match function against the Command instance. If both checks pass, the rule proceeds to generate corrections via get_corrected_commands().

What distinguishes CorrectedCommand from the original Command object?

While Command represents the failed input, CorrectedCommand represents a candidate fix ready for execution. It stores the corrected script string, the priority for ranking suggestions, and an optional side_effect callable. Its run() method outputs the fix to stdout for shell capture and triggers any side effects, bridging the gap between rule logic and actual shell execution.

Where are these data structures instantiated in the actual application flow?

Command objects are created in thefuck/types.py via from_raw_script() when the shell alias invokes the tool. Rule instances are loaded from files in thefuck/rules/*.py using Rule.from_path(). CorrectedCommand objects are generated within rule.get_corrected_commands() and ultimately executed by the main entry point interacting with thefuck/shells/*.py for shell-specific integration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →