Frigid Modules¶
Introduction¶
The frigid.modules
submodule provides functionality to enhance Python
modules with immutability and concealment, with optional automatic
documentation generation. This is particularly useful for package authors who
want to prevent accidental modification of their module’s public API while
providing rich documentation.
The module provides two main approaches:
Module finalization - combines documentation generation with reclassification in a single convenient function (recommended)
Module reclassification - converts standard modules to have immutable and concealed attributes (deprecated)
Module Finalization with Documentation¶
The finalize_module
function provides a convenient way to combine automatic
documentation generation (via Dynadoc integration) with module reclassification.
This is the recommended approach for most packages.
Basic Usage¶
# mypackage/__init__.py
import frigid
from . import core
from . import utils
from . import exceptions
# Finalize the module with documentation and reclassification
frigid.finalize_module( __name__, recursive = True )
The finalize_module
function will:
Generate comprehensive documentation for the module and its members using Dynadoc introspection
Apply any documentation fragments you provide
Reclassify the module and its submodules for immutability and concealment
Advanced Configuration¶
For complex packages, you might want to configure different parts differently:
# mypackage/__init__.py
import frigid
# Configure main package with full documentation
frigid.finalize_module(
__name__,
recursive = False # Handle submodules individually
)
# Configure submodules with different settings
frigid.finalize_module(
f"{__name__}.core",
recursive = True
)
frigid.finalize_module(
f"{__name__}.utils",
recursive = True
)
This approach allows you to provide different documentation and introspection settings for different parts of your package.
Best Practices¶
Package-Level Application¶
For most packages, apply finalize_module
at the package level in your
__init__.py
file:
# mypackage/__init__.py
import frigid
# Package metadata
__version__ = '1.0.0'
# Import public API
from .core import PublicClass, public_function
from .utils import helper_function
# Finalize the entire package
frigid.finalize_module( __name__, recursive = True )
This pattern ensures that:
Your package’s public API is documented
All modules in the package are immutable and concealed
The entire package hierarchy is protected from accidental modification
The recursive = True
parameter provides the same mass reclassification
behavior as the deprecated reclassify_modules
function, but with the
added benefit of automatic documentation generation.
Error Handling¶
When using module finalization, be aware that the resulting modules will raise
AttributeImmutability
exceptions if code attempts to modify them:
import frigid.exceptions
# After finalization, this will raise an exception
try:
mypackage.core.some_function = lambda: "modified"
except frigid.exceptions.AttributeImmutability as e:
print( f"Cannot modify module: {e}" )
Design your package APIs to avoid dynamic modification after finalization. If you need dynamic behavior, consider using configuration objects or factory functions instead of direct module attribute modification.
Integration with Build Systems¶
Module finalization integrates well with modern Python build systems. The immutability ensures that your package’s API surface is clearly defined and cannot be accidentally modified at runtime.
For packages that use entry points or plugin systems, apply finalization after all dynamic setup is complete:
# mypackage/__init__.py
import frigid
# Dynamic setup (plugin registration, etc.)
_setup_plugins()
_register_entry_points()
# Final API definition
from .api import *
# Lock down the package
frigid.finalize_module( __name__, recursive = True )
This ensures that your package initialization is complete before the immutability protections are applied.
Module Reclassification (Deprecated)¶
Deprecated since version The: reclassify_modules
function is deprecated. Use finalize_module
with recursive = True
instead, which provides the same functionality
along with automatic documentation generation.
The reclassify_modules
function converts modules to use a custom module
class that provides immutability and concealment behaviors. For new code,
use finalize_module
instead:
# Deprecated approach
# frigid.reclassify_modules( __name__, recursive = True )
# Recommended approach
frigid.finalize_module( __name__, recursive = True )
The finalize_module
function provides the same module protection behaviors
while also generating comprehensive documentation for your modules.