Example #1
0
def test_pipes():
    assert c.list_comp(c.inline_expr("{0} ** 2").pass_args(c.this())).pipe(
        c.call_func(sum, c.this())).pipe(
            c.call_func(
                lambda x, a: x + a,
                c.this(),
                c.naive({
                    "abc": 10
                }).item(c.input_arg("key_name")),
            )).pipe([c.this(), c.this()]).execute([1, 2, 3],
                                                  key_name="abc",
                                                  debug=False) == [
                                                      24,
                                                      24,
                                                  ]
    assert c.item(0).pipe(
        datetime.strptime,
        "%Y-%m-%d",
    ).pipe(c.call_func(lambda dt: dt.date(),
                       c.this())).execute([
                           "2019-01-01",
                       ], debug=False) == date(2019, 1, 1)

    assert c.item(0).pipe(
        datetime.strptime,
        "%Y-%m-%d",
    ).pipe(c.this().call_method("date")).execute([
        "2019-01-01",
    ], debug=False) == date(2019, 1, 1)

    with pytest.raises(c.ConversionException):
        c.naive(True).pipe(c.item("key1", _predefined_input={"key1": 777}))
Example #2
0
def test_naive_conversion_attr():
    TestType = namedtuple("TestType", ["field_a", "field_b"])
    obj = TestType(1, 2)

    assert c.naive(obj).attr("field_b").gen_converter()(100) == 2
    assert c.naive(obj).attr("field_b", "real").gen_converter()(100) == 2
    with pytest.raises(AttributeError):
        c.naive(obj).attr("field_c").gen_converter()(100)

    assert c.attr(c.naive(["field_a"]).item(0)).gen_converter()(obj) == 1
Example #3
0
def test_naive_conversion_call():
    assert c.naive("TEST").attr("lower").call().gen_converter()(100) == "test"
    assert c.call_func(str.lower, c.this()).gen_converter()("TEST") == "test"
    assert (c.naive("TE ST").attr("replace").call(
        " ", "").gen_converter()(100) == "TEST")

    f = MagicMock(return_value=1)
    c.naive(f).call(1, 2, test1=True, test2="test3").gen_converter()(100)
    f.assert_called_with(1, 2, test1=True, test2="test3")
    c.call(10, test="abc").gen_converter()(f)
    f.assert_called_with(10, test="abc")
Example #4
0
def test_naive_conversion_apply():
    f = MagicMock(return_value=1)
    c.naive(f).apply((1, 2), dict(test1=True,
                                  test2="test3")).gen_converter()(100)
    f.assert_called_with(1, 2, test1=True, test2="test3")
    c.apply((10, ), dict(test="abc")).gen_converter()(f)
    f.assert_called_with(10, test="abc")

    c.apply((), {}).execute(f)
    f.assert_called_with()

    c.apply((1, ), {}).execute(f)
    f.assert_called_with(1)
Example #5
0
def test_naive_conversion_or_and():
    assert c.naive(False).or_(c.naive(False)).gen_converter()(100) is False
    assert (c.naive(False) | c.naive(False)).gen_converter()(100) is False
    assert c.naive(0).or_(c.naive(10)).gen_converter()(100) == 10
    assert c.naive(10).and_(c.naive(0)).gen_converter()(100) == 0
    assert (c.naive(10) & c.naive(0)).gen_converter()(100) == 0

    assert (c.this.and_(1).and_(2).execute(1) == c.and_(c.this, 1,
                                                        2).execute(1) == 2)
    assert (c.this.or_(1).or_(2).execute(1) == c.or_(c.this, 1, 2).execute(1)
            == 1)

    assert (c.this.and_(1).and_(2).or_(3).execute(1) == c.and_(
        c.this, 1, 2).or_(3).execute(1) == 2)
    def _gen_code_and_update_ctx(self, code_input, ctx):
        suffix = self.gen_name("_", ctx, ("take_while", self, code_input))
        converter_name = f"drop_while{suffix}"
        var_chain = f"chain{suffix}"
        var_it = f"it{suffix}"
        var_item = f"item{suffix}"

        (
            code_args,
            positional_args_as_conversions,
            keyword_args_as_conversions,
            namespace_ctx,
        ) = self.get_args_def_info(ctx)
        with namespace_ctx:
            condition_code = self.condition.gen_code_and_update_ctx(
                var_item, ctx)

            code = Code()
            code.add_line(
                f"def {converter_name}({var_it},{var_chain}{code_args}):", 1)
            code.add_line(f"{var_it} = iter({var_it})", 0)
            code.add_line(f"for {var_item} in {var_it}:", 1)
            code.add_line(f"if not ({condition_code}):", 1)
            code.add_line("break", -2)
            code.add_line("else:", 1)
            code.add_line("return ()", -1)
            code.add_line(f"return {var_chain}(({var_item},), {var_it})", -1)
            self._code_to_converter(converter_name, code.to_string(0), ctx)
            return (c.escaped_string(converter_name).call(
                c.this,
                c.naive(chain),
                *positional_args_as_conversions,
                **keyword_args_as_conversions,
            ).gen_code_and_update_ctx(code_input, ctx))
Example #7
0
def test_naive_conversion():
    d = {1: 2}
    assert c.naive(d).gen_converter()(1) == d
    assert c.naive("abc").gen_converter()(1) == "abc"
    assert c.naive(1).gen_converter()(10) == 1
    assert c.naive(True).gen_converter()(10) is True
    assert c.naive(False).gen_converter()(10) is False
    assert c.naive(None).gen_converter()(10) is None
    assert c.naive("1").as_type(int).gen_converter()(10) == 1
    assert c.naive(1).gen_converter(method=True)(None, 10) == 1
Example #8
0
def test_or_and_not():
    assert c.or_(None, 0).gen_converter()(100) == 0
    assert c.and_(None, 0).gen_converter()(100) is None
    assert c.not_(True).gen_converter()(100) is False
    assert (~c.this).gen_converter()(True) is False
    assert c.naive(None).not_().execute(100) is True

    with pytest.raises(ValueError):
        c.or_()
Example #9
0
def test_base_reducer():
    assert c.aggregate((
        c.reduce(lambda a, b: a + b, c.this, initial=0),
        c.reduce(c.naive(lambda a, b: a + b), c.this, initial=int),
        c.reduce(
            c.inline_expr("{0} + {1}"),
            c.this,
            initial=c.inline_expr("int()"),
            default=0,
        ),
        c.reduce(
            c.inline_expr("{0} + {1}"),
            c.this,
            initial=c(int),
            default=0,
        ),
        c.reduce(
            c.inline_expr("{0} + {1}"),
            c.this,
            initial=int,
            default=0,
        ),
    )).filter(c.this > 5).gen_converter(debug=False)([1, 2, 3]) == [
        6,
        6,
        6,
        6,
        6,
    ]

    with pytest.raises(ValueError):
        c.aggregate(c.ReduceFuncs.Sum(c.reduce(
            c.ReduceFuncs.Count))).gen_converter()
    with pytest.raises(ValueError):
        c.aggregate(c.ReduceFuncs.Sum(c.ReduceFuncs.Count() +
                                      1)).gen_converter()
    with pytest.raises(ValueError):
        c.aggregate((c.ReduceFuncs.Count() +
                     2).pipe(c.ReduceFuncs.Sum(c.this) + 1)).gen_converter()

    conv = c.aggregate(c.ReduceFuncs.DictArray(
        c.item(0), c.item(1))).gen_converter(debug=False)
    data = [
        ("a", 1),
        ("a", 2),
        ("b", 3),
    ]
    result = {"a": [1, 2], "b": [3]}
    assert conv(data) == result
    assert conv([]) is None

    conv2 = c.aggregate({
        "key": c.ReduceFuncs.DictArray(c.item(0), c.item(1))
    }).gen_converter(debug=False)
    assert conv2([]) == {"key": None}
    assert conv2(data) == {"key": result}
Example #10
0
def test_pipes():
    assert c.list_comp(c.inline_expr("{0} ** 2").pass_args(c.this)).pipe(
        c.call_func(sum, c.this)).pipe(
            c.call_func(
                lambda x, a: x + a,
                c.this,
                c.naive({
                    "abc": 10
                }).item(c.input_arg("key_name")),
            )).pipe([c.this, c.this]).execute([1, 2, 3],
                                              key_name="abc",
                                              debug=False) == [
                                                  24,
                                                  24,
                                              ]
    assert c.item(0).pipe(datetime.strptime, "%Y-%m-%d").pipe(
        c.call_func(lambda dt: dt.date(),
                    c.this)).execute(["2019-01-01"],
                                     debug=False) == date(2019, 1, 1)

    assert c.item(0).pipe(datetime.strptime, "%Y-%m-%d").pipe(
        c.this.call_method("date")).execute(["2019-01-01"],
                                            debug=False) == date(2019, 1, 1)

    conv = c.dict_comp(
        c.item("name"),
        c.item("transactions").pipe(
            c.list_comp({
                "id":
                c.item(0).as_type(str),
                "amount":
                c.item(1).pipe(c.if_(c.this, c.this.as_type(Decimal), None)),
            })),
    ).gen_converter(debug=False)
    assert conv([{
        "name": "test",
        "transactions": [(0, 0), (1, 10)]
    }]) == {
        "test": [
            {
                "id": "0",
                "amount": None
            },
            {
                "id": "1",
                "amount": Decimal("10")
            },
        ]
    }

    assert c.this.pipe(lambda it: it).filter(
        c.this).sort().as_type(list).execute((2, 1, 0)) == [1, 2]
Example #11
0
def test_naive_conversion():
    d = {1: 2}
    prev_max_counter = c.BaseConversion.max_counter
    c.BaseConversion.max_counter = 3
    try:
        assert c.naive(d).gen_converter()(1) == d
        assert c.naive("abc").gen_converter()(1) == "abc"
        assert c.naive(1).gen_converter()(10) == 1
        assert c.naive(True).gen_converter()(10) is True
        assert c.naive(False).gen_converter()(10) is False
        assert c.naive(None).gen_converter()(10) is None
        assert c.naive("1").as_type(int).gen_converter()(10) == 1
        assert c.naive(1).gen_converter(method=True)(None, 10) == 1
    finally:
        c.BaseConversion.max_counter = prev_max_counter
Example #12
0
def test_filter():
    assert list(c.naive([1, 2, 3]).filter(c.this().gt(2)).execute(None)) == [3]
    assert c.filter(c.this().gt(1), cast=list).execute([1, 2, 3]) == [2, 3]
    assert c.filter(c.this().gt(1), cast=tuple).execute([1, 2, 3]) == (2, 3)
    assert c.filter(c.this().gt(1), cast=set).execute([1, 2, 3]) == {2, 3}
    assert c.filter(c.this().gt(1),
                    cast=lambda x: list(x)).execute([1, 2, 3]) == [2, 3]
    assert c.list_comp(c.this()).filter(c.this().gt(1)).execute([1, 2, 3]) == [
        2,
        3,
    ]
    assert c.this().filter(c.this().gt(1), cast=list).execute([1, 2, 3]) == [
        2,
        3,
    ]
Example #13
0
def test_filter():
    assert list(c.naive([1, 2, 3]).filter(c.this.gt(2)).execute(None)) == [3]
    assert c.filter(c.this.gt(1), cast=list).execute([1, 2, 3]) == [2, 3]
    assert c.filter(c.this.gt(1), cast=tuple).execute([1, 2, 3]) == (2, 3)
    assert c.filter(c.this.gt(1), cast=set).execute([1, 2, 3]) == {2, 3}
    assert c.filter(c.this.gt(1),
                    cast=lambda x: list(x)).execute([1, 2, 3]) == [2, 3]
    assert c.list_comp(c.this).filter(c.this.gt(1)).execute([1, 2, 3],
                                                            debug=False) == [
                                                                2,
                                                                3,
                                                            ]
    assert c.this.filter(c.this.gt(1), cast=list).execute([1, 2, 3],
                                                          debug=False) == [
                                                              2,
                                                              3,
                                                          ]
    assert c.list_comp(c.this).filter(
        c.this > 1, cast=lambda x: list(x)).execute(range(4)) == [2, 3]
Example #14
0
def test_pipe_conversion():
    from convtools import conversion as c
    from convtools.base import PipeConversion

    assert PipeConversion(c.naive([1, 2, 3]), c.item(1)).execute(None) == 2
    assert (PipeConversion(c.item("key1"),
                           c.item("key2")).execute({"key1": {
                               "key2": 3
                           }},
                                                   debug=False) == 3)
    assert (c.this.pipe(c.list_comp(c.this + 1)).filter(c.this > 3).execute(
        [1, 2, 3, 4, 5, 6], debug=False)) == [4, 5, 6, 7]

    c.aggregate(
        c.ReduceFuncs.Array(c.item("key"), default=list).pipe(
            c.if_(
                c.call_func(any, c.generator_comp(c.this.is_(None))),
                c.call_func(list),
                c.this,
            ))).gen_converter(debug=False)
Example #15
0
def test_naive_conversion_or_and():
    assert c.naive(False).or_(c.naive(False)).gen_converter()(100) is False
    assert (c.naive(False) | c.naive(False)).gen_converter()(100) is False
    assert c.naive(0).or_(c.naive(10)).gen_converter()(100) == 10
    assert c.naive(10).and_(c.naive(0)).gen_converter()(100) == 0
    assert (c.naive(10) & c.naive(0)).gen_converter()(100) == 0
Example #16
0
def test_naive_conversion_callmethod():
    mock = Mock()
    c.naive(mock).call_method("test_method", 1, abc=2).gen_converter()(100)
    mock.test_method.assert_called_with(1, abc=2)
Example #17
0
def test_naive_conversion():
    d = {1: 2}
    assert c.naive(d).gen_converter()(1) == d
    assert c.naive("abc").gen_converter()(1) == "abc"
    assert c.naive(1).gen_converter()(10) == 1
    assert c.naive(True).gen_converter()(10) is True
    assert c.naive(False).gen_converter()(10) is False
    assert c.naive(None).gen_converter()(10) is None
    assert c.naive("1").as_type(int).gen_converter()(10) == 1
    assert c.naive(1).gen_converter(method=True)(None, 10) == 1

    assert ("%" not in next(
        iter(c.naive("%abc").gen_converter()._name_to_converter.values()))
            ["code_str"])
    assert ("{" not in next(
        iter(c.naive("{abc").gen_converter()._name_to_converter.values()))
            ["code_str"])
    assert ("abc" in next(
        iter(c.naive("abc").gen_converter()._name_to_converter.values()))
            ["code_str"])
Example #18
0
def test_pipes():
    assert c.list_comp(c.inline_expr("{0} ** 2").pass_args(c.this())).pipe(
        c.call_func(sum, c.this())).pipe(
            c.call_func(
                lambda x, a: x + a,
                c.this(),
                c.naive({
                    "abc": 10
                }).item(c.input_arg("key_name")),
            )).pipe([c.this(), c.this()]).execute([1, 2, 3],
                                                  key_name="abc",
                                                  debug=False) == [
                                                      24,
                                                      24,
                                                  ]
    assert c.item(0).pipe(datetime.strptime, "%Y-%m-%d").pipe(
        c.call_func(lambda dt: dt.date(),
                    c.this())).execute(["2019-01-01"],
                                       debug=False) == date(2019, 1, 1)

    assert c.item(0).pipe(datetime.strptime, "%Y-%m-%d").pipe(
        c.this().call_method("date")).execute(["2019-01-01"],
                                              debug=False) == date(2019, 1, 1)

    with c.OptionsCtx() as options:
        max_pipe_length = options.max_pipe_length = 10
        with pytest.raises(c.ConversionException):
            conv = c.this()
            for i in range(max_pipe_length + 1):
                conv = c.this().pipe(conv)

        with c.OptionsCtx() as options2, pytest.raises(c.ConversionException):
            options2.max_pipe_length = 5
            conv.clone()

    conv = c.dict_comp(
        c.item("name"),
        c.item("transactions").pipe(
            c.list_comp({
                "id":
                c.item(0).as_type(str),
                "amount":
                c.item(1).pipe(c.if_(c.this(),
                                     c.this().as_type(Decimal), None)),
            })),
    ).gen_converter(debug=True)
    assert conv([{
        "name": "test",
        "transactions": [(0, 0), (1, 10)]
    }]) == {
        "test": [
            {
                "id": "0",
                "amount": None
            },
            {
                "id": "1",
                "amount": Decimal("10")
            },
        ]
    }

    with c.OptionsCtx() as options:
        max_pipe_length = options.max_pipe_length = 10
        conv1 = c.item(0).pipe(c.item(1).pipe(c.item(2)))

        def measure_pipe_length(conv):
            length = 0
            for i in range(max_pipe_length):
                if conv._predefined_input is not None:
                    length += 1
                    conv = conv._predefined_input
                else:
                    break
            return length

        pipe_length_before = measure_pipe_length(conv1)
        for i in range(max_pipe_length + 20):
            c.generator_comp(c.this().pipe(conv1))
        pipe_length_after = measure_pipe_length(conv1)
        assert pipe_length_after == pipe_length_before
Example #19
0
def test_docs():
    print(1 < c.naive(2))
Example #20
0
def test_naive_conversion_item():
    d = {1: 2, 10: {"test": 15, 2: 777}, 100: {"test2": 200}}
    assert c.naive(d).item(1).execute(100) == 2
    assert c.item(1).gen_converter()(d) == 2
    assert c.item(10, "test").gen_converter()(d) == 15

    assert c.item(11, "test", default=77).gen_converter()(d) == 77
    assert (c.item(10, c.input_arg("arg1"),
                   default=c.input_arg("arg2")).gen_converter()(d,
                                                                arg1="test",
                                                                arg2=77) == 15)
    assert (c.item(10, c.input_arg("arg1"),
                   default=c.input_arg("arg2")).gen_converter()(d,
                                                                arg1="tst",
                                                                arg2=77) == 77)
    assert (c.item(11, "test", default=77).gen_converter(method=True)(None,
                                                                      d) == 77)
    assert c.item(10, "testt", default=77).gen_converter()(d) == 77

    assert c.item(10, "testt", default=c.this()).gen_converter()(d) == d

    assert c.item(10, c.item(1)).gen_converter()(d) == 777
    assert c.item(10).item(2).gen_converter()(d) == 777

    with pytest.raises(KeyError):
        c.naive(d).item(11).gen_converter()(100)
    with pytest.raises(IndexError):
        c.naive([]).item(11).gen_converter()(100)
    with pytest.raises(TypeError):
        c.naive(None).item(11).gen_converter()(100)

    assert (c.naive(d).item(100).item("test2").gen_converter(
        debug=False)(100) == 200)
    assert (c.naive(d).item(c.this(),
                            "test2").gen_converter(debug=False)(100) == 200)
    assert (c.naive(d).item(100, default=30).item(
        "test2", default=30).gen_converter(debug=False)(100) == 200)

    # testing defaults
    assert (c.naive(d).item(100, default=30).item(
        "test", default=30).gen_converter()(100) == 30)
    assert (c.naive(d).item(10).item("test2",
                                     default=30).gen_converter()(100) == 30)
    assert c.naive(True).is_(True).execute(100) is True
    assert c.naive(True).is_not(True).execute(100) is False
    assert c.naive(1).in_({1, 2}).execute(100) is True
    assert c.naive(1).in_({3, 2}).execute(100) is False
    assert c.naive(1).not_in({3, 2}).execute(100) is True
    assert c.naive(1).eq(1).execute(100) is True
    assert (c.naive(1) == 1).execute(100) is True
    assert c.naive(1).not_eq(1).execute(100) is False
    assert (c.naive(1) != 1).execute(100) is False
    assert c.naive(1).gte(1).execute(100) is True
    assert (c.naive(1) >= 1).execute(100) is True
    assert c.naive(2).gte(1).execute(100) is True
    assert (c.naive(2) >= 1).execute(100) is True
    assert c.naive(10).gt(1).execute(100) is True
    assert (c.naive(10) > 1).execute(100) is True
    assert c.naive(1).lte(1).execute(100) is True
    assert (c.naive(1) <= 1).execute(100) is True
    assert c.naive(0).lte(1).execute(100) is True
    assert (c.naive(0) <= 1).execute(100) is True
    assert c.naive(0).lt(1).execute(100) is True
    assert (c.naive(0) < 1).execute(100) is True

    assert c.this().neg().execute(2) == -2
    assert (-c.this()).execute(2) == -2
    assert (c.this() + c.this()).execute(2) == 4
    assert (c.this() * c.this()).execute(3) == 9
    assert (c.this() - c.this()).execute(2) == 0
    assert (c.naive(5) / c.this()).execute(2) == 2.5
    assert (c.naive(5) // c.this()).execute(2) == 2
    assert (c.naive(5) % c.this()).execute(2) == 1
Example #21
0
def test_base_reducer():
    from convtools.aggregations import _ReducerExpression, _ReducerStatements

    assert c.aggregate((
        c.reduce(
            _ReducerExpression(lambda a, b: a + b, expr=c.this(), initial=0)),
        c.reduce(
            _ReducerExpression(c.naive(lambda a, b: a + b),
                               expr=c.this(),
                               initial=int)),
        c.reduce(_ReducerExpression("{0} + {1}", expr=c.this(), default=0)),
        c.reduce(
            _ReducerExpression(
                "{0} + {1}",
                expr=c.this(),
                initial_from_first=int,
                default=0,
            )),
        c.reduce(
            _ReducerStatements(
                reduce="%(result)s += ({1} or 0)",
                initial_from_first="%(result)s = ({0} or 0)",
                default=0,
            ),
            c.this(),
        ),
        c.reduce(
            _ReducerStatements(
                reduce="%(result)s += ({1} or 0)",
                default=c.naive(int),
            ),
            c.this(),
        ),
        c.reduce(
            _ReducerStatements(
                reduce="%(result)s = ({1} or 0)",
                initial=0,
            ),
            c.this(),
        ),
    )).filter(c.this() > 5, cast=tuple).gen_converter(debug=True)([1, 2,
                                                                   3]) == (
                                                                       6,
                                                                       6,
                                                                       6,
                                                                       6,
                                                                       6,
                                                                       6,
                                                                   )

    with pytest.raises(AssertionError):
        c.aggregate((c.reduce(
            c.ReduceFuncs.Sum,
            c.reduce(c.ReduceFuncs.Count),
        ), )).gen_converter()

    conv = c.aggregate(
        c.reduce(c.ReduceFuncs.DictArray,
                 (c.item(0), c.item(1)))).gen_converter(debug=True)
    data = [
        ("a", 1),
        ("a", 2),
        ("b", 3),
    ]
    result = {"a": [1, 2], "b": [3]}
    assert conv(data) == result
    assert conv([]) is None

    conv2 = c.aggregate({
        "key":
        c.reduce(c.ReduceFuncs.DictArray, (c.item(0), c.item(1)))
    }).gen_converter(debug=True)
    assert conv2([]) == {"key": None}
    assert conv2(data) == {"key": result}
def test_doc__index_deserialization():
    class Employee:
        def __init__(self, **kwargs):
            self.kwargs = kwargs

    input_data = {
        "objects": [
            {
                "id": 1,
                "first_name": "john",
                "last_name": "black",
                "dob": None,
                "salary": "1,000.00",
                "department": "D1 ",
                "date": "2000-01-01",
            },
            {
                "id": 2,
                "first_name": "bob",
                "last_name": "wick",
                "dob": "1900-01-01",
                "salary": "1,001.00",
                "department": "D3 ",
                "date": "2000-01-01",
            },
        ]
    }

    # prepare a few conversions to reuse
    c_strip = c.this.call_method("strip")
    c_capitalize = c.this.call_method("capitalize")
    c_decimal = c.this.call_method("replace", ",", "").as_type(Decimal)
    c_date = c.call_func(datetime.strptime, c.this,
                         "%Y-%m-%d").call_method("date")
    # reusing c_date
    c_optional_date = c.if_(c.this, c_date, None)

    first_name = c.item("first_name").pipe(c_capitalize)
    last_name = c.item("last_name").pipe(c_capitalize)
    # call "format" method of a string and pass first & last names as
    # parameters
    full_name = c("{} {}").call_method("format", first_name, last_name)

    conv = (
        c.item("objects").pipe(
            c.generator_comp({
                "id":
                c.item("id"),
                "first_name":
                first_name,
                "last_name":
                last_name,
                "full_name":
                full_name,
                "date_of_birth":
                c.item("dob").pipe(c_optional_date),
                "salary":
                c.item("salary").pipe(c_decimal),
                # pass a hardcoded dict and to get value by "department"
                # key
                "department_id":
                c.naive({
                    "D1": 10,
                    "D2": 11,
                    "D3": 12,
                }).item(c.item("department").pipe(c_strip)),
                "date":
                c.item("date").pipe(c_date),
            })).pipe(
                c.dict_comp(
                    c.item("id"),  # key
                    c.apply_func(  # value
                        Employee,
                        args=(),
                        kwargs=c.this,
                    ),
                )).gen_converter(debug=True)  # to see print generated code
    )

    result = conv(input_data)
    assert result[1].kwargs == {
        "date": date(2000, 1, 1),
        "date_of_birth": None,
        "department_id": 10,
        "first_name": "John",
        "full_name": "John Black",
        "id": 1,
        "last_name": "Black",
        "salary": Decimal("1000.00"),
    }
    assert result[2].kwargs == {
        "date": date(2000, 1, 1),
        "date_of_birth": date(1900, 1, 1),
        "department_id": 12,
        "first_name": "Bob",
        "full_name": "Bob Wick",
        "id": 2,
        "last_name": "Wick",
        "salary": Decimal("1001.00"),
    }
Example #23
0
def test_doc__index_deserialization():
    class Employee:
        def __init__(self, **kwargs):
            self.kwargs = kwargs

    input_data = {
        "objects": [
            {
                "id": 1,
                "first_name": "john",
                "last_name": "black",
                "dob": None,
                "salary": "1,000.00",
                "department": "D1 ",
                "date": "2000-01-01",
            },
            {
                "id": 2,
                "first_name": "bob",
                "last_name": "wick",
                "dob": "1900-01-01",
                "salary": "1,001.00",
                "department": "D3 ",
                "date": "2000-01-01",
            },
        ]
    }

    # get by "department" key and then call method "strip"
    department = c.item("department").call_method("strip")
    first_name = c.item("first_name").call_method("capitalize")
    last_name = c.item("last_name").call_method("capitalize")

    # call "format" method of a string and pass first & last names as
    # parameters
    full_name = c("{} {}").call_method("format", first_name, last_name)
    date_of_birth = c.item("dob")

    # partially initialized "strptime"
    parse_date = c.call_func(datetime.strptime, c.this(),
                             "%Y-%m-%d").call_method("date")

    conv = (
        c.item("objects").pipe(
            c.generator_comp({
                "id":
                c.item("id"),
                "first_name":
                first_name,
                "last_name":
                last_name,
                "full_name":
                full_name,
                "date_of_birth":
                c.if_(
                    date_of_birth,
                    date_of_birth.pipe(parse_date),
                    None,
                ),
                "salary":
                c.call_func(
                    Decimal,
                    c.item("salary").call_method("replace", ",", ""),
                ),
                # pass a hardcoded dict and to get value by "department"
                # key
                "department_id":
                c.naive({
                    "D1": 10,
                    "D2": 11,
                    "D3": 12,
                }).item(department),
                "date":
                c.item("date").pipe(parse_date),
            })).
        pipe(
            c.dict_comp(
                c.item(
                    "id"),  # key
                # write a python code expression, format with passed parameters
                c.inline_expr("{employee_cls}(**{kwargs})").pass_args(
                    employee_cls=Employee,
                    kwargs=c.this(),
                ),  # value
            )).gen_converter(debug=True))

    result = conv(input_data)
    assert result[1].kwargs == {
        "date": date(2000, 1, 1),
        "date_of_birth": None,
        "department_id": 10,
        "first_name": "John",
        "full_name": "John Black",
        "id": 1,
        "last_name": "Black",
        "salary": Decimal("1000.00"),
    }
    assert result[2].kwargs == {
        "date": date(2000, 1, 1),
        "date_of_birth": date(1900, 1, 1),
        "department_id": 12,
        "first_name": "Bob",
        "full_name": "Bob Wick",
        "id": 2,
        "last_name": "Wick",
        "salary": Decimal("1001.00"),
    }
Example #24
0
def test_naive_conversion_applymethod():
    mock = Mock()
    c.naive(mock).apply_method("test_method", (1, ),
                               dict(abc=2)).gen_converter()(100)
    mock.test_method.assert_called_with(1, abc=2)
Example #25
0
def test_or_and_not():
    assert c.or_(None, 0).gen_converter()(100) == 0
    assert c.and_(None, 0).gen_converter()(100) is None
    assert c.not_(True).gen_converter()(100) is False
    assert (~c.this()).gen_converter()(True) is False
    assert c.naive(None).not_().execute(100) is True
Example #26
0
def test_gen_converter():
    class A:
        x = 10

        def __init__(self):
            self.x = 20

        conv1 = (c.this() +
                 c.input_arg("self").attr("x")).gen_converter(method=True)
        conv2 = (c.this() +
                 c.input_arg("cls").attr("x")).gen_converter(method=True)

        conv3 = classmethod(
            (c.this() +
             c.input_arg("cls").attr("x")).gen_converter(class_method=True))
        conv4 = classmethod(
            (c.this() +
             c.input_arg("self").attr("x")).gen_converter(class_method=True))

        conv5 = (c.this() + c.input_arg("self").attr("x") +
                 c.input_arg("n")).gen_converter(
                     signature="self, n=1000, data_=15")

        conv6 = staticmethod(
            ((c.this() + c.call_func(sum, c.input_arg("args"))) *
             c.input_arg("kwargs").call_method("get", "multiplicator", 1)
             ).gen_converter(signature="data_, *args, **kwargs"))

    assert A().conv1(100) == 120
    assert A.conv3(100) == 110

    with pytest.raises(NameError):
        A().conv2(100)
    with pytest.raises(NameError):
        A.conv4(100)

    assert A().conv5() == 1035
    assert A().conv5(data_=7) == 1027
    assert A().conv5(n=100) == 135

    assert A.conv6(20) == 20
    assert A.conv6(20, 1, 2, 3) == 26
    assert A.conv6(20, 1, 2, 3, multiplicator=10) == 260

    assert (c.call_func(sum,
                        c.this()).gen_converter(signature="*data_")(1, 2,
                                                                    3) == 6)
    assert (c.call_func(lambda i: globals().__setitem__("A", 1) or sum(i),
                        c.this()).gen_converter(signature="*data_")(1, 2,
                                                                    3) == 6)
    assert c({
        c.naive("-").call_method("join",
                                 c.this().call_method("keys")):
        c.call_func(sum,
                    c.this().call_method("values"))
    }).gen_converter(signature="**data_")(a=1, b=2, c=3) == {
        "a-b-c": 6
    }
    with pytest.raises(c.ConversionException):
        c.call_func(sum,
                    c.input_arg("x")).gen_converter(signature="*data_")(1, 2,
                                                                        3)
    with pytest.raises(c.ConversionException):
        c.this().gen_converter(method=True, class_method=True)
def test_doc__index_word_count():

    # Let's say we need to count words across all files
    input_data = [
        "war-and-peace-1.txt",
        "war-and-peace-2.txt",
        "war-and-peace-3.txt",
        "war-and-peace-4.txt",
    ]

    # # iterate an input and read file lines
    #
    # def read_file(filename):
    #     with open(filename) as f:
    #         for line in f:
    #             yield line
    # extract_strings = c.generator_comp(c.call_func(read_file, c.this()))

    # to simplify testing
    extract_strings = c.generator_comp(
        c.call_func(lambda filename: [filename], c.this()))

    # 1. make ``re`` pattern available to the code to be generated
    # 2. call ``finditer`` method of the pattern and pass the string
    #    as an argument
    # 3. pass the result to the next conversion
    # 4. iterate results, call ``.group()`` method of each re.Match
    #    and call ``.lower()`` on each result
    split_words = (c.naive(re.compile(r"\w+")).call_method(
        "finditer", c.this()).pipe(
            c.generator_comp(c.this().call_method("group",
                                                  0).call_method("lower"))))

    # ``extract_strings`` is the generator of strings
    # so we iterate it and pass each item to ``split_words`` conversion
    vectorized_split_words = c.generator_comp(c.this().pipe(split_words))

    # flattening the result of ``vectorized_split_words``, which is
    # a generator of generators of strings
    flatten = c.call_func(
        chain.from_iterable,
        c.this(),
    )

    # aggregate the input, the result is a single dict
    # words are keys, values are count of words
    dict_word_to_count = c.aggregate(
        c.ReduceFuncs.DictCount(c.this(), c.this(), default=dict))

    # take top N words by:
    #  - call ``.items()`` method of the dict (the result of the aggregate)
    #  - pass the result to ``sorted``
    #  - take the slice, using input argument named ``top_n``
    #  - cast to a dict
    take_top_n = (c.this().call_method("items").sort(
        key=lambda t: t[1],
        reverse=True).pipe(c.this()[:c.input_arg("top_n")]).as_type(dict))

    # the resulting pipeline is pretty self-descriptive, except the ``c.if_``
    # part, which checks the condition (first argument),
    # and returns the 2nd if True OR the 3rd (input data by default) otherwise
    pipeline = (
        extract_strings.pipe(flatten).pipe(vectorized_split_words).pipe(
            flatten).pipe(dict_word_to_count).pipe(
                c.if_(
                    c.input_arg("top_n").is_not(None),
                    c.this().pipe(take_top_n),
                ))
        # Define the resulting converter function signature.  In fact this
        # isn't necessary if you don't need to specify default values
    ).gen_converter(debug=True, signature="data_, top_n=None")

    assert pipeline(input_data, top_n=3) == {"war": 4, "and": 4, "peace": 4}