# How Holehe Sorts Results by Module Name in the `maincore` Function

> Learn how Holehe's maincore function sorts results by module name using Python's sorted function for clear, alphabetical output.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: internals
- Published: 2026-08-15

---

**Holehe sorts results alphabetically by module name using a standard Python `sorted()` call on the results list, extracting the function name from each module's string representation.**

The `maincore` function in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) orchestrates concurrent execution of multiple site-specific modules and ensures consistent output ordering. This article explains exactly how the sorting mechanism works, where the module names originate, and why this design ensures predictable results regardless of async completion order.

## Where Module Names Originate

Each module in Holehe is an asynchronous function defined in `holehe/modules/`. When a module executes—whether successfully or with an exception—its name is captured for the final output dictionary.

In the `launch_module` function, the module name is extracted from the function object's string representation:

```python

# holehe/core.py → lines 71-73

name = str(module).split('<function ')[1].split(' ')[0]
out.append({"name": name, ... })

```

This parsing extracts the function identifier (e.g., `"github"`, `"twitter"`, `"instagram"`) from a string like `<function github at 0x7f8b2c>`. The `name` value becomes the sorting key used later in `maincore`.

The extraction occurs in both success and exception paths, ensuring every result has a consistent `name` field for alphabetical ordering.

## The Sorting Implementation in `maincore`

After all modules complete their asynchronous execution, `maincore` performs the final ordering before displaying results. The sorting happens after the `trio.open_nursery()` context manager exits and all concurrent tasks have finished:

```python

# holehe/core.py → lines 22-24

# Sort by modules names

out = sorted(out, key=lambda i: i['name'])

```

This single line guarantees that:

- Results appear in **alphabetical order** by module name
- Output is **deterministic** regardless of network latency or execution timing
- Downstream consumers (CLI output, JSON export, etc.) receive consistently ordered data

The `sorted()` function returns a new list, replacing the original `out` list with its ordered version before passing to `print_result()`.

## Complete Workflow in Context

The full `maincore` function demonstrates how sorting fits into the broader execution flow:

```python

# holehe/core.py (excerpt)

async def maincore():
    ...
    async with trio.open_nursery() as nursery:
        for website in websites:
            nursery.start_soon(launch_module, website, email, client, out)
    # Sort by modules names

    out = sorted(out, key=lambda i: i['name'])
    await client.aclose()
    print_result(out, args, email, start_time, websites)
    ...

```

Key observations about this pattern:

- **Concurrent execution first**: All modules run simultaneously via `trio.start_soon()`, maximizing throughput
- **Aggregation unordered**: Results accumulate in `out` as modules complete, potentially in random order
- **Deterministic presentation**: The final `sorted()` call establishes user-friendly alphabetical ordering

## Exception Handling and Name Extraction

When a module raises an exception, the same name extraction logic applies. The error case still produces a valid result entry with the module name intact:

```python

# inside launch_module

except Exception:
    # Extract the function name from the callable

    name = str(module).split('<function ')[1].split(' ')[0]
    out.append({
        "name": name,
        "domain": data[name],
        "rateLimit": False,
        "error": True,
        "exists": False,
        # … other fields …

    })

```

This ensures that even failed modules participate correctly in the alphabetical sorting, maintaining consistent output structure.

## Key Source Files

Understanding the sorting behavior requires familiarity with these components:

| File | Purpose |
|------|---------|
| [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) | Main entry point, implements `maincore()`, `launch_module()`, and the sorting logic |
| `holehe/modules/*` | Individual site-specific async functions whose names become sort keys |
| [`holehe/instruments.py`](https://github.com/megadose/holehe/blob/main/holehe/instruments.py) | Progress bar instrumentation during concurrent execution |

## Summary

- **Name extraction**: `str(module).split('<function ')[1].split(' ')[0]` parses function identifiers from callable objects
- **Concurrent execution**: `trio.open_nursery()` runs all modules simultaneously without blocking
- **Alphabetical ordering**: `sorted(out, key=lambda i: i['name'])` produces deterministic, user-friendly output
- **Consistent application**: Sorting occurs after all tasks complete, affecting both success and error results equally

## Frequently Asked Questions

### Why does Holehe sort results alphabetically instead of by execution order?

Alphabetical sorting provides **predictable, scannable output** for users reviewing multiple site checks. Execution order varies due to network latency and rate limiting, making it unsuitable for consistent presentation. The `name` field sorting ensures identical inputs always produce identically ordered outputs.

### What happens if two modules have the same function name?

This scenario is unlikely given Holehe's module structure—each site typically has a unique function name. If collision occurred, Python's `sorted()` would preserve the original relative order of equal elements (stable sorting), though the codebase design avoids this situation entirely.

### Can I modify the sorting behavior in Holehe?

The sorting is hardcoded in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) at line 22-24. To change the sort order, you would modify or remove the `sorted()` call before `print_result()`. However, this requires editing the source directly as no configuration option exists for alternative ordering.

### Does sorting affect performance with many modules?

No. The `sorted()` operation is **O(n log n)** and executes on an in-memory list after all network operations complete. With typical usage (dozens to low hundreds of modules), this overhead is negligible compared to HTTP request latency.