Submit
Path:
~
/
/
opt
/
alt
/
python38
/
lib
/
python3.8
/
site-packages
/
File Content:
async_lru.py
import asyncio from collections import OrderedDict from functools import _CacheInfo, _make_key, partial, wraps try: from asyncio import ensure_future except ImportError: # pragma: no cover ensure_future = getattr(asyncio, 'async') __version__ = '1.0.2' __all__ = ('alru_cache',) def create_future(*, loop): try: return loop.create_future() except AttributeError: return asyncio.Future(loop=loop) def unpartial(fn): while hasattr(fn, 'func'): fn = fn.func return fn def _done_callback(fut, task): if task.cancelled(): fut.cancel() return exc = task.exception() if exc is not None: fut.set_exception(exc) return fut.set_result(task.result()) def _cache_invalidate(wrapped, typed, *args, **kwargs): key = _make_key(args, kwargs, typed) exists = key in wrapped._cache if exists: wrapped._cache.pop(key) return exists def _cache_clear(wrapped): wrapped.hits = wrapped.misses = 0 wrapped._cache = OrderedDict() wrapped.tasks = set() def _open(wrapped): if not wrapped.closed: raise RuntimeError('alru_cache is not closed') was_closed = ( wrapped.hits == wrapped.misses == len(wrapped.tasks) == len(wrapped._cache) == 0 ) if not was_closed: raise RuntimeError('alru_cache was not closed correctly') wrapped.closed = False def _close(wrapped, *, cancel=False, return_exceptions=True, loop=None): if wrapped.closed: raise RuntimeError('alru_cache is closed') wrapped.closed = True if cancel: for task in wrapped.tasks: if not task.done(): # not sure is it possible task.cancel() return _wait_closed( wrapped, return_exceptions=return_exceptions, loop=loop ) @asyncio.coroutine def _wait_closed(wrapped, *, return_exceptions, loop): if loop is None: loop = asyncio.get_event_loop() wait_closed = asyncio.gather( *wrapped.tasks, return_exceptions=return_exceptions, loop=loop ) wait_closed.add_done_callback(partial(_close_waited, wrapped)) ret = yield from wait_closed # hack to get _close_waited callback to be executed yield from asyncio.sleep(0, loop=loop) return ret def _close_waited(wrapped, _): wrapped.cache_clear() def _cache_info(wrapped, maxsize): return _CacheInfo( wrapped.hits, wrapped.misses, maxsize, len(wrapped._cache), ) def __cache_touch(wrapped, key): try: wrapped._cache.move_to_end(key) except KeyError: # not sure is it possible pass def _cache_hit(wrapped, key): wrapped.hits += 1 __cache_touch(wrapped, key) def _cache_miss(wrapped, key): wrapped.misses += 1 __cache_touch(wrapped, key) def _get_loop(cls, kwargs, fn, fn_args, fn_kwargs, *, loop): if isinstance(loop, str): assert cls ^ kwargs, 'choose self.loop or kwargs["loop"]' if cls: _self = getattr(fn, '__self__', None) if _self is None: assert fn_args, 'seems not unbound function' _self = fn_args[0] _loop = getattr(_self, loop) else: _loop = fn_kwargs[loop] elif loop is None: _loop = asyncio.get_event_loop() else: _loop = loop return _loop def alru_cache( fn=None, maxsize=128, typed=False, *, cls=False, kwargs=False, cache_exceptions=True, loop=None ): def wrapper(fn): _origin = unpartial(fn) if not asyncio.iscoroutinefunction(_origin): raise RuntimeError( 'Coroutine function is required, got {}'.format(fn)) # functools.partialmethod support if hasattr(fn, '_make_unbound_method'): fn = fn._make_unbound_method() @wraps(fn) @asyncio.coroutine def wrapped(*fn_args, **fn_kwargs): if wrapped.closed: raise RuntimeError( 'alru_cache is closed for {}'.format(wrapped)) _loop = _get_loop( cls, kwargs, wrapped._origin, fn_args, fn_kwargs, loop=loop ) key = _make_key(fn_args, fn_kwargs, typed) fut = wrapped._cache.get(key) if fut is not None: if not fut.done(): _cache_hit(wrapped, key) return (yield from asyncio.shield(fut, loop=_loop)) exc = fut._exception if exc is None or cache_exceptions: _cache_hit(wrapped, key) return fut.result() # exception here and cache_exceptions == False wrapped._cache.pop(key) fut = create_future(loop=_loop) coro = fn(*fn_args, **fn_kwargs) task = ensure_future(coro, loop=_loop) task.add_done_callback(partial(_done_callback, fut)) wrapped.tasks.add(task) task.add_done_callback(wrapped.tasks.remove) wrapped._cache[key] = fut if maxsize is not None and len(wrapped._cache) > maxsize: wrapped._cache.popitem(last=False) _cache_miss(wrapped, key) return (yield from asyncio.shield(fut, loop=_loop)) _cache_clear(wrapped) wrapped._origin = _origin wrapped.closed = False wrapped.cache_info = partial(_cache_info, wrapped, maxsize) wrapped.cache_clear = partial(_cache_clear, wrapped) wrapped.invalidate = partial(_cache_invalidate, wrapped, typed) wrapped.close = partial(_close, wrapped) wrapped.open = partial(_open, wrapped) return wrapped if fn is None: return wrapper if callable(fn) or hasattr(fn, '_make_unbound_method'): return wrapper(fn) raise NotImplementedError('{} decorating is not supported'.format(fn))
Edit
Rename
Chmod
Delete
FILE
FOLDER
Name
Size
Permission
Action
Babel-2.9.1-py3.8.egg-info
---
0755
Cerberus-1.3.4-py3.8.egg-info
---
0755
Jinja2-3.0.3-py3.8.egg-info
---
0755
PyJWT-2.1.0-py3.8.egg-info
---
0755
PyMySQL-0.7.11-py3.8.egg-info
---
0755
__pycache__
---
0755
_distutils_hack
---
0755
aiodns
---
0755
aiodns-3.0.0-py3.8.egg-info
---
0755
asn1crypto
---
0755
asn1crypto-0.22.0-py3.8.egg-info
---
0755
async_lru-1.0.2-py3.8.egg-info
---
0755
async_timeout
---
0755
async_timeout-1.3.0-py3.8.egg-info
---
0755
attr
---
0755
attrs-17.4.0-py3.8.egg-info
---
0755
babel
---
0755
blinker
---
0755
blinker-1.4-py3.8.egg-info
---
0755
cached_property-1.3.0-py3.8.egg-info
---
0755
cerberus
---
0755
certifi
---
0755
certifi-2018.4.16-py3.8.egg-info
---
0755
chardet
---
0755
chardet-3.0.4-py3.8.egg-info
---
0755
click
---
0755
click-6.6-py3.8.egg-info
---
0755
daemon
---
0755
dateutil
---
0755
distro-1.6.0-py3.8.egg-info
---
0755
funcsigs
---
0755
funcsigs-1.0.2-py3.8.egg-info
---
0755
geoip2
---
0755
geoip2-4.2.0-py3.8.egg-info
---
0755
humanize
---
0755
humanize-0.0.0-py3.8.egg-info
---
0755
idna
---
0755
idna-2.5-py3.8.egg-info
---
0755
jinja2
---
0755
jsonschema
---
0755
jsonschema-3.2.0-py3.8.egg-info
---
0755
jwt
---
0755
lockfile
---
0755
lockfile-0.12.2-py3.8.egg-info
---
0755
mock
---
0755
mock-3.0.5-py3.8.egg-info
---
0755
packaging
---
0755
packaging-16.8-py3.8.egg-info
---
0755
pbr
---
0755
pbr-1.8.1-py3.8.egg-info
---
0755
peewee_migrate
---
0755
peewee_migrate-0.6.4-py3.8.egg-info
---
0755
pip
---
0755
pip-20.2.4.dist-info
---
0755
pkg_resources
---
0755
ply
---
0755
ply-3.8-py3.8.egg-info
---
0755
pycparser
---
0755
pycparser-2.14-py3.8.egg-info
---
0755
pymysql
---
0755
pyparsing-2.1.10-py3.8.egg-info
---
0755
python_daemon-2.3.0-py3.8.egg-info
---
0755
python_dateutil-2.6.0-py3.8.egg-info
---
0755
python_pam-1.8.4-py3.8.egg-info
---
0755
pytz
---
0755
pytz-2017.2-py3.8.egg-info
---
0755
requests
---
0755
requests-2.26.0-py3.8.egg-info
---
0755
sdnotify
---
0755
sentry_sdk
---
0755
sentry_sdk-0.7.10-py3.8.egg-info
---
0755
setuptools
---
0755
setuptools-57.4.0.dist-info
---
0755
six-1.12.0-py3.8.egg-info
---
0755
typing_extensions-3.7.4.3-py3.8.egg-info
---
0755
urllib3
---
0755
urllib3-1.26.6-py3.8.egg-info
---
0755
PySocks-1.5.7-py3.8.egg-info
322 bytes
0644
async_lru.py
6124 bytes
0644
cached_property.py
3900 bytes
0644
distro.py
48414 bytes
0644
distutils-precedence.pth
152 bytes
0644
pam.py
7556 bytes
0644
pyparsing.py
229867 bytes
0644
sdnotify-0.3.2-py3.8.egg-info
1133 bytes
0644
six.py
32452 bytes
0644
socks.py
29952 bytes
0644
sockshandler.py
2913 bytes
0644
typing_extensions.py
83727 bytes
0644
N4ST4R_ID | Naxtarrr