sopel.tools.memories#

Thread-safe memory data-structures for Sopel.

Sopel uses lots of threads to manage rules and jobs and other features, and it needs to store shared information safely. This class contains various memory classes that are thread-safe, with some convenience features.

class sopel.tools.memories.SopelIdentifierMemory(
*args,
identifier_factory: sopel.tools.identifiers.IdentifierFactory = <class 'sopel.tools.identifiers.Identifier'>,
)#

Special Sopel memory that stores Identifier as key.

This is a convenient subclass of SopelMemory that always casts its keys as instances of Identifier:

>>> from sopel import tools
>>> memory = tools.SopelIdentifierMemory()
>>> memory['Exirel'] = 'king'
>>> list(memory.items())
[(Identifier('Exirel'), 'king')]
>>> tools.Identifier('exirel') in memory
True
>>> 'exirel' in memory
True

As seen in the example above, it is possible to perform various operations with both Identifier and str objects, taking advantage of the case-insensitive behavior of Identifier.

As it works with Identifier, it accepts an identifier factory. This factory usually comes from a bot instance, like in the example of a plugin setup function:

def setup(bot):
    bot.memory['my_plugin_storage'] = SopelIdentifierMemory(
        identifier_factory=bot.make_identifier,
    )

Note

Internally, it will try to do key = self.make_identifier(key), which will raise an exception if it cannot instantiate the key properly:

>>> memory[1] = 'error'
AttributeError: 'int' object has no attribute 'translate'

New in version 7.1.

Changed in version 8.0: Moved from tools to tools.memories.

The parameter identifier_factory has been added to properly transform str into Identifier. This factory is stored and accessible through make_identifier.

make_identifier: sopel.tools.identifiers.IdentifierFactory#

A factory to transform keys into identifiers.

class sopel.tools.memories.SopelMemory(*args)#

A simple thread-safe dict implementation.

In order to prevent exceptions when iterating over the values and changing them at the same time from different threads, we use a blocking lock in __setitem__ and __contains__.

New in version 3.1: As Willie.WillieMemory

Changed in version 4.0: Moved to tools.WillieMemory

Changed in version 6.0: Renamed from WillieMemory to SopelMemory

Changed in version 8.0: Moved from tools to tools.memories

class sopel.tools.memories.SopelMemoryWithDefault(*args)#

Same as SopelMemory, but subclasses from collections.defaultdict.

New in version 4.3: As WillieMemoryWithDefault

Changed in version 6.0: Renamed to SopelMemoryWithDefault

Changed in version 8.0: Moved from tools to tools.memories