Modules¶
Module Objects¶
Immutable modules prevent any modification of attributes after creation. This makes them useful for ensuring that module-level constants remain constant and that module interfaces remain stable during runtime.
>>> from frigid import Module
Creation¶
While modules are typically initialized during import of their sources, they may also be created dynamically. As with standard Python modules, a name is required when dynamically creating a module.
>>> constants = Module( 'constants' )
>>> constants
<module 'constants'>
Immutability¶
Once created, a module becomes completely immutable. Even built-in attributes cannot be modified:
>>> constants.__name__ = 'renamed'
Traceback (most recent call last):
...
frigid.exceptions.AttributeImmutabilityError: Cannot assign or delete attribute '__name__'.
Attributes cannot be deleted:
>>> del constants.__name__
Traceback (most recent call last):
...
frigid.exceptions.AttributeImmutabilityError: Cannot assign or delete attribute '__name__'.
And new attributes cannot be added:
>>> constants.PI = 3.14159
Traceback (most recent call last):
...
frigid.exceptions.AttributeImmutabilityError: Cannot assign or delete attribute 'PI'.
Reclassification¶
Existing modules can be reclassified as immutable modules. This can be useful for protecting critical modules from modification, whether accidental or malicious.
Here’s an example of protecting a configuration module:
>>> import types
>>> config = types.ModuleType( 'config' )
>>> # Set initial configuration
>>> config.DEBUG = False
>>> config.API_KEY = 'secret'
>>> # Make it immutable
>>> config.__class__ = Module
>>> # Now it's protected
>>> config.DEBUG = True
Traceback (most recent call last):
...
frigid.exceptions.AttributeImmutabilityError: Cannot assign or delete attribute 'DEBUG'.
Mass Reclassification¶
For cases where multiple modules need to be protected, the
reclassify_modules
function can convert all modules in a package to
immutable modules. This is particularly useful in package __init__.py
files
to protect all submodules:
from frigid import reclassify_modules
reclassify_modules( __name__ )
Warning
While immutable modules prevent direct attribute modification, they cannot
prevent all forms of tampering. In particular, direct manipulation of a
module’s __dict__
is still possible. Use immutable modules to prevent
accidental modifications and basic tampering attempts, but do not rely on
them for security-critical protections.