forked from cython/cython
-
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.
Add
clear_method_caches
to Utils.py (cython#4338)
* Utils.py: add _find_cache_attributes, clear_method_caches * TestCythonUtils.py: add tests for Cached Methods * Utils.py: add constants * Utils.py: update comment * TestCythonUtils.py: remove excess blank line * Change names to `_CACHE_NAME` and `_CACHE_NAME_PATTERN` * ci.yml: extend timeout to 40 minutes * _CACHE_NAME -> _build_cache_name
- Loading branch information
1 parent
db19667
commit cfb8879
Showing
3 changed files
with
115 additions
and
4 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 |
---|---|---|
@@ -1,10 +1,96 @@ | ||
import unittest | ||
|
||
from ..Utils import build_hex_version | ||
from Cython.Utils import ( | ||
_CACHE_NAME_PATTERN, _build_cache_name, _find_cache_attributes, | ||
build_hex_version, cached_method, clear_method_caches) | ||
|
||
METHOD_NAME = "cached_next" | ||
CACHE_NAME = _build_cache_name(METHOD_NAME) | ||
NAMES = CACHE_NAME, METHOD_NAME | ||
|
||
class Cached(object): | ||
@cached_method | ||
def cached_next(self, x): | ||
return next(x) | ||
|
||
|
||
class TestCythonUtils(unittest.TestCase): | ||
def test_build_hex_version(self): | ||
self.assertEqual('0x001D00A1', build_hex_version('0.29a1')) | ||
self.assertEqual('0x001D03C4', build_hex_version('0.29.3rc4')) | ||
self.assertEqual('0x001D00F0', build_hex_version('0.29')) | ||
self.assertEqual('0x040000F0', build_hex_version('4.0')) | ||
|
||
############################## Cached Methods ############################## | ||
|
||
def test_cache_method_name(self): | ||
method_name = "foo" | ||
cache_name = _build_cache_name(method_name) | ||
match = _CACHE_NAME_PATTERN.match(cache_name) | ||
|
||
self.assertIsNot(match, None) | ||
self.assertEqual(match.group(1), method_name) | ||
|
||
def test_requirements_for_Cached(self): | ||
obj = Cached() | ||
|
||
self.assertFalse(hasattr(obj, CACHE_NAME)) | ||
self.assertTrue(hasattr(obj, METHOD_NAME)) | ||
self.set_of_names_equal(obj, set()) | ||
|
||
def set_of_names_equal(self, obj, value): | ||
self.assertEqual(set(_find_cache_attributes(obj)), value) | ||
|
||
def test_find_cache_attributes(self): | ||
obj = Cached() | ||
method_name = "bar" | ||
cache_name = _build_cache_name(method_name) | ||
|
||
setattr(obj, CACHE_NAME, {}) | ||
setattr(obj, cache_name, {}) | ||
|
||
self.assertFalse(hasattr(obj, method_name)) | ||
self.set_of_names_equal(obj, {NAMES, (cache_name, method_name)}) | ||
|
||
def test_cached_method(self): | ||
obj = Cached() | ||
value = iter(range(3)) # iter for Py2 | ||
cache = {(value,): 0} | ||
|
||
# cache args | ||
self.assertEqual(obj.cached_next(value), 0) | ||
self.set_of_names_equal(obj, {NAMES}) | ||
self.assertEqual(getattr(obj, CACHE_NAME), cache) | ||
|
||
# use cache | ||
self.assertEqual(obj.cached_next(value), 0) | ||
self.set_of_names_equal(obj, {NAMES}) | ||
self.assertEqual(getattr(obj, CACHE_NAME), cache) | ||
|
||
def test_clear_method_caches(self): | ||
obj = Cached() | ||
value = iter(range(3)) # iter for Py2 | ||
cache = {(value,): 1} | ||
|
||
obj.cached_next(value) # cache args | ||
|
||
clear_method_caches(obj) | ||
self.set_of_names_equal(obj, set()) | ||
|
||
self.assertEqual(obj.cached_next(value), 1) | ||
self.set_of_names_equal(obj, {NAMES}) | ||
self.assertEqual(getattr(obj, CACHE_NAME), cache) | ||
|
||
def test_clear_method_caches_with_missing_method(self): | ||
obj = Cached() | ||
method_name = "bar" | ||
cache_name = _build_cache_name(method_name) | ||
names = cache_name, method_name | ||
|
||
setattr(obj, cache_name, object()) | ||
|
||
self.assertFalse(hasattr(obj, method_name)) | ||
self.set_of_names_equal(obj, {names}) | ||
|
||
clear_method_caches(obj) | ||
self.set_of_names_equal(obj, {names}) |
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