Skip to content

Commit

Permalink
fix(mypy): load_into also accepts bytes so return value is fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
robinvandernoord committed Sep 20, 2023
1 parent e523c02 commit db509f0
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/configuraptor/abs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# t_typelike is anything that can be type hinted
T_typelike: typing.TypeAlias = type | types.UnionType # | typing.Union
# t_data is anything that can be fed to _load_data
T_data_types = str | Path | dict[str, typing.Any] | None
T_data_types = str | Path | bytes | dict[str, typing.Any] | None
T_data = T_data_types | list[T_data_types]

# c = a config class instance, can be any (user-defined) class
Expand Down
15 changes: 13 additions & 2 deletions src/configuraptor/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ def __load_data(
E.g. class Tool will be mapped to key tool.
It also deals with nested keys (tool.extra -> {"tool": {"extra": ...}}
"""
if isinstance(data, bytes):
# instantly return, don't modify
# bytes as inputs -> bytes as output
# but since `T_data` is re-used, that's kind of hard to type for mypy.
return data # type: ignore

if isinstance(data, list):
if not data:
raise ValueError("Empty list passed!")
Expand All @@ -82,10 +88,12 @@ def __load_data(

if isinstance(data, str):
data = Path(data)

if isinstance(data, Path):
with data.open("rb") as f:
loader = loaders.get(data.suffix or data.name)
data = loader(f, data.resolve())

if not data:
return {}

Expand Down Expand Up @@ -353,7 +361,7 @@ def _split_init(init: T_init) -> tuple[T_init_list, T_init_dict]:

def _load_into_recurse(
cls: typing.Type[C],
data: dict[str, typing.Any],
data: dict[str, typing.Any] | bytes,
init: T_init = None,
strict: bool = True,
convert_types: bool = False,
Expand All @@ -367,9 +375,12 @@ def _load_into_recurse(
"""
init_args, init_kwargs = _split_init(init)

if issubclass(cls, BinaryConfig):
if isinstance(data, bytes) or issubclass(cls, BinaryConfig):
if not isinstance(data, (bytes, dict)): # pragma: no cover
raise NotImplementedError("BinaryConfig can only deal with `bytes` or a dict of bytes as input.")
elif not issubclass(cls, BinaryConfig): # pragma: no cover
raise NotImplementedError("Only BinaryConfig can be used with `bytes` (or a dict of bytes) as input.")

inst = typing.cast(C, cls._parse_into(data))
elif dc.is_dataclass(cls):
to_load = check_and_convert_data(cls, data, init_kwargs.keys(), strict=strict, convert_types=convert_types)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def test_nested_binary_config():

assert inst.data1.name != inst.data2.name

assert inst._pack() == data1 + data2 + data3
assert inst._pack() == data1 + data2 + data3 == asbytes(inst)


class Version(BinaryConfig):
Expand All @@ -85,7 +85,7 @@ def test_binary_config_with_external_block():
assert data.first.patch == 5
assert data.second.major == 0

assert data._pack() == v1 + v2
assert data._pack() == v1 + v2 == asbytes(data)


class IsNumber(BinaryConfig):
Expand Down

0 comments on commit db509f0

Please sign in to comment.