Griffelib
Griffelib, pronounced "grif" (/ɡʁif/), is a Python library that provides core components for extracting signatures (structure, frame, skeleton) of entire Python programs. It is a fundamental part of the larger 'Griffe' project, which is used for generating API documentation (e.g., by mkdocstrings) and detecting breaking changes in an API. The library is currently at version 2.0.2 and follows a regular release cadence as part of the Griffe ecosystem.
Warnings
- breaking Griffe 2.0.0 (and thus griffelib components) introduced significant breaking changes. Key changes include refactoring of internal APIs, changes in data structures for representing code objects, and modifications to the loading and inspection processes. Direct usage of internal APIs from Griffe 1.x will likely fail.
- gotcha Users might confuse `griffelib` with the main `griffe` package. `griffelib` specifically refers to the library components, meaning programmatic access to the core functionalities, while `griffe` might include command-line tools and higher-level integrations. Import paths might differ slightly, as `griffelib`'s core is often exposed through `griffe.*` imports.
- breaking The separation into `griffe`, `griffecli`, and `griffelib` as an 'uv workspace' means that some functionalities previously bundled might now be in different packages or accessed differently. Tools depending on `griffe` directly might need to explicitly depend on `griffelib` for certain library-only features.
Install
-
pip install griffelib
Imports
- load
from griffe.loader import GriffeLoader; loader = GriffeLoader(); module = loader.load_module("your_module") - Module
from griffe.dataclasses import Module
Quickstart
import os
from griffe.loader import GriffeLoader
from griffe.dataclasses import Module, Class, Function
from pathlib import Path
# Create a dummy Python module for demonstration
dummy_module_code = """
def my_function(param1: str, param2: int) -> bool:
"""A sample function."""
return len(param1) == param2
class MyClass:
"""A sample class."""
def __init__(self, name: str):
self.name = name
def get_name(self) -> str:
"""Returns the name."""
return self.name
"""
# Create a temporary directory and file for the dummy module
# In a real scenario, you would load an existing module
tmp_dir = Path("./_griffelib_temp_module")
tmp_dir.mkdir(exist_ok=True)
dummy_file = tmp_dir / "dummy_example.py"
dummy_file.write_text(dummy_module_code)
# Initialize the Griffe loader and load the module
loader = GriffeLoader()
loaded_module: Module = loader.load_module("dummy_example", search_paths=[tmp_dir])
print(f"Module name: {loaded_module.name}")
# Iterate through members (functions, classes)
for member in loaded_module.members.values():
if isinstance(member, Function):
print(f" Function: {member.name}")
print(f" Signature: {member.signature}")
print(f" Docstring: {member.docstring.value if member.docstring else 'N/A'}")
elif isinstance(member, Class):
print(f" Class: {member.name}")
print(f" Docstring: {member.docstring.value if member.docstring else 'N/A'}")
for method in member.members.values():
if isinstance(method, Function):
print(f" Method: {method.name}")
print(f" Signature: {method.signature}")
# Clean up temporary directory (optional)
import shutil
shutil.rmtree(tmp_dir)