Install & Compatibility
Where this runs
tested against v1.8.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.000s · 23.1MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 2.2s · import 0.000s · 24MB
22MB installed
● package 22MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
find_annotations
✓ from code_annotations import find_annotations
✗ from code_annotations import find_annotations
This quickstart demonstrates how to define a custom AnnotationContext to identify specific comment-based annotations (like TODOs and REVIEWs) and then use `find_annotations` to scan a temporary Python file for these annotations.
import tempfile
import os
import shutil
from pathlib import Path
from code_annotations.find_annotations import find_annotations
from code_annotations.annotation_contexts import AnnotationContext
# 1. Define a custom AnnotationContext
class MyCustomAnnotationContext(AnnotationContext):
"""
A simple context to find annotations like:
# TODO: Finish this feature
# REVIEW: Check performance
"""
context_name = "MY_CUSTOM"
@staticmethod
def is_inline_annotation_context(line):
return "# TODO:" in line or "# REVIEW:" in line
@staticmethod
def get_inline_annotation_key(line):
if "# TODO:" in line:
return "TODO"
elif "# REVIEW:" in line:
return "REVIEW"
return None
@staticmethod
def get_inline_annotation_value(line):
if "# TODO:" in line:
return line.split("# TODO:", 1)[1].strip()
elif "# REVIEW:" in line:
return line.split("# REVIEW:", 1)[1].strip()
return None
# 2. Create a dummy file in a temporary directory
temp_dir = Path(tempfile.mkdtemp())
dummy_file = temp_dir / "example_code.py"
dummy_file.write_text("""
def my_function():
# TODO: Implement actual logic
print("Hello, World!")
# REVIEW: This might be slow for large inputs
pass
class MyClass:
# TODO: Add docstrings
def __init__(self):
pass
""")
try:
# 3. Find annotations
results = find_annotations(
src_dir=str(temp_dir),
annotation_contexts=[MyCustomAnnotationContext],
file_extensions=['.py'],
root_dir_to_scan=str(temp_dir),
)
# 4. Print results
print(f"Found annotations in: {temp_dir}")
for file_path, annotations in results.items():
print(f" File: {file_path}")
for annotation in annotations:
print(f" [{annotation.context_name}] {annotation.key}: {annotation.value} at line {annotation.line}")
finally:
# Clean up the temporary directory
shutil.rmtree(temp_dir)
code_annotations --version
Upgrade
Version history
3.0.0latest on PyPI · released Mar 13, 2026
Audit
Dependencies
django-cache-annotationrequiredRequired for caching mechanisms within the annotation processing.