Beispiel #1
0
def test_call_and_target():
    class F(object):
        def __init__(s, a, b, c):
            s.a, s.b, s.c = a, b, c

    call_f = Call(F, kwargs=dict(a=T, b=T, c=T))
    assert repr(call_f)
    val = glom(1, call_f)
    assert (val.a, val.b, val.c) == (1, 1, 1)

    class F(object):
        def __init__(s, a):
            s.a = a

    val = glom({'one': F('two')}, Call(F, args=(T['one'].a, )))
    assert val.a == 'two'
    assert glom({'a': 1}, Call(F, kwargs=T)).a == 1
    assert glom([1], Call(F, args=T)).a == 1
    assert glom(F, T(T)).a == F
    assert glom([F, 1], T[0](T[1]).a) == 1
    assert glom([[1]], S[UP][Val(T)][0][0]) == 1
    assert glom([[1]], S[UP][UP][UP][Val(T)]) == [[1]]  # tops out

    assert list(glom({'a': 'b'}, Call(T.values))) == ['b']

    with pytest.raises(TypeError, match='expected func to be a callable or T'):
        Call(func=object())

    assert glom(lambda: 'hi', Call()) == 'hi'
    return
Beispiel #2
0
def test_precedence():
    """test corner cases of dict key precedence"""
    glom({(0, 1): 3},
        Match({
            (0, 1): Val(1),  # this should match
            (0, int): Val(2),  # optional
            (0, M == 1): Val(3),  # optional
        })
    )
    with pytest.raises(ValueError):
        Optional(int)  # int is already optional so not valid to wrap
Beispiel #3
0
def test_val():
    assert Literal is Val
    expected = {'value': 'c', 'type': 'a.b'}
    target = {'a': {'b': 'c'}}
    val = glom(target, {'value': 'a.b', 'type': Val('a.b')})

    assert val == expected

    assert glom(None, Val('success')) == 'success'
    assert repr(Val(3.14)) == 'Val(3.14)'
    assert repr(Val(3.14)) == 'Val(3.14)'
Beispiel #4
0
def test_s_scope_assign():
    data = {'a': 1, 'b': [{'c': 2}, {'c': 3}]}
    output = [{'a': 1, 'c': 2}, {'a': 1, 'c': 3}]
    assert glom(data, (S(a='a'), ('b', [{'a': S['a'], 'c': 'c'}]))) == output
    assert glom(data, ('b', [{'a': S[ROOT][Val(T)]['a'], 'c': 'c'}])) == output

    with pytest.raises(TypeError):
        S('posarg')
    with pytest.raises(TypeError):
        S()

    assert glom([[1]], (S(v=Vars()), [[A.v.a]], S.v.a)) == 1
    assert glom(1, (S(v=lambda t: {}), A.v['a'], S.v['a'])) == 1
    with pytest.raises(GlomError):
        glom(1, (S(v=lambda t: 1), A.v.a))

    class FailAssign(object):
        def __setattr__(self, name, val):
            raise Exception('nope')

    with pytest.raises(PathAssignError):
        glom(1, (S(v=lambda t: FailAssign()), Path(A.v, 'a')))

    assert repr(S(a=T.a.b)) == 'S(a=T.a.b)'

    spec = (S(a='x'), S.a)
    assert glom({'x': 'y'}, spec) == 'y'

    return
Beispiel #5
0
def test_max_skip():
    target = list(range(10)) + list(range(5))

    max_spec = (S(max=Vars(max=0)),
                [((M > M(S.max.max)) & A.max.max) | Val(SKIP)], S.max)
    result = glom(target, max_spec)
    assert result.max == 9
Beispiel #6
0
def test_pattern_matching():
    pattern_matcher = Or(And(Match(1), Val('one')), And(Match(2), Val('two')),
                         And(Match(float), Val('float')))
    assert glom(1, pattern_matcher) == 'one'
    assert glom(1.1, pattern_matcher) == 'float'

    # obligatory fibonacci

    fib = (M > 2) & (lambda n: glom(n - 1, fib) + glom(n - 2, fib)) | T

    assert glom(5, fib) == 8

    factorial = (lambda t: t + 1,
                 Ref('fact', (lambda t: t - 1, (M == 0) & Fill(1) |
                              (S(r=Ref('fact')), S, lambda s: s['r'] * s[T]))))

    assert glom(4, factorial) == 4 * 3 * 2
Beispiel #7
0
def test_json_ref():
    assert glom(
        {'a': {'b': [0, 1]}},
        Ref('json',
            Match(Or(
                And(dict, {Ref('json'): Ref('json')}),
                And(list, [Ref('json')]),
                And(0, Val(None)),
                object)))) == {'a': {'b': [None, 1]}}
Beispiel #8
0
def test_check_ported_tests():
    """
    Tests ported from Check() to make sure all the functionality has an analogue.
    """
    target = [{'id': 0}, {'id': 1}, {'id': 2}]

    # check that skipping non-passing values works
    assert glom(target, [Coalesce(M(T['id']) == 0, default=SKIP)]) == [{'id': 0}]

    # TODO: should M(subspec, default='') work? I lean no.
    # NB: this is not a very idiomatic use of Match, just brought over for Check reasons
    assert glom(target, [Match({'id': And(int, M == 1)}, default=SKIP)]) == [{'id': 1}]
    assert glom(target, [Match({'id': And(int, M <= 1)}, default=STOP)]) == [{'id': 0}, {'id': 1}]

    # check that stopping chain execution on non-passing values works
    spec = (Or(Match(len), Val(STOP)), T[0])
    assert glom('hello', spec, glom_debug=True) == 'h'
    assert glom('', spec) == ''  # would fail with IndexError if STOP didn't work

    target = [1, u'a']
    assert glom(target, [Match(unicode, default=SKIP)]) == ['a']
    assert glom(target, Match([Or(unicode, int)])) == [1, 'a']

    target = ['1']
    assert glom(target, [(M(T), int)]) == [1]
    assert glom(target, M(T)) == ['1']

    failing_checks = [({'a': {'b': 1}}, {'a': ('a', 'b', Match(str))},
                       '''expected type str, not int'''),  # TODO: bbrepr at least, maybe include path like Check did
                      ({'a': {'b': 1}}, {'a': ('a', Match({'b': str}))},
                       '''expected type str, not int'''),  # TODO: include subspec path ('b')
                      (1, Match(Or(unicode, bool))),
                      (1, Match(unicode)),
                      (1, Match(0)),
                      (1, Match(Or(0, 2))),
                      ('-3.14', Match(lambda x: int(x) > 0)),
                      # ('-3.14', M(lambda x: int(x) > 0)),
                      # TODO: M doesn't behave quite like Match because it's mode-free
    ]

    for fc in failing_checks:
        if len(fc) == 2:
            target, check = fc
            msg = None
        else:
            target, check, msg = fc

        with pytest.raises(MatchError) as exc_info:
            glom(target, check)

        if msg is not None:
            actual_msg = str(exc_info.value)
            assert actual_msg.find(msg) != -1
        assert repr(exc_info.value)

    return
Beispiel #9
0
def test_vars():
    assert glom(1, A.a) == 1  # A should not change the target
    assert glom(1, (A.a, S.a)) == 1
    # check that tuple vars don't "leak" into parent tuple
    assert glom(1, (A.t, Val(2), A.t, S.t)) == 2
    assert glom(1, (A.t, (Val(2), A.t), S.t)) == 1
    let = S(v=Vars({'b': 2}, c=3))
    assert glom(1, (let, A.v.a, S.v.a)) == 1
    with pytest.raises(AttributeError):
        glom(
            1,
            (let, S.v.a))  # check that Vars() inside a spec doesn't hold state
    assert glom(1, (let, Path(A, 'v', 'a'), S.v.a)) == 1
    assert glom(1, (let, S.v.b)) == 2
    assert glom(1, (let, S.v.c)) == 3
    assert repr(let) == "S(v=Vars({'b': 2}, c=3))"
    assert repr(Vars(a=1, b=2)) in ("Vars(a=1, b=2)", "Vars(b=2, a=1)")
    assert repr(Vars(a=1, b=2).glomit(None,
                                      None)) in ("ScopeVars({'a': 1, 'b': 2})",
                                                 "Vars({'b': 2, 'a': 1})")

    assert repr(A.b["c"]) == "A.b['c']"
Beispiel #10
0
def test_let():  # backwards compat 2020-07
    data = {'a': 1, 'b': [{'c': 2}, {'c': 3}]}
    output = [{'a': 1, 'c': 2}, {'a': 1, 'c': 3}]
    assert glom(data, (Let(a='a'), ('b', [{'a': S['a'], 'c': 'c'}]))) == output
    assert glom(data, ('b', [{'a': S[ROOT][Val(T)]['a'], 'c': 'c'}])) == output

    with pytest.raises(TypeError):
        Let('posarg')
    with pytest.raises(TypeError):
        Let()

    assert glom([[1]], (Let(v=Vars()), [[A.v.a]], S.v.a)) == 1
    assert glom(1, (Let(v=lambda t: {}), A.v['a'], S.v['a'])) == 1
    with pytest.raises(GlomError):
        glom(1, (Let(v=lambda t: 1), A.v.a))

    class FailAssign(object):
        def __setattr__(self, name, val):
            raise Exception('nope')

    with pytest.raises(PathAssignError):
        glom(1, (Let(v=lambda t: FailAssign()), Path(A.v, 'a')))

    assert repr(Let(a=T.a.b)) == 'Let(a=T.a.b)'
Beispiel #11
0
def generer_fichier_deputes(
    deputes_path,
    groupes_path,
    partis_path,
    deputes_groupes_path,
    deputes_partis_path,
    dest,
):
    deputes = pd.read_csv(deputes_path)
    groupes = pd.read_csv(groupes_path)
    deputes_groupes = pd.read_csv(deputes_groupes_path).join(
        groupes.set_index("code")[["nom", "sigle"]], on="code")
    deputes_groupes = (
        deputes_groupes[deputes_groupes.date_fin.isnull()].sort_values(
            ["code_depute", "relation"]).drop_duplicates(
                "code_depute",
                keep="last")  # garder "P" (président) plutôt que "M" (membre)
        .set_index("code_depute"))
    deputes_groupes[
        "groupe"] = deputes_groupes.nom + " (" + deputes_groupes.sigle + ")"

    partis = pd.read_csv(partis_path)
    deputes_partis = pd.read_csv(deputes_partis_path).join(
        partis.set_index("code")[["nom", "sigle"]], on="code")
    deputes_partis = deputes_partis[
        deputes_partis.date_fin.isnull()].set_index("code_depute")
    deputes_partis = deputes_partis.nom + " (" + deputes_partis.sigle + ")"
    deputes_partis.name = "parti"

    deputes = deputes.join(deputes_groupes[["groupe", "relation"]],
                           on=["code"]).join(deputes_partis, on=["code"])

    with lzma.open(dest, "wt") as f, id_from_file(
            "circonscriptions_legislatives.csv") as id_circos, id_from_file(
                "deputes.csv") as id_deputes:

        spec = {
            "id":
            Invoke(id_deputes).specs(code=T.code),
            "circonscription_id":
            Invoke(id_circos).specs(code=T.circonscription),
            **{
                c: getattr(T, c)
                for c in [
                    "code",
                    "nom",
                    "prenom",
                    "sexe",
                    "date_naissance",
                    "legislature",
                    "date_debut_mandat",
                ]
            },
            "groupe":
            Coalesce(T.groupe, skip=pd.isna, default=""),
            "parti":
            Coalesce(T.parti, skip=pd.isna, default=""),
            "date_fin_mandat":
            Coalesce(T.date_fin_mandat, skip=pd.isna, default=NULL),
            "relation":
            Coalesce(T.relation, skip=pd.isna, default=""),
            "profession":
            Val(NULL),
        }

        w = csv.DictWriter(f, fieldnames=spec)
        w.writeheader()
        w.writerows(glom(deputes.itertuples(), Iter(spec)))
Beispiel #12
0
def test_clamp():
    assert glom(range(10), [(M < 7) | Val(7)]) == [0, 1, 2, 3, 4, 5, 6, 7, 7, 7]
    assert glom(range(10), [(M < 7) | Val(SKIP)]) == [0, 1, 2, 3, 4, 5, 6]
Beispiel #13
0
def test_examples():
    assert glom(8, (M > 7) & Val(7)) == 7
    assert glom(range(10), [(M > 7) & Val(7) | T]) == [0, 1, 2, 3, 4, 5, 6, 7, 7, 7]
    assert glom(range(10), [(M > 7) & Val(SKIP) | T]) == [0, 1, 2, 3, 4, 5, 6, 7]