Esempio n. 1
0
def set_with(obj, path, value, customizer=None):
    """This method is like :func:`set_` except that it accepts customizer which
    is invoked to produce the objects of path. If customizer returns undefined
    path creation is handled by the method instead. The customizer is invoked
    with three arguments: ``(nested_value, key, nested_object)``.

    Args:
        obj (list|dict): Object to modify.
        path (str | list): Target path to set value to.
        value (mixed): Value to set.
        customizer (function, optional): The function to customize assigned
            values.

    Returns:
        mixed: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> set_with({}, '[0][1]', 'a', lambda: {})
        {0: {1: 'a'}}

    .. versionadded:: 4.0.0

    .. versionchanged:: 4.3.1
        Fixed bug where a callable `value` was called when being set.
    """
    return update_with(obj, path, pyd.constant(value), customizer=customizer)
Esempio n. 2
0
def set_with(obj, path, value, customizer=None):
    """
    This method is like :func:`set_` except that it accepts customizer which is invoked to produce
    the objects of path. If customizer returns undefined path creation is handled by the method
    instead. The customizer is invoked with three arguments: ``(nested_value, key, nested_object)``.

    Args:
        obj (list|dict): Object to modify.
        path (str | list): Target path to set value to.
        value (mixed): Value to set.
        customizer (callable, optional): The function to customize assigned values.

    Returns:
        mixed: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> set_with({}, '[0][1]', 'a', lambda: {})
        {0: {1: 'a'}}

    .. versionadded:: 4.0.0

    .. versionchanged:: 4.3.1
        Fixed bug where a callable `value` was called when being set.
    """
    return update_with(obj, path, pyd.constant(value), customizer=customizer)
Esempio n. 3
0
def _FilesExist(paths, get_missing=False):
    '''Returns true if all files exist.

    if get_missing is true, returns a list of all missing files.

    '''
    def all_exist():
        return all(os.path.isfile(path) for path in paths)

    def return_missing():
        non_existing = [path for path in paths if not os.path.isfile(path)]
        return non_existing

    if not get_missing:
        return all_exist()

    return pydash.cond([(all_exist, pydash.constant([])),
                        (pydash.stub_true, return_missing)])()
Esempio n. 4
0
        'earth': {
            'rome': 'Republic'
        }
    }, ['earth', 'rome'], lambda value: 'Empire'
      if value == 'Republic' else value), {
          'earth': {
              'rome': 'Empire'
          }
      }),
])
def test_update(case, expected):
    assert _.update(*case) == expected


@parametrize('case,expected', [
    (({}, '[0][1]', _.constant('a'), lambda *_: {}), {
        0: {
            1: 'a'
        }
    }),
    (({}, '[0][1]', _.constant('a'), {}), {
        0: {
            1: 'a'
        }
    }),
    (({}, '[0][1]', 'a', {}), {
        0: {
            1: 'a'
        }
    }),
])
Esempio n. 5
0
def update_with(obj, path, updater, customizer=None):  # noqa: C901
    """
    This method is like :func:`update` except that it accepts customizer which is invoked to produce
    the objects of path. If customizer returns ``None``, path creation is handled by the method
    instead. The customizer is invoked with three arguments: ``(nested_value, key, nested_object)``.

    Args:
        obj (list|dict): Object to modify.
        path (str|list): A string or list of keys that describe the object path to modify.
        updater (callable): Function that returns updated value.
        customizer (callable, optional): The function to customize assigned values.

    Returns:
        mixed: Updated `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> update_with({}, '[0][1]', lambda: 'a', lambda: {})
        {0: {1: 'a'}}

    .. versionadded:: 4.0.0
    """
    if not callable(updater):
        updater = pyd.constant(updater)

    if customizer is not None and not callable(customizer):
        call_customizer = partial(callit, clone, customizer, argcount=1)
    elif customizer:
        call_customizer = partial(callit,
                                  customizer,
                                  argcount=getargcount(customizer, maxargs=3))
    else:
        call_customizer = None

    default_type = dict if isinstance(obj, dict) else list
    tokens = to_path_tokens(path)

    if not pyd.is_list(tokens):  # pragma: no cover
        tokens = [tokens]

    last_key = pyd.last(tokens)

    if isinstance(last_key, PathToken):
        last_key = last_key.key

    target = obj

    for idx, token in enumerate(pyd.initial(tokens)):
        if isinstance(token, PathToken):
            key = token.key
            default_factory = pyd.get(tokens, [idx + 1, "default_factory"],
                                      default=default_type)
        else:
            key = token
            default_factory = default_type

        obj_val = base_get(target, key, default=None)
        path_obj = None

        if call_customizer:
            path_obj = call_customizer(obj_val, key, target)

        if path_obj is None:
            path_obj = default_factory()

        base_set(target, key, path_obj, allow_override=False)

        try:
            target = base_get(target, key, default=None)
        except TypeError as exc:  # pragma: no cover
            try:
                target = target[int(key)]
                _failed = False
            except Exception:
                _failed = True

            if _failed:
                raise TypeError(
                    "Unable to update object at index {!r}. {}".format(
                        key, exc))

    value = base_get(target, last_key, default=None)
    base_set(target, last_key, callit(updater, value))

    return obj
Esempio n. 6
0

@parametrize('case,expected', [((lambda a, b: a / b, 4, 2), 2)])
def test_attempt(case, expected):
    assert _.attempt(*case) == expected


@parametrize('case,expected',
             [((lambda a, b: a / b, 4, 0), ZeroDivisionError)])
def test_attempt_exception(case, expected):
    assert isinstance(_.attempt(*case), expected)


@parametrize(
    'pairs,case,expected',
    [(([_.matches({'b': 2}), _.constant('matches B')
        ], [_.matches({'a': 1}), _.constant('matches A')]), {
            'a': 1,
            'b': 2
        }, 'matches B'),
     (([_.matches({'b': 2}), _.constant('matches B')
        ], [_.matches({'a': 1}), _.invert]), {
            'a': 1,
            'b': 3
        }, {
            1: 'a',
            3: 'b'
        }),
     (([_.matches({'a': 1}), _.constant('matches A')
        ], [_.matches({'b': 2}), _.constant('matches B')]), {
            'a': 1,
Esempio n. 7
0
     {'rome': 'Empire'}),
    (({},
      ['rome'],
      lambda value: 'Empire' if value == 'Republic' else value),
     {'rome': None}),
    (({'earth': {'rome': 'Republic'}},
      ['earth', 'rome'],
      lambda value: 'Empire' if value == 'Republic' else value),
     {'earth': {'rome': 'Empire'}}),
])
def test_update(case, expected):
    assert _.update(*case) == expected


@parametrize('case,expected', [
    (({}, '[0][1]', _.constant('a'), lambda *_: {}), {0: {1: 'a'}}),
    (({}, '[0][1]', _.constant('a'), {}), {0: {1: 'a'}}),
    (({}, '[0][1]', 'a', {}), {0: {1: 'a'}}),
])
def test_update_with(case, expected):
    assert _.update_with(*case) == expected


@parametrize('obj,path,expected,new_obj', [
    ({'a': [{'b': {'c': 7}}]}, 'a.0.b.c', True, {'a': [{'b': {}}]}),
    ([1, 2, 3], '1', True, [1, 3]),
    ([1, 2, 3], 1, True, [1, 3]),
    ([1, [2, 3]], [1, 1], True, [1, [2]]),
    ([1, 2, 3], '[0][0]', False, [1, 2, 3]),
    ([1, 2, 3], '[0][0][0]', False, [1, 2, 3]),
])
Esempio n. 8
0
            {
                "earth": {
                    "rome": "Empire"
                }
            },
        ),
    ],
)
def test_update(case, expected):
    assert _.update(*case) == expected


@parametrize(
    "case,expected",
    [
        (({}, "[0][1]", _.constant("a"), lambda *_: {}), {
            0: {
                1: "a"
            }
        }),
        (({}, "[0][1]", _.constant("a"), {}), {
            0: {
                1: "a"
            }
        }),
        (({}, "[0][1]", "a", {}), {
            0: {
                1: "a"
            }
        }),
    ],
Esempio n. 9
0
def update_with(obj, path, updater, customizer=None):
    """This method is like :func:`update` except that it accepts customizer
    which is invoked to produce the objects of path. If customizer returns
    ``None``, path creation is handled by the method instead. The customizer is
    invoked with three arguments: ``(nested_value, key, nested_object)``.

    Args:
        obj (list|dict): Object to modify.
        path (str|list): A string or list of keys that describe the object path
            to modify.
        updater (function): Function that returns updated value.
        customizer (function, optional): The function to customize assigned
            values.

    Returns:
        mixed: Updated `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> update_with({}, '[0][1]', lambda: 'a', lambda: {})
        {0: {1: 'a'}}

    .. versionadded:: 4.0.0
    """
    if not callable(updater):
        updater = pyd.constant(updater)

    if customizer is not None and not callable(customizer):
        call_customizer = partial(callit, clone, customizer, argcount=1)
    elif customizer:
        call_customizer = partial(callit, customizer,
                                  argcount=getargcount(customizer, maxargs=3))
    else:
        call_customizer = None

    default_type = dict if isinstance(obj, dict) else list
    tokens = to_path_tokens(path)

    if not pyd.is_list(tokens):  # pragma: no cover
        tokens = [tokens]

    last_key = pyd.last(tokens)

    if isinstance(last_key, PathToken):
        last_key = last_key.key

    target = obj

    for idx, token in enumerate(pyd.initial(tokens)):
        if isinstance(token, PathToken):
            key = token.key
            default_factory = pyd.get(tokens,
                                      [idx + 1, 'default_factory'],
                                      default=default_type)
        else:
            key = token
            default_factory = default_type

        obj_val = base_get(target, key, default=None)
        path_obj = None

        if call_customizer:
            path_obj = call_customizer(obj_val, key, target)

        if path_obj is None:
            path_obj = default_factory()

        base_set(target, key, path_obj, allow_override=False)

        try:
            target = target[key]
        except TypeError as exc:  # pragma: no cover
            try:
                target = target[int(key)]
                _failed = False
            except Exception:
                _failed = True

            if _failed:
                raise TypeError('Unable to update object at index {!r}. {}'
                                .format(key, exc))

    value = base_get(target, last_key, default=None)
    base_set(target, last_key, callit(updater, value))

    return obj
Esempio n. 10
0
def test_constant(case):
    assert _.constant(case)() == case
Esempio n. 11
0
@parametrize('case,expected', [
    ((lambda a, b: a / b, 4, 2), 2)
])
def test_attempt(case, expected):
    assert _.attempt(*case) == expected


@parametrize('case,expected', [
    ((lambda a, b: a / b, 4, 0), ZeroDivisionError)
])
def test_attempt_exception(case, expected):
    assert isinstance(_.attempt(*case), expected)


@parametrize('pairs,case,expected', [
    (([_.matches({'b': 2}), _.constant('matches B')],
      [_.matches({'a': 1}), _.constant('matches A')]),
     {'a': 1, 'b': 2},
     'matches B'),
    (([_.matches({'b': 2}), _.constant('matches B')],
      [_.matches({'a': 1}), _.invert]),
     {'a': 1, 'b': 3},
     {1: 'a', 3: 'b'}),
    (([_.matches({'a': 1}), _.constant('matches A')],
      [_.matches({'b': 2}), _.constant('matches B')]),
     {'a': 1, 'b': 2},
     'matches A')
])
def test_cond(pairs, case, expected):
    func = _.cond(*pairs)
    assert func(case) == expected
Esempio n. 12
0
    assert _.attempt(*case) == expected


@parametrize("case,expected",
             [((lambda a, b: a / b, 4, 0), ZeroDivisionError)])
def test_attempt_exception(case, expected):
    assert isinstance(_.attempt(*case), expected)


@parametrize(
    "pairs,case,expected",
    [
        (
            (
                [_.matches({"b": 2}),
                 _.constant("matches B")],
                [_.matches({"a": 1}),
                 _.constant("matches A")],
            ),
            {
                "a": 1,
                "b": 2
            },
            "matches B",
        ),
        (
            ([_.matches({"b": 2}),
              _.constant("matches B")], [_.matches({"a": 1}), _.invert]),
            {
                "a": 1,
                "b": 3
Esempio n. 13
0
                {"earth": {"rome": "Republic"}},
                ["earth", "rome"],
                lambda value: "Empire" if value == "Republic" else value,
            ),
            {"earth": {"rome": "Empire"}},
        ),
    ],
)
def test_update(case, expected):
    assert _.update(*case) == expected


@parametrize(
    "case,expected",
    [
        (({}, "[0][1]", _.constant("a"), lambda *_: {}), {0: {1: "a"}}),
        (({}, "[0][1]", _.constant("a"), {}), {0: {1: "a"}}),
        (({}, "[0][1]", "a", {}), {0: {1: "a"}}),
    ],
)
def test_update_with(case, expected):
    assert _.update_with(*case) == expected


@parametrize(
    "obj,path,expected,new_obj",
    [
        ({"a": [{"b": {"c": 7}}]}, "a.0.b.c", True, {"a": [{"b": {}}]}),
        ([1, 2, 3], "1", True, [1, 3]),
        ([1, 2, 3], 1, True, [1, 3]),
        ([1, [2, 3]], [1, 1], True, [1, [2]]),