Skip to content

Commit ef8e898

Browse files
just1602WhyNotHugo
authored andcommitted
Add Typing annotation to cli/config.py
1 parent 08616ab commit ef8e898

File tree

1 file changed

+57
-28
lines changed

1 file changed

+57
-28
lines changed

vdirsyncer/cli/config.py

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
import string
66
from configparser import RawConfigParser
77
from itertools import chain
8+
from typing import IO
9+
from typing import Any
10+
from typing import Generator
811

912
from .. import PROJECT_HOME
1013
from .. import exceptions
1114
from ..utils import cached_property
1215
from ..utils import expand_path
16+
from ..vobject import Item
1317
from .fetchparams import expand_fetch_params
1418
from .utils import storage_class_from_config
1519

@@ -29,10 +33,10 @@ def validate_section_name(name, section_type):
2933
)
3034

3135

32-
def _validate_general_section(general_config):
36+
def _validate_general_section(general_config: dict[str, str]):
3337
invalid = set(general_config) - GENERAL_ALL
3438
missing = GENERAL_REQUIRED - set(general_config)
35-
problems = []
39+
problems: list[str] = []
3640

3741
if invalid:
3842
problems.append(
@@ -92,17 +96,22 @@ def _validate_collections_param(collections):
9296

9397

9498
class _ConfigReader:
95-
def __init__(self, f):
96-
self._file = f
99+
def __init__(self, f: IO[Any]):
100+
self._file: IO[Any] = f
97101
self._parser = c = RawConfigParser()
98102
c.read_file(f)
99-
self._seen_names = set()
100-
101-
self._general = {}
102-
self._pairs = {}
103-
self._storages = {}
104-
105-
def _parse_section(self, section_type, name, options):
103+
self._seen_names: set = set()
104+
105+
self._general: dict[str, str] = {}
106+
self._pairs: dict[str, dict[str, str]] = {}
107+
self._storages: dict[str, dict[str, str]] = {}
108+
109+
def _parse_section(
110+
self,
111+
section_type: str,
112+
name: str,
113+
options: dict[str, Any]
114+
) -> None:
106115
validate_section_name(name, section_type)
107116
if name in self._seen_names:
108117
raise ValueError(f'Name "{name}" already used.')
@@ -119,7 +128,9 @@ def _parse_section(self, section_type, name, options):
119128
else:
120129
raise ValueError("Unknown section type.")
121130

122-
def parse(self):
131+
def parse(
132+
self
133+
) -> tuple[dict[str, str], dict[str, dict[str, str]], dict[str, dict[str, str]]]:
123134
for section in self._parser.sections():
124135
if " " in section:
125136
section_type, name = section.split(" ", 1)
@@ -145,7 +156,10 @@ def parse(self):
145156
return self._general, self._pairs, self._storages
146157

147158

148-
def _parse_options(items, section=None):
159+
def _parse_options(
160+
items: list[tuple[str, str]],
161+
section: str | None = None
162+
) -> Generator[tuple[str, dict[str, str]], None, None]:
149163
for key, value in items:
150164
try:
151165
yield key, json.loads(value)
@@ -154,26 +168,31 @@ def _parse_options(items, section=None):
154168

155169

156170
class Config:
157-
def __init__(self, general, pairs, storages):
171+
def __init__(
172+
self,
173+
general: dict[str, str],
174+
pairs: dict[str, dict[str, str]],
175+
storages: dict[str, dict[str, str]]
176+
) -> None:
158177
self.general = general
159178
self.storages = storages
160179
for name, options in storages.items():
161180
options["instance_name"] = name
162181

163-
self.pairs = {}
182+
self.pairs: dict[str, PairConfig] = {}
164183
for name, options in pairs.items():
165184
try:
166185
self.pairs[name] = PairConfig(self, name, options)
167186
except ValueError as e:
168187
raise exceptions.UserError(f"Pair {name}: {e}")
169188

170189
@classmethod
171-
def from_fileobject(cls, f):
190+
def from_fileobject(cls, f: IO[Any]):
172191
reader = _ConfigReader(f)
173192
return cls(*reader.parse())
174193

175194
@classmethod
176-
def from_filename_or_environment(cls, fname=None):
195+
def from_filename_or_environment(cls, fname: str | None = None):
177196
if fname is None:
178197
fname = os.environ.get("VDIRSYNCER_CONFIG", None)
179198
if fname is None:
@@ -190,7 +209,7 @@ def from_filename_or_environment(cls, fname=None):
190209
except Exception as e:
191210
raise exceptions.UserError(f"Error during reading config {fname}: {e}")
192211

193-
def get_storage_args(self, storage_name):
212+
def get_storage_args(self, storage_name: str):
194213
try:
195214
args = self.storages[storage_name]
196215
except KeyError:
@@ -211,13 +230,13 @@ def get_pair(self, pair_name: str) -> PairConfig:
211230

212231

213232
class PairConfig:
214-
def __init__(self, full_config, name, options):
215-
self._config = full_config
216-
self.name = name
217-
self.name_a = options.pop("a")
218-
self.name_b = options.pop("b")
233+
def __init__(self, full_config: Config, name: str, options: dict[str, str]):
234+
self._config: Config = full_config
235+
self.name: str = name
236+
self.name_a: str = options.pop("a")
237+
self.name_b: str = options.pop("b")
219238

220-
self._partial_sync = options.pop("partial_sync", None)
239+
self._partial_sync: str | None = options.pop("partial_sync", None)
221240
self.metadata = options.pop("metadata", None) or ()
222241

223242
self.conflict_resolution = self._process_conflict_resolution_param(
@@ -238,7 +257,10 @@ def __init__(self, full_config, name, options):
238257
if options:
239258
raise ValueError("Unknown options: {}".format(", ".join(options)))
240259

241-
def _process_conflict_resolution_param(self, conflict_resolution):
260+
def _process_conflict_resolution_param(
261+
self,
262+
conflict_resolution: str | list[str] | None
263+
):
242264
if conflict_resolution in (None, "a wins", "b wins"):
243265
return conflict_resolution
244266
elif (
@@ -302,10 +324,10 @@ def partial_sync(self):
302324

303325

304326
class CollectionConfig:
305-
def __init__(self, pair, name, config_a, config_b):
327+
def __init__(self, pair, name: str, config_a, config_b):
306328
self.pair = pair
307329
self._config = pair._config
308-
self.name = name
330+
self.name: str = name
309331
self.config_a = config_a
310332
self.config_b = config_b
311333

@@ -314,7 +336,14 @@ def __init__(self, pair, name, config_a, config_b):
314336
load_config = Config.from_filename_or_environment
315337

316338

317-
def _resolve_conflict_via_command(a, b, command, a_name, b_name, _check_call=None):
339+
def _resolve_conflict_via_command(
340+
a,
341+
b,
342+
command,
343+
a_name,
344+
b_name,
345+
_check_call=None
346+
) -> Item:
318347
import shutil
319348
import tempfile
320349

0 commit comments

Comments
 (0)