Ticket #11115: trac11115-cached_cython.patch

File trac11115-cached_cython.patch, 148.5 KB (added by SimonKing, 3 years ago)

Cythonized cached_method: Usable in Cython code, faster than handwritten Python cache. Special case for methods w/o arguments. Make ClearCacheOnPickle? usable. Lazy attributes

  • module_list.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1305526656 -7200
    # Node ID 1be94e1beaae845273fa8b6363e86be660222c9f
    # Parent  9ef16f06aa8195b4bf587c9ebee85f3b2ba4f8b9
    #11115: Cython version of cached_method and friends (relative to #11298, #9138).
    Make cached_in_parent methods work for the element class of categories,
    including cached_in_parent methods
    Provide lazy attributes for all parents
    
    diff --git a/module_list.py b/module_list.py
    a b  
    997997    Extension('sage.misc.bitset', 
    998998              sources = ['sage/misc/bitset.pyx']), 
    999999 
     1000    Extension('sage.misc.cachefunc', 
     1001              sources = ['sage/misc/cachefunc.pyx']), 
     1002 
    10001003    Extension('sage.misc.citation', 
    10011004              sources = ['sage/misc/citation.pyx']), 
    10021005 
  • sage/combinat/sf/dual.py

    diff --git a/sage/combinat/sf/dual.py b/sage/combinat/sf/dual.py
    a b  
    178178         
    179179        EXAMPLES:: 
    180180         
    181             sage: e = SFAElementary(QQ) 
     181            sage: e = SFAElementary(QQ['t']) 
    182182            sage: f = e.dual_basis() 
    183183            sage: f._precompute(0) 
    184184            sage: f._precompute(1) 
  • new file sage/misc/cachefunc.pxd

    diff --git a/sage/misc/cachefunc.pxd b/sage/misc/cachefunc.pxd
    new file mode 100644
    - +  
     1cdef class CachedFunction(object): 
     2    cdef public str __name__ 
     3    cdef public str __module__ 
     4    cdef object _argument_fixer 
     5    cdef public object _fix_to_pos 
     6    cdef public object f 
     7    # cache is not always of type "dict"! 
     8    cdef public object cache 
     9    cdef tuple _default_key 
     10    cpdef get_cache(self) 
     11    cpdef clear_cache(self) 
     12 
     13cdef class CachedMethod 
     14 
     15cdef class CachedMethodCaller(CachedFunction): 
     16    cdef public object _instance 
     17    cdef public bint _inst_in_key 
     18    cdef public CachedMethod _cachedmethod 
     19 
     20cdef class CachedMethodCallerNoArgs(CachedFunction): 
     21    cdef public object _instance 
     22 
     23cdef class CachedMethod(object): 
     24    cdef str _cache_name 
     25    cdef CachedFunction _cachedfunc 
     26    cpdef dict _get_instance_cache(self, inst) 
     27 
  • deleted file sage/misc/cachefunc.py

    diff --git a/sage/misc/cachefunc.py b/sage/misc/cachefunc.py
    deleted file mode 100644
    + -  
    1 """ 
    2 Cached Functions and Methods 
    3  
    4 AUTHORS: 
    5  
    6 - William Stein (inspired by conversation with Justin Walker). 
    7 - Mike Hansen (added doctests and made it work with class methods). 
    8 - Willem Jan Palenstijn (add CachedMethodCaller for binding cached 
    9   methods to instances). 
    10 - Tom Boothby (added DiskCachedFunction). 
    11 - Simon King (improved performance, more doctests). 
    12  
    13 """ 
    14 ######################################################################## 
    15 #       Copyright (C) 2008 William Stein <wstein@gmail.com> 
    16 #                          Mike Hansen <mhansen@gmail.com> 
    17 # 
    18 #  Distributed under the terms of the GNU General Public License (GPL) 
    19 # 
    20 #                  http://www.gnu.org/licenses/ 
    21 ######################################################################## 
    22 from function_mangling import ArgumentFixer 
    23 import os 
    24  
    25 class CachedFunction(object): 
    26     """ 
    27     Create a cached version of a function, which only recomputes 
    28     values it hasn't already computed. Synonyme: ``cached_function`` 
    29  
    30     If ``f`` is a function, do either ``g = CachedFunction(f)``  
    31     or ``g = cached_function(f)`` to make a cached version of ``f``, 
    32     or put ``@cached_function`` right before the definition of ``f`` 
    33     (i.e., use Python decorators):: 
    34  
    35         @cached_function 
    36         def f(...): 
    37             .... 
    38  
    39     The inputs to the function must be hashable. 
    40  
    41     EXAMPLES:: 
    42  
    43         sage: @cached_function 
    44         ... def mul(x, y=2): 
    45         ...     return x*y 
    46         ... 
    47         sage: mul(3) 
    48         6 
    49  
    50     We demonstrate that the result is cached, and that, moreover, 
    51     the cache takes into account the various ways of providing 
    52     default arguments:: 
    53  
    54         sage: mul(3) is mul(3,2) 
    55         True 
    56         sage: mul(3,y=2) is mul(3,2) 
    57         True 
    58  
    59     The user can clear the cache:: 
    60  
    61         sage: a = mul(4) 
    62         sage: mul.clear_cache() 
    63         sage: a is mul(4) 
    64         False 
    65  
    66     It is also possible to explicitly override the cache with 
    67     a different value:: 
    68  
    69         sage: mul.set_cache('foo',5) 
    70         sage: mul(5,2) 
    71         'foo' 
    72  
    73     """ 
    74     def __init__(self, f, classmethod=False): 
    75         """ 
    76         Create a cached version of a function, which only recomputes 
    77         values it hasn't already computed. 
    78  
    79         If f is a function, do either g = CachedFunction(f) to make 
    80         a cached version of f, or put @CachedFunction right before 
    81         the definition of f (i.e., use Python decorators):: 
    82  
    83             @CachedFunction 
    84             def f(...): 
    85                 .... 
    86  
    87         The inputs to the function must be hashable. 
    88  
    89         TESTS:: 
    90  
    91             sage: g = CachedFunction(number_of_partitions) 
    92             sage: g.__name__ 
    93             'number_of_partitions' 
    94             sage: 'partitions' in g.__doc__ 
    95             True 
    96             sage: g(5) 
    97             7 
    98             sage: g.cache 
    99             {((5, None, 'default'), ()): 7} 
    100             sage: def f(t=1): print(t) 
    101             sage: h = CachedFunction(f) 
    102             sage: w = walltime() 
    103             sage: h(); h(1); h(t=1) 
    104             1 
    105             sage: walltime(w) < 2 
    106             True 
    107  
    108         """ 
    109         self._common_init(f, ArgumentFixer(f,classmethod=classmethod)) 
    110         self.cache = {} 
    111  
    112     def _common_init(self, f, argumentfixer): 
    113         """ 
    114         Perform initialization common to CachedFunction and CachedMethodCaller. 
    115  
    116         TESTS:: 
    117  
    118             sage: @cached_function 
    119             ... def test_cache(x): 
    120             ...     return -x 
    121             sage: hasattr(test_cache, '_argumentfixer')  # indirect doctest 
    122             True 
    123         """ 
    124         self.f = f 
    125         if hasattr(f, "func_doc"): 
    126             self.__doc__ = f.func_doc 
    127         if hasattr(f, "func_name"): 
    128             self.__name__ = f.func_name 
    129         self.__module__ = f.__module__ 
    130         self._argumentfixer = argumentfixer 
    131  
    132     def _sage_src_(self): 
    133         """ 
    134         Returns the source code for the wrapped function. 
    135  
    136         TESTS:: 
    137  
    138             sage: from sage.misc.sageinspect import sage_getsource 
    139             sage: g = CachedFunction(number_of_partitions) 
    140             sage: 'bober' in sage_getsource(g)  # indirect doctest 
    141             True 
    142  
    143         """ 
    144         from sage.misc.sageinspect import sage_getsource 
    145         return sage_getsource(self.f) 
    146  
    147     def __call__(self, *args, **kwds): 
    148         """ 
    149         Return value from cache or call the wrapped function, 
    150         caching the output. 
    151  
    152         TESTS:: 
    153  
    154             sage: g = CachedFunction(number_of_partitions) 
    155             sage: a = g(5) 
    156             sage: g.get_cache() 
    157             {((5, None, 'default'), ()): 7} 
    158             sage: a = g(10^5) 
    159             sage: a == number_of_partitions(10^5) 
    160             True 
    161             sage: a is g(10^5) 
    162             True 
    163             sage: a is number_of_partitions(10^5) 
    164             False 
    165  
    166         """ 
    167         # We shortcut a common case of no arguments 
    168         if args or kwds: 
    169             k = self._argumentfixer.fix_to_pos(*args, **kwds) 
    170         else: 
    171             try: 
    172                 k = self._default_key 
    173             except AttributeError: 
    174                 k = self._default_key = self._argumentfixer.fix_to_pos() 
    175         try: 
    176             return self.cache[k] 
    177         except KeyError: 
    178             w = self.f(*args, **kwds) 
    179             self.cache[k] = w 
    180             return w 
    181  
    182     def get_cache(self): 
    183         """ 
    184         Returns the cache dictionary. 
    185  
    186         EXAMPLES:: 
    187  
    188             sage: g = CachedFunction(number_of_partitions) 
    189             sage: a = g(5) 
    190             sage: g.get_cache() 
    191             {((5, None, 'default'), ()): 7} 
    192  
    193         """ 
    194         return self.cache 
    195  
    196     def is_in_cache(self, *args, **kwds): 
    197         """ 
    198         Checks if the argument list is in the cache. 
    199  
    200         EXAMPLES:: 
    201  
    202             sage: class Foo: 
    203             ...       def __init__(self, x): 
    204             ...           self._x = x 
    205             ...       @cached_method 
    206             ...       def f(self, z, y=0): 
    207             ...           return self._x*z+y 
    208             ... 
    209             sage: a = Foo(2) 
    210             sage: a.f.is_in_cache(3) 
    211             False 
    212             sage: a.f(3) 
    213             6 
    214             sage: a.f.is_in_cache(3,y=0) 
    215             True 
    216         """ 
    217         return self._argumentfixer.fix_to_pos(*args, **kwds) in self.cache 
    218  
    219     def set_cache(self, value, *args, **kwds): 
    220         """ 
    221         Set the value for those args and keyword args 
    222         Mind the unintuitive syntax (value first). 
    223         Any idea on how to improve that welcome! 
    224  
    225         EXAMPLES:: 
    226  
    227             sage: g = CachedFunction(number_of_partitions) 
    228             sage: a = g(5) 
    229             sage: g.get_cache() 
    230             {((5, None, 'default'), ()): 7} 
    231             sage: g.set_cache(17, 5) 
    232             sage: g.get_cache() 
    233             {((5, None, 'default'), ()): 17} 
    234             sage: g(5) 
    235             17 
    236  
    237         DEVELOPER NOTE: 
    238  
    239         Is there a way to use the following intuitive syntax? 
    240  
    241         :: 
    242  
    243             sage: g(5) = 19    # todo: not implemented 
    244             sage: g(5)         # todo: not implemented 
    245             19 
    246         """ 
    247         self.cache[self._argumentfixer.fix_to_pos(*args, **kwds)] = value 
    248  
    249     def get_key(self, *args, **kwds): 
    250         """ 
    251         Returns the key in the cache to be used when args 
    252         and kwds are passed in as parameters. 
    253  
    254         EXAMPLES:: 
    255  
    256             sage: @cached_function 
    257             ... def foo(x): 
    258             ...    return x^2 
    259             ... 
    260             sage: foo(2) 
    261             4 
    262             sage: foo.get_key(2) 
    263             ((2,), ()) 
    264             sage: foo.get_key(x=3) 
    265             ((3,), ()) 
    266         """ 
    267         return self._argumentfixer.fix_to_pos(*args, **kwds) 
    268  
    269     def __repr__(self): 
    270         """ 
    271         EXAMPLES:: 
    272  
    273             sage: g = CachedFunction(number_of_partitions) 
    274             sage: g 
    275             Cached version of <function number_of_partitions at 0x...> 
    276         """ 
    277         try: 
    278             return "Cached version of %s"%self.f 
    279         except AttributeError: 
    280             return "Cached version of a method (pending reassignment)" 
    281  
    282     def clear_cache(self): 
    283         """ 
    284         Clear the cache dictionary. 
    285  
    286         EXAMPLES:: 
    287  
    288             sage: g = CachedFunction(number_of_partitions) 
    289             sage: a = g(5) 
    290             sage: g.get_cache() 
    291             {((5, None, 'default'), ()): 7} 
    292             sage: g.clear_cache() 
    293             sage: g.get_cache() 
    294             {} 
    295         """ 
    296         cache = self.cache 
    297         for key in cache.keys(): 
    298             del cache[key] 
    299  
    300     def precompute(self, arglist, num_processes=1): 
    301         """ 
    302  
    303         Cache values for a number of inputs.  Do the computation 
    304         in parallel, and only bother to compute values that we 
    305         haven't already cached. 
    306  
    307         EXAMPLES:: 
    308  
    309             sage: @cached_function 
    310             ... def oddprime_factors(n): 
    311             ...     l = [p for p,e in factor(n) if p != 2] 
    312             ...     return len(l) 
    313             sage: oddprime_factors.precompute(range(1,100), 4) 
    314             sage: oddprime_factors(25) is oddprime_factors(25) 
    315             True 
    316         """ 
    317         from sage.parallel.decorate import parallel, normalize_input 
    318         P = parallel(num_processes)(self.f) 
    319         cache = self.cache 
    320         get_key = self._argumentfixer.fix_to_pos 
    321         new = lambda x: not cache.has_key(get_key(*x[0],**x[1])) 
    322         arglist = filter(new, map(normalize_input, arglist)) 
    323         for ((args,kwargs), val) in P(arglist): 
    324             self.set_cache(val, *args, **kwargs) 
    325  
    326  
    327 cached_function = CachedFunction 
    328  
    329 class CachedMethodPickle: 
    330     """ 
    331     This class helps to unpickle cached methods. 
    332  
    333     NOTE: 
    334  
    335     Since trac ticket #8611, a cached method is an attribute 
    336     of the instance (provided that it has a ``__dict__``). 
    337     Hence, when pickling the instance, it would be attempted 
    338     to pickle that attribute as well, but this is a problem, 
    339     since functions can not be pickled, currently. Therefore, 
    340     we replace the actual cached method by a place holder, 
    341     that kills itself as soon as any attribute is requested. 
    342     Then, the original cached attribute is reinstated. 
    343  
    344     EXAMPLE:: 
    345  
    346         sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
    347         sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
    348         sage: I.groebner_basis() 
    349         [y^5*z^3 - 1/4*x^2*z^6 + 1/2*x*y*z^6 + 1/4*y^2*z^6, x^2*y*z^3 - x*y^2*z^3 + 2*y^3*z^3 + z^6, x*y^3 + y^4 + x*z^3, x^3 + y^3 + z^3] 
    350         sage: I.groebner_basis 
    351         Cached version of <function groebner_basis at 0x...> 
    352  
    353     We now pickle and unpickle the ideal. The cached method 
    354     ``groebner_basis`` is replaced by a placeholder:: 
    355  
    356         sage: J = loads(dumps(I)) 
    357         sage: J.groebner_basis 
    358         Pickle of the cached method "groebner_basis" 
    359  
    360     But as soon as any other attribute is requested from the 
    361     placeholder, it replaces itself by the cached method, and 
    362     the entries of the cache are actually preserved:: 
    363  
    364         sage: J.groebner_basis.is_in_cache() 
    365         True 
    366         sage: J.groebner_basis 
    367         Cached version of <function groebner_basis at 0x...> 
    368         sage: J.groebner_basis() == I.groebner_basis() 
    369         True 
    370  
    371     AUTHOR: 
    372  
    373     - Simon King (2011-01) 
    374     """ 
    375     def __init__(self, inst, name): 
    376         """ 
    377         INPUT: 
    378  
    379         - ``inst`` - some instance. 
    380         - ``name`` (string) - usually the name of an attribute 
    381           of ``inst`` to which ``self`` is assigned. 
    382  
    383         TEST:: 
    384  
    385             sage: from sage.misc.cachefunc import CachedMethodPickle 
    386             sage: P = CachedMethodPickle(1, 'foo') 
    387             sage: P 
    388             Pickle of the cached method "foo" 
    389  
    390         """ 
    391         self._instance = inst 
    392         self._name = name 
    393     def __repr__(self): 
    394         """ 
    395         TEST:: 
    396  
    397             sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
    398             sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
    399             sage: G = I.groebner_basis() 
    400             sage: J = loads(dumps(I)) 
    401             sage: J.groebner_basis  #indirect doctest 
    402             Pickle of the cached method "groebner_basis" 
    403         """ 
    404         return 'Pickle of the cached method "%s"'%self._name 
    405     def __getattr__(self,s): 
    406         """ 
    407         TEST:: 
    408  
    409             sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
    410             sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
    411             sage: G = I.groebner_basis() 
    412             sage: J = loads(dumps(I)) 
    413             sage: J.groebner_basis 
    414             Pickle of the cached method "groebner_basis" 
    415  
    416         If an attribute of name ``s`` is requested (say, 
    417         ``is_in_cache``), the attribute ``self._name`` of 
    418         ``self._instance`` is deleted. Then, the attribute 
    419         of name ``s`` of the attribute ``self._name`` of 
    420         ``self._instance`` is requested. Since ``self._name`` 
    421         is a cached method defined for the class of 
    422         ``self._instance``, retrieving the just-deleted 
    423         attribute ``self._name`` succeeds. 
    424  
    425         In that way, the unpickling of the cached method is 
    426         finally accomplished:: 
    427  
    428             sage: J.groebner_basis.is_in_cache()  #indirect doctest 
    429             True 
    430             sage: J.groebner_basis 
    431             Cached version of <function groebner_basis at 0x...> 
    432  
    433         """ 
    434         self._instance.__dict__.__delitem__(self._name) 
    435         return getattr(getattr(self._instance,self._name),s) 
    436  
    437 class CachedMethodCaller(CachedFunction): 
    438     """ 
    439     Utility class that is used by :class:`CachedMethod` to bind a 
    440     cached method to an instance. 
    441  
    442     EXAMPLE:: 
    443  
    444         sage: class A: 
    445         ...    @cached_method 
    446         ...    def bar(self,x): 
    447         ...        return x^2 
    448         sage: a = A() 
    449         sage: a.bar 
    450         Cached version of <function bar at 0x...> 
    451         sage: type(a.bar) 
    452         <class 'sage.misc.cachefunc.CachedMethodCaller'> 
    453         sage: a.bar(2) is a.bar(x=2) 
    454         True 
    455  
    456     """ 
    457     def __init__(self, cachedmethod, inst, cache=None, inst_in_key=False): 
    458         """ 
    459         EXAMPLES:: 
    460  
    461             sage: class Foo: 
    462             ...       def __init__(self, x): 
    463             ...           self._x = x 
    464             ...       @cached_method 
    465             ...       def f(self): 
    466             ...           return self._x^2 
    467             ... 
    468             sage: a = Foo(2) 
    469             sage: a.f.get_cache() 
    470             {} 
    471             sage: a.f() 
    472             4 
    473             sage: a.f.get_cache() 
    474             {((), ()): 4} 
    475         """ 
    476         # initialize CachedFunction, but re-use the ArgumentFixer 
    477         self._common_init(cachedmethod._cachedfunc.f, cachedmethod._cachedfunc._argumentfixer) 
    478         self.cache = {} if cache is None else cache 
    479         self._instance = inst 
    480         self._inst_in_key = inst_in_key 
    481         self._cachedmethod = cachedmethod 
    482  
    483     def __reduce__(self): 
    484         """ 
    485         The pickle of a :class:`CachedMethodCaller` unpickles 
    486         to a :class:`CachedMethodPickle`, that is able to replace 
    487         itself by a copy of the original :class:`CachedMethodCaller`. 
    488  
    489         TEST:: 
    490  
    491             sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
    492             sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
    493             sage: G = I.groebner_basis() 
    494             sage: J = loads(dumps(I))  #indirect doctest 
    495             sage: J.groebner_basis 
    496             Pickle of the cached method "groebner_basis" 
    497             sage: J.groebner_basis.is_in_cache() 
    498             True 
    499             sage: J.groebner_basis 
    500             Cached version of <function groebner_basis at 0x...> 
    501  
    502         """ 
    503         return CachedMethodPickle,(self._instance,self.__name__) 
    504  
    505     def __call__(self, *args, **kwds): 
    506         """ 
    507         Call the cached method. 
    508  
    509         TESTS:: 
    510  
    511             sage: class Foo: 
    512             ...       @cached_method 
    513             ...       def f(self, x,y=1): 
    514             ...           return x+y 
    515             ... 
    516             sage: a = Foo() 
    517             sage: a.f(1)  #indirect doctest 
    518             2 
    519  
    520         The result is cached, taking into account 
    521         the three ways of providing (named) arguments:: 
    522  
    523             sage: a.f(5) is a.f(5,1) 
    524             True 
    525             sage: a.f(5) is a.f(5,y=1) 
    526             True 
    527             sage: a.f(5) is a.f(y=1,x=5) 
    528             True 
    529  
    530         We test that #5843 is fixed:: 
    531  
    532             sage: class Foo: 
    533             ...       def __init__(self, x): 
    534             ...           self._x = x 
    535             ...       @cached_method 
    536             ...       def f(self, y): 
    537             ...           return self._x 
    538             ... 
    539             sage: a = Foo(2) 
    540             sage: b = Foo(3) 
    541             sage: a.f(b.f) 
    542             2 
    543         """ 
    544         # We shortcut a common case of no arguments 
    545         if args or kwds: 
    546             k = self.get_key(*args, **kwds) 
    547         else: 
    548             try: 
    549                 k = self._default_key 
    550             except AttributeError: 
    551                 k = self._default_key = self.get_key() 
    552         try: 
    553             return self.cache[k] 
    554         except KeyError: 
    555             w = self._cachedmethod._instance_call(self._instance, *args, **kwds) 
    556             self.cache[k] = w 
    557             return w 
    558  
    559     def get_key(self, *args, **kwds): 
    560         """ 
    561         Convert arguments to the key for this instance's cache. 
    562  
    563         EXAMPLES:: 
    564  
    565             sage: class Foo: 
    566             ...       def __init__(self, x): 
    567             ...           self._x = x 
    568             ...       @cached_method 
    569             ...       def f(self, y, z=0): 
    570             ...           return self._x * y + z 
    571             ... 
    572             sage: a = Foo(2) 
    573             sage: z = a.f(37) 
    574             sage: k = a.f.get_key(37); k 
    575             ((37, 0), ()) 
    576             sage: a.f.get_cache()[k] is z 
    577             True 
    578  
    579         Note that the method does not test whether there are 
    580         too many arguments, or wrong argument names:: 
    581  
    582             sage: a.f.get_key(1,2,3,x=4,y=5,z=6) 
    583             ((1, 2, 3), (('x', 4), ('y', 5), ('z', 6))) 
    584  
    585         It does, however, take into account the different 
    586         ways of providing named arguments, possibly with a 
    587         default value:: 
    588  
    589             sage: a.f.get_key(5) 
    590             ((5, 0), ()) 
    591             sage: a.f.get_key(y=5) 
    592             ((5, 0), ()) 
    593             sage: a.f.get_key(5,0) 
    594             ((5, 0), ()) 
    595             sage: a.f.get_key(5,z=0) 
    596             ((5, 0), ()) 
    597             sage: a.f.get_key(y=5,z=0) 
    598             ((5, 0), ()) 
    599  
    600         """ 
    601         if self._inst_in_key: 
    602             return (self._instance,self._argumentfixer.fix_to_pos(*args,**kwds)) 
    603         return self._argumentfixer.fix_to_pos(*args,**kwds) 
    604  
    605     def __get__(self, inst, cls=None): 
    606         """ 
    607         Get a :class:`CachedMethodCaller` bound to a specific 
    608         instance of the class of the cached method. 
    609  
    610         NOTE: 
    611  
    612         :class:`CachedMethodCaller` has a separate ``__get__`` 
    613         since the categories framework creates and caches the 
    614         return value of ``CachedMethod.__get__`` with 
    615         ``inst==None``. 
    616  
    617         TESTS: 
    618  
    619         Due to the separate ``__get__`` method, it is possible 
    620         to define a cached method in one class and use it as 
    621         an attribute of another class. 
    622  
    623             sage: class Foo: 
    624             ...       @cached_method 
    625             ...       def f(self, y): 
    626             ...           return y - 1 
    627             sage: class Bar: 
    628             ...       f = Foo.f 
    629             sage: b1 = Bar() 
    630             sage: b2 = Bar() 
    631  
    632         The :class:`CachedMethod` is replaced by an instance 
    633         of :class:`CachedMethodCaller` that (by trac ticket 
    634         #8611) is set as an attribute. Hence, we have:: 
    635  
    636             sage: b1.f is b1.f 
    637             True 
    638  
    639         Any instance of ``Bar`` gets its own instance of 
    640         :class:`CachedMethodCaller``:: 
    641  
    642             sage: b1.f is b2.f 
    643             False 
    644   
    645         The method caller knows the instance that it belongs 
    646         to:: 
    647  
    648             sage: Foo.f._instance is None 
    649             True 
    650             sage: b1.f._instance is b1 
    651             True 
    652             sage: b2.f._instance is b2 
    653             True 
    654  
    655         """ 
    656         Caller = CachedMethodCaller(self._cachedmethod, inst, cache=self._cachedmethod._get_instance_cache(inst), inst_in_key=self._inst_in_key) 
    657         try: 
    658             setattr(inst,self._cachedmethod._cachedfunc.f.__name__, Caller) 
    659         except AttributeError: 
    660             pass 
    661         return Caller 
    662  
    663 class CachedMethod(object): 
    664     """ 
    665     A decorator that creates a cached version of an instance 
    666     method of a class. 
    667  
    668     NOTE: 
    669  
    670     For proper behavior, the method must be a pure function 
    671     (no side effects). Arguments to the method must be hashable. 
    672  
    673     EXAMPLES:: 
    674  
    675         sage: class Foo(object): 
    676         ...       @cached_method 
    677         ...       def f(self, t, x=2): 
    678         ...           print 'computing' 
    679         ...           return t**x 
    680         sage: a = Foo() 
    681  
    682     The example shows that the actual computation 
    683     takes place only once, and that the result is 
    684     identic for equivalent input:: 
    685     
    686         sage: res = a.f(3, 2); res 
    687         computing 
    688         9 
    689         sage: a.f(t = 3, x = 2) is res 
    690         True 
    691         sage: a.f(3) is res 
    692         True 
    693  
    694     """ 
    695     def __init__(self, f): 
    696         """ 
    697         EXAMPLES:: 
    698  
    699             sage: class Foo: 
    700             ...       def __init__(self, x): 
    701             ...           self._x = x 
    702             ...       @cached_method 
    703             ...       def f(self,n): 
    704             ...           return self._x^n 
    705             ... 
    706             sage: a = Foo(2) 
    707             sage: a.f(2) 
    708             4 
    709  
    710         The computations in method ``f`` are 
    711         stored in a dictionary assigned to the 
    712         instance ``a``:: 
    713  
    714             sage: hasattr(a, '_cache__f') 
    715             True 
    716             sage: a._cache__f 
    717             {((2,), ()): 4} 
    718  
    719         As a shortcut, useful to speed up internal computations, 
    720         the same dictionary is also available as an attribute 
    721         of the ``CachedMethodCaller``:: 
    722  
    723             sage: type(a.f) 
    724             <class 'sage.misc.cachefunc.CachedMethodCaller'> 
    725             sage: a.f.cache is a._cache__f 
    726             True 
    727  
    728         """ 
    729         self._cache_name = '_cache__' + f.__name__ 
    730         self._cachedfunc = CachedFunction(f, classmethod=True) 
    731         self._argument_fix_to_pos = self._cachedfunc._argumentfixer.fix_to_pos 
    732  
    733     def _instance_call(self, inst, *args, **kwds): 
    734         """ 
    735         Call the cached method *without* using the cache. 
    736  
    737         INPUT: 
    738  
    739         - ``inst`` - an instance at which the method is to be called 
    740         - Further positional or named arguments. 
    741  
    742         EXAMPLES:: 
    743  
    744             sage: class Foo(object): 
    745             ...       def __init__(self, x): 
    746             ...           self._x = x 
    747             ...       @cached_method 
    748             ...       def f(self): 
    749             ...           return self._x^2 
    750             ... 
    751             sage: a = Foo(2) 
    752             sage: a.f() 
    753             4 
    754  
    755         Usually, a cached meth is indeed cached:: 
    756  
    757             sage: a.f() is a.f() 
    758             True 
    759  
    760         However, when it becomes necessary, one can call 
    761         it without using the cache:: 
    762  
    763             sage: a.f._cachedmethod._instance_call(a) is a.f() 
    764             False 
    765             sage: a.f._cachedmethod._instance_call(a) == a.f() 
    766             True 
    767  
    768         It is also possible to call the method with a 
    769         different instance:: 
    770  
    771             sage: b = Foo(3) 
    772             sage: b.f() 
    773             9 
    774             sage: a.f._cachedmethod._instance_call(b) 
    775             9 
    776  
    777         """ 
    778         return self._cachedfunc.f(inst, *args, **kwds) 
    779  
    780     def _get_instance_cache(self, inst): 
    781         """ 
    782         Returns the cache dictionary. 
    783  
    784         TESTS:: 
    785  
    786             sage: class Foo: 
    787             ...       def __init__(self, x): 
    788             ...           self._x = x 
    789             ...       @cached_method 
    790             ...       def f(self): 
    791             ...           return self._x^2 
    792             ... 
    793             sage: a = Foo(2) 
    794             sage: a.f() 
    795             4 
    796             sage: a.f._cachedmethod._get_instance_cache(a) 
    797             {((), ()): 4} 
    798         """ 
    799         try: 
    800             return inst.__dict__.setdefault(self._cache_name, {}) 
    801         except AttributeError: 
    802             return {} 
    803  
    804     def __get__(self, inst, cls=None): 
    805         """ 
    806         Get a CachedMethodCaller bound to this specific instance of 
    807         the class of the cached method. 
    808  
    809         TESTS:: 
    810  
    811             sage: class Foo: 
    812             ...       @cached_method 
    813             ...       def f(self): 
    814             ...           return 1 
    815             sage: a = Foo() 
    816             sage: type(a.f) 
    817             <class 'sage.misc.cachefunc.CachedMethodCaller'> 
    818  
    819         By trac ticket #8611, the CachedMethodCaller is set as 
    820         an attribute of the instance ``a``, replacing the original 
    821         cached attribute. Therefore, the ``__get__`` method will 
    822         be used only once, which saves much time. Hence, we have:: 
    823   
    824             sage: a.f is a.f 
    825             True 
    826  
    827         """ 
    828         Caller = CachedMethodCaller(self, inst, cache=self._get_instance_cache(inst)) 
    829         try: 
    830             setattr(inst,self._cachedfunc.f.__name__, Caller) 
    831         except AttributeError,msg: 
    832             pass 
    833         return Caller 
    834  
    835         # Note: a simpler approach to this would be 
    836         # def caller(*args, **kwds): 
    837         #     return self._instance_call(inst, *args, **kwds) 
    838         # return caller 
    839         # The disadvantage to this is that it does not provide 
    840         # is_in_cache(), set_cache(), clear_cache(), ... methods. 
    841  
    842  
    843 cached_method = CachedMethod 
    844  
    845 class CachedInParentMethod(CachedMethod): 
    846     """ 
    847     A decorator that creates a cached version of an instance 
    848     method of a class. 
    849  
    850     In contrast to :class:`CachedMethod`, 
    851     the cache dictionary is an attribute of the parent of 
    852     the instance to which the method belongs. 
    853  
    854     ASSUMPTION: 
    855  
    856     This way of caching works only if 
    857  
    858     - the instances *have* a parent, 
    859     - the parent allows assignment of attributes, and 
    860     - the instances are hashable (they are part of the cache key). 
    861  
    862     NOTE: 
    863  
    864     For proper behavior, the method must be a pure function 
    865     (no side effects). Arguments to the method must be hashable. 
    866  
    867     EXAMPLES:: 
    868  
    869         sage: class MyParent(Parent): 
    870         ...       pass 
    871         ... 
    872         sage: class Foo: 
    873         ...       def __init__(self, x): 
    874         ...           self._x = x 
    875         ...       _parent = MyParent() 
    876         ...       def parent(self): 
    877         ...           return self._parent 
    878         ...       def __eq__(self, other): 
    879         ...           return self._x^2 == other._x^2 
    880         ...       def __hash__(self): 
    881         ...           return hash(self._x^2) 
    882         ...       def __repr__(self): 
    883         ...           return 'My %s'%self._x 
    884         ...       @cached_in_parent_method 
    885         ...       def f(self): 
    886         ...           return self._x^3 
    887         ... 
    888         sage: a = Foo(2) 
    889         sage: a.f() 
    890         8 
    891         sage: a.f.get_cache()   #indirect doctest 
    892         {(My 2, ((), ())): 8} 
    893  
    894     Since the key for the cache depends on equality of 
    895     the instances, we obtain *identical* result for 
    896     *equal* instances - even though in this particular 
    897     example the result of the method should be different 
    898     for ``a`` and ``b``:: 
    899  
    900         sage: b = Foo(-2) 
    901         sage: a is not b 
    902         True 
    903         sage: a == b 
    904         True 
    905         sage: b.f() is a.f() 
    906         True 
    907  
    908     Non-equal instances do not share the result of 
    909     the cached method, but they do share the cache:: 
    910  
    911         sage: c = Foo(3) 
    912         sage: c.f() 
    913         27 
    914         sage: c.f.get_cache() is a.f.get_cache() #indirect doctest 
    915         True 
    916  
    917     Note that the cache is also available as an 
    918     attribute of the cached method, which speeds 
    919     up internal computations:: 
    920  
    921         sage: a.f.cache is b.f.get_cache() is c.f._cachedmethod._get_instance_cache(c) 
    922         True 
    923     """ 
    924     def __init__(self, f): 
    925         """ 
    926         Constructs a new method with cache stored in the parent of the instance. 
    927  
    928         See also ``cached_method`` and ``cached_function``. 
    929  
    930         EXAMPLES:: 
    931  
    932             sage: class MyParent(Parent): 
    933             ...       pass 
    934             sage: class Foo: 
    935             ...       def __init__(self, x): 
    936             ...           self._x = x 
    937             ...       _parent = MyParent() 
    938             ...       def parent(self): 
    939             ...           return self._parent 
    940             ...       @cached_in_parent_method  #indirect doctest 
    941             ...       def f(self): 
    942             ...           return self._x^2 
    943             ... 
    944             sage: a = Foo(2) 
    945             sage: a.f() 
    946             4 
    947             sage: hasattr(a.parent(), '_cache__element_f') 
    948             True 
    949  
    950         For speeding up internal computations, this dictionary 
    951         is also accessible as an attribute of the CachedMethodCaller 
    952         (by trac ticket #8611):: 
    953  
    954             sage: a.parent()._cache__element_f is a.f.cache 
    955             True 
    956         """ 
    957         self._cache_name = '_cache__' + 'element_' + f.__name__ 
    958         self._cachedfunc = CachedFunction(f, classmethod=True) 
    959         self._argument_fix_to_pos = self._cachedfunc._argumentfixer.fix_to_pos 
    960  
    961     def _get_instance_cache(self, inst): 
    962         """ 
    963         Returns the cache dictionary, which is stored in the parent. 
    964  
    965         EXAMPLES:: 
    966  
    967             sage: class MyParent(Parent): 
    968             ...       pass 
    969             ... 
    970             sage: class Foo: 
    971             ...       def __init__(self, x): 
    972             ...           self._x = x 
    973             ...       _parent = MyParent() 
    974             ...       def parent(self): 
    975             ...           return self._parent 
    976             ...       def __eq__(self, other): 
    977             ...           return self._x^2 == other._x^2 
    978             ...       def __hash__(self): 
    979             ...           return hash(self._x^2) 
    980             ...       def __repr__(self): 
    981             ...           return 'My %s'%self._x 
    982             ...       @cached_in_parent_method 
    983             ...       def f(self): 
    984             ...           return self._x^3 
    985             ... 
    986             sage: a = Foo(2) 
    987             sage: a.f() 
    988             8 
    989             sage: a.f.get_cache()   #indirect doctest 
    990             {(My 2, ((), ())): 8} 
    991  
    992         Since the key for the cache depends on equality of 
    993         the instances, we obtain *identical* result for 
    994         *equal* instance - even though in this particular 
    995         example the result is wrong:: 
    996  
    997             sage: b = Foo(-2) 
    998             sage: a is not b 
    999             True 
    1000             sage: a == b 
    1001             True 
    1002             sage: b.f() is a.f() 
    1003             True 
    1004  
    1005         Non-equal instances do not share the result of 
    1006         the cached method, but they do share the cache:: 
    1007  
    1008             sage: c = Foo(3) 
    1009             sage: c.f() 
    1010             27 
    1011             sage: c.f.get_cache() is a.f.get_cache() #indirect doctest 
    1012             True 
    1013  
    1014         Note that the cache is also available as an 
    1015         attribute of the cached method, which speeds 
    1016         up internal computations:: 
    1017  
    1018             sage: a.f.cache is b.f.get_cache() is c.f._cachedmethod._get_instance_cache(c) 
    1019             True 
    1020  
    1021         """ 
    1022         try: 
    1023             return inst.parent().__dict__.setdefault(self._cache_name, {}) 
    1024         except AttributeError: 
    1025             return {} 
    1026  
    1027     def __get__(self, inst, cls=None): 
    1028         """ 
    1029         Get a CachedMethodCaller bound to this specific instance of 
    1030         the class of the cached-in-parent method. 
    1031         """ 
    1032         Caller = CachedMethodCaller(self, inst, cache=self._get_instance_cache(inst), inst_in_key=True) 
    1033         try: 
    1034             setattr(inst,self._cachedfunc.f.__name__, Caller) 
    1035         except AttributeError: 
    1036             pass 
    1037         return Caller 
    1038  
    1039 cached_in_parent_method = CachedInParentMethod 
    1040  
    1041 class FileCache: 
    1042     """ 
    1043     FileCache is a dictionary-like class which stores keys and 
    1044     values on disk.  The keys take the form of a tuple (A,K) 
    1045  
    1046     - A is a tuple of objects t where each t is an exact 
    1047       object which is uniquely identified by a short string. 
    1048  
    1049     - K is a tuple of tuples (s,v) where s is a valid 
    1050       variable name and v is an exact object which is uniquely 
    1051       identified by a short string with letters [a-zA-Z0-9-._] 
    1052  
    1053     The primary use case is the DiskCachedFunction.  If 
    1054     ``memory_cache == True``, we maintain a cache of objects seen 
    1055     during this session in memory -- but we don't load them from 
    1056     disk until necessary.  The keys and values are stored in a 
    1057     pair of files: 
    1058  
    1059     - ``prefix-argstring.key.sobj`` contains the ``key`` only, 
    1060     - ``prefix-argstring.sobj`` contains the tuple ``(key,val)`` 
    1061  
    1062     where ``self[key] == val``. 
    1063  
    1064     NOTE: 
    1065  
    1066     We assume that each FileCache lives in its own directory. 
    1067     Use **extreme** caution if you wish to break that assumption. 
    1068     """ 
    1069     def __init__(self, dir, prefix = '', memory_cache = False): 
    1070         """ 
    1071         EXAMPLES:: 
    1072  
    1073             sage: from sage.misc.cachefunc import FileCache 
    1074             sage: dir = tmp_dir() 
    1075             sage: FC = FileCache(dir, memory_cache = True) 
    1076             sage: FC[((),())] = 1 
    1077             sage: FC[((1,2),())] = 2 
    1078             sage: FC[((),())] 
    1079             1 
    1080         """ 
    1081         if len(dir) == 0 or dir[-1] != '/': 
    1082             dir += '/' 
    1083         self._dir = dir 
    1084         if not os.path.exists(dir): 
    1085             os.mkdir(dir) 
    1086  
    1087         self._prefix = prefix + '-' 
    1088  
    1089         if memory_cache: 
    1090             self._cache = {} 
    1091         else: 
    1092             self._cache = None 
    1093  
    1094     def file_list(self): 
    1095         """ 
    1096         Returns the list of files corresponding to self. 
    1097  
    1098         EXAMPLES:: 
    1099  
    1100             sage: from sage.misc.cachefunc import FileCache 
    1101             sage: dir = tmp_dir() 
    1102             sage: FC = FileCache(dir, memory_cache = True, prefix='t') 
    1103             sage: FC[((),())] = 1 
    1104             sage: FC[((1,2),())] = 2 
    1105             sage: FC[((1,),(('a',1),))] = 3 
    1106             sage: for f in sorted(FC.file_list()): print f[len(dir):] 
    1107             /t-.key.sobj 
    1108             /t-.sobj 
    1109             /t-1_2.key.sobj 
    1110             /t-1_2.sobj 
    1111             /t-a-1.1.key.sobj 
    1112             /t-a-1.1.sobj 
    1113         """ 
    1114         files = [] 
    1115         prefix = self._prefix 
    1116         dir = self._dir 
    1117         l = len(prefix) 
    1118         for f in os.listdir(dir): 
    1119             if f[:l] == prefix: 
    1120                 files.append( dir + f ) 
    1121         return files 
    1122  
    1123     def items(self): 
    1124         """ 
    1125         Returns a list of tuples ``(k,v)`` where ``self[k] = v``. 
    1126  
    1127         EXAMPLES:: 
    1128  
    1129             sage: from sage.misc.cachefunc import FileCache 
    1130             sage: dir = tmp_dir() 
    1131             sage: FC = FileCache(dir, memory_cache = False) 
    1132             sage: FC[((),())] = 1 
    1133             sage: FC[((1,2),())] = 2 
    1134             sage: FC[((1,),(('a',1),))] = 3 
    1135             sage: I = FC.items() 
    1136             sage: I.sort(); print I 
    1137             [(((), ()), 1), (((1,), (('a', 1),)), 3), (((1, 2), ()), 2)] 
    1138         """ 
    1139         return [(k,self[k]) for k in self] 
    1140  
    1141     def values(self): 
    1142         """ 
    1143         Returns a list of values that are stored in ``self``. 
    1144  
    1145         EXAMPLES:: 
    1146  
    1147             sage: from sage.misc.cachefunc import FileCache 
    1148             sage: dir = tmp_dir() 
    1149             sage: FC = FileCache(dir, memory_cache = False) 
    1150             sage: FC[((),())] = 1 
    1151             sage: FC[((1,2),())] = 2 
    1152             sage: FC[((1,),(('a',1),))] = 3 
    1153             sage: FC[((),(('a',1),))] = 4 
    1154             sage: v = FC.values() 
    1155             sage: v.sort(); print v 
    1156             [1, 2, 3, 4] 
    1157         """ 
    1158         return [self[k] for k in self] 
    1159  
    1160     def __iter__(self): 
    1161         """ 
    1162         Returns a list of keys of ``self``. 
    1163  
    1164         EXAMPLES:: 
    1165  
    1166             sage: from sage.misc.cachefunc import FileCache 
    1167             sage: dir = tmp_dir() 
    1168             sage: FC = FileCache(dir, memory_cache = False) 
    1169             sage: FC[((),())] = 1 
    1170             sage: FC[((1,2),())] = 2 
    1171             sage: FC[((1,),(('a',1),))] = 3 
    1172             sage: for k in sorted(FC): print k 
    1173             ((), ()) 
    1174             ((1,), (('a', 1),)) 
    1175             ((1, 2), ()) 
    1176         """ 
    1177         from sage.structure.sage_object import load 
    1178  
    1179         for f in self.file_list(): 
    1180             if f[-9:] == '.key.sobj': 
    1181                  yield load(f) 
    1182  
    1183     def keys(self): 
    1184         """ 
    1185         Returns a list of keys ``k`` where ``self[k]`` is defined. 
    1186  
    1187         EXAMPLES:: 
    1188  
    1189             sage: from sage.misc.cachefunc import FileCache 
    1190             sage: dir = tmp_dir() 
    1191             sage: FC = FileCache(dir, memory_cache = False) 
    1192             sage: FC[((),())] = 1 
    1193             sage: FC[((1,2),())] = 2 
    1194             sage: FC[((1,),(('a',1),))] = 3 
    1195             sage: K = FC.keys() 
    1196             sage: K.sort(); print K 
    1197             [((), ()), ((1,), (('a', 1),)), ((1, 2), ())] 
    1198         """ 
    1199         return [k for k in self] 
    1200  
    1201     def _filename(self, key): 
    1202         """ 
    1203         Computes the filename associated with a certain key. 
    1204  
    1205         EXAMPLES:: 
    1206  
    1207             sage: from sage.misc.cachefunc import FileCache 
    1208             sage: dir = tmp_dir() + '/' 
    1209             sage: FC = FileCache(dir, memory_cache = False, prefix='foo') 
    1210             sage: N = FC._filename(((1,2), (('a',1),('b',2)))) 
    1211             sage: print N[len(dir):] 
    1212             foo-a-1_b-2.1_2 
    1213             sage: N = FC._filename(((), (('a',1),('b',2)))) 
    1214             sage: print N[len(dir):] 
    1215             foo-a-1_b-2 
    1216             sage: N = FC._filename(((1,2), ())) 
    1217             sage: print N[len(dir):] 
    1218             foo-1_2 
    1219         """ 
    1220         a,k = key 
    1221         kwdstr = '_'.join('%s-%s'%x for x in k) 
    1222         argstr = '_'.join('%s'%x for x in a) 
    1223         if kwdstr and argstr: 
    1224             keystr = kwdstr + '.' + argstr 
    1225         else: 
    1226             keystr = kwdstr + argstr 
    1227         return self._dir + self._prefix + keystr 
    1228  
    1229     def has_key(self, key): 
    1230         """ 
    1231         Returns ``True`` if ``self[key]`` is defined and False otherwise. 
    1232  
    1233         EXAMPLES:: 
    1234  
    1235             sage: from sage.misc.cachefunc import FileCache 
    1236             sage: dir = tmp_dir() + '/' 
    1237             sage: FC = FileCache(dir, memory_cache = False, prefix='foo') 
    1238             sage: k = ((),(('a',1),)) 
    1239             sage: FC[k] = True 
    1240             sage: FC.has_key(k) 
    1241             True 
    1242             sage: FC.has_key(((),())) 
    1243             False 
    1244         """ 
    1245         return os.path.exists(self._filename(key) + '.key.sobj') 
    1246  
    1247     def __getitem__(self, key): 
    1248         """ 
    1249         Returns the value set by ``self[key] = val``, in this session 
    1250         or a previous one. 
    1251  
    1252         EXAMPLES:: 
    1253  
    1254             sage: from sage.misc.cachefunc import FileCache 
    1255             sage: dir = tmp_dir() + '/' 
    1256             sage: FC1 = FileCache(dir, memory_cache = False, prefix='foo') 
    1257             sage: FC2 = FileCache(dir, memory_cache = False, prefix='foo') 
    1258             sage: k = ((),(('a',1),)) 
    1259             sage: t = randint(0, 1000) 
    1260             sage: FC1[k] = t 
    1261             sage: FC2[k] == FC1[k] == t 
    1262             True 
    1263             sage: FC1[(1,2),(('a',4),('b',2))] 
    1264             Traceback (most recent call last): 
    1265             ... 
    1266             KeyError: ((1, 2), (('a', 4), ('b', 2))) 
    1267  
    1268         """ 
    1269         from sage.structure.sage_object import load 
    1270  
    1271         cache = self._cache 
    1272         if cache is not None: 
    1273             if cache.has_key(key): 
    1274                 return cache[key] 
    1275  
    1276         f = self._filename(key) + '.sobj' 
    1277         try: 
    1278             k,v = load(f) 
    1279         except IOError: 
    1280             raise KeyError, key  
    1281         if k != key: 
    1282             raise RuntimeError, "cache corrupted" 
    1283  
    1284         if cache is not None: 
    1285             cache[key] = v 
    1286         return v 
    1287  
    1288     def __setitem__(self, key, value): 
    1289         """ 
    1290         Sets ``self[key] = value`` and stores both key and value on 
    1291         disk. 
    1292  
    1293         EXAMPLES:: 
    1294  
    1295             sage: from sage.misc.cachefunc import FileCache 
    1296             sage: dir = tmp_dir() + '/' 
    1297             sage: FC1 = FileCache(dir, memory_cache = False, prefix='foo') 
    1298             sage: FC2 = FileCache(dir, memory_cache = False, prefix='foo') 
    1299             sage: k = ((),(('a',1),)) 
    1300             sage: t = randint(0, 1000) 
    1301             sage: FC1[k] = t 
    1302             sage: FC2[k] == t 
    1303             True 
    1304             sage: FC1[k] = 2000 
    1305             sage: FC2[k]!= t 
    1306             True 
    1307         """ 
    1308         from sage.structure.sage_object import save 
    1309  
    1310         f = self._filename(key) 
    1311  
    1312         save(key, f+'.key.sobj') 
    1313         save((key,value), f + '.sobj') 
    1314         if self._cache is not None: 
    1315             self._cache[key] = value 
    1316  
    1317     def __delitem__(self, key): 
    1318         """ 
    1319         Delete the key,value pair from self and unlink the associated 
    1320         files from the file cache. 
    1321  
    1322         EXAMPLES:: 
    1323  
    1324             sage: from sage.misc.cachefunc import FileCache 
    1325             sage: dir = tmp_dir() + '/' 
    1326             sage: FC1 = FileCache(dir, memory_cache = False, prefix='foo') 
    1327             sage: FC2 = FileCache(dir, memory_cache = False, prefix='foo') 
    1328             sage: k = ((),(('a',1),)) 
    1329             sage: t = randint(0, 1000) 
    1330             sage: FC1[k] = t 
    1331             sage: del FC2[k] 
    1332             sage: FC1.has_key(k) 
    1333             False 
    1334        """ 
    1335         f = self._filename(key) 
    1336         cache = self._cache 
    1337         if cache is not None and cache.has_key(key): 
    1338             del self._cache[key] 
    1339         if os.path.exists(f + '.sobj'): 
    1340             os.remove(f + '.sobj') 
    1341         if  os.path.exists(f + '.key.sobj'): 
    1342            os.remove(f + '.key.sobj') 
    1343  
    1344  
    1345 class DiskCachedFunction(CachedFunction): 
    1346     """ 
    1347     Works similar to CachedFunction, but instead, we keep the 
    1348     cache on disk (optionally, we keep it in memory too). 
    1349  
    1350     EXAMPLES:: 
    1351  
    1352         sage: from sage.misc.cachefunc import DiskCachedFunction 
    1353         sage: dir = tmp_dir() 
    1354         sage: factor = DiskCachedFunction(factor, dir, memory_cache=True) 
    1355         sage: f = factor(2775); f 
    1356         3 * 5^2 * 37 
    1357         sage: f is factor(2775) 
    1358         True 
    1359     """ 
    1360     def __init__(self, f, dir, memory_cache=False): 
    1361         """ 
    1362         EXAMPLES:: 
    1363  
    1364             sage: from sage.misc.cachefunc import DiskCachedFunction 
    1365             sage: def foo(x): sleep(x) 
    1366             sage: dir = tmp_dir() 
    1367             sage: bar = DiskCachedFunction(foo, dir, memory_cache = False) 
    1368             sage: w = walltime() 
    1369             sage: for i in range(10): bar(1) 
    1370             sage: walltime(w) < 2 
    1371             True 
    1372         """ 
    1373         CachedFunction.__init__(self, f) 
    1374         prefix = f.__name__ 
    1375         self.cache = FileCache(dir, prefix=prefix, memory_cache = memory_cache) 
    1376  
    1377  
    1378 class disk_cached_function: 
    1379     """ 
    1380     Decorator for :class:`DiskCachedFunction`. 
    1381  
    1382     EXAMPLES:: 
    1383  
    1384         sage: dir = tmp_dir() 
    1385         sage: @disk_cached_function(dir) 
    1386         ... def foo(x): return next_prime(2^x)%x 
    1387         sage: x = foo(200);x 
    1388         11 
    1389         sage: @disk_cached_function(dir) 
    1390         ... def foo(x): return 1/x 
    1391         sage: foo(200) 
    1392         11 
    1393         sage: foo.clear_cache() 
    1394         sage: foo(200) 
    1395         1/200 
    1396     """ 
    1397     def __init__(self, dir, memory_cache = False): 
    1398         """ 
    1399         EXAMPLES:: 
    1400  
    1401             sage: dir = tmp_dir() 
    1402             sage: @disk_cached_function(dir, memory_cache=True) 
    1403             ... def foo(x): return next_prime(2^x) 
    1404             sage: x = foo(200) 
    1405             sage: x is foo(200) 
    1406             True 
    1407             sage: @disk_cached_function(dir, memory_cache=False) 
    1408             ... def foo(x): return next_prime(2^x) 
    1409             sage: x is foo(200) 
    1410             False 
    1411         """ 
    1412         self._dir = dir 
    1413         self._memory_cache = memory_cache 
    1414  
    1415     def __call__(self, f): 
    1416         """ 
    1417         EXAMPLES:: 
    1418  
    1419             sage: dir = tmp_dir() 
    1420             sage: @disk_cached_function(dir) 
    1421             ... def foo(x): return ModularSymbols(x) 
    1422             sage: foo(389) 
    1423             Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2 with sign 0 over Rational Field 
    1424         """ 
    1425         return DiskCachedFunction(f, self._dir, memory_cache = self._memory_cache) 
    1426  
    1427 class ClearCacheOnPickle(object): 
    1428     """ 
    1429     This class implements an appropriate __getstate__ method that 
    1430     clears the cache of the methods (see @cached_method) before 
    1431     passing them on to the caller, typically the pickle and copy modules. 
    1432  
    1433     The implemented __getstate__ method calls the __getstate__ methods 
    1434     of classes later in the method resolution order. Therefore, 
    1435     classes which wants this behaviour should inherit first from this 
    1436     one. 
    1437  
    1438     """ 
    1439     def __getstate__(self): 
    1440         """ 
    1441         """ 
    1442         return dict( (key, value) for (key, value) in super(ClearCacheOnPickle, self).__getstate__().iteritems() if not (type(key) == str and key[0:8] == '_cache__') ) 
  • new file sage/misc/cachefunc.pyx

    diff --git a/sage/misc/cachefunc.pyx b/sage/misc/cachefunc.pyx
    new file mode 100644
    - +  
     1r""" 
     2Cached Functions and Methods 
     3 
     4AUTHORS: 
     5 
     6- William Stein (inspired by conversation with Justin Walker). 
     7- Mike Hansen (added doctests and made it work with class methods). 
     8- Willem Jan Palenstijn (add CachedMethodCaller for binding cached 
     9  methods to instances). 
     10- Tom Boothby (added DiskCachedFunction). 
     11- Simon King (improved performance, more doctests, cython version, 
     12  added CachedMethodCallerNoArgs). 
     13 
     14EXAMPLES: 
     15 
     16By trac ticket #11115, cached functions and methods are now also 
     17available in Cython code. The following examples cover various ways 
     18of usage. 
     19 
     20Python functions:: 
     21 
     22    sage: @cached_function 
     23    ... def test_pfunc(x): 
     24    ...     ''' 
     25    ...     Some documentation 
     26    ...     ''' 
     27    ...     return -x 
     28    ...  
     29    sage: test_pfunc(5) is test_pfunc(5) 
     30    True 
     31 
     32Unfortunately, cython functions do not allow arbitrary 
     33decorators. However, one can wrap a Cython function and 
     34turn it into a cached function, by trac ticket #11115. 
     35We need to provide the name that the wrapped method or 
     36function should have, since otherwise the name of the  
     37original function would be used:: 
     38 
     39    sage: cython('''cpdef test_funct(x): return -x''') 
     40    sage: wrapped_funct = cached_function(test_funct, name='wrapped_funct') 
     41    sage: wrapped_funct 
     42    Cached version of <built-in function test_funct> 
     43    sage: wrapped_funct.__name__ 
     44    'wrapped_funct' 
     45    sage: wrapped_funct(5) 
     46    -5 
     47    sage: wrapped_funct(5) is wrapped_funct(5) 
     48    True 
     49 
     50We can proceed similarly for cached methods of Cython classes, 
     51provided that they allow attribute assignment or have a public 
     52attribute ``__cached_methods`` of type ``<dict>``. Since trac ticket 
     53#11115, this is the case for all classes inheriting from 
     54:class:`~sage.structure.parent.Parent`:: 
     55 
     56    sage: cython_code = ['cpdef test_meth(self,x):', 
     57    ... '    "some doc for a wrapped cython method"', 
     58    ... '    return -x', 
     59    ... 'from sage.all import cached_method', 
     60    ... 'from sage.structure.parent cimport Parent', 
     61    ... 'cdef class MyClass(Parent):', 
     62    ... '    wrapped_method = cached_method(test_meth,name="wrapped_method")'] 
     63    sage: cython('\n'.join(cython_code)) 
     64    sage: O = MyClass() 
     65    sage: O.wrapped_method 
     66    Cached version of <built-in function test_meth> 
     67    sage: O.wrapped_method.__name__ 
     68    'wrapped_method' 
     69    sage: O.wrapped_method(5) 
     70    -5 
     71    sage: O.wrapped_method(5) is O.wrapped_method(5) 
     72    True 
     73 
     74By trac ticket #11115, even if a parent does not allow attribute 
     75assignment, it can inherit a cached method from the parent class of a 
     76category (previously, the cache would have been broken):: 
     77 
     78    sage: cython_code = ["from sage.all import cached_method, cached_in_parent_method, Category", 
     79    ... "class MyCategory(Category):", 
     80    ... "    @cached_method", 
     81    ... "    def super_categories(self):", 
     82    ... "        return [Objects()]", 
     83    ... "    class ElementMethods:", 
     84    ... "        @cached_method", 
     85    ... "        def element_cache_test(self):", 
     86    ... "            return -self", 
     87    ... "        @cached_in_parent_method", 
     88    ... "        def element_via_parent_test(self):", 
     89    ... "            return -self", 
     90    ... "    class ParentMethods:", 
     91    ... "        @cached_method", 
     92    ... "        def one(self):", 
     93    ... "            return self.element_class(self,1)", 
     94    ... "        @cached_method", 
     95    ... "        def invert(self, x):", 
     96    ... "            return -x"] 
     97    sage: cython('\n'.join(cython_code)) 
     98    sage: C = MyCategory() 
     99 
     100To make cacheing work on the elements, we need to provide it with 
     101a public attribute ``__cached_methods``, as in the second class below:: 
     102 
     103    sage: cython_code = ["from sage.structure.element cimport Element", 
     104    ... "cdef class MyBrokenElement(Element):", 
     105    ... "    cdef public object x", 
     106    ... "    def __init__(self,P,x):", 
     107    ... "        self.x=x", 
     108    ... "        Element.__init__(self,P)", 
     109    ... "    def __neg__(self):", 
     110    ... "        return MyElement(self.parent(),-self.x)", 
     111    ... "    def _repr_(self):", 
     112    ... "        return '<%s>'%self.x", 
     113    ... "    def __hash__(self):", 
     114    ... "        return hash(self.x)", 
     115    ... "    def __cmp__(self,other):", 
     116    ... "        if isinstance(other, MyBrokenElement):", 
     117    ... "            return cmp(self.x,other.x)", 
     118    ... "        return -1", 
     119    ... "    def raw_test(self):", 
     120    ... "        return -self", 
     121    ... "cdef class MyElement(MyBrokenElement):", 
     122    ... "    cdef public dict __cached_methods", 
     123    ... "from sage.structure.parent cimport Parent", 
     124    ... "cdef class MyParent(Parent):", 
     125    ... "    Element = MyElement"] 
     126    sage: cython('\n'.join(cython_code)) 
     127    sage: P = MyParent(category=C) 
     128    sage: ebroken = MyBrokenElement(P,5) 
     129    sage: e = MyElement(P,5) 
     130 
     131The cached methods inherited by the parent works:: 
     132 
     133    sage: P.one() 
     134    <1> 
     135    sage: P.one() is P.one() 
     136    True 
     137    sage: P.invert(e) 
     138    <-5> 
     139    sage: P.invert(e) is P.invert(e) 
     140    True 
     141 
     142The cached methods inherited by the element with ``__cached_method`` works:: 
     143 
     144    sage: e.element_cache_test() 
     145    <-5> 
     146    sage: e.element_cache_test() is e.element_cache_test() 
     147    True 
     148    sage: e.element_via_parent_test() 
     149    <-5> 
     150    sage: e.element_via_parent_test() is e.element_via_parent_test() 
     151    True 
     152 
     153The other element class can only inherit a `cached_in_parent_method`, since 
     154the cache is stored in the parent. In fact, equal elements share the cache, 
     155even if they are of different types:: 
     156 
     157    sage: e == ebroken 
     158    True 
     159    sage: type(e) == type(ebroken) 
     160    False 
     161    sage: ebroken.element_via_parent_test() is e.element_via_parent_test() 
     162    True 
     163 
     164However, the cache of the other inherited method breaks, although the method 
     165as such works:: 
     166 
     167    sage: ebroken.element_cache_test() 
     168    <-5> 
     169    sage: ebroken.element_cache_test() is ebroken.element_cache_test() 
     170    False 
     171 
     172The cache can be emptied:: 
     173 
     174    sage: a = test_pfunc(5) 
     175    sage: test_pfunc.clear_cache() 
     176    sage: a is test_pfunc(5) 
     177    False 
     178    sage: a = P.one() 
     179    sage: P.one.clear_cache() 
     180    sage: a is P.one() 
     181    False    
     182 
     183Since ``e`` and ``ebroken`` share the cache, when we empty it for one element 
     184it is empty for the other as well:: 
     185 
     186    sage: b = ebroken.element_via_parent_test() 
     187    sage: e.element_via_parent_test.clear_cache() 
     188    sage: b is ebroken.element_via_parent_test() 
     189    False 
     190 
     191Introspection works:: 
     192 
     193    sage: from sage.misc.edit_module import file_and_line 
     194    sage: from sage.misc.sageinspect import sage_getdoc, sage_getfile, sage_getsource 
     195    sage: print sage_getdoc(test_pfunc) 
     196       Some documentation 
     197    sage: print sage_getdoc(O.wrapped_method) 
     198    File: ... 
     199    (starting at line ...) some doc for a wrapped cython method 
     200    sage: print sage_getsource(O.wrapped_method) 
     201    cpdef test_meth(self,x): 
     202        "some doc for a wrapped cython method" 
     203        return -x 
     204 
     205It is a very common special case to cache a method that has no 
     206arguments. In that special case, the time needed to access the cache 
     207can be drastically reduced by using a special implmentation. The 
     208cached method decorator automatically determines which implementation 
     209ought to be chosen. A typical example is 
     210:meth:`sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal.gens` 
     211(no arguments) versus 
     212:meth:`sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal.groebner_basis` 
     213(several arguments):: 
     214 
     215    sage: P.<a,b,c,d> = QQ[] 
     216    sage: I = P*[a,b] 
     217    sage: I.gens() 
     218    [a, b] 
     219    sage: I.gens() is I.gens() 
     220    True 
     221    sage: I.groebner_basis() 
     222    [a, b] 
     223    sage: I.groebner_basis() is I.groebner_basis() 
     224    True 
     225    sage: type(I.gens) 
     226    <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     227    sage: type(I.groebner_basis) 
     228    <type 'sage.misc.cachefunc.CachedMethodCaller'> 
     229 
     230""" 
     231######################################################################## 
     232#       Copyright (C) 2008 William Stein <wstein@gmail.com> 
     233#                          Mike Hansen <mhansen@gmail.com> 
     234# 
     235#  Distributed under the terms of the GNU General Public License (GPL) 
     236# 
     237#                  http://www.gnu.org/licenses/ 
     238######################################################################## 
     239from function_mangling import ArgumentFixer 
     240import os 
     241from sage.misc.sageinspect import sage_getfile, sage_getsourcelines 
     242 
     243cdef class CachedFunction(object): 
     244    """ 
     245    Create a cached version of a function, which only recomputes 
     246    values it hasn't already computed. Synonyme: ``cached_function`` 
     247 
     248    INPUT: 
     249 
     250    - ``f`` -- a function 
     251    - ``name`` (optional string) -- name that the cached version 
     252      of ``f`` should be provided with. 
     253 
     254    If ``f`` is a function, do either ``g = CachedFunction(f)``  
     255    or ``g = cached_function(f)`` to make a cached version of ``f``, 
     256    or put ``@cached_function`` right before the definition of ``f`` 
     257    (i.e., use Python decorators):: 
     258 
     259        @cached_function 
     260        def f(...): 
     261            .... 
     262 
     263    The inputs to the function must be hashable. 
     264 
     265    EXAMPLES:: 
     266 
     267        sage: @cached_function 
     268        ... def mul(x, y=2): 
     269        ...     return x*y 
     270        ... 
     271        sage: mul(3) 
     272        6 
     273 
     274    We demonstrate that the result is cached, and that, moreover, 
     275    the cache takes into account the various ways of providing 
     276    default arguments:: 
     277 
     278        sage: mul(3) is mul(3,2) 
     279        True 
     280        sage: mul(3,y=2) is mul(3,2) 
     281        True 
     282 
     283    The user can clear the cache:: 
     284 
     285        sage: a = mul(4) 
     286        sage: mul.clear_cache() 
     287        sage: a is mul(4) 
     288        False 
     289 
     290    It is also possible to explicitly override the cache with 
     291    a different value:: 
     292 
     293        sage: mul.set_cache('foo',5) 
     294        sage: mul(5,2) 
     295        'foo' 
     296 
     297    """ 
     298    def __init__(self, f, classmethod=False, name=None): 
     299        """ 
     300        Create a cached version of a function, which only recomputes 
     301        values it hasn't already computed. A custom name can be 
     302        provided by an optional argument "name". 
     303 
     304        If f is a function, do either g = CachedFunction(f) to make 
     305        a cached version of f, or put @CachedFunction right before 
     306        the definition of f (i.e., use Python decorators, but then 
     307        the optional argument ``name`` can not be used):: 
     308 
     309            @CachedFunction 
     310            def f(...): 
     311                .... 
     312 
     313        The inputs to the function must be hashable. 
     314 
     315        TESTS:: 
     316 
     317            sage: g = CachedFunction(number_of_partitions) 
     318            sage: g.__name__ 
     319            'number_of_partitions' 
     320            sage: 'partitions' in sage.misc.sageinspect.sage_getdoc(g) 
     321            True 
     322            sage: g(5) 
     323            7 
     324            sage: g.cache 
     325            {((5, None, 'default'), ()): 7} 
     326            sage: def f(t=1): print(t) 
     327            sage: h = CachedFunction(f) 
     328            sage: w = walltime() 
     329            sage: h(); h(1); h(t=1) 
     330            1 
     331            sage: walltime(w) < 2 
     332            True 
     333 
     334        """ 
     335        self._common_init(f, ArgumentFixer(f,classmethod=classmethod), name=name) 
     336        self.cache = {} 
     337 
     338    def _common_init(self, f, argument_fixer, name=None): 
     339        """ 
     340        Perform initialization common to CachedFunction and CachedMethodCaller. 
     341 
     342        TESTS:: 
     343 
     344            sage: @cached_function 
     345            ... def test_cache(x): 
     346            ...     return -x 
     347            sage: test_cache._fix_to_pos is not None  # indirect doctest 
     348            True 
     349 
     350        """ 
     351        self.f = f 
     352        if name is not None: 
     353            self.__name__ = name 
     354        elif hasattr(f, "func_name"): 
     355            self.__name__ = f.func_name 
     356        else: 
     357            self.__name__ = f.__name__ 
     358        self.__module__ = f.__module__ 
     359        if argument_fixer is not None: # it is None for CachedMethodCallerNoArgs 
     360            self._argument_fixer = argument_fixer 
     361            self._fix_to_pos = argument_fixer.fix_to_pos 
     362 
     363    ######### 
     364    ## Introspection 
     365    ## 
     366    ## We provide some methods explicitly, and 
     367    ## forward other questions to the cached function. 
     368 
     369    def _sage_doc_(self): 
     370        """ 
     371        Provide documentation for the cached function. 
     372 
     373        A cached function shall inherit the documentation 
     374        from the function that is wrapped, not from the 
     375        documentation of the wrapper. 
     376 
     377        TEST:: 
     378 
     379            sage: P.<x,y> = QQ[] 
     380            sage: I = P*[x,y] 
     381            sage: from sage.misc.sageinspect import sage_getdoc 
     382            sage: print sage_getdoc(I.groebner_basis) # indirect doctest 
     383            File: sage/rings/polynomial/multi_polynomial_ideal.py (starting at 
     384            line ...) 
     385            ... 
     386               ALGORITHM: Uses Singular, Magma (if available), Macaulay2 (if 
     387               available), or a toy implementation. 
     388 
     389        """ 
     390        f = self.f 
     391        if hasattr(f, "func_doc"): 
     392            try: 
     393                sourcelines = sage_getsourcelines(f) 
     394            except IOError: 
     395                sourcelines = None 
     396            if sourcelines is not None: 
     397                import os 
     398                SAGE_ROOT = os.environ['SAGE_ROOT'] 
     399                filename = sage_getfile(f) 
     400                # The following is a heuristics to get 
     401                # the file name of the cached function 
     402                # or method 
     403                if filename.startswith(SAGE_ROOT+'/devel/sage/'): 
     404                    filename = filename[len(SAGE_ROOT+'/devel/sage/'):] 
     405                elif 'site-packages/' in filename: 
     406                    filename = filename.split('site-packages/',1)[1] 
     407                file_info = "File: %s (starting at line %d)"%(filename,sourcelines[1]) 
     408                doc = file_info+(f.func_doc or '') 
     409            else: 
     410                doc = f.func_doc 
     411        else: 
     412            doc = f.__doc__ 
     413        return doc 
     414 
     415    def _sage_src_(self): 
     416        """ 
     417        Returns the source code for the wrapped function. 
     418 
     419        TESTS:: 
     420 
     421            sage: from sage.misc.sageinspect import sage_getsource 
     422            sage: g = CachedFunction(number_of_partitions) 
     423            sage: 'bober' in sage_getsource(g)  # indirect doctest 
     424            True 
     425 
     426        """ 
     427        from sage.misc.sageinspect import sage_getsource 
     428        return sage_getsource(self.f) 
     429 
     430    def _sage_src_lines_(self): 
     431        r""" 
     432        Returns the list of source lines and the first line number 
     433        of the wrapped function. 
     434 
     435        TEST:: 
     436 
     437            sage: P.<x,y> = QQ[] 
     438            sage: I = P*[x,y] 
     439            sage: from sage.misc.sageinspect import sage_getsourcelines 
     440            sage: l = "        elif algorithm == 'macaulay2:gb':\n" 
     441            sage: l in sage_getsourcelines(I.groebner_basis)[0] # indirect doctest 
     442            True 
     443 
     444        """ 
     445        from sage.misc.sageinspect import sage_getsourcelines 
     446        return sage_getsourcelines(self.f) 
     447 
     448    def _sage_argspec_(self): 
     449        """ 
     450        Return the argspec of the wrapped function or method. 
     451 
     452        This was implemented in trac ticket #11115. 
     453 
     454        EXAMPLE:: 
     455 
     456            sage: P.<x,y> = QQ[] 
     457            sage: I = P*[x,y] 
     458            sage: from sage.misc.sageinspect import sage_getargspec 
     459            sage: sage_getargspec(I.groebner_basis)   # indirect doctest 
     460            ArgSpec(args=['self', 'algorithm', 'deg_bound', 'mult_bound', 'prot'], 
     461            varargs='args', keywords='kwds', defaults=('', None, None, 
     462            False)) 
     463 
     464        """ 
     465        from sage.misc.sageinspect import sage_getargspec 
     466        return sage_getargspec(self.f) 
     467 
     468    def __call__(self, *args, **kwds): 
     469        """ 
     470        Return value from cache or call the wrapped function, 
     471        caching the output. 
     472 
     473        TESTS:: 
     474 
     475            sage: g = CachedFunction(number_of_partitions) 
     476            sage: a = g(5) 
     477            sage: g.get_cache() 
     478            {((5, None, 'default'), ()): 7} 
     479            sage: a = g(10^5)   # indirect doctest 
     480            sage: a == number_of_partitions(10^5) 
     481            True 
     482            sage: a is g(10^5) 
     483            True 
     484            sage: a is number_of_partitions(10^5) 
     485            False 
     486 
     487        """ 
     488        # We shortcut a common case of no arguments 
     489        if args or kwds: 
     490            k = self._fix_to_pos(*args, **kwds) 
     491        else: 
     492            if self._default_key is not None: 
     493                k = self._default_key 
     494            else: 
     495                k = self._default_key = self._fix_to_pos() 
     496 
     497        try: 
     498            return (<dict>self.cache)[k] 
     499        except KeyError: 
     500            w = self.f(*args, **kwds) 
     501            self.cache[k] = w 
     502            return w 
     503 
     504    cpdef get_cache(self): 
     505        """ 
     506        Returns the cache dictionary. 
     507 
     508        EXAMPLES:: 
     509 
     510            sage: g = CachedFunction(number_of_partitions) 
     511            sage: a = g(5) 
     512            sage: g.get_cache() 
     513            {((5, None, 'default'), ()): 7} 
     514 
     515        """ 
     516        return self.cache 
     517 
     518    def is_in_cache(self, *args, **kwds): 
     519        """ 
     520        Checks if the argument list is in the cache. 
     521 
     522        EXAMPLES:: 
     523 
     524            sage: class Foo: 
     525            ...       def __init__(self, x): 
     526            ...           self._x = x 
     527            ...       @cached_method 
     528            ...       def f(self, z, y=0): 
     529            ...           return self._x*z+y 
     530            ... 
     531            sage: a = Foo(2) 
     532            sage: a.f.is_in_cache(3) 
     533            False 
     534            sage: a.f(3) 
     535            6 
     536            sage: a.f.is_in_cache(3,y=0) 
     537            True 
     538        """ 
     539        return self._fix_to_pos(*args, **kwds) in (<dict>self.cache) 
     540 
     541    def set_cache(self, value, *args, **kwds): 
     542        """ 
     543        Set the value for those args and keyword args 
     544        Mind the unintuitive syntax (value first). 
     545        Any idea on how to improve that welcome! 
     546 
     547        EXAMPLES:: 
     548 
     549            sage: g = CachedFunction(number_of_partitions) 
     550            sage: a = g(5) 
     551            sage: g.get_cache() 
     552            {((5, None, 'default'), ()): 7} 
     553            sage: g.set_cache(17, 5) 
     554            sage: g.get_cache() 
     555            {((5, None, 'default'), ()): 17} 
     556            sage: g(5) 
     557            17 
     558 
     559        DEVELOPER NOTE: 
     560 
     561        Is there a way to use the following intuitive syntax? 
     562 
     563        :: 
     564 
     565            sage: g(5) = 19    # todo: not implemented 
     566            sage: g(5)         # todo: not implemented 
     567            19 
     568        """ 
     569        (<dict>self.cache)[self._fix_to_pos(*args, **kwds)] = value 
     570 
     571    def get_key(self, *args, **kwds): 
     572        """ 
     573        Returns the key in the cache to be used when args 
     574        and kwds are passed in as parameters. 
     575 
     576        EXAMPLES:: 
     577 
     578            sage: @cached_function 
     579            ... def foo(x): 
     580            ...    return x^2 
     581            ... 
     582            sage: foo(2) 
     583            4 
     584            sage: foo.get_key(2) 
     585            ((2,), ()) 
     586            sage: foo.get_key(x=3) 
     587            ((3,), ()) 
     588        """ 
     589        return self._fix_to_pos(*args, **kwds) 
     590 
     591    def __repr__(self): 
     592        """ 
     593        EXAMPLES:: 
     594 
     595            sage: g = CachedFunction(number_of_partitions) 
     596            sage: g     # indirect doctest 
     597            Cached version of <function number_of_partitions at 0x...> 
     598        """ 
     599        try: 
     600            return "Cached version of %s"%self.f 
     601        except AttributeError: 
     602            return "Cached version of a method (pending reassignment)" 
     603 
     604    cpdef clear_cache(self): 
     605        """ 
     606        Clear the cache dictionary. 
     607 
     608        EXAMPLES:: 
     609 
     610            sage: g = CachedFunction(number_of_partitions) 
     611            sage: a = g(5) 
     612            sage: g.get_cache() 
     613            {((5, None, 'default'), ()): 7} 
     614            sage: g.clear_cache() 
     615            sage: g.get_cache() 
     616            {} 
     617        """ 
     618        cdef object cache = self.cache 
     619        for key in cache.keys(): 
     620            del cache[key] 
     621 
     622    def precompute(self, arglist, num_processes=1): 
     623        """ 
     624        Cache values for a number of inputs.  Do the computation 
     625        in parallel, and only bother to compute values that we 
     626        haven't already cached. 
     627 
     628        EXAMPLES:: 
     629 
     630            sage: @cached_function 
     631            ... def oddprime_factors(n): 
     632            ...     l = [p for p,e in factor(n) if p != 2] 
     633            ...     return len(l) 
     634            sage: oddprime_factors.precompute(range(1,100), 4) 
     635            sage: oddprime_factors.cache[(25,),()] 
     636            1 
     637        """ 
     638        from sage.parallel.decorate import parallel, normalize_input 
     639        P = parallel(num_processes)(self.f) 
     640        has_key = self.cache.has_key 
     641        get_key = self._fix_to_pos 
     642        new = lambda x: not has_key(get_key(*x[0],**x[1])) 
     643        arglist = filter(new, map(normalize_input, arglist)) 
     644        for ((args,kwargs), val) in P(arglist): 
     645            self.set_cache(val, *args, **kwargs) 
     646 
     647 
     648cached_function = CachedFunction 
     649 
     650class CachedMethodPickle(object): 
     651    """ 
     652    This class helps to unpickle cached methods. 
     653 
     654    NOTE: 
     655 
     656    Since trac ticket #8611, a cached method is an attribute 
     657    of the instance (provided that it has a ``__dict__``). 
     658    Hence, when pickling the instance, it would be attempted 
     659    to pickle that attribute as well, but this is a problem, 
     660    since functions can not be pickled, currently. Therefore, 
     661    we replace the actual cached method by a place holder, 
     662    that kills itself as soon as any attribute is requested. 
     663    Then, the original cached attribute is reinstated. But the 
     664    cached values are in fact saved. 
     665 
     666    EXAMPLE:: 
     667 
     668        sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
     669        sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
     670        sage: I.groebner_basis() 
     671        [y^5*z^3 - 1/4*x^2*z^6 + 1/2*x*y*z^6 + 1/4*y^2*z^6, x^2*y*z^3 - x*y^2*z^3 + 2*y^3*z^3 + z^6, x*y^3 + y^4 + x*z^3, x^3 + y^3 + z^3] 
     672        sage: I.groebner_basis 
     673        Cached version of <function groebner_basis at 0x...> 
     674 
     675    We now pickle and unpickle the ideal. The cached method 
     676    ``groebner_basis`` is replaced by a placeholder:: 
     677 
     678        sage: J = loads(dumps(I)) 
     679        sage: J.groebner_basis 
     680        Pickle of the cached method "groebner_basis" 
     681 
     682    But as soon as any other attribute is requested from the 
     683    placeholder, it replaces itself by the cached method, and 
     684    the entries of the cache are actually preserved:: 
     685 
     686        sage: J.groebner_basis.is_in_cache() 
     687        True 
     688        sage: J.groebner_basis 
     689        Cached version of <function groebner_basis at 0x...> 
     690        sage: J.groebner_basis() == I.groebner_basis() 
     691        True 
     692 
     693    TESTS: 
     694 
     695    Since Trac Ticket #11115, there is a special implementation for 
     696    cached methods that don't take arguments:: 
     697 
     698        sage: P.<a,b,c,d> = QQ[] 
     699        sage: I = P*[a,b] 
     700        sage: type(I.gens) 
     701        <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     702        sage: type(I.groebner_basis) 
     703        <type 'sage.misc.cachefunc.CachedMethodCaller'> 
     704 
     705    We demonstrate that both implementations can be pickled and 
     706    preserve the cache. For that purpose, we assign nonsense to the 
     707    cache. Of course, it is a very bad idea to override the cache in 
     708    that way.  So, please don't try this at home:: 
     709 
     710        sage: I.groebner_basis.set_cache('foo',algorithm='singular') 
     711        sage: I.groebner_basis(algorithm='singular') 
     712        'foo' 
     713        sage: I.gens.set_cache('bar') 
     714        sage: I.gens() 
     715        'bar' 
     716        sage: J = loads(dumps(I)) 
     717        sage: J.gens() 
     718        'bar' 
     719        sage: J.groebner_basis(algorithm='singular') 
     720        'foo' 
     721 
     722    Anyway, the cache will be automatically reconstructed after 
     723    clearing it:: 
     724 
     725        sage: J.gens.clear_cache() 
     726        sage: J.gens() 
     727        [a, b] 
     728        sage: J.groebner_basis.clear_cache() 
     729        sage: J.groebner_basis(algorithm='singular') 
     730        [a, b] 
     731 
     732    AUTHOR: 
     733 
     734    - Simon King (2011-01) 
     735    """ 
     736    def __init__(self, inst, name, cache=None): 
     737        """ 
     738        INPUT: 
     739 
     740        - ``inst`` - some instance. 
     741        - ``name`` (string) - usually the name of an attribute 
     742          of ``inst`` to which ``self`` is assigned. 
     743 
     744        TEST:: 
     745 
     746            sage: from sage.misc.cachefunc import CachedMethodPickle 
     747            sage: P = CachedMethodPickle(1, 'foo') 
     748            sage: P 
     749            Pickle of the cached method "foo" 
     750 
     751        """ 
     752        self._instance = inst 
     753        self._name = name 
     754        self._cache = cache 
     755    def __repr__(self): 
     756        """ 
     757        TEST:: 
     758 
     759            sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
     760            sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
     761            sage: G = I.groebner_basis() 
     762            sage: J = loads(dumps(I)) 
     763            sage: J.groebner_basis  #indirect doctest 
     764            Pickle of the cached method "groebner_basis" 
     765        """ 
     766        return 'Pickle of the cached method "%s"'%self._name 
     767    def __reduce__(self): 
     768        """ 
     769        This class is a pickle. However, sometimes, pickles 
     770        need to be pickled another time. 
     771 
     772        TEST:: 
     773 
     774            sage: PF = WeylGroup(['A',3]).pieri_factors() 
     775            sage: a = PF.an_element() 
     776            sage: a.bruhat_lower_covers() 
     777            [[0 1 0 0] 
     778            [0 0 1 0] 
     779            [1 0 0 0] 
     780            [0 0 0 1], [0 1 0 0] 
     781            [1 0 0 0] 
     782            [0 0 0 1] 
     783            [0 0 1 0], [1 0 0 0] 
     784            [0 0 1 0] 
     785            [0 0 0 1] 
     786            [0 1 0 0]] 
     787            sage: b = loads(dumps(a)) 
     788            sage: b.bruhat_lower_covers 
     789            Pickle of the cached method "bruhat_lower_covers" 
     790 
     791        When we now pickle ``b``, the pickle of the cached method 
     792        needs to be taken care of:: 
     793 
     794            sage: c = loads(dumps(b))  # indirect doctest 
     795            sage: c.bruhat_lower_covers 
     796            Pickle of the cached method "bruhat_lower_covers" 
     797            sage: c.bruhat_lower_covers() 
     798            [[0 1 0 0] 
     799            [0 0 1 0] 
     800            [1 0 0 0] 
     801            [0 0 0 1], [0 1 0 0] 
     802            [1 0 0 0] 
     803            [0 0 0 1] 
     804            [0 0 1 0], [1 0 0 0] 
     805            [0 0 1 0] 
     806            [0 0 0 1] 
     807            [0 1 0 0]] 
     808 
     809        """ 
     810        return CachedMethodPickle,(self._instance,self._name,self._cache) 
     811    def __call__(self,*args,**kwds): 
     812        """ 
     813        The purpose of this call method is to kill ``self`` and to 
     814        replace it by an actual :class:`CachedMethodCaller`. The last 
     815        thing that ``self`` does before disappearing is to call the 
     816        :class:`CachedMethodCaller` and return the result. 
     817 
     818        EXAMPLE:: 
     819 
     820            sage: P.<a,b,c,d> = QQ[] 
     821            sage: I = P*[a,b] 
     822            sage: I.gens 
     823            Cached version of <function gens at 0x...> 
     824            sage: J = loads(dumps(I)) 
     825            sage: J.gens 
     826            Pickle of the cached method "gens" 
     827            sage: J.gens()   # indirect doctest 
     828            [a, b] 
     829            sage: J.gens 
     830            Cached version of <function gens at 0x...> 
     831 
     832        """ 
     833        self._instance.__dict__.__delitem__(self._name) 
     834        CM = getattr(self._instance,self._name) 
     835        if self._cache is not None: 
     836            if isinstance(CM, CachedMethodCallerNoArgs): 
     837                CM.cache = self._cache 
     838            else: 
     839                for k,v in self._cache: 
     840                    CM.cache[k] = v 
     841        return CM(*args,**kwds) 
     842         
     843    def __getattr__(self,s): 
     844        """ 
     845        TEST:: 
     846 
     847            sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
     848            sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
     849            sage: G = I.groebner_basis() 
     850            sage: J = loads(dumps(I)) 
     851            sage: J.groebner_basis 
     852            Pickle of the cached method "groebner_basis" 
     853 
     854        If an attribute of name ``s`` is requested (say, 
     855        ``is_in_cache``), the attribute ``self._name`` of 
     856        ``self._instance`` is deleted. Then, the attribute 
     857        of name ``s`` of the attribute ``self._name`` of 
     858        ``self._instance`` is requested. Since ``self._name`` 
     859        is a cached method defined for the class of 
     860        ``self._instance``, retrieving the just-deleted 
     861        attribute ``self._name`` succeeds. 
     862 
     863        In that way, the unpickling of the cached method is 
     864        finally accomplished:: 
     865 
     866            sage: J.groebner_basis.is_in_cache()  #indirect doctest 
     867            True 
     868            sage: J.groebner_basis 
     869            Cached version of <function groebner_basis at 0x...> 
     870 
     871        """ 
     872        self._instance.__dict__.__delitem__(self._name) 
     873        CM = getattr(self._instance,self._name) 
     874        if self._cache is not None: 
     875            if isinstance(CM, CachedMethodCallerNoArgs): 
     876                CM.cache = self._cache 
     877            else: 
     878                for k,v in self._cache: 
     879                    CM.cache[k] = v 
     880        return getattr(CM,s) 
     881 
     882cdef class CachedMethodCaller(CachedFunction): 
     883    """ 
     884    Utility class that is used by :class:`CachedMethod` to bind a 
     885    cached method to an instance. 
     886 
     887    NOTE: 
     888 
     889    Since Trac Ticket #11115, there is a special implementation 
     890    :class:`CachedMethodCallerNoArgs` for methods that do not take 
     891    arguments. 
     892 
     893    EXAMPLE:: 
     894 
     895        sage: class A: 
     896        ...    @cached_method 
     897        ...    def bar(self,x): 
     898        ...        return x^2 
     899        sage: a = A() 
     900        sage: a.bar 
     901        Cached version of <function bar at 0x...> 
     902        sage: type(a.bar) 
     903        <type 'sage.misc.cachefunc.CachedMethodCaller'> 
     904        sage: a.bar(2) is a.bar(x=2) 
     905        True 
     906 
     907    """ 
     908    def __init__(self, CachedMethod cachedmethod, inst, cache=None, inst_in_key=False, name=None): 
     909        """ 
     910        EXAMPLES:: 
     911 
     912            sage: class Foo: 
     913            ...       def __init__(self, x): 
     914            ...           self._x = x 
     915            ...       @cached_method 
     916            ...       def f(self,*args): 
     917            ...           return self._x^2 
     918            ... 
     919            sage: a = Foo(2) 
     920            sage: a.f.get_cache() 
     921            {} 
     922            sage: a.f() 
     923            4 
     924            sage: a.f.get_cache() 
     925            {((), ()): 4} 
     926        """ 
     927        # initialize CachedFunction, but re-use the ArgumentFixer 
     928        self._common_init(cachedmethod._cachedfunc.f, cachedmethod._cachedfunc._argument_fixer, name=name) 
     929        self.cache = {} if cache is None else cache 
     930        self._instance = inst 
     931        self._inst_in_key = inst_in_key 
     932        self._cachedmethod = cachedmethod 
     933 
     934    def __reduce__(self): 
     935        """ 
     936        The pickle of a :class:`CachedMethodCaller` unpickles 
     937        to a :class:`CachedMethodPickle`, that is able to replace 
     938        itself by a copy of the original :class:`CachedMethodCaller`. 
     939 
     940        TEST:: 
     941 
     942            sage: R.<x, y, z> = PolynomialRing(QQ, 3) 
     943            sage: I = R*(x^3 + y^3 + z^3,x^4-y^4) 
     944            sage: G = I.groebner_basis() 
     945            sage: J = loads(dumps(I))  #indirect doctest 
     946            sage: J.groebner_basis 
     947            Pickle of the cached method "groebner_basis" 
     948            sage: J.groebner_basis.is_in_cache() 
     949            True 
     950            sage: J.groebner_basis 
     951            Cached version of <function groebner_basis at 0x...> 
     952 
     953        """ 
     954#        if hasattr(self._instance,self._cachedmethod._cache_name): 
     955#            return CachedMethodPickle,(self._instance,self.__name__) 
     956        if isinstance(self._cachedmethod, CachedInParentMethod) or hasattr(self._instance,self._cachedmethod._cache_name): 
     957            return CachedMethodPickle,(self._instance,self.__name__) 
     958        return CachedMethodPickle,(self._instance,self.__name__,self.cache.items()) 
     959 
     960    def _instance_call(self, *args, **kwds): 
     961        """ 
     962        Call the cached method without using the cache. 
     963 
     964        EXAMPLE:: 
     965 
     966            sage: P.<a,b,c,d> = QQ[] 
     967            sage: I = P*[a,b] 
     968            sage: I.groebner_basis() 
     969            [a, b] 
     970            sage: I.groebner_basis._instance_call() is I.groebner_basis() 
     971            False 
     972            sage: I.groebner_basis._instance_call() == I.groebner_basis() 
     973            True 
     974 
     975        """ 
     976        return self._cachedmethod._instance_call(self._instance, *args, **kwds) 
     977 
     978    def __call__(self, *args, **kwds): 
     979        """ 
     980        Call the cached method. 
     981 
     982        TESTS:: 
     983 
     984            sage: class Foo: 
     985            ...       @cached_method 
     986            ...       def f(self, x,y=1): 
     987            ...           return x+y 
     988            ... 
     989            sage: a = Foo() 
     990            sage: a.f(1)  #indirect doctest 
     991            2 
     992 
     993        The result is cached, taking into account 
     994        the three ways of providing (named) arguments:: 
     995 
     996            sage: a.f(5) is a.f(5,1) 
     997            True 
     998            sage: a.f(5) is a.f(5,y=1) 
     999            True 
     1000            sage: a.f(5) is a.f(y=1,x=5) 
     1001            True 
     1002 
     1003        We test that #5843 is fixed:: 
     1004 
     1005            sage: class Foo: 
     1006            ...       def __init__(self, x): 
     1007            ...           self._x = x 
     1008            ...       @cached_method 
     1009            ...       def f(self, y): 
     1010            ...           return self._x 
     1011            ... 
     1012            sage: a = Foo(2) 
     1013            sage: b = Foo(3) 
     1014            sage: a.f(b.f) 
     1015            2 
     1016        """ 
     1017        # We shortcut a common case of no arguments 
     1018        # and we avoid calling another python function, 
     1019        # although that means to duplicate code. 
     1020        cdef int lenargs 
     1021        cdef int nargs 
     1022        cdef tuple k 
     1023        cdef dict cache = self.cache 
     1024        if kwds: 
     1025            if self._inst_in_key: 
     1026                k = (self._instance,self._fix_to_pos(*args, **kwds)) 
     1027            else: 
     1028                k = self._fix_to_pos(*args, **kwds) 
     1029        else: 
     1030            if args: 
     1031                lenargs = len(args) 
     1032                nargs = self._argument_fixer._nargs 
     1033                if self._inst_in_key: 
     1034                    if lenargs>=nargs: 
     1035                        k = (self._instance,(args,())) 
     1036                    else: 
     1037                        k = (self._instance,(<tuple>args+(<tuple>self._argument_fixer._default_tuple)[-nargs+lenargs:],())) 
     1038                else: 
     1039                    if lenargs>=nargs: 
     1040                        k = (args,()) 
     1041                    else: 
     1042                        k = (<tuple>args+(<tuple>self._argument_fixer._default_tuple)[-nargs+lenargs:],()) 
     1043            elif self._default_key is not None: 
     1044                k = self._default_key 
     1045            else: 
     1046                if self._inst_in_key: 
     1047                    k = self._default_key = (self._instance,self._fix_to_pos()) 
     1048                else: 
     1049                    k = self._default_key = self._fix_to_pos() 
     1050        try: 
     1051            return cache[k] 
     1052        except KeyError: 
     1053            w = self._cachedmethod._instance_call(self._instance, *args, **kwds) 
     1054            cache[k] = w 
     1055            return w 
     1056 
     1057    def get_key(self, *args, **kwds): 
     1058        """ 
     1059        Convert arguments to the key for this instance's cache. 
     1060 
     1061        EXAMPLES:: 
     1062 
     1063            sage: class Foo: 
     1064            ...       def __init__(self, x): 
     1065            ...           self._x = x 
     1066            ...       @cached_method 
     1067            ...       def f(self, y, z=0): 
     1068            ...           return self._x * y + z 
     1069            ... 
     1070            sage: a = Foo(2) 
     1071            sage: z = a.f(37) 
     1072            sage: k = a.f.get_key(37); k 
     1073            ((37, 0), ()) 
     1074            sage: a.f.get_cache()[k] is z 
     1075            True 
     1076 
     1077        Note that the method does not test whether there are 
     1078        too many arguments, or wrong argument names:: 
     1079 
     1080            sage: a.f.get_key(1,2,3,x=4,y=5,z=6) 
     1081            ((1, 2, 3), (('x', 4), ('y', 5), ('z', 6))) 
     1082 
     1083        It does, however, take into account the different 
     1084        ways of providing named arguments, possibly with a 
     1085        default value:: 
     1086 
     1087            sage: a.f.get_key(5) 
     1088            ((5, 0), ()) 
     1089            sage: a.f.get_key(y=5) 
     1090            ((5, 0), ()) 
     1091            sage: a.f.get_key(5,0) 
     1092            ((5, 0), ()) 
     1093            sage: a.f.get_key(5,z=0) 
     1094            ((5, 0), ()) 
     1095            sage: a.f.get_key(y=5,z=0) 
     1096            ((5, 0), ()) 
     1097 
     1098        """ 
     1099        if self._inst_in_key: 
     1100            return (self._instance,self._fix_to_pos(*args,**kwds)) 
     1101        return self._fix_to_pos(*args,**kwds) 
     1102 
     1103    def __get__(self, inst, cls): #cls=None): 
     1104        r""" 
     1105        Get a :class:`CachedMethodCaller` bound to a specific 
     1106        instance of the class of the cached method. 
     1107 
     1108        NOTE: 
     1109 
     1110        :class:`CachedMethodCaller` has a separate ``__get__`` 
     1111        since the categories framework creates and caches the 
     1112        return value of ``CachedMethod.__get__`` with 
     1113        ``inst==None``. 
     1114 
     1115        This getter attempts to assign a bound method as an 
     1116        attribute to the given instance. If this is not 
     1117        possible (for example, for some extension classes), 
     1118        it is attempted to find an attribute ``__cached_methods``, 
     1119        and store/retrieve the bound method there. In that 
     1120        way, cached methods can be implemented for extension 
     1121        classes deriving from :class:`~sage.structure.parent.Parent` 
     1122        and :class:`~sage.structure.element.Element`. 
     1123 
     1124        TESTS: 
     1125 
     1126        Due to the separate ``__get__`` method, it is possible 
     1127        to define a cached method in one class and use it as 
     1128        an attribute of another class. 
     1129 
     1130            sage: class Foo: 
     1131            ...       @cached_method 
     1132            ...       def f(self, y): 
     1133            ...           return y - 1 
     1134            sage: class Bar: 
     1135            ...       f = Foo.f 
     1136            sage: b1 = Bar() 
     1137            sage: b2 = Bar() 
     1138 
     1139        The :class:`CachedMethod` is replaced by an instance 
     1140        of :class:`CachedMethodCaller` that (by trac ticket 
     1141        #8611) is set as an attribute. Hence, we have:: 
     1142 
     1143            sage: b1.f is b1.f 
     1144            True 
     1145 
     1146        Any instance of ``Bar`` gets its own instance of 
     1147        :class:`CachedMethodCaller``:: 
     1148 
     1149            sage: b1.f is b2.f 
     1150            False 
     1151  
     1152        The method caller knows the instance that it belongs 
     1153        to:: 
     1154 
     1155            sage: Foo.f._instance is None 
     1156            True 
     1157            sage: b1.f._instance is b1 
     1158            True 
     1159            sage: b2.f._instance is b2 
     1160            True 
     1161 
     1162        An extension class can inherit a cached method from the 
     1163        parent or element class of a category (trac ticket #11115). 
     1164        See :class:`CachedMethodCaller` for examples. 
     1165 
     1166        """ 
     1167        # This is for Parents or Elements that do not allow attribute assignment 
     1168        try: 
     1169            return (<dict>inst.__cached_methods).__getitem__(self._cachedmethod._cachedfunc.__name__) 
     1170        except (AttributeError,TypeError,KeyError): 
     1171            pass 
     1172        Caller = CachedMethodCaller(self._cachedmethod, inst, cache=self._cachedmethod._get_instance_cache(inst), inst_in_key=self._inst_in_key, name=self._cachedmethod._cachedfunc.__name__) 
     1173        try: 
     1174            setattr(inst,self._cachedmethod._cachedfunc.__name__, Caller) 
     1175            return Caller 
     1176        except AttributeError,msg: 
     1177            pass 
     1178        try: 
     1179            if inst.__cached_methods is None: 
     1180                inst.__cached_methods = {self._cachedmethod._cachedfunc.__name__ : Caller} 
     1181            else: 
     1182                (<dict>inst.__cached_methods).__setitem__(self._cachedmethod._cachedfunc.__name__, Caller) 
     1183        except AttributeError,msg: 
     1184            pass 
     1185        return Caller 
     1186 
     1187cdef class CachedMethodCallerNoArgs(CachedFunction): 
     1188    """ 
     1189    Utility class that is used by :class:`CachedMethod` to bind a 
     1190    cached method to an instance, in the case of a method that does 
     1191    not accept any arguments except ``self``. 
     1192 
     1193    NOTE: 
     1194 
     1195    The return value ``None`` would not be cached. So, if you have 
     1196    a method that does not accept arguments and may return ``None`` 
     1197    after a lengthy computation, then ``@cached_method`` should not 
     1198    be used. 
     1199 
     1200    EXAMPLE:: 
     1201 
     1202        sage: P.<a,b,c,d> = QQ[] 
     1203        sage: I = P*[a,b] 
     1204        sage: I.gens 
     1205        Cached version of <function gens at 0x...> 
     1206        sage: type(I.gens) 
     1207        <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     1208        sage: I.gens is I.gens 
     1209        True 
     1210        sage: I.gens() is I.gens() 
     1211        True 
     1212 
     1213    AUTHOR: 
     1214 
     1215    - Simon King (2011-04) 
     1216    """ 
     1217    def __init__(self, inst, f, cache=None, name=None): 
     1218        """ 
     1219        EXAMPLES:: 
     1220 
     1221            sage: class Foo: 
     1222            ...       def __init__(self, x): 
     1223            ...           self._x = x 
     1224            ...       @cached_method 
     1225            ...       def f(self): 
     1226            ...           return self._x^2 
     1227            ... 
     1228            sage: a = Foo(2) 
     1229            sage: print a.f.get_cache() 
     1230            None 
     1231            sage: a.f() 
     1232            4 
     1233            sage: a.f.get_cache() 
     1234            4 
     1235 
     1236        """ 
     1237        # initialize CachedFunction 
     1238        if isinstance(f,basestring): 
     1239            try: 
     1240                F = getattr(inst.__class__,f) 
     1241            except AttributeError: 
     1242                 F = getattr(inst,f) 
     1243            if isinstance(F,CachedFunction): 
     1244                f = F.f 
     1245            else: 
     1246                f = F 
     1247        self._common_init(f, None, name=name) 
     1248        # This is for unpickling a CachedMethodCallerNoArgs out 
     1249        # of an old CachedMethodCaller: 
     1250        cachename = '_cache__' + self.__name__ 
     1251        if hasattr(inst, cachename): 
     1252            # This is for data that are pickled in an old format 
     1253            CACHE = getattr(inst, cachename) 
     1254            if len(CACHE)>1: 
     1255                raise TypeError, "Apparently you are opening a pickle in which '%s' was a method accepting arguments"%name 
     1256            if len(CACHE)==1: 
     1257                self.cache = CACHE.values()[0] 
     1258            else: 
     1259                self.cache = cache 
     1260            delattr(inst, cachename) 
     1261        else: 
     1262            self.cache = cache  # None means: the underlying method will be called 
     1263        self._instance = inst 
     1264 
     1265    def __reduce__(self): 
     1266        """ 
     1267        Since functions can not be pickled, the cached method caller 
     1268        is pickled by a :class:`CachedMethodPickle`, that replaces 
     1269        itself by an actual :class:`CachedMethodCallerNoArgs` as soon 
     1270        as it is asked to do anything. 
     1271 
     1272        TEST:: 
     1273 
     1274            sage: P.<a,b,c,d> = QQ[] 
     1275            sage: I = P*[a,b] 
     1276            sage: I.gens() 
     1277            [a, b] 
     1278            sage: I.gens 
     1279            Cached version of <function gens at 0x...> 
     1280            sage: J = loads(dumps(I)) 
     1281            sage: J.gens 
     1282            Pickle of the cached method "gens" 
     1283            sage: J.gens.cache 
     1284            [a, b] 
     1285            sage: J.gens 
     1286            Cached version of <function gens at 0x...> 
     1287 
     1288        """ 
     1289        return CachedMethodPickle,(self._instance,self.__name__,self.cache) 
     1290 
     1291    def _instance_call(self): 
     1292        """ 
     1293        Call the cached method without using the cache. 
     1294 
     1295        EXAMPLE:: 
     1296 
     1297            sage: P.<a,b,c,d> = QQ[] 
     1298            sage: I = P*[a,b] 
     1299            sage: I.gens() 
     1300            [a, b] 
     1301            sage: I.gens._instance_call() is I.gens() 
     1302            False 
     1303            sage: I.gens._instance_call() == I.gens() 
     1304            True 
     1305 
     1306        """ 
     1307        return self.f(self._instance) 
     1308 
     1309    def __call__(self): 
     1310        """ 
     1311        Call the cached method. 
     1312 
     1313        EXAMPLE:: 
     1314 
     1315            sage: P.<a,b,c,d> = QQ[] 
     1316            sage: I = P*[a,b] 
     1317            sage: I.gens()    # indirect doctest 
     1318            [a, b] 
     1319            sage: I.gens() is I.gens() 
     1320            True 
     1321 
     1322        """ 
     1323        if self.cache is None: 
     1324            f = self.f 
     1325            self.cache = f(self._instance) 
     1326        return self.cache 
     1327 
     1328    def set_cache(self, value): 
     1329        """ 
     1330        Override the cache with a specific value. 
     1331 
     1332        NOTE: 
     1333 
     1334        ``None`` is not suitable for a cached value. It would be 
     1335        interpreted as an empty cache, forcing a new computation. 
     1336 
     1337        EXAMPLES:: 
     1338 
     1339            sage: P.<a,b,c,d> = QQ[] 
     1340            sage: I = P*[a,b] 
     1341            sage: I.gens() 
     1342            [a, b]  
     1343            sage: I.gens.set_cache('bar') 
     1344            sage: I.gens() 
     1345            'bar' 
     1346 
     1347        The cache can be emptied and thus the original value will 
     1348        be reconstructed:: 
     1349 
     1350            sage: I.gens.clear_cache() 
     1351            sage: I.gens() 
     1352            [a, b] 
     1353 
     1354        The attempt to assign ``None`` to the cache fails:: 
     1355 
     1356            sage: I.gens.set_cache(None) 
     1357            sage: I.gens() 
     1358            [a, b] 
     1359 
     1360        """ 
     1361        self.cache = value 
     1362 
     1363    cpdef clear_cache(self): 
     1364        r""" 
     1365        Clear the cache dictionary. 
     1366 
     1367        EXAMPLES:: 
     1368 
     1369            sage: P.<a,b,c,d> = QQ[] 
     1370            sage: I = P*[a,b] 
     1371            sage: I.gens() 
     1372            [a, b]  
     1373            sage: I.gens.set_cache('bar') 
     1374            sage: I.gens() 
     1375            'bar' 
     1376 
     1377        The cache can be emptied and thus the original value will 
     1378        be reconstructed:: 
     1379 
     1380            sage: I.gens.clear_cache() 
     1381            sage: I.gens() 
     1382            [a, b] 
     1383 
     1384        """ 
     1385        self.cache = None 
     1386 
     1387    def is_in_cache(self): 
     1388        """ 
     1389        Answers whether the return value is already in the cache. 
     1390 
     1391        NOTE: 
     1392 
     1393        Recall that a cached method without arguments can not cache 
     1394        the return value ``None``. 
     1395 
     1396        EXAMPLE:: 
     1397 
     1398            sage: P.<x,y> = QQ[] 
     1399            sage: I = P*[x,y] 
     1400            sage: I.gens.is_in_cache() 
     1401            False 
     1402            sage: I.gens() 
     1403            [x, y] 
     1404            sage: I.gens.is_in_cache() 
     1405            True 
     1406 
     1407        """ 
     1408        return self.cache is not None 
     1409 
     1410    def __get__(self, inst, cls): #cls=None): 
     1411        """ 
     1412        Get a :class:`CachedMethodCallerNoArgs` bound to a specific 
     1413        instance of the class of the cached method. 
     1414 
     1415        NOTE: 
     1416 
     1417        :class:`CachedMethodCallerNoArgs` has a separate ``__get__`` 
     1418        since the categories framework creates and caches the 
     1419        return value of ``CachedMethod.__get__`` with 
     1420        ``inst==None``. 
     1421 
     1422        This getter attempts to assign a bound method as an 
     1423        attribute to the given instance. If this is not 
     1424        possible (for example, for some extension classes), 
     1425        it is attempted to find an attribute ``__cached_methods``, 
     1426        and store/retrieve the bound method there. In that 
     1427        way, cached methods can be implemented for extension 
     1428        classes deriving from :class:`~sage.structure.parent.Parent` 
     1429        and :class:`~sage.structure.element.Element`. 
     1430 
     1431        TESTS: 
     1432 
     1433        Due to the separate ``__get__`` method, it is possible 
     1434        to define a cached method in one class and use it as 
     1435        an attribute of another class. 
     1436 
     1437            sage: class Foo: 
     1438            ...       def __init__(self, n): 
     1439            ...           self.__n = n 
     1440            ...       @cached_method 
     1441            ...       def f(self): 
     1442            ...           return self.__n^2 
     1443            ... 
     1444            sage: class Bar: 
     1445            ...       f = Foo.f 
     1446            ... 
     1447            sage: b1 = Bar() 
     1448            sage: b2 = Bar() 
     1449 
     1450        The :class:`CachedMethod` is replaced by an instance of 
     1451        :class:`CachedMethodCallerNoArgs` that is set as an 
     1452        attribute. Hence, we have:: 
     1453 
     1454            sage: b1.f is b1.f 
     1455            True 
     1456            sage: type(b1.f) 
     1457            <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     1458 
     1459        Any instance of ``Bar`` gets its own instance of 
     1460        :class:`CachedMethodCaller``:: 
     1461 
     1462            sage: b1.f is b2.f 
     1463            False 
     1464  
     1465        The method caller knows the instance that it belongs 
     1466        to:: 
     1467 
     1468            sage: Foo.f._instance is None 
     1469            True 
     1470            sage: b1.f._instance is b1 
     1471            True 
     1472            sage: b2.f._instance is b2 
     1473            True 
     1474 
     1475        """ 
     1476        # This is for Parents or Elements that do not allow attribute assignment 
     1477        try: 
     1478            return (<dict>inst.__cached_methods).__getitem__(self.__name__) 
     1479        except (AttributeError,TypeError,KeyError),msg: 
     1480            pass 
     1481        Caller = CachedMethodCallerNoArgs(inst, self.f, name=self.__name__) 
     1482        try: 
     1483            setattr(inst,self.__name__, Caller) 
     1484            return Caller 
     1485        except AttributeError: 
     1486            pass 
     1487        try: 
     1488            if inst.__cached_methods is None: 
     1489                inst.__cached_methods = {self.__name__ : Caller} 
     1490            else: 
     1491                (<dict>inst.__cached_methods).__setitem__(self.__name__, Caller) 
     1492        except AttributeError,msg: 
     1493            pass 
     1494        return Caller 
     1495 
     1496cdef class CachedMethod(object): 
     1497    """ 
     1498    A decorator that creates a cached version of an instance 
     1499    method of a class. 
     1500 
     1501    NOTE: 
     1502 
     1503    For proper behavior, the method must be a pure function 
     1504    (no side effects). Arguments to the method must be hashable. 
     1505 
     1506    EXAMPLES:: 
     1507 
     1508        sage: class Foo(object): 
     1509        ...       @cached_method 
     1510        ...       def f(self, t, x=2): 
     1511        ...           print 'computing' 
     1512        ...           return t**x 
     1513        sage: a = Foo() 
     1514 
     1515    The example shows that the actual computation 
     1516    takes place only once, and that the result is 
     1517    identic for equivalent input:: 
     1518    
     1519        sage: res = a.f(3, 2); res 
     1520        computing 
     1521        9 
     1522        sage: a.f(t = 3, x = 2) is res 
     1523        True 
     1524        sage: a.f(3) is res 
     1525        True 
     1526 
     1527    Note, however, that the :class:`CachedMethod` is replaced by a 
     1528    :class:`CachedMethodCaller` or :class:`CachedMethodCallerNoArgs` 
     1529    as soon as it is bound to an instance or class:: 
     1530 
     1531        sage: P.<a,b,c,d> = QQ[] 
     1532        sage: I = P*[a,b] 
     1533        sage: type(I.__class__.gens) 
     1534        <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     1535 
     1536    So, you would hardly ever see an instance of this class alive. 
     1537    """ 
     1538    def __init__(self, f, name=None): 
     1539        """ 
     1540        EXAMPLES:: 
     1541 
     1542            sage: class Foo: 
     1543            ...       def __init__(self, x): 
     1544            ...           self._x = x 
     1545            ...       @cached_method 
     1546            ...       def f(self,n): 
     1547            ...           return self._x^n 
     1548            ...       @cached_method 
     1549            ...       def f0(self): 
     1550            ...           return self._x^2 
     1551            ... 
     1552            sage: a = Foo(2) 
     1553            sage: a.f(2) 
     1554            4 
     1555            sage: a.f0() 
     1556            4 
     1557 
     1558        The computations in method ``f`` are tried to store in a 
     1559        dictionary assigned to the instance ``a``:: 
     1560 
     1561            sage: hasattr(a, '_cache__f') 
     1562            True 
     1563            sage: a._cache__f 
     1564            {((2,), ()): 4} 
     1565 
     1566        As a shortcut, useful to speed up internal computations, 
     1567        the same dictionary is also available as an attribute 
     1568        of the ``CachedMethodCaller``:: 
     1569 
     1570            sage: type(a.f) 
     1571            <type 'sage.misc.cachefunc.CachedMethodCaller'> 
     1572            sage: a.f.cache is a._cache__f 
     1573            True 
     1574 
     1575        Note that if the instance ``a`` would not accept attribute 
     1576        assignment, the computations would still be cached in 
     1577        ``a.f.cache``, and they would in fact be preserved when 
     1578        pickling. 
     1579 
     1580        The cached method ``f0`` accepts no arguments, which allows 
     1581        for an improved way of caching: By an attribute of the cached 
     1582        method itsel. This cache is *only* available in that way, i.e., 
     1583        it is not additionally stored as an attribute of ``a``:: 
     1584 
     1585            sage: type(a.f0) 
     1586            <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     1587            sage: a.f0.cache 
     1588            4 
     1589            sage: sorted(dir(a)) 
     1590            ['__doc__', '__init__', '__module__', '_cache__f', '_x', 'f', 'f0'] 
     1591 
     1592        """ 
     1593        self._cache_name = '_cache__' + (name or f.__name__) 
     1594        self._cachedfunc = CachedFunction(f, classmethod=True, name=name) 
     1595 
     1596    def _instance_call(self, inst, *args, **kwds): 
     1597        """ 
     1598        Call the cached method *without* using the cache. 
     1599 
     1600        INPUT: 
     1601 
     1602        - ``inst`` - an instance at which the method is to be called 
     1603        - Further positional or named arguments. 
     1604 
     1605        EXAMPLES:: 
     1606 
     1607            sage: class Foo(object): 
     1608            ...       def __init__(self, x): 
     1609            ...           self._x = x 
     1610            ...       @cached_method 
     1611            ...       def f(self,n=2): 
     1612            ...           return self._x^n 
     1613            ... 
     1614            sage: a = Foo(2) 
     1615            sage: a.f() 
     1616            4 
     1617 
     1618        Usually, a cached method is indeed cached:: 
     1619 
     1620            sage: a.f() is a.f() 
     1621            True 
     1622 
     1623        However, when it becomes necessary, one can call it without 
     1624        using the cache. Note that ``a.f`` is an instance of 
     1625        :class:`CachedMethodCaller`.  But its 
     1626        :meth:`CachedMethodCaller._instance_call` relies on this 
     1627        method, so, we have an indirect doctest:: 
     1628 
     1629            sage: a.f._instance_call() is a.f() # indirect doctest 
     1630            False 
     1631            sage: a.f._instance_call() == a.f() 
     1632            True 
     1633 
     1634        """ 
     1635        return self._cachedfunc.f(inst, *args, **kwds) 
     1636 
     1637    cpdef dict _get_instance_cache(self, inst): 
     1638        """ 
     1639        Returns the cache dictionary. 
     1640 
     1641        TESTS:: 
     1642 
     1643            sage: class Foo: 
     1644            ...       def __init__(self, x): 
     1645            ...           self._x = x 
     1646            ...       @cached_method 
     1647            ...       def f(self,n=2): 
     1648            ...           return self._x^n 
     1649            ... 
     1650            sage: a = Foo(2) 
     1651            sage: a.f() 
     1652            4 
     1653 
     1654        Note that we can not provide a direct test, since ``a.f`` is 
     1655        an instance of :class:`CachedMethodCaller`.  But during its 
     1656        initialisation, this method was called in order to provide the 
     1657        cached method caller with its cache, and, if possible, assign 
     1658        it to an attribute of ``a``.  So, the following is an indirect 
     1659        doctest:: 
     1660 
     1661            sage: a.f.get_cache()    # indirect doctest 
     1662            {((2,), ()): 4} 
     1663            sage: a._cache__f 
     1664            {((2,), ()): 4} 
     1665 
     1666        """ 
     1667        try: 
     1668            return inst.__dict__.setdefault(self._cache_name, {}) 
     1669        except AttributeError: 
     1670            return {} 
     1671 
     1672    def __get__(self, inst, cls): #cls=None): 
     1673        """ 
     1674        Get a CachedMethodCaller bound to this specific instance of 
     1675        the class of the cached method. 
     1676 
     1677        TESTS:: 
     1678 
     1679            sage: class Foo: 
     1680            ...       @cached_method 
     1681            ...       def f(self): 
     1682            ...           return 1 
     1683            ...       @cached_method 
     1684            ...       def g(self, x,n=3): 
     1685            ...           return x^n 
     1686            ... 
     1687            sage: a = Foo() 
     1688            sage: type(a.f) 
     1689            <type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'> 
     1690            sage: type(a.g) 
     1691            <type 'sage.misc.cachefunc.CachedMethodCaller'> 
     1692 
     1693        By trac ticket #8611, it is attempted to set the 
     1694        CachedMethodCaller as an attribute of the instance ``a``, 
     1695        replacing the original cached attribute. Therefore, the 
     1696        ``__get__`` method will be used only once, which saves much 
     1697        time. Hence, we have:: 
     1698  
     1699            sage: a.f is a.f 
     1700            True 
     1701            sage: a.g is a.g 
     1702            True 
     1703 
     1704        """ 
     1705        # This is for Parents or Elements that do not allow attribute assignment: 
     1706        try: 
     1707            name = self._cachedfunc.__name__ 
     1708        except AttributeError: 
     1709            name = self.__name__ 
     1710        try: 
     1711            return (<dict>inst.__cached_methods).__getitem__(name) 
     1712        except (AttributeError,TypeError,KeyError),msg: 
     1713            pass 
     1714        # Apparently we need to construct the caller. 
     1715        # Since we have an optimized version for functions that do not accept arguments, 
     1716        # we need to analyse the argspec 
     1717        f = (<CachedFunction>self._cachedfunc).f 
     1718        from sage.misc.sageinspect import sage_getargspec 
     1719        args, varargs, keywords, defaults = sage_getargspec(f) 
     1720        if varargs is None and keywords is None and len(args)<=1: 
     1721            Caller = CachedMethodCallerNoArgs(inst, f, name=name) 
     1722        else: 
     1723            Caller = CachedMethodCaller(self, inst, 
     1724            cache=self._get_instance_cache(inst), name=name) 
     1725        try: 
     1726            setattr(inst,name, Caller) 
     1727            return Caller 
     1728        except AttributeError: 
     1729            pass 
     1730        try: 
     1731            if inst.__cached_methods is None: 
     1732                inst.__cached_methods = {name : Caller} 
     1733            else: 
     1734                (<dict>inst.__cached_methods).__setitem__(name, Caller) 
     1735        except AttributeError: 
     1736            pass 
     1737        return Caller 
     1738 
     1739        # Note: a simpler approach to this would be 
     1740        # def caller(*args, **kwds): 
     1741        #     return self._instance_call(inst, *args, **kwds) 
     1742        # return caller 
     1743        # The disadvantage to this is that it does not provide 
     1744        # is_in_cache(), set_cache(), clear_cache(), ... methods. 
     1745 
     1746 
     1747cached_method = CachedMethod 
     1748 
     1749cdef class CachedInParentMethod(CachedMethod): 
     1750    r""" 
     1751    A decorator that creates a cached version of an instance 
     1752    method of a class. 
     1753 
     1754    In contrast to :class:`CachedMethod`, 
     1755    the cache dictionary is an attribute of the parent of 
     1756    the instance to which the method belongs. 
     1757 
     1758    ASSUMPTION: 
     1759 
     1760    This way of caching works only if 
     1761 
     1762    - the instances *have* a parent, and 
     1763    - the instances are hashable (they are part of the cache key). 
     1764 
     1765    NOTE: 
     1766 
     1767    For proper behavior, the method must be a pure function (no side 
     1768    effects). If this decorator is used on a method, it will have 
     1769    identical output on equal elements. This is since the element is 
     1770    part of the hash key. Arguments to the method and the instance 
     1771    it is assigned to must be hashable.  
     1772 
     1773    Examples can be found at :mod:`~sage.misc.cachefunc`. 
     1774 
     1775    """ 
     1776 
     1777    def __init__(self, f, name=None): 
     1778        """ 
     1779        Constructs a new method with cache stored in the parent of the instance. 
     1780 
     1781        See also ``cached_method`` and ``cached_function``. 
     1782 
     1783        EXAMPLES:: 
     1784 
     1785            sage: class MyParent(Parent): 
     1786            ...       pass 
     1787            sage: class Foo: 
     1788            ...       def __init__(self, x): 
     1789            ...           self._x = x 
     1790            ...       _parent = MyParent() 
     1791            ...       def parent(self): 
     1792            ...           return self._parent 
     1793            ...       @cached_in_parent_method  #indirect doctest 
     1794            ...       def f(self): 
     1795            ...           return self._x^2 
     1796            ... 
     1797            sage: a = Foo(2) 
     1798            sage: a.f() 
     1799            4 
     1800            sage: hasattr(a.parent(), '_cache__element_f') 
     1801            True 
     1802 
     1803        For speeding up internal computations, this dictionary 
     1804        is also accessible as an attribute of the CachedMethodCaller 
     1805        (by trac ticket #8611):: 
     1806 
     1807            sage: a.parent()._cache__element_f is a.f.cache 
     1808            True 
     1809        """ 
     1810        self._cache_name = '_cache__' + 'element_' + (name or f.__name__) 
     1811        self._cachedfunc = CachedFunction(f, classmethod=True, name=name) 
     1812 
     1813    cpdef dict _get_instance_cache(self, inst): 
     1814        """ 
     1815        Returns the cache dictionary, which is stored in the parent. 
     1816 
     1817        EXAMPLES:: 
     1818 
     1819            sage: class MyParent(Parent): 
     1820            ...       pass 
     1821            ... 
     1822            sage: class Foo: 
     1823            ...       def __init__(self, x): 
     1824            ...           self._x = x 
     1825            ...       _parent = MyParent() 
     1826            ...       def parent(self): 
     1827            ...           return self._parent 
     1828            ...       def __eq__(self, other): 
     1829            ...           return self._x^2 == other._x^2 
     1830            ...       def __hash__(self): 
     1831            ...           return hash(self._x^2) 
     1832            ...       def __repr__(self): 
     1833            ...           return 'My %s'%self._x 
     1834            ...       @cached_in_parent_method 
     1835            ...       def f(self): 
     1836            ...           return self._x^3 
     1837            ... 
     1838            sage: a = Foo(2) 
     1839            sage: a.f() 
     1840            8 
     1841            sage: a.f.get_cache()   #indirect doctest 
     1842            {(My 2, ((), ())): 8} 
     1843 
     1844        Since the key for the cache depends on equality of 
     1845        the instances, we obtain *identical* result for 
     1846        *equal* instance - even though in this particular 
     1847        example the result is wrong:: 
     1848 
     1849            sage: b = Foo(-2) 
     1850            sage: a is not b 
     1851            True 
     1852            sage: a == b 
     1853            True 
     1854            sage: b.f() is a.f() 
     1855            True 
     1856 
     1857        Non-equal instances do not share the result of 
     1858        the cached method, but they do share the cache:: 
     1859 
     1860            sage: c = Foo(3) 
     1861            sage: c.f() 
     1862            27 
     1863            sage: c.f.get_cache() is a.f.get_cache() #indirect doctest 
     1864            True 
     1865 
     1866        Note that the cache is also available as an 
     1867        attribute of the cached method, which speeds 
     1868        up internal computations:: 
     1869 
     1870            sage: a.f.cache is b.f.get_cache() is c.f._cachedmethod._get_instance_cache(c) 
     1871            True 
     1872 
     1873        """ 
     1874        if inst is None: 
     1875            return {} 
     1876        try: 
     1877            P = inst.parent() 
     1878            return P.__dict__.setdefault(self._cache_name, {}) 
     1879        except AttributeError: 
     1880            pass 
     1881        if not hasattr(P,'__cached_methods'): 
     1882            raise TypeError, "The parent of this element does not allow attribute assignment\n    and does not descend from the Parent base class.\n    Can not use CachedInParentMethod." 
     1883        if P.__cached_methods is None: 
     1884            P.__cached_methods = {} 
     1885        return (<dict>P.__cached_methods).setdefault(self._cache_name, {}) 
     1886 
     1887    def __get__(self, inst, cls): #cls=None): 
     1888        """ 
     1889        Get a CachedMethodCaller bound to this specific instance of 
     1890        the class of the cached-in-parent method. 
     1891        """ 
     1892        Caller = CachedMethodCaller(self, inst, cache=self._get_instance_cache(inst), inst_in_key=True) 
     1893        try: 
     1894            setattr(inst,self._cachedfunc.__name__, Caller) 
     1895        except AttributeError: 
     1896            pass 
     1897        return Caller 
     1898 
     1899cached_in_parent_method = CachedInParentMethod 
     1900 
     1901class FileCache: 
     1902    """ 
     1903    FileCache is a dictionary-like class which stores keys and 
     1904    values on disk.  The keys take the form of a tuple (A,K) 
     1905 
     1906    - A is a tuple of objects t where each t is an exact 
     1907      object which is uniquely identified by a short string. 
     1908 
     1909    - K is a tuple of tuples (s,v) where s is a valid 
     1910      variable name and v is an exact object which is uniquely 
     1911      identified by a short string with letters [a-zA-Z0-9-._] 
     1912 
     1913    The primary use case is the DiskCachedFunction.  If 
     1914    ``memory_cache == True``, we maintain a cache of objects seen 
     1915    during this session in memory -- but we don't load them from 
     1916    disk until necessary.  The keys and values are stored in a 
     1917    pair of files: 
     1918 
     1919    - ``prefix-argstring.key.sobj`` contains the ``key`` only, 
     1920    - ``prefix-argstring.sobj`` contains the tuple ``(key,val)`` 
     1921 
     1922    where ``self[key] == val``. 
     1923 
     1924    NOTE: 
     1925 
     1926    We assume that each FileCache lives in its own directory. 
     1927    Use **extreme** caution if you wish to break that assumption. 
     1928    """ 
     1929    def __init__(self, dir, prefix = '', memory_cache = False): 
     1930        """ 
     1931        EXAMPLES:: 
     1932 
     1933            sage: from sage.misc.cachefunc import FileCache 
     1934            sage: dir = tmp_dir() 
     1935            sage: FC = FileCache(dir, memory_cache = True) 
     1936            sage: FC[((),())] = 1 
     1937            sage: FC[((1,2),())] = 2 
     1938            sage: FC[((),())] 
     1939            1 
     1940        """ 
     1941        if len(dir) == 0 or dir[-1] != '/': 
     1942            dir += '/' 
     1943        self._dir = dir 
     1944        if not os.path.exists(dir): 
     1945            os.mkdir(dir) 
     1946 
     1947        self._prefix = prefix + '-' 
     1948 
     1949        if memory_cache: 
     1950            self._cache = {} 
     1951        else: 
     1952            self._cache = None 
     1953 
     1954    def file_list(self): 
     1955        """ 
     1956        Returns the list of files corresponding to self. 
     1957 
     1958        EXAMPLES:: 
     1959 
     1960            sage: from sage.misc.cachefunc import FileCache 
     1961            sage: dir = tmp_dir() 
     1962            sage: FC = FileCache(dir, memory_cache = True, prefix='t') 
     1963            sage: FC[((),())] = 1 
     1964            sage: FC[((1,2),())] = 2 
     1965            sage: FC[((1,),(('a',1),))] = 3 
     1966            sage: for f in sorted(FC.file_list()): print f[len(dir):] 
     1967            /t-.key.sobj 
     1968            /t-.sobj 
     1969            /t-1_2.key.sobj 
     1970            /t-1_2.sobj 
     1971            /t-a-1.1.key.sobj 
     1972            /t-a-1.1.sobj 
     1973        """ 
     1974        files = [] 
     1975        prefix = self._prefix 
     1976        dir = self._dir 
     1977        l = len(prefix) 
     1978        for f in os.listdir(dir): 
     1979            if f[:l] == prefix: 
     1980                files.append( dir + f ) 
     1981        return files 
     1982 
     1983    def items(self): 
     1984        """ 
     1985        Returns a list of tuples ``(k,v)`` where ``self[k] = v``. 
     1986 
     1987        EXAMPLES:: 
     1988 
     1989            sage: from sage.misc.cachefunc import FileCache 
     1990            sage: dir = tmp_dir() 
     1991            sage: FC = FileCache(dir, memory_cache = False) 
     1992            sage: FC[((),())] = 1 
     1993            sage: FC[((1,2),())] = 2 
     1994            sage: FC[((1,),(('a',1),))] = 3 
     1995            sage: I = FC.items() 
     1996            sage: I.sort(); print I 
     1997            [(((), ()), 1), (((1,), (('a', 1),)), 3), (((1, 2), ()), 2)] 
     1998        """ 
     1999        return [(k,self[k]) for k in self] 
     2000 
     2001    def values(self): 
     2002        """ 
     2003        Returns a list of values that are stored in ``self``. 
     2004 
     2005        EXAMPLES:: 
     2006 
     2007            sage: from sage.misc.cachefunc import FileCache 
     2008            sage: dir = tmp_dir() 
     2009            sage: FC = FileCache(dir, memory_cache = False) 
     2010            sage: FC[((),())] = 1 
     2011            sage: FC[((1,2),())] = 2 
     2012            sage: FC[((1,),(('a',1),))] = 3 
     2013            sage: FC[((),(('a',1),))] = 4 
     2014            sage: v = FC.values() 
     2015            sage: v.sort(); print v 
     2016            [1, 2, 3, 4] 
     2017        """ 
     2018        return [self[k] for k in self] 
     2019 
     2020    def __iter__(self): 
     2021        """ 
     2022        Returns a list of keys of ``self``. 
     2023 
     2024        EXAMPLES:: 
     2025 
     2026            sage: from sage.misc.cachefunc import FileCache 
     2027            sage: dir = tmp_dir() 
     2028            sage: FC = FileCache(dir, memory_cache = False) 
     2029            sage: FC[((),())] = 1 
     2030            sage: FC[((1,2),())] = 2 
     2031            sage: FC[((1,),(('a',1),))] = 3 
     2032            sage: for k in sorted(FC): print k 
     2033            ((), ()) 
     2034            ((1,), (('a', 1),)) 
     2035            ((1, 2), ()) 
     2036        """ 
     2037        return self.keys().__iter__() 
     2038 
     2039    def keys(self): 
     2040        """ 
     2041        Returns a list of keys ``k`` where ``self[k]`` is defined. 
     2042 
     2043        EXAMPLES:: 
     2044 
     2045            sage: from sage.misc.cachefunc import FileCache 
     2046            sage: dir = tmp_dir() 
     2047            sage: FC = FileCache(dir, memory_cache = False) 
     2048            sage: FC[((),())] = 1 
     2049            sage: FC[((1,2),())] = 2 
     2050            sage: FC[((1,),(('a',1),))] = 3 
     2051            sage: K = FC.keys() 
     2052            sage: K.sort(); print K 
     2053            [((), ()), ((1,), (('a', 1),)), ((1, 2), ())] 
     2054        """ 
     2055        cdef list K = [] 
     2056        from sage.structure.sage_object import load 
     2057        for f in self.file_list(): 
     2058            if f[-9:] == '.key.sobj': 
     2059                K.append(load(f)) 
     2060        return K 
     2061 
     2062    def _filename(self, key): 
     2063        """ 
     2064        Computes the filename associated with a certain key. 
     2065 
     2066        EXAMPLES:: 
     2067 
     2068            sage: from sage.misc.cachefunc import FileCache 
     2069            sage: dir = tmp_dir() + '/' 
     2070            sage: FC = FileCache(dir, memory_cache = False, prefix='foo') 
     2071            sage: N = FC._filename(((1,2), (('a',1),('b',2)))) 
     2072            sage: print N[len(dir):] 
     2073            foo-a-1_b-2.1_2 
     2074            sage: N = FC._filename(((), (('a',1),('b',2)))) 
     2075            sage: print N[len(dir):] 
     2076            foo-a-1_b-2 
     2077            sage: N = FC._filename(((1,2), ())) 
     2078            sage: print N[len(dir):] 
     2079            foo-1_2 
     2080        """ 
     2081        a,k = key 
     2082        kwdstr = '_'.join(['%s-%s'%x for x in k]) 
     2083        argstr = '_'.join(['%s'%x for x in a]) 
     2084        if kwdstr and argstr: 
     2085            keystr = kwdstr + '.' + argstr 
     2086        else: 
     2087            keystr = kwdstr + argstr 
     2088        return self._dir + self._prefix + keystr 
     2089 
     2090    def has_key(self, key): 
     2091        """ 
     2092        Returns ``True`` if ``self[key]`` is defined and False otherwise. 
     2093 
     2094        EXAMPLES:: 
     2095 
     2096            sage: from sage.misc.cachefunc import FileCache 
     2097            sage: dir = tmp_dir() + '/' 
     2098            sage: FC = FileCache(dir, memory_cache = False, prefix='foo') 
     2099            sage: k = ((),(('a',1),)) 
     2100            sage: FC[k] = True 
     2101            sage: FC.has_key(k) 
     2102            True 
     2103            sage: FC.has_key(((),())) 
     2104            False 
     2105        """ 
     2106        return os.path.exists(self._filename(key) + '.key.sobj') 
     2107 
     2108    def __getitem__(self, key): 
     2109        """ 
     2110        Returns the value set by ``self[key] = val``, in this session 
     2111        or a previous one. 
     2112 
     2113        EXAMPLES:: 
     2114 
     2115            sage: from sage.misc.cachefunc import FileCache 
     2116            sage: dir = tmp_dir() + '/' 
     2117            sage: FC1 = FileCache(dir, memory_cache = False, prefix='foo') 
     2118            sage: FC2 = FileCache(dir, memory_cache = False, prefix='foo') 
     2119            sage: k = ((),(('a',1),)) 
     2120            sage: t = randint(0, 1000) 
     2121            sage: FC1[k] = t 
     2122            sage: FC2[k] == FC1[k] == t 
     2123            True 
     2124            sage: FC1[(1,2),(('a',4),('b',2))] 
     2125            Traceback (most recent call last): 
     2126            ... 
     2127            KeyError: ((1, 2), (('a', 4), ('b', 2))) 
     2128 
     2129        """ 
     2130        from sage.structure.sage_object import load 
     2131 
     2132        cache = self._cache 
     2133        if cache is not None: 
     2134            if cache.has_key(key): 
     2135                return cache[key] 
     2136 
     2137        f = self._filename(key) + '.sobj' 
     2138        try: 
     2139            k,v = load(f) 
     2140        except IOError: 
     2141            raise KeyError, key  
     2142        if k != key: 
     2143            raise RuntimeError, "cache corrupted" 
     2144 
     2145        if cache is not None: 
     2146            cache[key] = v 
     2147        return v 
     2148 
     2149    def __setitem__(self, key, value): 
     2150        """ 
     2151        Sets ``self[key] = value`` and stores both key and value on 
     2152        disk. 
     2153 
     2154        EXAMPLES:: 
     2155 
     2156            sage: from sage.misc.cachefunc import FileCache 
     2157            sage: dir = tmp_dir() + '/' 
     2158            sage: FC1 = FileCache(dir, memory_cache = False, prefix='foo') 
     2159            sage: FC2 = FileCache(dir, memory_cache = False, prefix='foo') 
     2160            sage: k = ((),(('a',1),)) 
     2161            sage: t = randint(0, 1000) 
     2162            sage: FC1[k] = t 
     2163            sage: FC2[k] == t 
     2164            True 
     2165            sage: FC1[k] = 2000 
     2166            sage: FC2[k]!= t 
     2167            True 
     2168        """ 
     2169        from sage.structure.sage_object import save 
     2170 
     2171        f = self._filename(key) 
     2172 
     2173        save(key, f+'.key.sobj') 
     2174        save((key,value), f + '.sobj') 
     2175        if self._cache is not None: 
     2176            self._cache[key] = value 
     2177 
     2178    def __delitem__(self, key): 
     2179        """ 
     2180        Delete the key,value pair from self and unlink the associated 
     2181        files from the file cache. 
     2182 
     2183        EXAMPLES:: 
     2184 
     2185            sage: from sage.misc.cachefunc import FileCache 
     2186            sage: dir = tmp_dir() + '/' 
     2187            sage: FC1 = FileCache(dir, memory_cache = False, prefix='foo') 
     2188            sage: FC2 = FileCache(dir, memory_cache = False, prefix='foo') 
     2189            sage: k = ((),(('a',1),)) 
     2190            sage: t = randint(0, 1000) 
     2191            sage: FC1[k] = t 
     2192            sage: del FC2[k] 
     2193            sage: FC1.has_key(k) 
     2194            False 
     2195       """ 
     2196        f = self._filename(key) 
     2197        cache = self._cache 
     2198        if cache is not None and cache.has_key(key): 
     2199            del self._cache[key] 
     2200        if os.path.exists(f + '.sobj'): 
     2201            os.remove(f + '.sobj') 
     2202        if  os.path.exists(f + '.key.sobj'): 
     2203           os.remove(f + '.key.sobj') 
     2204 
     2205 
     2206class DiskCachedFunction(CachedFunction): 
     2207    """ 
     2208    Works similar to CachedFunction, but instead, we keep the 
     2209    cache on disk (optionally, we keep it in memory too). 
     2210 
     2211    EXAMPLES:: 
     2212 
     2213        sage: from sage.misc.cachefunc import DiskCachedFunction 
     2214        sage: dir = tmp_dir() 
     2215        sage: factor = DiskCachedFunction(factor, dir, memory_cache=True) 
     2216        sage: f = factor(2775); f 
     2217        3 * 5^2 * 37 
     2218        sage: f is factor(2775) 
     2219        True 
     2220    """ 
     2221    def __init__(self, f, dir, memory_cache=False): 
     2222        """ 
     2223        EXAMPLES:: 
     2224 
     2225            sage: from sage.misc.cachefunc import DiskCachedFunction 
     2226            sage: def foo(x): sleep(x) 
     2227            sage: dir = tmp_dir() 
     2228            sage: bar = DiskCachedFunction(foo, dir, memory_cache = False) 
     2229            sage: w = walltime() 
     2230            sage: for i in range(10): bar(1) 
     2231            sage: walltime(w) < 2 
     2232            True 
     2233        """ 
     2234        CachedFunction.__init__(self, f) 
     2235        prefix = f.__name__ 
     2236        self.cache = FileCache(dir, prefix=prefix, memory_cache = memory_cache) 
     2237 
     2238 
     2239class disk_cached_function: 
     2240    """ 
     2241    Decorator for :class:`DiskCachedFunction`. 
     2242 
     2243    EXAMPLES:: 
     2244 
     2245        sage: dir = tmp_dir() 
     2246        sage: @disk_cached_function(dir) 
     2247        ... def foo(x): return next_prime(2^x)%x 
     2248        sage: x = foo(200);x 
     2249        11 
     2250        sage: @disk_cached_function(dir) 
     2251        ... def foo(x): return 1/x 
     2252        sage: foo(200) 
     2253        11 
     2254        sage: foo.clear_cache() 
     2255        sage: foo(200) 
     2256        1/200 
     2257    """ 
     2258    def __init__(self, dir, memory_cache = False): 
     2259        """ 
     2260        EXAMPLES:: 
     2261 
     2262            sage: dir = tmp_dir() 
     2263            sage: @disk_cached_function(dir, memory_cache=True) 
     2264            ... def foo(x): return next_prime(2^x) 
     2265            sage: x = foo(200) 
     2266            sage: x is foo(200) 
     2267            True 
     2268            sage: @disk_cached_function(dir, memory_cache=False) 
     2269            ... def foo(x): return next_prime(2^x) 
     2270            sage: x is foo(200) 
     2271            False 
     2272        """ 
     2273        self._dir = dir 
     2274        self._memory_cache = memory_cache 
     2275 
     2276    def __call__(self, f): 
     2277        """ 
     2278        EXAMPLES:: 
     2279 
     2280            sage: dir = tmp_dir() 
     2281            sage: @disk_cached_function(dir) 
     2282            ... def foo(x): return ModularSymbols(x) 
     2283            sage: foo(389) 
     2284            Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2 with sign 0 over Rational Field 
     2285        """ 
     2286        return DiskCachedFunction(f, self._dir, memory_cache = self._memory_cache) 
     2287 
     2288class ClearCacheOnPickle(object): 
     2289    r""" 
     2290    This class implements an appropriate ``__getstate__`` method that 
     2291    clears the cache of the methods (see @cached_method) before 
     2292    passing them on to the caller, typically the pickle and copy modules. 
     2293 
     2294    The implemented ``__getstate__`` method calls the ``__getstate__`` 
     2295    methods of classes later in the method resolution 
     2296    order. Therefore, classes which want this behaviour should inherit 
     2297    first from this one. 
     2298 
     2299    EXAMPLE: 
     2300 
     2301    In the following example, we create a Python class that inherits 
     2302    from multivariate polynomial ideals, but does not pickle cached 
     2303    values.  We provide the definition in Cython, however, since 
     2304    interactive Cython definitions provide introspection by trac 
     2305    ticket #9976, whereas Python definitions don't. 
     2306    :: 
     2307 
     2308        sage: P.<a,b,c,d> = QQ[] 
     2309        sage: I = P*[a,b] 
     2310        sage: classdef = ['from sage.misc.cachefunc import ClearCacheOnPickle', 
     2311        ...    'from sage.all import QQ', 
     2312        ...    'P = QQ["a","b","c","d"]; I = P*[P.gen(0),P.gen(1)]', 
     2313        ...    'class MyClass(ClearCacheOnPickle,I.__class__):', 
     2314        ...    '    def __init__(self,ring,gens):', 
     2315        ...    '        I.__class__.__init__(self,ring,gens)', 
     2316        ...    '    def __getnewargs__(self):', 
     2317        ...    '        return (self._Ideal_generic__ring,self._Ideal_generic__gens)'] 
     2318        sage: cython('\n'.join(classdef)) 
     2319 
     2320    We destroy the cache of two methods of ``I`` on purpose 
     2321    (demonstrating that the two different implementations of cached 
     2322    methods are correctly dealt with).  Pickling ``I`` preserves the 
     2323    cache:: 
     2324 
     2325        sage: I.gens.set_cache('bar') 
     2326        sage: I.groebner_basis.set_cache('foo',algorithm='singular') 
     2327        sage: J = loads(dumps(I)) 
     2328        sage: J.gens() 
     2329        'bar' 
     2330        sage: J.groebner_basis(algorithm='singular') 
     2331        'foo' 
     2332 
     2333    However, if we have an ideal that additionally descends from 
     2334    :class:`ClearCacheOnPickle`, the carefully corrupted cache is not 
     2335    pickled:: 
     2336 
     2337        sage: A = MyClass(P,[a,b]) 
     2338        sage: A 
     2339        Ideal (a, b) of Multivariate Polynomial Ring in a, b, c, d over Rational Field 
     2340        sage: A.gens.set_cache('foo') 
     2341        sage: A.groebner_basis.set_cache('bar',algorithm='singular') 
     2342        sage: A.gens() 
     2343        'foo' 
     2344        sage: A.groebner_basis(algorithm='singular') 
     2345        'bar' 
     2346        sage: B = loads(dumps(A)) 
     2347        sage: B.gens() 
     2348        [a, b] 
     2349        sage: B.groebner_basis(algorithm='singular') 
     2350        [a, b] 
     2351        sage: A.gens() 
     2352        'foo' 
     2353 
     2354    """ 
     2355    def __getstate__(self): 
     2356        r""" 
     2357        The idea is to remove that might provide a cache to some cached method 
     2358        from the return value of the ``__getstate__`` method. 
     2359 
     2360        EXAMPLE: 
     2361 
     2362        In the following example, we create a Python class that 
     2363        inherits from multivariate polynomial ideals, but clears the 
     2364        cache as well. 
     2365 
     2366            sage: P.<a,b,c,d> = QQ[] 
     2367            sage: I = P*[a,b] 
     2368 
     2369        We destroy the cache of two methods if ``I`` on purpose 
     2370        (demonstrating that the two different implementations of cached 
     2371        methods are correctly dealt with).  Pickling ``I`` preserves the 
     2372        cache:: 
     2373 
     2374            sage: I.gens.set_cache('bar') 
     2375            sage: I.groebner_basis.set_cache('foo',algorithm='singular') 
     2376            sage: J = loads(dumps(I)) 
     2377            sage: J.gens() 
     2378            'bar' 
     2379            sage: J.groebner_basis(algorithm='singular') 
     2380            'foo' 
     2381 
     2382        However, if we do the same with a class that additionally 
     2383        descends from :class:`ClearCacheOnPickle`, the cache is not 
     2384        pickled. We provide the definition in Cython, however, since 
     2385        interactive Cython definitions provide introspection by trac 
     2386        ticket #9976, whereas Python definitions don't. 
     2387        :: 
     2388 
     2389            sage: classdef = ['from sage.misc.cachefunc import ClearCacheOnPickle', 
     2390            ...    'from sage.all import QQ', 
     2391            ...    'from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal', 
     2392            ...    'class MyClass(ClearCacheOnPickle,MPolynomialIdeal):', 
     2393            ...    '    def __init__(self,ring,gens):', 
     2394            ...    '        MPolynomialIdeal.__init__(self,ring,gens)', 
     2395            ...    '    def __getnewargs__(self):', 
     2396            ...    '        return (self._Ideal_generic__ring,self._Ideal_generic__gens)'] 
     2397            sage: cython('\n'.join(classdef)) 
     2398            sage: A = MyClass(P,[a,b]) 
     2399            sage: A 
     2400            Ideal (a, b) of Multivariate Polynomial Ring in a, b, c, d over Rational Field 
     2401            sage: A.gens.set_cache('foo') 
     2402            sage: A.groebner_basis.set_cache('bar',algorithm='singular') 
     2403            sage: A.gens() 
     2404            'foo' 
     2405            sage: A.groebner_basis(algorithm='singular') 
     2406            'bar' 
     2407            sage: B = loads(dumps(A)) 
     2408            sage: B.gens() 
     2409            [a, b] 
     2410            sage: B.groebner_basis(algorithm='singular') 
     2411            [a, b] 
     2412            sage: A.gens() 
     2413            'foo' 
     2414             
     2415        And here is why the example works:: 
     2416 
     2417            sage: ST = I.__getstate__(); ST[0],sorted(ST[1].items()) 
     2418            (Monoid of ideals of Multivariate Polynomial Ring in a, b, c, d over Rational Field, [('_Ideal_generic__gens', (a, b)), ('_Ideal_generic__ring', Multivariate Polynomial Ring in a, b, c, d over Rational Field), ('_cache__groebner_basis', {(('singular', None, None, False), ()): 'foo'}), ('gens', Cached version of <function gens at 0x...>), ('groebner_basis', Cached version of <function groebner_basis at 0x...>)]) 
     2419            sage: ST = A.__getstate__(); ST[0],sorted(ST[1].items()) 
     2420            (Monoid of ideals of Multivariate Polynomial Ring in a, b, c, d over Rational Field, [('_Ideal_generic__gens', (a, b)), ('_Ideal_generic__ring', Multivariate Polynomial Ring in a, b, c, d over Rational Field)]) 
     2421 
     2422        """ 
     2423        OrigState = super(ClearCacheOnPickle, self).__getstate__() 
     2424        def clear_list(T): 
     2425            L = [] 
     2426            for x in T: 
     2427                if isinstance(x,list): 
     2428                    L.append(clear_list(x)) 
     2429                elif isinstance(x,tuple): 
     2430                    L.append(clear_tuple(x)) 
     2431                elif isinstance(x,dict): 
     2432                    L.append(clear_dict(x)) 
     2433                elif not isinstance(x,CachedFunction): 
     2434                    L.append(x) 
     2435            return L 
     2436        def clear_tuple(T): 
     2437            return tuple(clear_list(T)) 
     2438        def clear_dict(T): 
     2439            D = {} 
     2440            for key,value in T.iteritems(): 
     2441                if not ((type(key) == str and key[0:8] == '_cache__') or 
     2442                            isinstance(value,CachedFunction)): 
     2443                    if isinstance(value,list): 
     2444                        D[key] = clear_list(value) 
     2445                    elif isinstance(value,tuple): 
     2446                        D[key] = clear_tuple(value) 
     2447                    elif isinstance(value,dict): 
     2448                        D[key] = clear_dict(value) 
     2449                    else: 
     2450                        D[key] = value 
     2451            return D 
     2452        if isinstance(OrigState,tuple): 
     2453            return clear_tuple(OrigState) 
     2454        if isinstance(OrigState,list): 
     2455            return clear_list(OrigState) 
     2456        if isinstance(OrigState,dict): 
     2457            return clear_dict(OrigState) 
     2458        return OrigState 
  • sage/misc/function_mangling.pyx

    diff --git a/sage/misc/function_mangling.pyx b/sage/misc/function_mangling.pyx
    a b  
    109109        ...      def __init__(self, x = 1): 
    110110        ...         self.x = x 
    111111        sage: af = ArgumentFixer(one.__init__.im_func, classmethod=True) 
    112         sage: af.fix_to_pos() 
    113         ((1,), ()) 
    114         sage: af.fix_to_named() 
    115         ((), (('x', 1),)) 
    116     """         
    117     cdef dict _defaults 
    118     cdef int _ndefault, _nargs 
    119     cdef tuple _arg_names 
    120     cdef object f 
    121     cdef bint _classmethod 
    122     def __init__(self, f, classmethod = False): 
    123         """ 
    124         INPUT: 
    125  
    126         - ``f`` -- a function 
    127         - ``classmethod`` (optional bool, default ``False``) --  
    128           tells whether ``f`` is supposed to be a method of a class 
    129  
    130         NOTE: 
    131  
    132         Currently, we need to assume that ``f`` is a Python function, not 
    133         a Cython function. This is since some essential arguments are not 
    134         available from Cython functions. 
    135  
    136         TESTS:: 
    137  
    138             sage: from sage.misc.function_mangling import ArgumentFixer 
    139             sage: def f(a,b,m=1,n=2): return a*m+b*n 
    140             sage: a = ArgumentFixer(f, classmethod=False) 
    141             sage: a.fix_to_pos(a=31,b=2,n=3) 
    142             ((31, 2, 1, 3), ()) 
    143             sage: a = ArgumentFixer(f, classmethod=True) 
    144             sage: a.fix_to_pos(a=31,b=2,n=3) 
    145             ((2, 1, 3), (('a', 31),)) 
     112        sage: af.fix_to_pos(1,2,3,a=31,b=2,n=3) 
     113        ((1, 2, 3), (('a', 31), ('b', 2), ('n', 3))) 
    146114 
    147115        """ 
    148         defaults = f.func_defaults 
     116 
     117    cdef public object f 
     118    cdef public int _ndefault 
     119    cdef public int _nargs 
     120    cdef tuple _arg_names 
     121    cdef bint _classmethod 
     122    cdef dict _defaults 
     123    cdef public tuple _default_tuple 
     124    def __init__(self, f, classmethod = False): 
     125        from sage.misc.sageinspect import sage_getargspec 
     126        arg_names, varargs, varkw, defaults = sage_getargspec(f) 
    149127        if defaults is None: 
    150             defaults = [] 
     128            self._default_tuple = defaults = () 
     129        else: 
     130            self._default_tuple = tuple(defaults) 
    151131 
    152         code = f.func_code 
     132        #code = f.func_code 
    153133 
    154134        self.f = f 
    155135        self._ndefault = len(defaults) 
    156136        if classmethod: 
    157             self._nargs = code.co_argcount-1 
    158             self._arg_names = code.co_varnames[1:self._nargs+1] 
     137            self._nargs = len(arg_names)-1 #code.co_argcount-1 
     138            self._arg_names = tuple(arg_names[1:]) #code.co_varnames[1:self._nargs+1] 
    159139        else: 
    160             self._nargs = code.co_argcount 
    161             self._arg_names = code.co_varnames[:self._nargs] 
     140            self._nargs = len(arg_names) #code.co_argcount 
     141            self._arg_names = tuple(arg_names) #code.co_varnames[:self._nargs] 
    162142        self._classmethod = classmethod 
    163143 
    164         default_map = {} 
     144        cdef dict default_map 
     145        self._defaults = default_map = {} 
    165146        for k,v in zip(self._arg_names[-self._ndefault:], defaults): 
    166147            default_map[k] = v 
    167         self._defaults = default_map 
    168148 
    169149    def __repr__(self): 
    170150        """ 
     
    248228            ARGS.append((k,kwargs_[k])) 
    249229        return tuple(extra_args), tuple(ARGS) 
    250230 
    251     def fix_to_pos(self, *args, **kwargs): 
     231    cpdef tuple defaults_to_pos(self, tuple Args): 
     232        cdef int lenargs = len(Args) 
     233        cdef int nargs = self._nargs 
     234        if lenargs>=nargs: 
     235            return Args, () 
     236        return Args+self._default_tuple[-nargs+lenargs:],() 
     237 
     238    def fix_to_pos(self, *args, **kwds): 
    252239        """ 
    253240        Normalize the arguments with a preference for positional arguments. 
    254241 
    255242        INPUT: 
    256243 
    257         - any positional and named arguments. 
     244        Any positional or named arguments 
    258245 
    259246        OUTPUT: 
    260247 
     
    264251  
    265252        where `n_1, ... , n_m` are the names of the arguments and 
    266253        `v_1, ..., v_m` are the values passed in; and `e_1, ..., e_k` 
    267         are the unnamed arguments.  We minimize `m`. 
     254        are the unnamed arguments. We minimize `m`. 
    268255 
    269256        The commands 
    270257        :: 
     
    295282            sage: do_something(1,2,3,4,5,6,f=14,e=16) 
    296283            1 2 3 (4, 5, 6) {'e': 16, 'f': 14} 
    297284        """ 
     285        cdef tuple Args = args 
     286        cdef dict kwargs = kwds 
     287        cdef int lenargs = len(Args) 
     288        cdef int nargs = self._nargs 
     289        cdef tuple arg_names = self._arg_names 
     290        cdef dict defaults = self._defaults 
    298291        # a shortpath for the case of no named arguments: 
    299292        if not kwargs: 
     293            if lenargs>=nargs: 
     294                return args, () 
    300295            # we take the given arguments, plus the default arguments 
    301             return tuple(list(args)+[self._defaults[k] for k in self._arg_names[len(args):]]),() 
    302         cdef tuple arg_names = self._arg_names 
    303         cdef int lenargs = len(args) 
    304         cdef list ARGS = [] 
    305         cdef dict defaults = self._defaults 
    306         cdef dict kwargs_ = dict(kwargs) 
     296            return Args+self._default_tuple[-nargs+lenargs:],() #tuple(list(Args)+[defaults[k] for k in arg_names[lenargs:]]),() 
     297        cdef list Largs = list(Args) 
    307298        cdef int i 
    308         for i from 0<=i<self._nargs: 
    309             if i >= lenargs: 
    310                 name = arg_names[i] 
    311                 if name in kwargs_: 
    312                     val = kwargs_[name] 
    313                     del kwargs_[name] 
    314                 else: 
    315                     val = defaults[name] 
     299        for i from lenargs<=i<nargs: 
     300        #for name,val in defaults.iteritems(): 
     301            # in addition to the positional arguments, we take the 
     302            # ones with default values, unless they are overridded by 
     303            # the named arguments. 
     304            name = arg_names[i] 
     305            if name in kwargs: 
     306                val = kwargs[name] 
     307                del kwargs[name] 
    316308            else: 
    317                 val = args[i] 
    318             ARGS.append(val) 
    319         ARGS+= args[self._nargs:] 
    320         cdef list Items = kwargs_.items() 
     309                val = defaults[name] 
     310            Largs.append(val) #kwargs.pop(name,val)) 
     311        cdef list Items = kwargs.items() 
    321312        Items.sort() 
    322         return tuple(ARGS), tuple(Items) #(k,kwargs_[k]) for k in sorted(kwargs_.keys())) 
     313        return tuple(Largs), tuple(Items) #(k,kwargs_[k]) for k in sorted(kwargs_.keys())) 
    323314  
    324315 
  • sage/misc/lazy_attribute.py

    diff --git a/sage/misc/lazy_attribute.py b/sage/misc/lazy_attribute.py
    a b  
    202202    second one brings up the code of this class, both being not very 
    203203    useful. 
    204204 
    205     TESTS:: 
     205    TESTS: 
    206206 
    207207    .. rubric:: Partial support for old style classes 
    208208 
     
    301301        calculating x from y in B 
    302302        1 
    303303 
    304     .. rubric:: lazy_attributes and cpdef functions 
     304    .. rubric:: lazy_attributes and Cython 
    305305 
    306306    This attempts to check that lazy_attributes work with built-in 
    307307    functions like cpdef methods:: 
     
    314314        sage: A().len 
    315315        5 
    316316 
     317    Since #11115, extension classes derived from :class:`~sage.structure.parent.Parent` 
     318    can inherit a lazy attribute, such as ``element_class``:: 
     319 
     320        sage: cython_code = ["from sage.structure.parent cimport Parent", 
     321        ... "from sage.structure.element cimport Element", 
     322        ... "cdef class MyElement(Element): pass", 
     323        ... "cdef class MyParent(Parent):", 
     324        ... "    Element = MyElement"] 
     325        sage: cython('\n'.join(cython_code)) 
     326        sage: P = MyParent(category=Rings()) 
     327        sage: P.element_class    # indirect doctest 
     328        <type '...MyElement'> 
     329 
    317330    .. rubric:: About descriptor specifications 
    318331 
    319332    The specifications of descriptors (see 3.4.2.3 Invoking 
     
    505518        """ 
    506519        if a is None: # when doing cls.x for cls a class and x a lazy attribute 
    507520            return self 
     521        if hasattr(a.__class__, '__cached_methods'): 
     522            CM = getattr(a, '__cached_methods') 
     523            if CM is None: 
     524                CM = a.__cached_methods = {} 
     525        else: 
     526            CM = None 
     527        if CM is not None: 
     528            try: 
     529                return CM[self.f.__name__] 
     530            except KeyError: 
     531                pass 
    508532        result = self.f(a) 
    509533        if result is NotImplemented: 
    510534            # Workaround: we make sure that cls is the class 
     
    515539                if self.f.__name__ in supercls.__dict__ and self is supercls.__dict__[self.f.__name__]: 
    516540                    cls = supercls 
    517541            return getattr(super(cls, a),self.f.__name__) 
    518         setattr(a, self.f.__name__, result) 
     542        try: 
     543            setattr(a, self.f.__name__, result) 
     544        except AttributeError: 
     545            if CM is not None: 
     546                CM[self.f.__name__] = result 
     547                return result 
     548            raise 
    519549        return result 
    520550 
    521  
    522551class lazy_class_attribute(lazy_attribute): 
    523552    """ 
    524553    A lazy class attribute for an class is like a usual class attribute, 
  • sage/rings/ideal.py

    diff --git a/sage/rings/ideal.py b/sage/rings/ideal.py
    a b  
    3232import sage.rings.infinity 
    3333from sage.structure.sequence import Sequence 
    3434 
    35  
    3635def Ideal(*args, **kwds): 
    3736    r""" 
    3837    Create the ideal in ring with given generators. 
  • sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py

    diff --git a/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py b/sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py
    a b  
    347347    def _Cartier_matrix_cached(self): 
    348348        r""" 
    349349        INPUT: 
    350         - 'E' - Hyperelliptic Curve of the form `y^2 = f(x)` over a finite field, `\mathbb{F}_q` 
     350 
     351        - 'E' - Hyperelliptic Curve of the form `y^2 = f(x)` over a 
     352          finite field, `\mathbb{F}_q` 
    351353         
    352354        OUTPUT: 
     355 
    353356        - matrix(Fq,M)' The matrix $M = (c_(pi-j)), f(x)^((p-1)/2) = \sum c_i x^i$ 
    354357        - 'Coeff' List of Coeffs of F, this is needed for Hasse-Witt function.  
    355358        - 'g' genus of the curve self, this is needed by a-number.  
     
    564567            ValueError: so curve is not smooth 
    565568 
    566569        """ 
    567         #checking first that Cartier matrix is not already cached. Since it can be called by either Hasse_Witt or a_number 
    568         #This way it does not matter which function is called first in the code.         
    569          
    570         A=self._Cartier_matrix_cached.get_cache() 
    571         if len(A) !=0: 
    572             if A.items()[-1][-1][-1]==self: 
    573                 M,Coeffs,g, Fq, p,E = A.items()[-1][1]; 
    574             else: 
    575                 A.clear() 
    576                 M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
    577         else: 
    578             A.clear() 
    579             M, Coeffs,g, Fq, p, E = self._Cartier_matrix_cached() 
     570        #checking first that Cartier matrix is not already cached. Since 
     571        #it can be called by either Hasse_Witt or a_number. 
     572        #This way it does not matter which function is called first 
     573        #in the code. 
     574        # Trac Ticket #11115: Why shall we waste time by studying 
     575        # the cache manually? We only need to check whether the cached 
     576        # data belong to self. 
     577        M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
     578        if E!=self: 
     579            self._Cartier_matrix_cached.clear_cache() 
     580            M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
     581#        A=self._Cartier_matrix_cached.get_cache() 
     582#        if len(A) !=0: 
     583#            if A.items()[-1][-1][-1]==self: 
     584#                M,Coeffs,g, Fq, p,E = A.items()[-1][1]; 
     585#            else: 
     586#                A.clear() 
     587#                M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
     588#        else: 
     589#            A.clear() 
     590#            M, Coeffs,g, Fq, p, E = self._Cartier_matrix_cached() 
    580591        return M 
    581592             
    582593    #This where Hasse_Witt is actually computed. This is either called by E.Hasse_Witt or p_rank 
     
    643654        #is already computed it is stored in list A. If it was not cached (i.e. A is empty), we simply 
    644655        #compute it. If it is cached then we need to make sure that we have the correct one. So check 
    645656        #which curve does the matrix correspond to. Since caching stores a lot of stuff, we only check 
    646         #the last entry in A. If it does not match, clear A and compute Cartier.       
    647         A=self._Cartier_matrix_cached.get_cache() 
    648         if len(A) !=0: 
    649             if A.items()[-1][-1][-1]==self: 
    650                 M,Coeffs,g, Fq, p,E = A.items()[-1][1]; 
    651             else: 
    652                 A.clear() 
    653                 M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
    654         else: 
    655             A.clear() 
    656             M, Coeffs,g, Fq, p, E = self._Cartier_matrix_cached() 
     657        #the last entry in A. If it does not match, clear A and compute Cartier. 
     658        # 
     659        #Since Trac Ticket #11115, there is a different cache for methods 
     660        #that don't  accept arguments. Anyway, the easiest is to call 
     661        #the cached method and simply see whether the data belong to self. 
     662        M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
     663        if E!=self: 
     664            self._Cartier_matrix_cached.clear_cache() 
     665            M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
     666 
     667#        A=self._Cartier_matrix_cached.get_cache() 
     668#        if len(A) !=0: 
     669#            if A.items()[-1][-1][-1]==self: 
     670#                M,Coeffs,g, Fq, p,E = A.items()[-1][1]; 
     671#            else: 
     672#                A.clear() 
     673#                M, Coeffs,g, Fq, p, E= self._Cartier_matrix_cached() 
     674#        else: 
     675#            A.clear() 
     676#            M, Coeffs,g, Fq, p, E = self._Cartier_matrix_cached() 
    657677         
    658678        #This compute the action of p^kth Frobenius  on list of coefficients        
    659679        def frob_mat(Coeffs, k): 
     
    727747 
    728748         
    729749        """ 
    730         A=self._Hasse_Witt_cached.get_cache() 
    731         if len(A) !=0: 
    732             if A.items()[-1][-1][-1]==self: 
    733                 N, E = A.items()[-1][1]; 
    734             else: 
    735                 A.clear() 
    736                 N, E= self._Hasse_Witt_cached() 
    737         else: 
    738             A.clear() 
     750        # Since Trac Ticket #11115, there is a special 
     751        # type of cached for those methods that don't 
     752        # accept arguments. We want to get Hasse-Witt 
     753        # from the cache - but apparently it could be 
     754        # that the cached value does not belong to self. 
     755        # So, the easiest is: 
     756        N, E= self._Hasse_Witt_cached() 
     757        if E!=self: 
     758            self._Hasse_Witt_cached.clear_cache() 
    739759            N, E= self._Hasse_Witt_cached() 
    740760        return N 
     761#        A=self._Hasse_Witt_cached.get_cache() 
     762#        if len(A) !=0: 
     763#            if A.items()[-1][-1][-1]==self: 
     764#                N, E = A.items()[-1][1]; 
     765#            else: 
     766#                A.clear() 
     767#                N, E= self._Hasse_Witt_cached() 
     768#        else: 
     769#            A.clear() 
     770#            N, E= self._Hasse_Witt_cached() 
     771#        return N 
    741772 
    742773    def a_number(self): 
    743774        r""" 
     
    775806        #compute it. If it is cached then we need to make sure that we have the correct one. So check 
    776807        #which curve does the matrix correspond to. Since caching stores a lot of stuff, we only check 
    777808        #the last entry in A. If it does not match, clear A and compute Cartier.       
     809        # Since Trac Ticket #11115, there is a special cache for methods 
     810        # that don't accept arguments. The easiest is: Call the cached 
     811        # method, and test whether the last entry is self. 
    778812 
    779         A=self._Cartier_matrix_cached.get_cache() 
    780         if len(A) !=0: 
    781             if A.items()[-1][-1][-1]==self: 
    782                 M,Coeffs,g, Fq, p,E = A.items()[-1][1]; 
    783             else: 
    784                 A.clear() 
    785                 M,Coeffs,g, Fq, p,E= self._Cartier_matrix_cached() 
    786         else: 
    787             A.clear() 
     813#        A=self._Cartier_matrix_cached.get_cache() 
     814#        if len(A) !=0: 
     815#            if A.items()[-1][-1][-1]==self: 
     816#                M,Coeffs,g, Fq, p,E = A.items()[-1][1]; 
     817#            else: 
     818#                A.clear() 
     819#                M,Coeffs,g, Fq, p,E= self._Cartier_matrix_cached() 
     820#        else: 
     821#            A.clear() 
     822#            M,Coeffs,g, Fq, p,E= self._Cartier_matrix_cached() 
     823        M,Coeffs,g, Fq, p,E= self._Cartier_matrix_cached() 
     824        if E != self: 
     825            self._Cartier_matrix_cached.clear_cache() 
    788826            M,Coeffs,g, Fq, p,E= self._Cartier_matrix_cached() 
    789  
    790827        a=g-rank(M); 
    791828        return a; 
     829 
    792830    def p_rank(self): 
    793831        r""" 
    794832        INPUT: 
     
    825863        #is already computed it is stored in list A. If it was not cached (i.e. A is empty), we simply 
    826864        #compute it. If it is cached then we need to make sure that we have the correct one. So check 
    827865        #which curve does the matrix correspond to. Since caching stores a lot of stuff, we only check 
    828         #the last entry in A. If it does not match, clear A and compute Hasse Witt.       
    829          
    830         A=self._Hasse_Witt_cached.get_cache() 
    831         if len(A) !=0: 
    832             if A.items()[-1][-1][-1]==self: 
    833                 N,E = A.items()[-1][1]; 
    834             else: 
    835                 A.clear() 
    836                 N,E= self._Hasse_Witt_cached() 
    837         else: 
    838             A.clear() 
     866        #the last entry in A. If it does not match, clear A and compute Hasse Witt. 
     867        # However, it seems a waste of time to manually analyse the cache 
     868        # -- See Trac Ticket #11115 
     869 
     870        N,E= self._Hasse_Witt_cached() 
     871        if E!=self: 
     872            self._Hasse_Witt_cached.clear_cache() 
    839873            N,E= self._Hasse_Witt_cached() 
    840  
    841  
    842          
     874#        A=self._Hasse_Witt_cached.get_cache() 
     875#        if len(A) !=0: 
     876#            if A.items()[-1][-1][-1]==self: 
     877#                N,E = A.items()[-1][1]; 
     878#            else: 
     879#                A.clear() 
     880#                N,E= self._Hasse_Witt_cached() 
     881#        else: 
     882#            A.clear() 
     883#            N,E= self._Hasse_Witt_cached() 
    843884        pr=rank(N); 
    844885        return pr 
    845886         
  • sage/structure/parent.pxd

    diff --git a/sage/structure/parent.pxd b/sage/structure/parent.pxd
    a b  
    1717    cdef public _element_constructor 
    1818    cdef public _convert_method_name 
    1919    cdef public bint _element_init_pass_parent 
     20    cdef public dict __cached_methods 
    2021    cdef public _initial_coerce_list 
    2122    cdef public _initial_action_list 
    2223    cdef public _initial_convert_list 
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b  
    262262        sage: getattr_from_other_class(1, A, "inc")() 
    263263        2 
    264264 
    265     Caveat: lazy attributes don't work currently with extension types, 
    266     with or without a __dict__: 
     265    Caveat: lazy attributes work with extension types only 
     266    if they allow attribute assignment or have a public attribute 
     267    ``__cached_methods`` of type ``<dict>``. This condition 
     268    is satisfied, e.g., by any class that is derived from 
     269    :class:`Parent`:: 
    267270 
    268271        sage: getattr_from_other_class(1, A, "lazy_attribute") 
    269272        Traceback (most recent call last): 
    270273        ... 
    271274        AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute' 
     275 
     276    The integer ring is a parent, so, lazy attributes work:: 
     277 
    272278        sage: getattr_from_other_class(ZZ, A, "lazy_attribute") 
    273         Traceback (most recent call last): 
    274         ... 
    275         AttributeError: 'sage.rings.integer_ring.IntegerRing_class' object has no attribute 'lazy_attribute' 
     279        'Integer Ring' 
    276280        sage: getattr_from_other_class(PolynomialRing(QQ, name='x', sparse=True).one(), A, "lazy_attribute") 
    277281        '1' 
    278282        sage: getattr_from_other_class(PolynomialRing(QQ, name='x', implementation="FLINT").one(), A, "lazy_attribute") 
     
    283287    In general, descriptors are not yet well supported, because they 
    284288    often do not accept to be cheated with the type of their instance:: 
    285289 
    286  
    287290        sage: A.__weakref__.__get__(1) 
    288291        Traceback (most recent call last): 
    289292        ... 
     
    810813            AttributeError: 'sage.structure.parent.Parent' object has no attribute '__foo' 
    811814 
    812815        """ 
     816        try: 
     817            return self.__cached_methods[name] 
     818        except (KeyError,TypeError): 
     819            pass 
    813820        if (name.startswith('__') and not name.endswith('_')) or self._category is None: 
    814821            raise AttributeError, AttributeErrorMessage(self, name) 
    815         return getattr_from_other_class(self, self._category.parent_class, name) 
     822        if self.__cached_methods is None: 
     823            self.__cached_methods  = {} 
     824        attr = getattr_from_other_class(self, self._category.parent_class, name) 
     825        self.__cached_methods[name] = attr 
     826        return attr 
    816827 
    817828    def __dir__(self): 
    818829        """ 
  • sage/structure/parent_old.pyx

    diff --git a/sage/structure/parent_old.pyx b/sage/structure/parent_old.pyx
    a b  
    9696     
    9797    cpdef coerce_map_from_c(self, S): 
    9898        """ 
    99         EXAMPLES: 
    100           Check to make sure that we handle coerce maps from Python native types 
    101           correctly. 
     99        EXAMPLES:: 
     100 
     101        Check to make sure that we handle coerce maps from Python 
     102        native types correctly:: 
     103 
    102104            sage: QQ['q,t'].coerce_map_from(int) 
    103105            Composite map: 
    104106              From: Set of Python objects of type 'int'