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)
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)
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)])()
'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 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
@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,
{'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]), ])
{ "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 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
def test_constant(case): assert _.constant(case)() == case
@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
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
{"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]]),