Module

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.