Where to Find the Command Object in thefuck: Complete Guide to the Core Data Model

The Command object in thefuck is defined in thefuck/types.py (lines 12‑66) and serves as the central data structure that encapsulates the original shell command, its captured output, and parsed arguments for the rule engine.

The Command object is the foundational data model in nvbn/thefuck, the popular Python utility that corrects mistyped console commands. Located in the repository’s type definitions, this class bridges raw shell input and the intelligent correction pipeline, making it essential for developers extending the tool or debugging rule behavior.

Location of the Command Class in thefuck

thefuck/types.py: The Core Definition

The canonical definition of the Command class resides in thefuck/types.py between lines 12 and 66. This file houses the primary data structures used throughout the application, including Rule and CorrectedCommand.

The class is implemented as a Python class with the following key characteristics:

  • Immutable-style design: While not strictly immutable, it provides an update() method that returns new instances rather than modifying state in place.
  • Rich properties: Beyond basic script and output attributes, it exposes script_parts (the tokenized command), and legacy accessors for stdout and stderr.
  • Equality and representation: Full __eq__, __hash__, and __repr__ implementations enable easy debugging and testing.

How to Create a Command Object in thefuck

Direct Instantiation with Command(script, output)

For internal testing or when you already have the command string and its captured output, instantiate the class directly:

from thefuck.types import Command

cmd = Command("git status", "fatal: not a git repository...")

This constructor stores the raw script string and the output (typically combined stdout and stderr from the failed command).

Using from_raw_script() for Shell Input

When integrating with the shell hook, use the from_raw_script() class method defined at lines 67‑83 in thefuck/types.py. This factory method handles the heavy lifting of shell integration:

from thefuck.types import Command

raw_script = ["git", "st"]  # As provided by the shell parser

cmd = Command.from_raw_script(raw_script)

Under the hood, this method:

  1. Formats the raw script fragments into a single command string
  2. Expands shell shortcuts and aliases via thefuck.utils.format_raw_script
  3. Executes the command to capture its output
  4. Returns a fully populated Command instance

Command Object Properties and Methods

The Command class exposes several attributes critical for rule development:

  • script (str): The complete command line as executed (e.g., "git status").
  • output (str): The captured output from the command execution, typically combining stdout and stderr.
  • script_parts (list): The tokenized command split into parts (e.g., ['git', 'status']), useful for parsing subcommands and arguments.
  • stdout / stderr (str): Legacy properties that now return the combined output with deprecation warnings.

Key methods include:

  • update(script=None, output=None): Returns a new Command instance with updated fields, supporting immutable-style modifications.
  • __repr__: Provides a debug-friendly string representation showing script and output.

Architectural Role of the Command Object

The Command object functions as the universal input to thefuck's rule engine. Every rule in thefuck/rules/ receives a Command instance through two primary interfaces:

  1. Rule.is_match(command): Determines whether the rule applies to the given command based on script, script_parts, or output.
  2. Rule.get_corrected_commands(command): Generates one or more CorrectedCommand objects proposing fixes.

This design decouples shell interaction from correction logic. The Command object normalizes raw shell input—handling aliases, environment variables, and output capture—into a consistent interface that rules can inspect without worrying about shell-specific parsing.

Code Examples: Working with Command Objects

Creating a Command Manually

from thefuck.types import Command

# Simulate a failed git command

script = "git status"
output = "fatal: not a git repository (or any of the parent directories): .git"

cmd = Command(script, output)

print(cmd)                       # Command(script=git status, output=...)

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

Using from_raw_script for Shell Integration

from thefuck.types import Command

# Raw fragments as parsed by the shell

raw_script = ["git", "st"]
cmd = Command.from_raw_script(raw_script)

# Contains expanded command and captured output

print(cmd.script)                 # "git status"

print(cmd.output)                 # Captured stderr/stdout

Feeding Commands to Rules

from thefuck.types import Command
from thefuck.rules.git_add import match, get_new_command

cmd = Command("git add", "fatal: pathspec '.' did not match any files")
if match(cmd):
    suggestion = get_new_command(cmd)
    print(suggestion)              # "git add ."

Immutable Updates

new_cmd = cmd.update(script="git add .", output="")
print(new_cmd.script)              # "git add ."

Understanding the Command object requires familiarity with several related modules:

File Purpose
thefuck/types.py Defines Command, Rule, and CorrectedCommand classes.
thefuck/utils.py Contains format_raw_script helper used by Command.from_raw_script.
thefuck/shells/__init__.py Shell abstraction layer for command splitting and alias expansion.
thefuck/rules/* Rule implementations that consume Command objects via is_match and get_corrected_commands.
thefuck/conf.py Configuration settings affecting command handling and rule loading.

Summary

  • The Command class is defined in thefuck/types.py (lines 12‑66) and represents the central data model for shell commands.
  • Instantiate directly with Command(script, output) for testing, or use Command.from_raw_script() (lines 67‑83) to handle shell-provided input with automatic expansion and output capture.
  • Key properties include script, output, and script_parts, which rules use to analyze and correct failed commands.
  • The Command object acts as the universal input to the rule engine, decoupling shell-specific parsing from correction logic.

Frequently Asked Questions

Where is the Command object defined in thefuck?

The Command object is defined in the file thefuck/types.py between lines 12 and 66. This module serves as the repository's central type definitions file, also housing the Rule and CorrectedCommand classes that work alongside Command in the correction pipeline.

What is the difference between Command() and Command.from_raw_script()?

Command(script, output) is the direct constructor that accepts a formatted command string and its captured output, primarily used for unit testing or internal rule processing. Command.from_raw_script(raw_script) is a classmethod (lines 67‑83) designed for shell integration—it receives raw command fragments, expands aliases, executes the command to capture output, and returns a fully populated instance.

How does the Command object interact with thefuck rules?

Every rule in thefuck receives a Command instance through its is_match(command) method to determine applicability and get_corrected_commands(command) to generate fixes. Rules inspect command.script, command.script_parts, and command.output to analyze the failure and construct appropriate corrections, making Command the universal interface between the shell and the rule engine.

What properties does the Command object expose for debugging?

The Command object exposes script (the full command string), output (combined stdout/stderr), and script_parts (tokenized command list). It also provides legacy stdout and stderr properties that return the combined output with deprecation warnings, plus a helpful __repr__ method for debug output showing both script and output contents.

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 →