How Holehe's Update Checker Compares Local and PyPI Versions
Holehe compares versions by reading __version__ from holehe/__init__.py, querying the PyPI JSON API for the latest release, and using packaging.version.parse to determine if an update is available.
Holehe is an OSINT tool for finding accounts by email address across multiple platforms. According to the megadose/holehe source code, the tool includes a lightweight update checker that runs automatically on startup to ensure users operate the latest version. This article explains exactly how the version comparison works, where the logic lives, and how you can inspect or customize it.
Where the Update Checker Lives
The update checking mechanism is implemented in holehe/core.py within the check_update function (lines 65-87). The checker performs a blocking HTTP request to PyPI every time the CLI initializes, which can add latency but guarantees users receive timely upgrade notifications.
The function sits near the CLI entry point:
# holehe/core.py
if __name__ == "__main__":
# ... argument parsing ...
check_update() # <-- version comparison triggers here
# ... main program execution ...
When check_update() detects a newer release, it prints an upgrade message and exits the program immediately rather than allowing outdated code to run.
Step-by-Step Version Comparison Process
Step 1: Read the Local Version
The local version string is defined in holehe/__init__.py as a module-level constant:
# holehe/__init__.py line 1
__version__ = "1.61"
This value is hardcoded during the release process and imported by core.py for comparison.
Step 2: Fetch the Latest Version from PyPI
The checker queries the public PyPI JSON API endpoint:
import requests
url = "https://pypi.org/pypi/holehe/json"
response = requests.get(url)
pypi_data = response.json()
latest_version = pypi_data["info"]["version"] # e.g., "1.62"
The info.version field contains the string of the most recently published release.
Step 3: Parse and Compare Versions
Both version strings are converted to comparable objects using packaging.version.parse:
from packaging.version import parse
from holehe import __version__
local = parse(__version__)
remote = parse(latest_version)
if remote > local:
print(f"A new version of holehe is available ({latest_version}). Run:")
print(" pip install -U holehe")
exit(0) # Exit to force upgrade
The packaging library handles complex versioning schemes (e.g., 1.61, 1.61.post1, 2.0.dev0) correctly, making simple string comparison unnecessary.
What Users See
When an Update is Available
$ holehe -u alice@example.com
Holehe has just been updated, you can restart it.
Run: pip install -U holehe
The program terminates after displaying this message.
When Running the Latest Version
No output appears; the CLI proceeds immediately to email checking.
Manually Triggering the Update Check
You can invoke the checker independently in scripts:
from holehe.core import check_update
check_update() # Exits if update needed, returns silently if current
Or simulate the PyPI query yourself:
import json
import urllib.request
from packaging.version import parse
from holehe import __version__
url = "https://pypi.org/pypi/holehe/json"
with urllib.request.urlopen(url) as resp:
data = json.load(resp)
remote = parse(data["info"]["version"])
local = parse(__version__)
print(f"Local: {local}")
print(f"PyPI: {remote}")
print(f"Update needed: {remote > local}")
Key Source Files
| File | Purpose | Location |
|---|---|---|
holehe/__init__.py |
Defines __version__ constant |
Line 1 |
holehe/core.py |
Implements check_update() and CLI entry point |
Lines 65-87 |
setup.py |
Declares package metadata for PyPI publication | Version must match __init__.py |
These three files form the complete update notification pipeline: __init__.py provides the source of truth, core.py performs the comparison, and setup.py ensures PyPI publishes the correct version string.
Configuration and Limitations
The current implementation has several characteristics worth noting:
- No disable option — the check runs unconditionally on every CLI startup
- Blocking I/O — slow or unavailable network connections delay tool execution
- Hard exit on mismatch — the program terminates rather than warn-and-continue
- No caching — PyPI is queried every time, not just once per day
Users requiring offline operation or custom behavior must modify holehe/core.py directly or patch the check_update import.
Summary
- Holehe's update checker is implemented in
holehe/core.pyas thecheck_update()function - The local version originates from
holehe/__init__.py(__version__) - The PyPI version is retrieved from
https://pypi.org/pypi/holehe/json packaging.version.parseenables semantically correct version comparison- The program exits immediately when a newer version is detected, forcing the user to upgrade
Frequently Asked Questions
How can I skip the update check in holehe?
The current megadose/holehe source code does not provide a command-line flag to disable the update check. To bypass it, you must either modify holehe/core.py to comment out the check_update() call or run holehe as a library import rather than through the CLI entry point.
Why does holehe exit instead of warning about updates?
According to the implementation in holehe/core.py, the exit(0) call ensures users do not accidentally run outdated code that may contain broken modules or missing features. This enforcement approach prioritizes consistency over convenience.
What happens if PyPI is unreachable when holehe starts?
The check_update() function performs a blocking HTTP request without explicit timeout handling or fallback logic. Network failures will likely raise an exception and prevent the tool from starting until connectivity is restored or the code is patched.
Does holehe respect semantic versioning in its update checks?
Yes. The use of packaging.version.parse in holehe/core.py ensures proper handling of semantic versions including pre-releases, post-releases, and development versions. This allows accurate comparison of version strings beyond simple lexical ordering.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →