Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion sfs2x/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
)

from .buffer import Buffer
from .registry import decode, register
from .registry import _registry, decode, register
from .type_codes import TypeCode

__all__ = [
Expand Down Expand Up @@ -51,3 +51,35 @@
"decode",
"register",
]


def patch_containers() -> None:
from collections.abc import Callable
from typing import Any

from .utils import camel_to_snake

for _cls in _registry.values():
name = _cls.__name__

def _make_put(tp: Any = _cls) -> Callable: # noqa: ANN401
# noinspection PyTypeChecker,PyArgumentList
def _put_x(self: SFSObject, key: str, value: Any) -> SFSObject: # noqa: ANN401
if type(value) not in (SFSObject, SFSArray):
return self.put(key, tp(value))
return self.put(key, value)

return _put_x

def _make_add(tp: Any = _cls) -> Callable: # noqa: ANN401
def _add_x(self: SFSArray, value: Any) -> SFSArray: # noqa: ANN401
if type(value) not in (SFSObject, SFSArray):
return self.add(tp(value))
return self.add(value)

return _add_x

setattr(SFSObject, f"put_{camel_to_snake(name)}", _make_put())
setattr(SFSArray, f"add_{camel_to_snake(name)}", _make_add())

patch_containers()
2 changes: 2 additions & 0 deletions sfs2x/core/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class FieldError(TypeError):
"""Exception appears when trying to use a non-field type in container."""
34 changes: 4 additions & 30 deletions sfs2x/core/types/containers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from collections.abc import Callable, Iterator
from collections.abc import Iterator
from dataclasses import dataclass
from typing import Any, Never

from sfs2x.core.buffer import Buffer
from sfs2x.core.field import Field
from sfs2x.core.registry import _registry, decode, register
from sfs2x.core.registry import decode, register
from sfs2x.core.type_codes import TypeCode
from sfs2x.core.utils import (
camel_to_snake,
read_small_string,
write_small_string,
)
Expand Down Expand Up @@ -65,6 +64,7 @@ def to_bytes(self) -> bytearray:
payload += v.to_bytes()
return payload

# noinspection PyTypeChecker
@classmethod
def from_buffer(cls, buf: Buffer) -> "SFSObject":
"""Load SFSObject from a buffer."""
Expand Down Expand Up @@ -152,6 +152,7 @@ def to_bytes(self) -> bytearray:
payload += elem.to_bytes()
return payload

# noinspection PyTypeChecker
@classmethod
def from_buffer(cls, buf: Buffer) -> "SFSArray":
"""Load SFSArray from buffer."""
Expand Down Expand Up @@ -182,30 +183,3 @@ def __iter__(self) -> Iterator[Any]:
yield v.value
else:
yield v


for _cls in _registry.values():
name = _cls.__name__


def _make_put(tp: Any = _cls) -> Callable: # noqa: ANN401
# noinspection PyTypeChecker,PyArgumentList
def _put_x(self: SFSObject, key: str, value: Any) -> SFSObject: # noqa: ANN401
if type(value) not in (SFSObject, SFSArray):
return self.put(key, tp(value))
return self.put(key, value)

return _put_x


def _make_add(tp: Any = _cls) -> Callable: # noqa: ANN401
def _add_x(self: SFSArray, value: Any) -> SFSArray: # noqa: ANN401
if type(value) not in (SFSObject, SFSArray):
return self.add(tp(value))
return self.add(value)

return _add_x


setattr(SFSObject, f"put_{camel_to_snake(name)}", _make_put())
setattr(SFSArray, f"add_{camel_to_snake(name)}", _make_add())
8 changes: 5 additions & 3 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
UtfStringArray,
decode,
)
from sfs2x.core.exceptions import FieldError
from sfs2x.core.utils import read_small_string, write_small_string

SAMPLE_TYPES_VALUES = {
Expand Down Expand Up @@ -84,8 +85,6 @@
])
}



def test_decode_unknown_type():
unknown_packet = bytearray([30])
with pytest.raises(ValueError):
Expand Down Expand Up @@ -154,4 +153,7 @@ def test_coding_styles_compatibility():

assert imperative == declarative


def test_field_error():
object = SFSObject()
with pytest.raises(FieldError):
object['key'] = 'value'
Loading