Concurrent Dict

class thread_factory.concurrency.concurrent_dictionary.ConcurrentDict(initial: Mapping[_K, _V] | Iterable[Tuple[_K, _V]] | None = None)[source]

Bases: Generic[_K, _V], IDisposable

A thread-safe dictionary implementation using:
  • An underlying Python dict

  • A reentrant lock (RLock) for synchronization

This class mimics many behaviors of a native Python dict, including common utility methods. It is designed for Python 3.13+ No-GIL environments (though it will also work fine in standard Python).

The dictionary can be frozen to prevent further modifications unless internal contents of dictionary are objects that are mutable.

batch_update(func: Callable[[Dict[_K, _V]], None]) None[source]

Perform a batch update on the dict under a single lock acquisition. This allows multiple operations to be performed atomically.

Parameters:

func (Callable[[Dict[_K, _V]], None]) – A function that accepts the internal dict as its only argument. The function should perform all necessary mutations.

clear() None[source]

Remove all items from the dict.

copy() ConcurrentDict[_K, _V][source]

Return a shallow copy of the ConcurrentDict.

Returns:

A new ConcurrentDict with copied items.

Return type:

ConcurrentDict[_K, _V]

dispose() None[source]

Dispose (clear) this ConcurrentDict, releasing its contents.

Once disposed, disposed becomes True and the internal dict is cleared. No further usage checks are enforced, so the user must avoid calling other methods after disposal.

This method is idempotent — multiple calls won’t cause errors.

filter(func: Callable[[_K, _V], bool]) ConcurrentDict[_K, _V][source]

Filter items based on a predicate function and return a new ConcurrentDict.

Parameters:

func (Callable[[_K, _V], bool]) – A function that takes (key, value) and returns True to keep the item, or False to discard it.

Returns:

A new dictionary containing only items where func(key, value) is True.

Return type:

ConcurrentDict[_K, _V]

freeze() None[source]

Freeze the dictionary to prevent further modifications. This is useful for making the dictionary immutable after initialization.

get(key: _K, default: _V | None = None) _V | None[source]

Return the value for key if it exists, else default.

Parameters:
  • key (_K) – The key to look up.

  • default (_V, optional) – The default if key is not found.

Returns:

Value if present, else default.

Return type:

_V or None

property is_frozen: bool

Check if the dictionary is frozen.

Returns:

True if the dictionary is frozen, False otherwise.

Return type:

bool

items() List[Tuple[_K, _V]][source]

Return a list of (key, value) pairs (in a copy).

Returns:

A list of all key-value pairs.

Return type:

List[Tuple[_K, _V]]

keys() List[_K][source]

Return a list of the dictionary’s keys (in a copy).

Returns:

A list of the keys.

Return type:

List[_K]

lockless_get(key: _K, default: _V | None = None) _V | None[source]

Get the value for key without acquiring the lock. This method is not thread-safe and should be used with caution.

Parameters:
  • key (_K) – The key to look up.

  • default (_V, optional) – The default if key is not found.

Returns:

Value if present, else None.

Return type:

_V or None

map(func: Callable[[_K, _V], Tuple[_K, _V]]) ConcurrentDict[_K, _V][source]

Apply a function to each (key, value) pair and return a new ConcurrentDict with the transformed results.

Parameters:

func (Callable[[_K, _V], Tuple[_K, _V]]]) – A function that takes (key, value) and returns a new (key, value) pair.

Returns:

A new dictionary with transformed pairs.

Return type:

ConcurrentDict[_K, _V]

pop(key: _K, default: _V | None = None) _V[source]

Remove the specified key and return its value. If the key is not found, return default if given, otherwise raise KeyError.

popitem() Tuple[_K, _V][source]

Remove and return an arbitrary (key, value) pair. Raises KeyError if the dict is empty.

Returns:

(key, value) as a tuple.

Raises:

KeyError – If the dictionary is empty.

reduce(func: Callable[[Any, Tuple[_K, _V]], Any], initial: Any | None = None) Any[source]

Apply a function of two arguments cumulatively to the dict items (in some iteration order).

Parameters:
  • func (Callable[[Any, (key, value)], Any]) – A function that takes (accumulator, (key, value)).

  • initial (Any, optional) – Starting value of the accumulator.

Returns:

The reduced value.

Return type:

Any

Raises:

TypeError – If the dict is empty and no initial value is provided.

Example

# Sum of all values def add_values(acc, item):

k, v = item return acc + v

total = concurrent_dict.reduce(add_values, 0)

setdefault(key: _K, default: _V | None = None) _V | None[source]

If key is in the dict, return its value. If not, insert key with a value of default and return default.

Parameters:
  • key (_K) – The key to set if missing.

  • default (_V, optional) – The value to store if key is missing.

Returns:

The existing or newly set value.

Return type:

_V or None

to_dict() Dict[_K, _V][source]

Return a shallow copy of the internal dictionary.

Returns:

A standard Python dict with the same keys and values.

Return type:

Dict[_K, _V]

unfreeze() None[source]

Unfreeze the dictionary to allow modifications. This is useful for making the dictionary mutable again after being frozen.

update(other: Mapping[_K, _V] | Iterable[Tuple[_K, _V]] | None = None, **kwargs: _V) None[source]

Update the dict with the key/value pairs from other, overwriting existing keys. Return None.

update() accepts either another dictionary, an iterable of key/value pairs, or keyword arguments.

Parameters:
  • other (Mapping[_K, _V] or Iterable of (_K, _V), optional) – Another dict or iterable of (key, value) pairs.

  • **kwargs – Additional key-value pairs provided as keyword arguments.

values() List[_V][source]

Return a list of the dictionary’s values (in a copy).

Returns:

A list of the values.

Return type:

List[_V]