Ticket #13826: 13826_star_imports_race_v2.patch

File 13826_star_imports_race_v2.patch, 3.5 KB (added by jdemeyer, 9 years ago)
  • sage/all.py

    # HG changeset patch
    # User Volker Braun <vbraun.name@gmail.com>
    # Date 1355406608 0
    # Node ID 6a1cd9662764c8ebe5eacf48968b5ff63e7bc9f3
    # Parent  1a3c62633a7c010eb5a73677781274a6a49859c8
    Use write_via_temp() to write the star import cache
    
    diff --git a/sage/all.py b/sage/all.py
    a b  
    7878
    7979from time                import sleep
    8080
     81import sage.misc.lazy_import
    8182from sage.misc.all       import *         # takes a while
    8283
    8384from sage.misc.sh import sh
     
    154155from sage.ext.fast_callable  import fast_callable
    155156from sage.ext.fast_eval      import fast_float
    156157
    157 from sage.sandpiles.all import *
     158sage.misc.lazy_import.lazy_import('sage.sandpiles.all', '*', globals())
    158159
    159160from sage.tensor.all     import *
    160161
     
    284285#sage.structure.sage_object.register_unpickle_override('sage.categories.category_types', '', )
    285286
    286287# Cache the contents of star imports.
    287 import sage.misc.lazy_import
    288288sage.misc.lazy_import.save_cache_file()
    289289
    290290
  • sage/misc/lazy_import.pyx

    diff --git a/sage/misc/lazy_import.pyx b/sage/misc/lazy_import.pyx
    a b  
    3939cdef extern from *:
    4040    cdef int Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE
    4141
    42 import os, shutil, tempfile, cPickle as pickle, operator
     42import os, cPickle as pickle, operator
    4343import inspect
    4444import sageinspect
    4545
     
    866866        sage: import sage.misc.lazy_import
    867867        sage: sage.misc.lazy_import.save_cache_file()
    868868    """
     869    from sage.misc.misc import sage_makedirs
     870    from sage.misc.temporary_file import atomic_write
     871
    869872    global star_imports
    870873    if star_imports is None:
    871874        star_imports = {}
    872     _, tmp_file = tempfile.mkstemp()
    873     pickle.dump(star_imports, open(tmp_file, "w"))
    874     cache_dir = os.path.dirname(get_cache_file())
    875     try:
    876         os.makedirs(cache_dir)
    877     except OSError:
    878         # Probably failed because directory already exists, but we make sure.
    879         if not os.path.isdir(cache_dir):
    880             raise
    881     shutil.move(tmp_file, get_cache_file())
     875    cache_file = get_cache_file()
     876    cache_dir = os.path.dirname(cache_file)
     877   
     878    sage_makedirs(cache_dir)
     879    with atomic_write(cache_file) as f:
     880        pickle.dump(star_imports, f)
    882881
    883882def get_star_imports(module_name):
    884883    """
     
    892891        True
    893892        sage: 'EllipticCurve' in get_star_imports('sage.schemes.all')
    894893        True
     894
     895    TESTS::
     896
     897        sage: import os, tempfile
     898        sage: fd, cache_file = tempfile.mkstemp()
     899        sage: os.write(fd, 'invalid')
     900        7
     901        sage: os.close(fd)
     902        sage: import sage.misc.lazy_import as lazy
     903        sage: lazy.get_cache_file = (lambda: cache_file)
     904        sage: lazy.star_imports = None
     905        sage: lazy.get_star_imports('sage.schemes.all')
     906        doctest:...: UserWarning: star_imports cache is corrupted
     907        [...]
     908        sage: os.remove(cache_file)
    895909    """
    896910    global star_imports
    897911    if star_imports is None:
    898         cache_file = get_cache_file()
    899         if os.path.exists(cache_file):
    900             star_imports = pickle.load(open(cache_file))
    901         else:
    902             star_imports = {}
     912        star_imports = {}
     913        try:
     914            with open(get_cache_file()) as cache_file:
     915                star_imports = pickle.load(cache_file)
     916        except IOError:        # file does not exist
     917            pass
     918        except Exception:  # unpickling failed
     919            import warnings
     920            warnings.warn('star_imports cache is corrupted')
    903921    try:
    904922        return star_imports[module_name]
    905923    except KeyError: