CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-taskipy

A task runner for Python projects that enables task definition and execution through pyproject.toml configuration.

Overview
Eval results
Files

task-execution.mddocs/

Task Execution

Core task execution engine that handles task discovery, execution, pre/post hooks, and process management with comprehensive signal handling.

Capabilities

TaskRunner Class

The central class for managing and executing tasks within a project directory.

class TaskRunner:
    def __init__(self, cwd: Union[str, Path]):
        """
        Initialize TaskRunner with working directory.
        
        Args:
            cwd: Working directory path (str or Path object)
        """

Task Listing

Display available tasks with descriptions and commands in a formatted output.

def list(self):
    """
    Lists tasks to stdout.
    
    Displays all available tasks with their names and descriptions
    (or commands if no description provided) in a formatted table.
    """

Task Execution

Execute a named task with optional arguments, including pre/post hook processing.

def run(self, task_name: str, args: List[str]) -> int:
    """
    Execute a task with optional arguments.
    
    Args:
        task_name: Name of the task to run
        args: Arguments to pass to the task command
        
    Returns:
        Exit code (0 for success, >0 for error)
    """

Usage Examples

Basic Task Execution

from taskipy.task_runner import TaskRunner
from pathlib import Path

# Initialize runner
runner = TaskRunner(Path('/path/to/project'))

# List available tasks
runner.list()

# Run a task
exit_code = runner.run('test', [])

# Run a task with arguments
exit_code = runner.run('test', ['--verbose', '--failfast'])

Error Handling

from taskipy.task_runner import TaskRunner
from taskipy.exceptions import TaskNotFoundError, TaskipyError

runner = TaskRunner(Path('.'))

try:
    exit_code = runner.run('nonexistent_task', [])
except TaskNotFoundError as e:
    print(f"Task not found: {e}")
    if e.suggestion:
        print(f"Did you mean: {e.suggestion}")
except TaskipyError as e:
    print(f"Taskipy error: {e}")
    exit_code = e.exit_code

Working with Different Project Structures

# Multi-project repository
runner = TaskRunner(Path('/path/to/monorepo/subproject'))

# Project with custom pyproject.toml location
# TaskRunner automatically searches parent directories for pyproject.toml
runner = TaskRunner(Path('/path/to/nested/directory'))

Pre and Post Hooks

TaskRunner automatically executes pre and post hooks for tasks:

Hook Execution Order

  1. Pre-hook: pre_{task_name} (if exists)
  2. Main task: {task_name}
  3. Post-hook: post_{task_name} (if exists)

Hook Behavior

  • If pre-hook fails (non-zero exit code), main task and post-hook are not executed
  • If main task fails, post-hook is not executed
  • If main task succeeds but post-hook fails, overall execution returns post-hook's exit code

Example Configuration

[tool.taskipy.tasks]
pre_test = "echo 'Setting up test environment'"
test = "python -m pytest"
post_test = "echo 'Cleaning up test artifacts'"

pre_lint = "echo 'Preparing linting'"
lint = "pylint src tests"
post_lint = "echo 'Linting complete'"

Variable Substitution

TaskRunner handles variable substitution in task commands when enabled:

# Variables are resolved before command execution
# Example with variables enabled:
# Task: "pylint {src_path}"
# Variables: {"src_path": "src/mypackage"}
# Executed: "pylint src/mypackage"

Process Management

Signal Handling

TaskRunner provides intelligent process management with proper signal handling:

  • SIGTERM: Gracefully terminates child processes
  • SIGINT (Ctrl+C): Handles keyboard interrupts appropriately
  • Cross-platform: Different behavior on macOS vs Linux for shell process handling

Working Directory Management

  • Tasks can specify custom working directories via cwd parameter
  • Global cwd setting applies to all tasks
  • Per-task cwd overrides global setting
  • Paths are resolved relative to pyproject.toml location

Command Execution

# Commands are executed through shell with proper argument quoting
# Example: task test --verbose "with spaces"
# Becomes: python -m pytest --verbose "with spaces"

Advanced Features

Custom Runners

TaskRunner supports custom command runners that prefix all task executions:

[tool.taskipy.settings]
runner = "poetry run"

This prefixes all task commands with the runner, useful for:

  • Virtual environment activation
  • Environment variable loading (e.g., dotenv run)
  • Remote execution (e.g., ssh server)

Argument Passing

Arguments passed to tasks are properly quoted and appended to the task command:

# runner.run('test', ['--verbose', '--output-file', 'results.xml'])
# Executes: python -m pytest --verbose --output-file results.xml

Note: Arguments are only passed to the main task, not to pre/post hooks.

Task Suggestions

When a task is not found, TaskRunner provides intelligent suggestions using difflib:

# If user types 'tets' instead of 'test'
# TaskNotFoundError will include suggestion: "did you mean 'test'?"

Process Architecture

TaskRunner creates subprocess with:

  • Shell execution: Commands run through system shell
  • Working directory: Configurable per task or globally
  • Signal forwarding: Proper signal handling to child processes
  • Exit code propagation: Task exit codes are preserved and returned

Install with Tessl CLI

npx tessl i tessl/pypi-taskipy

docs

cli.md

configuration.md

error-handling.md

index.md

task-composition.md

task-execution.md

variables.md

tile.json