bpod_core.misc¶
Miscellaneous tools that don’t fit the other categories.
Classes¶
- class bpod_core.misc.ByteEnum ¶
Bases:
IntEnumAn
IntEnumrestricted to single-byte values (0–255).Subclass this to define enums whose integer values fit in one unsigned byte. Each member additionally exposes its value as a
bytesobject viabyte_valuefor zero-allocation wire encoding.- Raises:
OverflowError – If a member’s value is outside the range of a single, unsigned byte.
- class bpod_core.misc.SettingsDict ¶
Bases:
MutableMapping[str,Any]A dictionary-like persistent settings storage backed by a JSON file.
This class implements the MutableMapping interface, storing key-value pairs that are automatically persisted to a JSON file on every write. It supports standard dictionary operations (get, set, delete, iterate) as well as nested key access.
File access is protected by a file lock for safe concurrent access from multiple processes.
- get_nested(keys, default=None) ¶
Retrieve a nested value using a sequence of keys.
- class bpod_core.misc.SuggestionDict ¶
-
A dictionary that suggests similar keys on failed lookup.
On
KeyError, raiseserror_classwith a message that includes the closest match from the existing keys viasuggest_similar(), making typos and near-misses easier to diagnose.- Parameters:
dictionary (
MutableMapping[str,TypeVar(V)]) – Initial key-value pairs.name (
str|None, default:None) – Human-readable label for the key type used in the error message.error_class (
type[Exception], default:<class 'KeyError'>) – Exception class to raise on failed lookup. Must accept a single string argument.
Examples
>>> d = SuggestionDict({'Port1': 1, 'Port2': 2}, name='channel') >>> d['Port1'] 1 >>> d['Prot1'] Traceback (most recent call last): ... KeyError: "No such channel: 'Prot1' - did you mean 'Port1'?"
- class bpod_core.misc.ValidatedDict ¶
Bases:
RootModel,MutableMapping[K,V]A dict-like container with runtime validation for keys and values.
This class wraps a standard
dictand integrates with Pydantic’sRootModelto validate keys and values upon mutation. It behaves like a mutable mapping for all common operations (get, set, delete, iterate, len) and compares equal to regular dicts with the same contents.- Parameters:
root (
TypeVar(RootModelRootType), default:PydanticUndefined) – Initial key-value pairs. Defaults to an emptydict.
Examples
Subclass
ValidatedDictto create a custom type with validation:>>> class TestDict(ValidatedDict[str, int]): ... pass
You can then instantiate your class
TestDictlike a regular dict:>>> test_dict = TestDict() >>> test_dict['foo'] = 1 >>> test_dict[42] = 2 Traceback (most recent call last): ... pydantic_core._pydantic_core.ValidationError: 1 validation error for TestDict 42.[key] Input should be a valid string [type=string_type, input_value=42, input_type=int] ...
Alternatively, you can also instantiate a ValidatedDict directly:
>>> my_validated_dict = ValidatedDict[str, int]({'foo': 1, 'bar': 2}) >>> my_validated_dict['foo'] = 'bar' Traceback (most recent call last): ... pydantic_core._pydantic_core.ValidationError: 1 validation error ... foo Input should be a valid integer, unable to parse string as an integer ... ...
Functions¶
- bpod_core.misc.extend_packed(byte_array, values, fmt) ¶
Extend a bytearray with packed binary values.
This function takes a sequence of integers, converts each one to bytes using the specified struct format character, and appends the result to the given bytearray. All values use the same format character and are packed in little-endian byte order.
- Parameters:
byte_array (
bytearray) – The bytearray that will be modified in-place by appending the packed binary data.values (
Sequence[int]) – Integer values to convert to binary. The number of values determines how many times the format character is repeated.fmt (
str) – A single struct format character that defines how each value is encoded. Common options: ‘b’ (int8), ‘h’ (int16), ‘i’ (int32), ‘q’ (int64), ‘B’ (uint8), ‘H’ (uint16), ‘I’ (uint32), ‘Q’ (uint64).
Examples
>>> from bpod_core.misc import extend_packed >>> buffer = bytearray() >>> extend_packed(buffer, [1, 2, 3], 'i') >>> len(buffer) 12 >>> buffer.hex() '010000000200000003000000'
See also
Format characters used by the
structmodule.
- bpod_core.misc.get_local_ipv4() ¶
Determine the primary local IPv4 address of the machine.
This function attempts to determine the IPv4 address of the local machine that would be used for an outbound connection to the internet. It does this by creating a UDP socket and connecting to a known public IP address (Google DNS at 8.8.8.8). No data is sent, but the OS uses the routing table to select the appropriate local interface.
- bpod_core.misc.get_nested(d, keys, default=None) ¶
Retrieve a value from a nested dict using a Sequence of keys.
- Parameters:
d (
MutableMapping) – The dictionary from which to get a value.keys (
Sequence[Any]) – A sequence of keys representing the path to the desired value.default (
Any, default:None) – The value to return if the path does not exist.
- Returns:
The value at the nested path, or default if any key in the path is missing.
- Return type:
Examples
>>> from bpod_core.misc import get_nested >>> dictionary = {'a': {'b': {'c': 42}}} >>> get_nested(dictionary, ['a', 'b', 'c']) 42
>>> get_nested(dictionary, ['a', 'x'], default='missing') 'missing'
- bpod_core.misc.prune_empty_parent_directories(target_directory, root_directory, *, remove_root=False) ¶
Remove empty parent directories recursively up to root directory.
Recursively removes the given directory if empty, then checks and removes parent directories up to (and optionally including) the root directory. Stops at the first non-empty directory encountered.
- Parameters:
- Raises:
ValueError – If target_directory is not a subpath of root_directory.
FileNotFoundError – If target_directory or root_directory does not exist.
NotADirectoryError – If target_directory or root_directory is not a directory.
- bpod_core.misc.set_nested(d, keys, value) ¶
Set a value in a nested dict, creating intermediate dicts as needed.
- Parameters:
d (
MutableMapping) – The dictionary in which to set the value.keys (
Sequence[Any]) – A sequence of keys representing the nested path where the value should be set.value (
Any) – The value to set at the specified path.
Examples
>>> from bpod_core.misc import set_nested >>> dictionary = {} >>> set_nested(dictionary, ['a', 'b', 'c'], 42) >>> dictionary {'a': {'b': {'c': 42}}}
>>> set_nested(dictionary, ['a', 'b', 'x'], 99) >>> dictionary {'a': {'b': {'c': 42, 'x': 99}}}
- bpod_core.misc.suggest_similar(invalid_string, valid_strings, format_string=" - did you mean '{}'?", cutoff=0.6) ¶
Suggest a similar valid string based on the given invalid string.
This function uses a similarity matching algorithm to find the closest match from an iterable of valid strings. If a match is found above the specified cutoff, it returns a formatted suggestion string.
- Parameters:
invalid_string (
str) – The string that is invalid or misspelled.valid_strings (
Iterable[str]) – An iterable of valid strings to compare against.format_string (
str, default:" - did you mean '{}'?") – The format string for the suggestion.cutoff (
float, default:0.6) – The similarity threshold for considering a match.
- Returns:
A formatted suggestion string if a match is found, otherwise an empty string.
- Return type:
Examples
>>> 'no such port' + suggest_similar('Prot1', ['Port1', 'Port2']) "no such port - did you mean 'Port1'?" >>> 'no such port' + suggest_similar('xyz', ['Port1', 'Port2']) 'no such port'
- bpod_core.misc.suppress_logging(level=50) ¶
Temporarily suppress logging up to and including the specified level.
The previous global logging disable level is restored when exiting the context, even if an exception is raised.
- bpod_core.misc.to_snake_case(string) ¶
Convert a given string to snake_case.
- Parameters:
string (
str) – The input string to be converted.- Returns:
The converted snake_case string.
- Return type:
Examples
>>> to_snake_case('CamelCase') 'camel_case' >>> to_snake_case('HTMLParser') 'html_parser' >>> to_snake_case('version2dot0') 'version_2_dot_0'
Attributes¶
- bpod_core.misc.K = ~K¶
Key type variable for generic mappings such as
ValidatedDict.
- bpod_core.misc.V = ~V¶
Value type variable for generic mappings such as
ValidatedDict.