1import gc
2import sys
3import weakref
4
5import pytest
6
7from diofant import cacheit, ordered, sstr, symbols
8from diofant.abc import x
9from diofant.core.cache import clear_cache, print_cache
10
11
12__all__ = ()
13
14
15@cacheit
16def _emptyfn():
17    """Test docstring."""
18
19
20@cacheit
21def _identity(x):
22    return x
23
24
25def test_cacheit_doc():
26    assert _emptyfn.__doc__ == 'Test docstring.'
27    assert _emptyfn.__name__ == '_emptyfn'
28
29
30def test_cacheit():
31    assert _identity(1) == 1
32    assert _identity(1) == 1
33
34
35def test_print_cache(capfd):
36    clear_cache()
37    _identity(x)
38    info = _identity.cache_info()
39    print_cache()
40    resout, _ = capfd.readouterr()
41    assert resout.find('_identity ' + str(info)) >= 0
42
43
44@pytest.fixture(scope='function')
45def clear_imports(request):
46    # Clear namespace
47    orig = sys.modules.copy()
48    for m in list(sys.modules):
49        if m.startswith('diofant'):
50            del sys.modules[m]
51
52    def restore_imports():
53        for m in list(sys.modules):
54            if m.startswith('diofant'):
55                del sys.modules[m]
56
57        for m in orig:
58            sys.modules[m] = orig[m]
59
60    request.addfinalizer(restore_imports)
61
62
63def test_nocache(clear_imports, monkeypatch):
64    """Regression tests with DIOFANT_USE_CACHE=False."""
65    monkeypatch.setenv('DIOFANT_USE_CACHE', 'False')
66    from diofant.core.cache import CACHE
67    from diofant.core.symbol import Symbol
68    from diofant.functions import exp, sin, sinh, sqrt
69
70    # test that we don't use cache
71    assert CACHE == []
72    x = Symbol('x')
73    assert CACHE == []
74
75    # issue sympy/sympy#8840
76    (1 + x)*x  # not raises
77
78    # issue sympy/sympy#9413
79    (2*x).is_complex  # not raises
80
81    # see commit c459d18
82    sin(x + x)  # not raises
83
84    # see commit 53dd1eb
85    mx = -Symbol('x', negative=False)
86    assert mx.is_positive is not True
87
88    px = 2*Symbol('x', positive=False)
89    assert px.is_positive is not True
90
91    # see commit 2eaaba2
92    s = 1/sqrt(x**2)
93    y = Symbol('y')
94    result = s.subs({sqrt(x**2): y})
95    assert result == 1/y
96
97    # problem from https://groups.google.com/forum/#!topic/sympy/LkTMQKC_BOw
98    # see commit c459d18
99    a = Symbol('a', positive=True)
100    f = exp(x*(-a - 1))
101    g = sinh(x)
102    f*g  # not raises
103
104
105def test_sympyissue_8825():
106    t1, t2 = symbols('t1:3')
107    d = weakref.WeakKeyDictionary([(t1, 1), (t2, 2)])
108    assert sstr(list(ordered(d.items()))) == '[(t1, 1), (t2, 2)]'
109    del t1
110    clear_cache()
111    gc.collect()
112    assert sstr(list(ordered(d.items()))) == '[(t2, 2)]'
113