Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop cachetools deps, use functools.lru_cache #647

Merged
merged 1 commit into from Jun 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 22 additions & 27 deletions diofant/core/cache.py
@@ -1,9 +1,8 @@
""" Caching facility for Diofant """

import functools
import os

from cachetools import cached

from .evaluate import global_evaluate


Expand All @@ -14,37 +13,20 @@
def print_cache():
"""Print cache content"""

for item, cache in CACHE:
item = str(item)

if cache:
head = '='*len(item)
print(head)
print(item)
print(head)

for k, v in list(cache.items()):
print(' %s : %s' % (k, v))
for item in CACHE:
print(item.__qualname__, item.cache_info())


def clear_cache():
"""Clear cache content"""
for item, cache in CACHE:
cache.clear()


def cache_key(*args, **kwargs):
key = [(x, type(x)) for x in args]
if kwargs:
key.extend([(x, kwargs[x], type(kwargs[x])) for x in sorted(kwargs)])
key.extend([tuple(global_evaluate)])
return tuple(key)
for item in CACHE:
item.cache_clear()


USE_CACHE = os.getenv('DIOFANT_USE_CACHE', 'True') == 'True'


def cacheit(f):
def cacheit(f, maxsize=None):
"""Caching decorator.

The result of cached function must be *immutable*.
Expand All @@ -65,8 +47,21 @@ def cacheit(f):
"""

if USE_CACHE:
f_cache_it_cache = {}
CACHE.append((f, f_cache_it_cache))
return cached(f_cache_it_cache, key=cache_key)(f)
cfunc = functools.lru_cache(maxsize=maxsize, typed=True)(f)

def wrapper(*args, **kwargs):
try:
if global_evaluate[0] and kwargs.get('evaluate', True):
return cfunc(*args, **kwargs)
except TypeError:
pass
return f(*args, **kwargs)

wrapper.cache_info = cfunc.cache_info
wrapper.cache_clear = cfunc.cache_clear
functools.update_wrapper(wrapper, f)

CACHE.append(wrapper)
return wrapper
else:
return f
13 changes: 4 additions & 9 deletions diofant/core/tests/test_cache.py
Expand Up @@ -5,9 +5,9 @@
import pytest

from diofant.abc import x
from diofant.core.cache import CACHE, cacheit, clear_cache, print_cache
from diofant.core.cache import cacheit, clear_cache, print_cache
from diofant.core.compatibility import ordered
from diofant.core.symbol import Symbol, symbols
from diofant.core.symbol import symbols
from diofant.printing.str import sstr


Expand Down Expand Up @@ -37,16 +37,11 @@ def test_cacheit():

def test_print_cache(capfd):
clear_cache()
wrapped = _identity.__wrapped__
_identity(x)
item = str(wrapped)
head = '='*len(item)
res = (head + "\n" + item + "\n" + head + "\n" +
" ((Symbol('x'), <class 'diofant.core.symbol.Symbol'>), (True,)) : x\n")
info = _identity.cache_info()
print_cache()
resout, _ = capfd.readouterr()
assert resout == res
assert dict(CACHE)[wrapped] == {((x, Symbol), (True,)): x}
assert resout.find('_identity ' + str(info)) >= 0


@pytest.fixture(scope='function')
Expand Down
7 changes: 0 additions & 7 deletions diofant/polys/densebasic.py
Expand Up @@ -1277,10 +1277,3 @@ def dup_random(n, a, b, K, percent=None):
f.insert(0, lt)

return f


def dmp_cache_key(*args, **kwargs):
"""Return a cache key, assuming dense recursive polynomials in some arguments. """
new_args = [dmp_to_tuple(p, dmp_validate(p)[1]) if isinstance(p, list) else p
for p in args]
return tuple(new_args + [(str(x), kwargs[x]) for x in sorted(kwargs)])
14 changes: 6 additions & 8 deletions diofant/polys/euclidtools.py
@@ -1,17 +1,15 @@
"""Euclidean algorithms, GCDs, LCMs and polynomial remainder sequences. """

import cachetools

from ..core import cacheit
from ..ntheory import nextprime
from .densearith import (dmp_add, dmp_div, dmp_max_norm, dmp_mul,
dmp_mul_ground, dmp_mul_term, dmp_neg, dmp_pow,
dmp_prem, dmp_quo, dmp_quo_ground, dmp_rem, dmp_sub,
dmp_sub_mul, dup_mul, dup_prem)
from .densebasic import (dmp_apply_pairs, dmp_cache_key, dmp_convert,
dmp_degree, dmp_degree_in, dmp_ground, dmp_ground_LC,
dmp_inflate, dmp_LC, dmp_multi_deflate, dmp_one,
dmp_one_p, dmp_raise, dmp_strip, dmp_zero, dmp_zero_p,
dmp_zeros)
from .densebasic import (dmp_apply_pairs, dmp_convert, dmp_degree,
dmp_degree_in, dmp_ground, dmp_ground_LC, dmp_inflate,
dmp_LC, dmp_multi_deflate, dmp_one, dmp_one_p,
dmp_raise, dmp_strip, dmp_zero, dmp_zero_p, dmp_zeros)
from .densetools import (dmp_clear_denoms, dmp_diff, dmp_eval, dmp_eval_in,
dmp_ground_extract, dmp_ground_monic,
dmp_ground_primitive, dmp_ground_trunc,
Expand Down Expand Up @@ -636,7 +634,7 @@ def dmp_qq_collins_resultant(f, g, u, K0):
return dmp_quo_ground(r, c, u - 1, K0)


@cachetools.cached({}, key=dmp_cache_key)
@cacheit
def dmp_resultant(f, g, u, K, includePRS=False):
"""
Computes resultant of two polynomials in `K[X]`.
Expand Down
4 changes: 3 additions & 1 deletion diofant/polys/rootisolation.py
Expand Up @@ -3,7 +3,8 @@
from ..core import I
from .densearith import dmp_neg, dmp_rem, dup_rshift
from .densebasic import (dmp_convert, dmp_degree, dmp_LC, dmp_permute,
dmp_strip, dmp_TC, dmp_terms_gcd, dup_reverse)
dmp_strip, dmp_TC, dmp_terms_gcd, dmp_to_tuple,
dup_reverse)
from .densetools import (dmp_compose, dmp_eval_in, dup_clear_denoms, dup_diff,
dup_eval, dup_mirror, dup_real_imag, dup_scale,
dup_shift, dup_sign_variations, dup_transform)
Expand Down Expand Up @@ -1857,6 +1858,7 @@ def is_disjoint(self, other, check_re_refinement=False, re_disjoint=False):
for i in (self, other):
re = dmp_permute(i.f1, [1, 0], 1, i.domain)
im = dmp_permute(i.f2, [1, 0], 1, i.domain)
re, im = map(lambda x: dmp_to_tuple(x, 1), [re, im])
resultants.append(dmp_resultant(re, im, 1, i.domain))
dom = self.domain.unify(other.domain)
gcd = dmp_gcd(*resultants, 0, dom)
Expand Down
10 changes: 2 additions & 8 deletions diofant/polys/tests/test_densebasic.py
Expand Up @@ -6,9 +6,8 @@

from diofant import Integer, Rational, oo
from diofant.domains import FF, QQ, ZZ
from diofant.polys.densebasic import (dmp_apply_pairs, dmp_cache_key,
dmp_convert, dmp_copy, dmp_deflate,
dmp_degree, dmp_degree_in,
from diofant.polys.densebasic import (dmp_apply_pairs, dmp_convert, dmp_copy,
dmp_deflate, dmp_degree, dmp_degree_in,
dmp_degree_list, dmp_eject, dmp_exclude,
dmp_from_dict, dmp_from_diofant,
dmp_ground, dmp_ground_LC,
Expand Down Expand Up @@ -730,8 +729,3 @@ def test_dup_random():
f = dup_random(3, -10, 10, ZZ, percent=50)
assert f[0]
assert len([c for c in f if c == 0]) == 2


def test_dmp_cache_key():
assert dmp_cache_key([[1], [2, 1]], [3, 1], ZZ,
spam=True) == (((1,), (2, 1)), (3, 1), ZZ, ('spam', True))
2 changes: 2 additions & 0 deletions docs/release/notes-0.10.rst
Expand Up @@ -52,6 +52,8 @@ Minor changes
Developer changes
=================

* Removed cachetools dependence, see :pull:`647`.

Issues closed
=============

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -63,7 +63,7 @@
],
python_requires='>=3.5',
tests_require=extra_reqs['develop'],
install_requires=['mpmath>=0.19', 'strategies>=0.2.3', 'cachetools'],
install_requires=['mpmath>=0.19', 'strategies>=0.2.3'],
setup_requires=setup_reqs,
extras_require=extra_reqs,
zip_safe=True)