-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a75f48a
commit 4892c30
Showing
7 changed files
with
308 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
"""A class to represent a cache of objects.""" | ||
# The MIT License (MIT) | ||
# | ||
# Copyright (c) 2018 Institute for Molecular Systems Biology, ETH Zurich. | ||
# Copyright (c) 2019 Novo Nordisk Foundation Center for Biosustainability, | ||
# Technical University of Denmark | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in | ||
# all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
# THE SOFTWARE. | ||
|
||
from typing import ( | ||
Dict, | ||
List, | ||
TypeVar | ||
) | ||
from logging import ( | ||
Logger, | ||
getLogger, | ||
ERROR | ||
) | ||
from copy import deepcopy | ||
|
||
|
||
class Cache: | ||
|
||
# static and private | ||
__objects = {} | ||
__logger = getLogger(__name__) | ||
__logger.setLevel(ERROR) | ||
|
||
@staticmethod | ||
def set_log_level(level: int) -> None: | ||
Cache.__logger.setLevel(level) | ||
|
||
@staticmethod | ||
def get_log_level() -> None: | ||
return Cache.__logger.level | ||
|
||
@staticmethod | ||
def add(obj: TypeVar, id: str = None) -> None: | ||
''' | ||
Add an object to the cache. | ||
Parameters | ||
---------- | ||
object: TypeVar | ||
The object to add | ||
id: str | ||
ID of the object to add | ||
''' | ||
if id is None: | ||
try: | ||
id = obj.get_id() | ||
except AttributeError: | ||
Cache.__logger.error(f'id is not given and obj has no attribute get_id, nothing added') | ||
Cache.__objects[id] = obj | ||
|
||
@staticmethod | ||
def remove(obj: TypeVar) -> None: | ||
''' | ||
Del an object from the cache. | ||
Parameters | ||
---------- | ||
object: TypeVar | ||
The object to remove | ||
''' | ||
if obj is not None: | ||
try: | ||
# Find object by ID | ||
Cache.remove_object_by_id( | ||
list(Cache.get_objects().keys())[list(Cache.get_objects().values()).index(object)] | ||
) | ||
except ValueError: | ||
Cache.__logger.warning(f'No such object {id} found in cache, nothing deleted.') | ||
else: | ||
Cache.__logger.warning(f'Object passed is None, nothing deleted.') | ||
|
||
@staticmethod | ||
def clean( | ||
) -> None: | ||
''' | ||
Remove all objects from the cache. | ||
''' | ||
for obj_id in Cache.get_list_of_objects(): | ||
Cache.remove_object_by_id(obj_id) | ||
|
||
@staticmethod | ||
def rename(id: str, new_id: str) -> None: | ||
''' | ||
Rename an object of the cache. | ||
Parameters | ||
---------- | ||
id: str | ||
ID of the object to add | ||
''' | ||
if id not in Cache.get_list_of_objects(): | ||
Cache.__logger.warning(f'Compound {id} already in cache, nothing added.') | ||
else: | ||
Cache.__objects[new_id] = deepcopy(Cache.get(id)) | ||
Cache.remove_object_by_id(id) | ||
|
||
@staticmethod | ||
def remove_object_by_id(id: str) -> None: | ||
''' | ||
Del an object from the cache by ID. | ||
Parameters | ||
---------- | ||
id: str | ||
ID of the object to remove | ||
''' | ||
if id in Cache.get_list_of_objects(): | ||
del Cache.__objects[id] | ||
else: | ||
Cache.__logger.warning(f'No such object {id} found in cache, nothing deleted.') | ||
|
||
@staticmethod | ||
def get(id: str) -> TypeVar: | ||
''' | ||
Return the object with ID from the cache | ||
Parameters | ||
---------- | ||
id: str | ||
ID of the object to return from the cache | ||
Returns | ||
------- | ||
object: TypeVar | ||
The object with the given ID | ||
''' | ||
try: | ||
return Cache.get_objects()[id] | ||
except KeyError: | ||
return None | ||
|
||
@staticmethod | ||
def get_objects() -> Dict: | ||
''' | ||
Return a dictionary of all objects in the cache. | ||
Returns | ||
------- | ||
objects: Dict | ||
All objects in the cache | ||
''' | ||
return Cache.__objects | ||
|
||
@staticmethod | ||
def get_list_of_objects() -> List[str]: | ||
''' | ||
Return IDs of all objects in the cache. | ||
Returns | ||
------- | ||
object_ids: List | ||
All object IDs in the cache | ||
''' | ||
return list(Cache.__objects.keys()) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = "1.12.0" | ||
__version__ = "1.13.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
""" | ||
Created on June 17 2020 | ||
@author: Joan Hérisson | ||
""" | ||
|
||
from unittest import TestCase | ||
|
||
from brs_utils import Cache | ||
|
||
|
||
class Test_Cache(TestCase): | ||
|
||
def setUp(self): | ||
self.__d = {'a': 1, 'b': 2} | ||
|
||
def test_add_with_id(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
self.assertDictEqual( | ||
Cache.get('d'), | ||
self.__d | ||
) | ||
|
||
def test_add_wo_id(self): | ||
Cache.clean() | ||
Cache.add(self.__d) | ||
self.assertEqual( | ||
Cache.get('d'), | ||
None | ||
) | ||
|
||
def test_log_level(self): | ||
Cache.clean() | ||
level = 40 | ||
Cache.set_log_level(level) | ||
self.assertEqual( | ||
Cache.get_log_level(), | ||
level | ||
) | ||
|
||
def test_remove(self): | ||
Cache.clean() | ||
self.assertEqual( | ||
Cache.remove('d'), | ||
None | ||
) | ||
|
||
def test_remove_none(self): | ||
Cache.clean() | ||
self.assertEqual( | ||
Cache.remove(None), | ||
None | ||
) | ||
|
||
def test_rename(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
Cache.rename('d', 'd1') | ||
self.assertDictEqual( | ||
Cache.get('d1'), | ||
self.__d | ||
) | ||
self.assertEqual( | ||
Cache.get('d'), | ||
None | ||
) | ||
|
||
def test_rename_wrong_id(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
Cache.rename('d2', 'd1') | ||
self.assertEqual( | ||
Cache.get('d1'), | ||
None | ||
) | ||
self.assertDictEqual( | ||
Cache.get('d'), | ||
self.__d | ||
) | ||
|
||
def test_remove_object_by_id(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
Cache.remove_object_by_id('d') | ||
self.assertEqual( | ||
Cache.get('d'), | ||
None | ||
) | ||
|
||
def test_remove_object_by_wrong_id(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
Cache.remove_object_by_id('d1') | ||
self.assertDictEqual( | ||
Cache.get('d'), | ||
self.__d | ||
) | ||
|
||
def test_get_wrong_id(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
self.assertEqual( | ||
Cache.get('d1'), | ||
None | ||
) | ||
|
||
def test_get_objects(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
self.assertDictEqual( | ||
Cache.get_objects(), | ||
{'d': self.__d} | ||
) | ||
|
||
def test_get_list_of_objects(self): | ||
Cache.clean() | ||
Cache.add(self.__d, 'd') | ||
self.assertListEqual( | ||
Cache.get_list_of_objects(), | ||
['d'] | ||
) | ||
|