Beispiel #1
0
 def test_forbid_mapping(self):
     factory = Factory(default_schema=Schema(unknown=Unknown.FORBID,
                                             name_mapping={"a":
                                                           "a_mapped"}), )
     serialized = {"a_mapped": "AA"}
     factory.load(serialized, Data)
Beispiel #2
0
from typing import Optional, Dict

from dataclasses import dataclass

from dataclass_factory import Factory, Schema


@dataclass
class Sub:
    b: str


@dataclass
class Data:
    a: str
    unknown: Optional[Dict] = None
    sub: Optional[Sub] = None


serialized = {
    "a": "A1",
    "b": "B2",
    "c": "C3",
}

factory = Factory(default_schema=Schema(unknown=["unknown", "sub"]))
data = factory.load(serialized, Data)
assert data == Data(a="A1", unknown={"b": "B2", "c": "C3"}, sub=Sub("B2"))
 def setUp(self) -> None:
     self.factory = Factory()
class Qwerty:
    qwerty: List[str]


@dataclass
class ComplexTodo:
    id: int
    title: str
    description: Qwerty


# my
factory = Factory(schemas={
    SimpleTodo: DSchema(
        name_mapping={
            "desc": ("description", "qwerty", 0),
        }
    )
})
simple_serializer = factory.serializer(List[SimpleTodo])
complex_serializer = factory.serializer(List[ComplexTodo])

# test
simple_todos = [SimpleTodo(
    id=i,
    title="title %s" % i,
    desc="5some long description %s %s %s" % (i, i * 10, i)
) for i in range(10)]

complex_todos = [ComplexTodo(
    id=i,
 def test_should_raise_when_invalid_int_field_provided(self):
     try:
         Factory(debug_path=True).parser(Foo)({"a": "20x", "b": 20})
         self.assertTrue(False, "ValueError exception expected")
     except InvalidFieldError as exc:
         self.assertEqual(['a'], exc.field_path)
Beispiel #6
0
    desc: str


# marshmallow
class TodoSchema(Schema):
    id = fields.Integer()
    title = fields.Str()
    description = fields.Str(attribute="desc")


todo_schema = TodoSchema(many=True)

# my
factory = Factory(schemas={
    Todo: DSchema(
        name_mapping={"desc": "description"}
    )
})
serializer = factory.serializer(List[Todo])

# test
todos = [Todo(
    id=i,
    title="title %s" % i,
    desc="5some long description %s %s %s" % (i, i * 10, i)
) for i in range(10)]


def do1():
    return serializer(todos)
    def test_none(self):
        data = {"styled_name": 1, "trailed_name": 2, "NameToMap": 3}
        d = Data(1, 2, 3)

        serializer = Factory().serializer(Data)
        self.assertEqual(serializer(d), data)
 def test_list(self):
     factory = Factory()
     self.assertEqual(factory.dump([A(1)]), [{"value": 1}])
 def test_dict(self):
     factory = Factory()
     self.assertEqual(factory.dump({"a": A(1)}), {"a": {"value": 1}})
Beispiel #10
0
import json
from enum import Enum
from typing import Dict, Union

from dataclasses import dataclass, field

from dataclass_factory import Factory, Schema


class A(Enum):
    X = "x"
    Y = 1


@dataclass
class Data:
    a: A
    dict_: Dict[str, Union[int, float]]
    dictw_: Dict[str, Union[int, float]] = field(default_factory=dict)
    optional_num: int = 0


factory = Factory(schemas={A: Schema(description="My super `A` class")})
print(json.dumps(factory.json_schema(Data), indent=2))
print(json.dumps(factory.json_schema_definitions(), indent=2))
Beispiel #11
0
from dataclasses import dataclass

from dataclass_factory import Factory, Schema, NameStyle

factory = Factory(default_schema=Schema(name_style=NameStyle.camel))


@dataclass
class Person:
    first_name: str
    last_name: str


person = Person("ivan", "petrov")

serial_person = {"FirstName": "ivan", "LastName": "petrov"}

assert factory.dump(person) == serial_person
Beispiel #12
0
class Telegram:
    def __init__(self,
                 bot_token,
                 connector=None,
                 close_session=True,
                 proxy=None,
                 message_callback=None):
        self.bot_token = bot_token
        self.session = aiohttp.ClientSession(connector=connector)
        self.close_session = close_session

        self.proxy = proxy

        self.loop = asyncio.get_event_loop()
        self.url = "https://api.telegram.org/bot%s/" % bot_token

        self.running = False

        self.factory = Factory(default_schema=Schema(
            trim_trailing_underscore=True))

        self.callback = message_callback

        self.me = None

    async def method(self, method_name, params=None):
        if params is None:
            params = {}
        async with self.session.post(self.url + method_name,
                                     data=params,
                                     proxy=self.proxy) as response:
            return loads(await response.text())

    async def get_updates(self, offset, timeout, limit):
        params = {
            'timeout': timeout,
            'offset': offset,
            'allowed_updates': '["message", "callback_query"]'
        }  # TODO: remove it

        if limit:
            params['limit'] = limit

        updates = await self.method("getUpdates", params)
        return self.factory.load(updates, Updates)

    async def process_message(self, update):
        if not self.callback:
            return  # skip update because message callback is not set
        msg = Message(update.message, self)
        cb_res = self.callback(msg)

        if iscoroutine(cb_res):
            await cb_res

    async def process_callback_query(self, update):
        if not self.callback:
            return

        query = CallbackQueryHandler(update.callback_query, self)
        cb_res = self.callback(query)

        if iscoroutine(cb_res):
            await cb_res

    async def process_updates(self, updates):
        for update in updates.result:
            if update.message:
                self.loop.create_task(self.process_message(update))
            elif update.callback_query:
                self.loop.create_task(self.process_callback_query(update))

    async def _loop(self, updates_limit, timeout):
        self.running = True
        self.me = self.factory.load((await self.method("getMe"))['result'],
                                    User)

        offset = None

        while self.running:
            updates = await self.get_updates(offset, timeout, updates_limit)

            if updates.result:
                offset = updates.result[-1].update_id + 1
                self.loop.create_task(self.process_updates(updates))

    def set_callback(self, callback):
        self.callback = callback

    def poll(self, updates_limit=None, timeout=None):
        self.loop.run_until_complete(self._loop(updates_limit, timeout))

    polling = poll  # alias for poll method

    def __del__(self):
        if self.close_session:
            self.loop.run_until_complete(self.session.close())
 def test_ignore_fields_with_init_false(self):
     serial = {"a": "A", "b": "B"}
     factory = Factory()
     self.assertTrue(factory.load(serial, Data))
Beispiel #14
0
 def test_include(self):
     factory = Factory(default_schema=Schema(unknown=Unknown.STORE, ), )
     serialized = {"a": "AA", "b": "b"}
     data = factory.load(serialized, DataWithExtras)
     self.assertEqual(data.a, "AA")
     self.assertEqual(data.extras, {"b": "b"})
class Qwerty:
    qwerty: List[str]


@dataclass
class ComplexTodo:
    id: int
    title: str
    description: Qwerty


# my
factory = Factory(schemas={
    SimpleTodo:
    Schema(name_mapping={
        "desc": ("description", "qwerty", 0),
    })
},
                  debug_path=True)
simple_parser = factory.parser(List[SimpleTodo])
complex_parser = factory.parser(List[ComplexTodo])

# test
todos = [{
    "description": {
        "qwerty": ["5some long description %s %s %s" % (i, i * 10, i)],
    },
    "id": i,
    "title": "title %s" % i,
} for i in range(10)]
Beispiel #16
0
 def test_optional(self):
     factory = Factory()
     y = factory.load({"x": None}, Data)
     self.assertEqual(y, Data(None))
Beispiel #17
0
from typing import Union

from dataclasses import dataclass

from dataclass_factory import Factory, Schema
from dataclass_factory.schema_helpers import type_checker


@dataclass
class Item:
    name: str
    type: str = "item"


@dataclass
class Group:
    name: str
    type: str = "group"


Something = Union[Item, Group]  # Available types

factory = Factory(schemas={
    Item: Schema(pre_parse=type_checker("item", field="type")),
    Group: Schema(pre_parse=type_checker("group")),  # `type` is default name for checked field
})

assert factory.load({"name": "some name", "type": "group"}, Something) == Group("some name")
Beispiel #18
0
 def test_optional_bool(self):
     factory = Factory()
     self.assertEqual(factory.load(None, Optional[bool]), None)
Beispiel #19
0
class TestLiteral(TestCase):
    def setUp(self) -> None:
        self.factory = Factory()

    @params(*LITERALS)
    def test_literal_fail(self, literal):
        abc = literal["a", "b", "c"]
        one = literal[1]
        with self.assertRaises(ValueError):
            self.factory.load("d", abc)
        with self.assertRaises(ValueError):
            self.factory.load(1.0, one)

    @params(*LITERALS)
    def test_literal(self, literal):
        abc = literal["a", "b", "c"]
        one = literal[1]
        self.assertEqual(self.factory.load("a", abc), "a")
        self.assertEqual(self.factory.load("b", abc), "b")
        self.assertEqual(self.factory.load("c", abc), "c")
        self.assertEqual(self.factory.load(1, one), 1)

        self.assertEqual(self.factory.dump("a", abc), "a")
        self.assertEqual(self.factory.dump("b", abc), "b")
        self.assertEqual(self.factory.dump("c", abc), "c")

        self.assertEqual(self.factory.dump("Z", abc), "Z")

        self.assertEqual(self.factory.dump(1, one), 1)
Beispiel #20
0
 def test_underscore(self):
     factory = Factory(default_schema=schema)
     self.assertEqual(factory.dump(DataUnderscore(100)), {"from": 100})
Beispiel #21
0
 def _init_factory(self):
     return Factory()
Beispiel #22
0
 def test_optional(self):
     factory = Factory(default_schema=schema)
     self.assertEqual(factory.dump(Data()), {})
     self.assertEqual(factory.dump(Data(1, [], "test")), {})
     self.assertEqual(factory.dump(Data(2, [], "test")), {"x": 2})
Beispiel #23
0
# marshmallow
class TodoSchema(Schema):
    id = fields.Integer()
    title = fields.Str()
    description = fields.Str(attribute="desc")

    @post_load
    def post(self, data, **kwargs):
        return Todo(**data)


todo_schema = TodoSchema(many=True)

# my
factory = Factory(
    schemas={Todo: DSchema(name_mapping={"desc": "description"})})
parser = factory.parser(List[Todo])

# my debug
factory_debug = Factory(
    schemas={Todo: DSchema(name_mapping={"desc": "description"})},
    debug_path=True)
parser_debug = factory_debug.parser(List[Todo])


# pydantic
class PydTodo(BaseModel):
    id: int
    title: str
    description: str
Beispiel #24
0
    @validate("int_field")  # use original field name in class
    def validate_field(self, data):
        if data > 100:
            raise ValueError
        return data * 100  # validator can change value

    # this validator will be called before parsing field
    @validate("complex_field", pre=True)
    def validate_field_pre(self, data):
        return data["value"]

    @validate("info")
    def validate_stub(self, data):
        return self.SOMETHING  # validator can access schema fields


@dataclass
class My:
    int_field: int
    complex_field: int
    info: str


factory = Factory(schemas={
    My: MySchema(name_style=NameStyle.upper_snake)  # name style does not affect how validators are bound to fields
})

result = factory.load({"INT_FIELD": 1, "COMPLEX_FIELD": {"value": 42}, "INFO": "ignored"}, My)
assert result == My(100, 42, "Some string")
from dataclasses import dataclass
import sys
import unittest
from unittest import TestCase

from dataclass_factory import Factory


@dataclass
class Model:
    name: str


factory = Factory()


@unittest.skipUnless(sys.version_info[:2] >= (3, 9), "requires Python 3.9+")
class TestTypeHintingGenericsInStandartCollections(TestCase):
    def test_dict(self):
        data = {
            "model": {
                "name": "name1",
            },
            "model2": {
                "name": "name2",
            },
        }
        expected = {"model": Model("name1"), "model2": Model("name2")}
        self.assertEqual(expected, factory.load(data, dict[str, Model]))

    def test_list(self):
 def test_slots(self):
     self.assertRaises(ValueError, Factory().serializer, SlotsClass)
class TestGeneric(TestCase):
    def setUp(self) -> None:
        self.factory = Factory()

    def test_simple_int(self):
        foo = Foo[int](1)
        foo_serial = {"value": 1}
        self.assertEqual(self.factory.load(foo_serial, Foo[int]), foo)
        self.assertEqual(self.factory.dump(foo, Foo[int]), foo_serial)

    def test_simple_str(self):
        foo = Foo[str]("hello")
        foo_serial = {"value": "hello"}
        self.assertEqual(self.factory.load(foo_serial, Foo[str]), foo)
        self.assertEqual(self.factory.dump(foo, Foo[str]), foo_serial)

    def test_implicit_simple(self):
        foo = Foo(1)
        foo_serial = {"value": 1}
        self.assertEqual(self.factory.load(foo_serial, Foo[int]), foo)
        self.assertEqual(self.factory.dump(foo), foo_serial)

    def test_two_vars(self):
        foo = FooBar(1, "str", 3)
        foo_serial = {"value": 1, "value2": "str", "value3": 3}
        self.assertEqual(self.factory.load(foo_serial, FooBar[int, str]), foo)
        self.assertEqual(self.factory.dump(foo), foo_serial)

    def test_inner(self):
        baz = FooBaz(Foo(1))
        baz_serial = {"foo": {"value": 1}}
        self.assertEqual(self.factory.load(baz_serial, FooBaz[int]), baz)
        self.assertEqual(self.factory.dump(baz), baz_serial)

    def test_inner2(self):
        baz = Foo(FooBaz(Foo(1)))
        baz_serial = {"value": {"foo": {"value": 1}}}
        self.assertEqual(self.factory.load(baz_serial, Foo[FooBaz[int]]), baz)
        self.assertEqual(self.factory.dump(baz, Foo[FooBaz[int]]), baz_serial)
        self.assertEqual(self.factory.dump(baz), baz_serial)

    def test_schema_load(self):
        factory = Factory(
            schemas={
                FakeFoo[str]: Schema(name_mapping={"value": "s"}),
                FakeFoo: Schema(name_mapping={"value": "v"}),
            })
        data = {"v": "hello", "i": 42, "s": "SSS"}
        self.assertEqual(factory.load(data, FakeFoo[str]), FakeFoo("SSS"))
        self.assertEqual(factory.load(data, FakeFoo[int]), FakeFoo("hello"))

    def test_schema_dump(self):
        factory = Factory(
            schemas={
                FakeFoo[str]: Schema(name_mapping={"value": "s"}),
                FakeFoo: Schema(name_mapping={"value": "v"}),
            })
        # self.assertEqual(factory.dump(FakeFoo("hello"), FakeFoo[str]), {"s": "hello"})
        self.assertEqual(factory.dump(FakeFoo("hello")), {"v": "hello"})

    def test_schema_dump_inner(self):
        factory = Factory(
            schemas={
                FooBaz[int]: Schema(name_mapping={"foo": "bar"}),
                Foo[int]: Schema(name_mapping={"value": "v"})
            })
        self.assertEqual(factory.dump(FooBaz(Foo(1)), FooBaz[int]),
                         {"bar": {
                             "v": 1
                         }})
 def test_slots_with_dict(self):
     self.assertRaises(ValueError, Factory().serializer, SlotsWithDict)
Beispiel #29
0
class TestSerializer(unittest.TestCase):
    def setUp(self) -> None:
        self.factory = Factory()

    def test_plain(self):
        serializer = self.factory.serializer(D)
        d = D(100, "hello")
        self.assertEqual(
            serializer(d),
            {
                "a": 100,
                "c": "hello"
            },
        )

    def test_list(self):
        serializer = self.factory.serializer(ListD)
        d1 = D(100, "hello")
        d2 = D(200, "hello2")

        dlist = ListD(
            [d1, d2],
            [123, 456, 789],
        )
        data = {
            "data": [
                {
                    "a": 100,
                    "c": "hello"
                },
                {
                    "a": 200,
                    "c": "hello2"
                },
            ],
            "ints": [123, 456, 789],
        }
        self.assertEqual(
            serializer(dlist),
            data,
        )

    def test_dict(self):
        serializer = self.factory.serializer(DictD)
        d1 = D(100, "hello")
        d2 = D(200, "hello2")

        dlist = DictD({"1": d1, "two": d2}, {"hello": "world", "foo": "bar"})
        data = {
            "data": {
                "1": {
                    "a": 100,
                    "c": "hello"
                },
                "two": {
                    "a": 200,
                    "c": "hello2"
                },
            },
            "strs": {
                "hello": "world",
                "foo": "bar"
            }
        }
        self.assertEqual(
            serializer(dlist),
            data,
        )

    def test_optional(self):
        serializer = self.factory.serializer(Optional[D])
        d1 = D(100, "hello")
        data1 = {"a": 100, "c": "hello"}
        self.assertEqual(
            serializer(d1),
            data1,
        )
        self.assertIs(
            serializer(None),
            None,
        )

    def test_any(self):
        serializer = self.factory.serializer(Any)
        d1 = D(100, "hello")
        data1 = {"a": 100, "c": "hello"}
        self.assertEqual(
            serializer(d1),
            data1,
        )
        self.assertIs(
            serializer(None),
            None,
        )

    def test_enum(self):
        self.assertEqual(self.factory.dump(State.one), "1")
        self.assertEqual(self.factory.dump(State.two, State), "two")
Beispiel #30
0
 def test_forbid(self):
     factory = Factory(default_schema=Schema(unknown=Unknown.FORBID, ), )
     serialized = {"a": "AA", "b": "b"}
     with self.assertRaises(ValueError):
         factory.load(serialized, Data)