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: MemoryConstructorInput,
identifier_factory: IdentifierFactory = 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.

copy()#

Get a shallow copy of this SopelIdentifierMemory.

See dict.copy().

get(
key: str,
default: Any = _NO_DEFAULT,
) Any#

Get the value of key from this SopelIdentifierMemory.

Takes an optional default value, just like dict.get().

make_identifier#

A factory to transform keys into identifiers.

pop(
key: str,
default: Any = _NO_DEFAULT,
) Any#

Pop the value of key from this SopelIdentifierMemory.

Takes an optional default value, just like dict.pop().

setdefault(
key: str,
default: Any | None = None,
) Any#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update(maybe_mapping=tuple())#

Update this SopelIdentifierMemory with key-value pairs.

See dict.update().

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__.

Note

Unlike the dict on which they are based, SopelMemory and its derivative types do not accept key-value pairs as keyword arguments at construction time.

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.

Note

Unlike the defaultdict on which it is based, SopelMemoryWithDefault does not accept key-value pairs as keyword arguments at construction time.

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