Files
OpenBB/build/pyinstaller/property_cached/__init__.py
Theodore Aptekarev ab4de1dd70 Create a packaged app bundle with Pyinstaller (#1525)
* Add dashboard widget assets

* Add ipywidgets and ipyflex to project

* Add currencies dashboard notebook

* Update docs and docstrings

* Add pyinstaller to project deps

* Add pyinstaller artifacts to gitignore

* Fix linter errors in terminal.py

* Update cspell hook and action with a pyinstaller specific word

* Add pyinstaller specfile and artifacts

* Add splashscreen image

* Add app icon

* adding splash screen support to terminal.spec and terminal.py

* Restore the conda env build files

* Sync deps

* Add border to the splashscreen image

* Clean up terminal launcher

* Add support for default feature flags in packages apps

* Fix types and linting

* Add splashscreen management to app bootup

* Check prediction feature flag when entering crypto/pred

* Update pyinstaller spec file

* fix .spec file to work for splash and icon - removed the ".."

* Allows to export when using installer (#1568)

* fix export for packaged apps

* fix filename

* Git : replace commit_hash when it is set in config_terminal

* Add update of the git commit hash in gtff default during build

* Add packaged app name and feature flag to logs

* Add platform specific icon assignment

* Add macOS build assets

* Add tensorflow to hidden imports

* Move LOGGING_COMMIT_HASH to gtff

* Adding files/folders needed to .spec  and pyinstaller folder. This will make certain commands work again.

* Linting

* Workflow : ignore ./build/pyinstaller from codespell

* Workflow : exclude ./build/pyinstaller from flake8

* Poetry + Workflow : add types-six

* Pyinstaller : remove property_cached, user_agent and vaderSentiment

* Revert "Pyinstaller : remove property_cached, user_agent and vaderSentiment"

This reverts commit dbb3e2b810.

* Clean up local paths in specfile

* Validate deps have correct Jinja version (they do)

* Fix logging commit hash to be set correctly for the logger to see it

Co-authored-by: Andrew <andrew.kenreich@gmail.com>
Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
Co-authored-by: Chavithra PARANA <chavithra@gmail.com>
2022-03-29 02:35:56 +03:00

162 lines
4.3 KiB
Python

import asyncio
import functools
import pkg_resources
import threading
import weakref
from time import time
# pylint: skip-file
__author__ = "Martin Larralde"
__email__ = "martin.larralde@ens-paris-saclay.fr"
__license__ = "BSD"
__version__ = (
pkg_resources.resource_string(__name__, "_version.txt").decode("utf-8").strip()
)
class cached_property(property):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Deleting the attribute resets the property.
Source: https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76
""" # noqa
_sentinel = object()
_update_wrapper = functools.update_wrapper
def __init__(self, func):
self.cache = weakref.WeakKeyDictionary()
self.func = func
self._update_wrapper(func)
def __get__(self, obj, cls):
if obj is None:
return self
if asyncio and asyncio.iscoroutinefunction(self.func):
return self._wrap_in_coroutine(obj)
value = self.cache.get(obj, self._sentinel)
if value is self._sentinel:
value = self.cache[obj] = self.func(obj)
return value
def __set_name__(self, owner, name):
self.__name__ = name
def __set__(self, obj, value):
self.cache[obj] = value
def __delete__(self, obj):
del self.cache[obj]
def _wrap_in_coroutine(self, obj):
@functools.wraps(obj)
@asyncio.coroutine
def wrapper():
value = self.cache.get(obj, self._sentinel)
if value is self._sentinel:
self.cache[obj] = value = asyncio.ensure_future(self.func(obj))
return value
return wrapper()
class threaded_cached_property(cached_property):
"""
A cached_property version for use in environments where multiple threads
might concurrently try to access the property.
"""
def __init__(self, func):
super().__init__(func)
self.lock = threading.RLock()
def __get__(self, obj, cls):
if obj is None:
return self
with self.lock:
return super().__get__(obj, cls)
def __set__(self, obj, value):
with self.lock:
super().__set__(obj, value)
def __delete__(self, obj):
with self.lock:
super().__delete__(obj)
class cached_property_with_ttl(cached_property):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Setting the ttl to a number expresses how long
the property will last before being timed out.
"""
def __init__(self, ttl=None):
if callable(ttl):
func = ttl
ttl = None
else:
func = None
self.ttl = ttl
super().__init__(func)
def __call__(self, func):
super().__init__(func)
return self
def __get__(self, obj, cls):
if obj is None:
return self
now = time()
if obj in self.cache:
value, last_updated = self.cache[obj]
if not self.ttl or self.ttl > now - last_updated:
return value
value, _ = self.cache[obj] = (self.func(obj), now)
return value
def __set__(self, obj, value):
super().__set__(obj, (value, time()))
# Aliases to make cached_property_with_ttl easier to use
cached_property_ttl = cached_property_with_ttl
timed_cached_property = cached_property_with_ttl
class threaded_cached_property_with_ttl(
cached_property_with_ttl, threaded_cached_property
):
"""
A cached_property version for use in environments where multiple threads
might concurrently try to access the property.
"""
def __init__(self, ttl=None):
super().__init__(ttl)
self.lock = threading.RLock()
def __get__(self, obj, cls):
with self.lock:
return super().__get__(obj, cls)
def __set__(self, obj, value):
with self.lock:
return super().__set__(obj, value)
def __delete__(self, obj):
with self.lock:
return super().__delete__(obj)
# Alias to make threaded_cached_property_with_ttl easier to use
threaded_cached_property_ttl = threaded_cached_property_with_ttl
timed_threaded_cached_property = threaded_cached_property_with_ttl