py.lib.aw_config

Yohn Y. 2024-05-04 Parent:bece3a8a67a5 Child:b76a704f31b1

1:81fc92335324 Go to Latest

py.lib.aw_config/src/aw_config/file.py

+ Модуль получения имени директории размещения приложения

History
1 # coding: utf-8
2 """\
3 Функции, помогающие в разборе конфигурационного файла
4 """
5 import toml
6 from os.path import exists
7 from typing import Union, Any
9 from .error import Error
10 from .type_helpers import BaseTypeHelper
13 class ConfigFileError(Error):
14 """\
15 Базовое исключение при обработке конфигурационного файла
16 """
19 class ConfigSectionNotFound(ConfigFileError):
20 """\
21 Отсутствие нужного раздела в конфигурации
22 """
25 class ConfigFileContent(object):
26 """\
27 Работа с содержимым файла конфигурации
28 """
29 def __init__(self, file_data, section_name=None):
30 """\
31 :param file_data: Разобранное в словарь содержимое файла конфигурации
32 :param section_name: Имя секции в конфигурации
33 """
34 self.d = file_data
35 self.section = section_name
37 def _format_err_msg(self, msg: str) -> str:
38 if self.section is not None:
39 return f'Раздел конфигурации "{self.section}": {msg}'
41 else:
42 return msg
44 def __enter__(self):
45 return self
47 def __exit__(self, exc_type, exc_val, exc_tb):
48 pass
50 def get_value(self, name: str,
51 val_type: Union[type, BaseTypeHelper],
52 default: Any = None,
53 mandatory: bool = True):
54 """\
55 Получить из текущего раздела конфигурации нужный элемент
56 :param name: имя параметра
57 :param val_type: тип параметра
58 :param default: значение параметра по умолчанию
59 :param mandatory: является ли параметр обязательным. Если ``False``, то в случае отсутствия
60 параметра будет использовано значение None
61 """
62 if name not in self.d:
63 if mandatory and default is None:
64 raise ConfigFileError(self._format_err_msg(f'Параметр "{name}" в файле отсутствует'))
66 else:
67 return default
69 else:
70 _buf = self.d[name]
71 try:
72 return val_type(_buf)
74 except (ValueError, TypeError) as e:
75 raise ConfigFileError(self._format_err_msg(f'Не удалось привести значение "{_buf}" к типу '
76 f'{repr(val_type)}: {e}'))
78 def get_section(self, name: str, mandatory: bool = True):
79 """\
80 Получить раздел конфигурационного файла из текущего или корневого раздела
81 :param name: имя раздела
82 :param mandatory: является ли раздел обязательным или он может отсутствовать в конфигурации. Во втором
83 случае, будет создан пустой словарь и использован в качестве данных раздела.
84 :returns Экземпляр того-же класса, только для новой секции
85 """
86 if name not in self.d:
87 if mandatory:
88 raise ConfigSectionNotFound(self._format_err_msg(f'Раздел "{name}" не найден'))
90 else:
91 return ConfigFileContent(file_data={}, section_name=f'{self.section}.{name}')
93 else:
94 _val = self.d[name]
96 if not isinstance(_val, dict):
97 raise ConfigFileError(self._format_err_msg(f'Параметр конфигурации "{name}" не является разделом'))
99 else:
100 return ConfigFileContent(file_data=_val, section_name=f'{self.section}.{name}')
103 class ConfigFile(object):
104 """\
105 Работа с самим файлом конфигурации
106 """
107 def __init__(self, file_name: str):
108 if not exists(file_name):
109 raise ConfigFileError(f'Файл конфигурации "{file_name}" не существует')
111 self.file_name = file_name
113 def get(self):
114 """\
115 Производим разбор файла конфигурации и создаём корневой раздел конфигурации
116 """
117 return ConfigFileContent(toml.load(self.file_name))
119 def __exit__(self, exc_type, exc_val, exc_tb):
120 pass
122 def __enter__(self):
123 return self.get()