diff options
author | Aleksandr <ivansduck@gmail.com> | 2022-02-10 16:47:52 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:52 +0300 |
commit | b05913d1c3c02a773578bceb7285084d2933ae86 (patch) | |
tree | c0748b5dcbade83af788c0abfa89c0383d6b779c /library/python/func | |
parent | ea6c5b7f172becca389cacaff7d5f45f6adccbe6 (diff) | |
download | ydb-b05913d1c3c02a773578bceb7285084d2933ae86.tar.gz |
Restoring authorship annotation for Aleksandr <ivansduck@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'library/python/func')
-rw-r--r-- | library/python/func/__init__.py | 194 | ||||
-rw-r--r-- | library/python/func/ut/test_func.py | 162 | ||||
-rw-r--r-- | library/python/func/ut/ya.make | 22 | ||||
-rw-r--r-- | library/python/func/ya.make | 8 |
4 files changed, 193 insertions, 193 deletions
diff --git a/library/python/func/__init__.py b/library/python/func/__init__.py index e37ea95c7c..7424361635 100644 --- a/library/python/func/__init__.py +++ b/library/python/func/__init__.py @@ -1,6 +1,6 @@ import functools -import threading -import collections +import threading +import collections def map0(func, value): @@ -20,12 +20,12 @@ class _Result(object): def lazy(func): result = _Result() - @functools.wraps(func) - def wrapper(*args): + @functools.wraps(func) + def wrapper(*args): try: return result.result except AttributeError: - result.result = func(*args) + result.result = func(*args) return result.result @@ -64,54 +64,54 @@ class lazy_classproperty(object): return getattr(owner, attr_name) -def memoize(limit=0, thread_local=False): - assert limit >= 0 - +def memoize(limit=0, thread_local=False): + assert limit >= 0 + def decorator(func): - memory = {} - lock = threading.Lock() - - if limit: - keys = collections.deque() - - def get(args): - try: - return memory[args] - except KeyError: - with lock: - if args not in memory: - fargs = args[-1] - memory[args] = func(*fargs) - keys.append(args) - if len(keys) > limit: - del memory[keys.popleft()] - return memory[args] - - else: - - def get(args): - if args not in memory: - with lock: - if args not in memory: - fargs = args[-1] - memory[args] = func(*fargs) - return memory[args] - - if thread_local: - - @functools.wraps(func) - def wrapper(*args): - th = threading.current_thread() - return get((th.ident, th.name, args)) - - else: - - @functools.wraps(func) - def wrapper(*args): - return get(('', '', args)) - - return wrapper - + memory = {} + lock = threading.Lock() + + if limit: + keys = collections.deque() + + def get(args): + try: + return memory[args] + except KeyError: + with lock: + if args not in memory: + fargs = args[-1] + memory[args] = func(*fargs) + keys.append(args) + if len(keys) > limit: + del memory[keys.popleft()] + return memory[args] + + else: + + def get(args): + if args not in memory: + with lock: + if args not in memory: + fargs = args[-1] + memory[args] = func(*fargs) + return memory[args] + + if thread_local: + + @functools.wraps(func) + def wrapper(*args): + th = threading.current_thread() + return get((th.ident, th.name, args)) + + else: + + @functools.wraps(func) + def wrapper(*args): + return get(('', '', args)) + + return wrapper + return decorator @@ -119,52 +119,52 @@ def memoize(limit=0, thread_local=False): def compose(*functions): def compose2(f, g): return lambda x: f(g(x)) - + return functools.reduce(compose2, functions, lambda x: x) - - -class Singleton(type): - _instances = {} - - def __call__(cls, *args, **kwargs): - if cls not in cls._instances: - cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) - return cls._instances[cls] - - -def stable_uniq(it): - seen = set() - res = [] - for e in it: - if e not in seen: - res.append(e) - seen.add(e) - return res - - -def first(it): - for d in it: - if d: - return d - - -def split(data, func): - l, r = [], [] - for e in data: - if func(e): - l.append(e) - else: - r.append(e) - return l, r + + +class Singleton(type): + _instances = {} + + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instances[cls] + + +def stable_uniq(it): + seen = set() + res = [] + for e in it: + if e not in seen: + res.append(e) + seen.add(e) + return res + + +def first(it): + for d in it: + if d: + return d + + +def split(data, func): + l, r = [], [] + for e in data: + if func(e): + l.append(e) + else: + r.append(e) + return l, r def flatten_dict(dd, separator='.', prefix=''): - return ( - { - prefix + separator + k if prefix else k: v - for kk, vv in dd.items() - for k, v in flatten_dict(vv, separator, kk).items() - } - if isinstance(dd, dict) - else {prefix: dd} - ) + return ( + { + prefix + separator + k if prefix else k: v + for kk, vv in dd.items() + for k, v in flatten_dict(vv, separator, kk).items() + } + if isinstance(dd, dict) + else {prefix: dd} + ) diff --git a/library/python/func/ut/test_func.py b/library/python/func/ut/test_func.py index d283402374..3c4fad1a07 100644 --- a/library/python/func/ut/test_func.py +++ b/library/python/func/ut/test_func.py @@ -1,13 +1,13 @@ import pytest -import threading +import threading import library.python.func as func def test_map0(): - assert None is func.map0(lambda x: x + 1, None) + assert None is func.map0(lambda x: x + 1, None) assert 3 == func.map0(lambda x: x + 1, 2) - assert None is func.map0(len, None) + assert None is func.map0(len, None) assert 2 == func.map0(len, [1, 2]) @@ -26,34 +26,34 @@ def test_memoize(): Counter._qty = getattr(Counter, '_qty', 0) + 1 return Counter._qty - @func.memoize() + @func.memoize() def t1(a): return a, Counter.inc() - @func.memoize() + @func.memoize() def t2(a): return a, Counter.inc() - @func.memoize() + @func.memoize() def t3(a): return a, Counter.inc() - @func.memoize() + @func.memoize() def t4(a): return a, Counter.inc() - @func.memoize() + @func.memoize() def t5(a, b, c): return a + b + c, Counter.inc() - @func.memoize() + @func.memoize() def t6(): return Counter.inc() - @func.memoize(limit=2) - def t7(a, _b): - return a, Counter.inc() - + @func.memoize(limit=2) + def t7(a, _b): + return a, Counter.inc() + assert (1, 1) == t1(1) assert (1, 1) == t1(1) assert (2, 2) == t1(2) @@ -82,48 +82,48 @@ def test_memoize(): assert 11 == t6() assert 11 == t6() - assert (1, 12) == t7(1, None) - assert (2, 13) == t7(2, None) - assert (1, 12) == t7(1, None) - assert (2, 13) == t7(2, None) - # removed result for (1, None) - assert (3, 14) == t7(3, None) - assert (1, 15) == t7(1, None) - - class ClassWithMemoizedMethod(object): - def __init__(self): - self.a = 0 - - @func.memoize(True) - def t(self, i): - self.a += i - return i - - obj = ClassWithMemoizedMethod() - assert 10 == obj.t(10) - assert 10 == obj.a - assert 10 == obj.t(10) - assert 10 == obj.a - - assert 20 == obj.t(20) - assert 30 == obj.a - assert 20 == obj.t(20) - assert 30 == obj.a - - -def test_first(): - assert func.first([0, [], (), None, False, {}, 0.0, '1', 0]) == '1' - assert func.first([]) is None - assert func.first([0]) is None - - -def test_split(): - assert func.split([1, 1], lambda x: x) == ([1, 1], []) - assert func.split([0, 0], lambda x: x) == ([], [0, 0]) - assert func.split([], lambda x: x) == ([], []) - assert func.split([1, 0, 1], lambda x: x) == ([1, 1], [0]) - - + assert (1, 12) == t7(1, None) + assert (2, 13) == t7(2, None) + assert (1, 12) == t7(1, None) + assert (2, 13) == t7(2, None) + # removed result for (1, None) + assert (3, 14) == t7(3, None) + assert (1, 15) == t7(1, None) + + class ClassWithMemoizedMethod(object): + def __init__(self): + self.a = 0 + + @func.memoize(True) + def t(self, i): + self.a += i + return i + + obj = ClassWithMemoizedMethod() + assert 10 == obj.t(10) + assert 10 == obj.a + assert 10 == obj.t(10) + assert 10 == obj.a + + assert 20 == obj.t(20) + assert 30 == obj.a + assert 20 == obj.t(20) + assert 30 == obj.a + + +def test_first(): + assert func.first([0, [], (), None, False, {}, 0.0, '1', 0]) == '1' + assert func.first([]) is None + assert func.first([0]) is None + + +def test_split(): + assert func.split([1, 1], lambda x: x) == ([1, 1], []) + assert func.split([0, 0], lambda x: x) == ([], [0, 0]) + assert func.split([], lambda x: x) == ([], []) + assert func.split([1, 0, 1], lambda x: x) == ([1, 1], [0]) + + def test_flatten_dict(): assert func.flatten_dict({"a": 1, "b": 2}) == {"a": 1, "b": 2} assert func.flatten_dict({"a": 1}) == {"a": 1} @@ -132,31 +132,31 @@ def test_flatten_dict(): assert func.flatten_dict({"a": 1, "b": {"c": {"d": 2}}}, separator="/") == {"a": 1, "b/c/d": 2} -def test_memoize_thread_local(): - class Counter(object): - def __init__(self, s): - self.val = s - - def inc(self): - self.val += 1 - return self.val - - @func.memoize(thread_local=True) - def get_counter(start): - return Counter(start) - - def th_inc(): - assert get_counter(0).inc() == 1 - assert get_counter(0).inc() == 2 - assert get_counter(10).inc() == 11 - assert get_counter(10).inc() == 12 - - th_inc() - - th = threading.Thread(target=th_inc) - th.start() - th.join() - - +def test_memoize_thread_local(): + class Counter(object): + def __init__(self, s): + self.val = s + + def inc(self): + self.val += 1 + return self.val + + @func.memoize(thread_local=True) + def get_counter(start): + return Counter(start) + + def th_inc(): + assert get_counter(0).inc() == 1 + assert get_counter(0).inc() == 2 + assert get_counter(10).inc() == 11 + assert get_counter(10).inc() == 12 + + th_inc() + + th = threading.Thread(target=th_inc) + th.start() + th.join() + + if __name__ == '__main__': pytest.main([__file__]) diff --git a/library/python/func/ut/ya.make b/library/python/func/ut/ya.make index 4d7e8b8f5b..5ec6c1225e 100644 --- a/library/python/func/ut/ya.make +++ b/library/python/func/ut/ya.make @@ -1,11 +1,11 @@ -OWNER(g:yatool) - -PY23_TEST() - -TEST_SRCS(test_func.py) - -PEERDIR( - library/python/func -) - -END() +OWNER(g:yatool) + +PY23_TEST() + +TEST_SRCS(test_func.py) + +PEERDIR( + library/python/func +) + +END() diff --git a/library/python/func/ya.make b/library/python/func/ya.make index 2f7b4890db..9d414a976e 100644 --- a/library/python/func/ya.make +++ b/library/python/func/ya.make @@ -5,7 +5,7 @@ PY23_LIBRARY() PY_SRCS(__init__.py) END() - -RECURSE_FOR_TESTS( - ut -) + +RECURSE_FOR_TESTS( + ut +) |