various improvements
This commit is contained in:
@ -5,13 +5,13 @@
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# Compute is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with Compute. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Configuration loader."""
|
||||
|
||||
|
77
compute/utils/dictutil.py
Normal file
77
compute/utils/dictutil.py
Normal file
@ -0,0 +1,77 @@
|
||||
# This file is part of Compute
|
||||
#
|
||||
# Compute is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Compute is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Compute. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Dict tools."""
|
||||
|
||||
from compute.exceptions import DictMergeConflictError
|
||||
|
||||
|
||||
def merge(a: dict, b: dict, path: list[str] | None = None) -> dict:
|
||||
"""
|
||||
Merge `b` into `a`. Return modified `a`.
|
||||
|
||||
:raise: :class:`DictMergeConflictError`
|
||||
"""
|
||||
if path is None:
|
||||
path = []
|
||||
for key in b:
|
||||
if key in a:
|
||||
if isinstance(a[key], dict) and isinstance(b[key], dict):
|
||||
merge(a[key], b[key], [*path, str(key)])
|
||||
elif a[key] != b[key]:
|
||||
raise DictMergeConflictError('.'.join([*path, str(key)]))
|
||||
else:
|
||||
a[key] = b[key]
|
||||
return a
|
||||
|
||||
|
||||
def override(a: dict, b: dict) -> dict:
|
||||
"""
|
||||
Override dict `a` by `b` values.
|
||||
|
||||
Keys that not exists in `a`, but exists in `b` will be
|
||||
appended to `a`.
|
||||
|
||||
.. code-block:: shell-session
|
||||
|
||||
>>> from compute.utils import dictutil
|
||||
>>> default = {
|
||||
... 'bus': 'virtio',
|
||||
... 'driver': {'name': 'qemu', 'type': 'qcow2'}
|
||||
... }
|
||||
>>> user = {
|
||||
... 'bus': 'ide',
|
||||
... 'target': 'vda',
|
||||
... 'driver': {'type': 'raw'}
|
||||
... }
|
||||
>>> dictutil.override(default, user)
|
||||
{'bus': 'ide', 'driver': {'name': 'qemu', 'type': 'raw'},
|
||||
'target': 'vda'}
|
||||
|
||||
NOTE: merging dicts contained in lists is not supported.
|
||||
|
||||
:param a: Dict to be overwritten.
|
||||
:param b: A dict whose values will be used to rewrite dict `a`.
|
||||
:return: Modified `a` dict.
|
||||
"""
|
||||
for key in b:
|
||||
if key in a:
|
||||
if isinstance(a[key], dict) and isinstance(b[key], dict):
|
||||
override(a[key], b[key])
|
||||
else:
|
||||
a[key] = b[key] # replace existing key's values
|
||||
else:
|
||||
a[key] = b[key]
|
||||
return a
|
@ -5,13 +5,13 @@
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# Compute is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with Compute. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Random identificators."""
|
||||
|
||||
|
@ -5,13 +5,13 @@
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# Compute is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with Compute. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Tools for data units convertion."""
|
||||
|
||||
@ -21,7 +21,7 @@ from compute.exceptions import InvalidDataUnitError
|
||||
|
||||
|
||||
class DataUnit(StrEnum):
|
||||
"""Data units enumerated."""
|
||||
"""Data units enumeration."""
|
||||
|
||||
BYTES = 'bytes'
|
||||
KIB = 'KiB'
|
||||
@ -29,6 +29,13 @@ class DataUnit(StrEnum):
|
||||
GIB = 'GiB'
|
||||
TIB = 'TiB'
|
||||
|
||||
@classmethod
|
||||
def _missing_(cls, name: str) -> 'DataUnit':
|
||||
for member in cls:
|
||||
if member.name.lower() == name.lower():
|
||||
return member
|
||||
return None
|
||||
|
||||
|
||||
def to_bytes(value: int, unit: DataUnit = DataUnit.BYTES) -> int:
|
||||
"""Convert value to bytes. See :class:`DataUnit`."""
|
||||
|
Reference in New Issue
Block a user