Sophie

Sophie

distrib > Mageia > 4 > x86_64 > by-pkgid > 82fd441cd3f2a8bc33fc3ed41403eced > files > 1531

python-astropy-0.2.4-4.mga4.x86_64.rpm


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>astropy.utils.data &mdash; Astropy v0.2.4</title>
    
    <link rel="stylesheet" href="../../../_static/bootstrap-astropy.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../../',
        VERSION:     '0.2.4',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../../_static/sidebar.js"></script>
    <link rel="shortcut icon" href="../../../_static/astropy_logo.ico"/>
    <link rel="top" title="Astropy v0.2.4" href="../../../index.html" />
    <link rel="up" title="astropy.utils" href="../utils.html" /> 
  </head>
  <body>
<div class="topbar">
  <a class="brand" title="Documentation Home" href="../../../index.html"></a>
  <ul>
    <li><a class="homelink" title="AstroPy Homepage" href="http://www.astropy.org"></a></li>
    <li><a title="General Index" href="../../../genindex.html">Index</a></li>
    <li><a title="Python Module Index" href="../../../py-modindex.html">Modules</a></li>
    <li>
      
      
<form action="../../../search.html" method="get">
  <input type="text" name="q" placeholder="Search" />
  <input type="hidden" name="check_keywords" value="yes" />
  <input type="hidden" name="area" value="default" />
</form>
      
    </li>
  </ul>
</div>

<div class="related">
    <h3>Navigation</h3>
    <ul>
      <li>
	<a href="../../../index.html">Astropy v0.2.4</a>
	 &raquo;
      </li>
      <li><a href="../../index.html" >Module code</a> &raquo;</li>
      <li><a href="../utils.html" accesskey="U">astropy.utils</a> &raquo;</li>
      
       
    </ul>
</div>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <h1>Source code for astropy.utils.data</h1><div class="highlight"><pre>
<span class="c"># Licensed under a 3-clause BSD style license - see LICENSE.rst</span>
<span class="sd">&quot;&quot;&quot; This module contains helper functions for accessing, downloading, and</span>
<span class="sd">caching data files.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">division</span>

<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">io</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">atexit</span>
<span class="kn">import</span> <span class="nn">contextlib</span>
<span class="kn">import</span> <span class="nn">urllib2</span>

<span class="kn">from</span> <span class="nn">..config.configuration</span> <span class="kn">import</span> <span class="n">ConfigurationItem</span>

<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;get_readable_fileobj&#39;</span><span class="p">,</span> <span class="s">&#39;get_file_contents&#39;</span><span class="p">,</span> <span class="s">&#39;get_pkg_data_fileobj&#39;</span><span class="p">,</span>
           <span class="s">&#39;get_pkg_data_filename&#39;</span><span class="p">,</span> <span class="s">&#39;get_pkg_data_contents&#39;</span><span class="p">,</span>
           <span class="s">&#39;get_pkg_data_fileobjs&#39;</span><span class="p">,</span> <span class="s">&#39;get_pkg_data_filenames&#39;</span><span class="p">,</span> <span class="s">&#39;compute_hash&#39;</span><span class="p">,</span>
           <span class="s">&#39;clear_download_cache&#39;</span><span class="p">,</span> <span class="s">&#39;CacheMissingWarning&#39;</span><span class="p">,</span>
           <span class="s">&#39;get_free_space_in_dir&#39;</span><span class="p">,</span> <span class="s">&#39;check_free_space_in_dir&#39;</span><span class="p">,</span> <span class="s">&#39;download_file&#39;</span><span class="p">,</span>
           <span class="s">&#39;download_files_in_parallel&#39;</span><span class="p">]</span>

<span class="n">DATAURL</span> <span class="o">=</span> <span class="n">ConfigurationItem</span><span class="p">(</span>
    <span class="s">&#39;dataurl&#39;</span><span class="p">,</span> <span class="s">&#39;http://data.astropy.org/&#39;</span><span class="p">,</span> <span class="s">&#39;URL for astropy remote data site.&#39;</span><span class="p">)</span>
<span class="n">REMOTE_TIMEOUT</span> <span class="o">=</span> <span class="n">ConfigurationItem</span><span class="p">(</span>
    <span class="s">&#39;remote_timeout&#39;</span><span class="p">,</span> <span class="mf">3.</span><span class="p">,</span> <span class="s">&#39;Time to wait for remote data query (in seconds).&#39;</span><span class="p">)</span>
<span class="n">COMPUTE_HASH_BLOCK_SIZE</span> <span class="o">=</span> <span class="n">ConfigurationItem</span><span class="p">(</span>
    <span class="s">&#39;hash_block_size&#39;</span><span class="p">,</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">16</span><span class="p">,</span>  <span class="c"># 64K</span>
    <span class="s">&#39;Block size for computing MD5 file hashes.&#39;</span><span class="p">)</span>
<span class="n">DOWNLOAD_CACHE_BLOCK_SIZE</span> <span class="o">=</span> <span class="n">ConfigurationItem</span><span class="p">(</span>
    <span class="s">&#39;download_block_size&#39;</span><span class="p">,</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">16</span><span class="p">,</span>  <span class="c"># 64K</span>
    <span class="s">&#39;Number of bytes of remote data to download per step.&#39;</span><span class="p">)</span>
<span class="n">DOWNLOAD_CACHE_LOCK_ATTEMPTS</span> <span class="o">=</span> <span class="n">ConfigurationItem</span><span class="p">(</span>
    <span class="s">&#39;download_cache_lock_attempts&#39;</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="s">&#39;Number of times to try to get the lock &#39;</span> <span class="o">+</span>
    <span class="s">&#39;while accessing the data cache before giving up.&#39;</span><span class="p">)</span>
<span class="n">DELETE_TEMPORARY_DOWNLOADS_AT_EXIT</span> <span class="o">=</span> <span class="n">ConfigurationItem</span><span class="p">(</span>
    <span class="s">&#39;delete_temporary_downloads_at_exit&#39;</span><span class="p">,</span> <span class="bp">True</span><span class="p">,</span> <span class="s">&#39;If True, temporary download&#39;</span> <span class="o">+</span>
    <span class="s">&#39; files created when the cache is inacessible will be deleted at the end&#39;</span> <span class="o">+</span>
    <span class="s">&#39; of the python session.&#39;</span><span class="p">)</span>


<span class="n">PY3K</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">3</span>


<div class="viewcode-block" id="CacheMissingWarning"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.CacheMissingWarning.html#astropy.utils.data.CacheMissingWarning">[docs]</a><span class="k">class</span> <span class="nc">CacheMissingWarning</span><span class="p">(</span><span class="ne">Warning</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    This warning indicates the standard cache directory is not accessible, with</span>
<span class="sd">    the first argument providing the warning message. If args[1] is present, it</span>
<span class="sd">    is a filename indicating the path to a temporary file that was created to</span>
<span class="sd">    store a remote data download in the absence of the cache.</span>
<span class="sd">    &quot;&quot;&quot;</span>

</div>
<span class="k">def</span> <span class="nf">_is_url</span><span class="p">(</span><span class="n">string</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Test whether a string is a valid URL</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    string : str</span>
<span class="sd">        The string to test</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">urlparse</span> <span class="kn">import</span> <span class="n">urlparse</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
    <span class="c"># url[0]==url.scheme, but url[0] is py 2.6-compat</span>
    <span class="c"># we can&#39;t just check that url[0] is not an empty string, because</span>
    <span class="c"># file paths in windows would return a non-empty scheme (e.g. e:\\</span>
    <span class="c"># returns &#39;e&#39;).</span>
    <span class="k">return</span> <span class="n">url</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="p">[</span><span class="s">&#39;http&#39;</span><span class="p">,</span> <span class="s">&#39;https&#39;</span><span class="p">,</span> <span class="s">&#39;ftp&#39;</span><span class="p">]</span>


<span class="k">def</span> <span class="nf">_is_inside</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">parent_path</span><span class="p">):</span>
    <span class="c"># We have to try realpath too to avoid issues with symlinks, but we leave</span>
    <span class="c"># abspath because some systems like debian have the absolute path (with no</span>
    <span class="c"># symlinks followed) match, but the real directories in different</span>
    <span class="c"># locations, so need to try both cases.</span>
    <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">parent_path</span><span class="p">))</span> \
        <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">parent_path</span><span class="p">))</span>

<span class="nd">@contextlib.contextmanager</span>
<div class="viewcode-block" id="get_readable_fileobj"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_readable_fileobj.html#astropy.utils.data.get_readable_fileobj">[docs]</a><span class="k">def</span> <span class="nf">get_readable_fileobj</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Given a filename or a readable file-like object, return a context</span>
<span class="sd">    manager that yields a readable file-like object.</span>

<span class="sd">    This supports passing filenames, URLs, and readable file-like</span>
<span class="sd">    objects, any of which can be compressed in gzip or bzip2.</span>

<span class="sd">    Notes</span>
<span class="sd">    -----</span>

<span class="sd">    This function is a context manager, and should be used for example</span>
<span class="sd">    as::</span>

<span class="sd">        with get_readable_fileobj(&#39;file.dat&#39;) as f:</span>
<span class="sd">            contents = f.read()</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    name_or_obj : str or file-like object</span>
<span class="sd">        The filename of the file to access (if given as a string), or</span>
<span class="sd">        the file-like object to access.</span>

<span class="sd">        If a file-like object, it must be opened in binary mode.</span>

<span class="sd">    encoding : str, optional</span>
<span class="sd">        When `None` (default), returns a file-like object with a</span>
<span class="sd">        `read` method that on Python 2.x returns `bytes` objects and</span>
<span class="sd">        on Python 3.x returns `str` (`unicode`) objects, using</span>
<span class="sd">        `locale.getpreferredencoding()` as an encoding.  This matches</span>
<span class="sd">        the default behavior of the built-in `open` when no `mode`</span>
<span class="sd">        argument is provided.</span>

<span class="sd">        When `&#39;binary&#39;`, returns a file-like object where its `read`</span>
<span class="sd">        method returns `bytes` objects.</span>

<span class="sd">        When another string, it is the name of an encoding, and the</span>
<span class="sd">        file-like object&#39;s `read` method will return `str` (`unicode`)</span>
<span class="sd">        objects, decoded from binary using the given encoding.</span>

<span class="sd">    cache : bool, optional</span>
<span class="sd">        Whether to cache the contents of remote URLs.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">tempfile</span>

    <span class="c"># close_fds is a list of file handles created by this function</span>
    <span class="c"># that need to be closed.  We don&#39;t want to always just close the</span>
    <span class="c"># returned file handle, because it may simply be the file handle</span>
    <span class="c"># passed in.  In that case it is not the responsibility of this</span>
    <span class="c"># function to close it: doing so could result in a &quot;double close&quot;</span>
    <span class="c"># and an &quot;invalid file descriptor&quot; exception.</span>
    <span class="n">close_fds</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">delete_fds</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="c"># Get a file object to the content</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="nb">basestring</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">_is_url</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">):</span>
            <span class="n">name_or_obj</span> <span class="o">=</span> <span class="n">download_file</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="n">cache</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">PY3K</span><span class="p">:</span>
            <span class="n">fileobj</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">FileIO</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">fileobj</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
        <span class="n">close_fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fileobj</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">fileobj</span> <span class="o">=</span> <span class="n">name_or_obj</span>

    <span class="c"># Check if the file object supports random access, and if not,</span>
    <span class="c"># then wrap it in a BytesIO buffer.  It would be nicer to use a</span>
    <span class="c"># BufferedReader to avoid reading loading the whole file first,</span>
    <span class="c"># but that is not compatible with streams or urllib2.urlopen</span>
    <span class="c"># objects on Python 2.x.</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">fileobj</span><span class="p">,</span> <span class="s">&#39;seek&#39;</span><span class="p">):</span>
        <span class="n">fileobj</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">fileobj</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>

    <span class="c"># Now read enough bytes to look at signature</span>
    <span class="n">signature</span> <span class="o">=</span> <span class="n">fileobj</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
    <span class="n">fileobj</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">signature</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="n">b</span><span class="s">&#39;</span><span class="se">\x1f\x8b\x08</span><span class="s">&#39;</span><span class="p">:</span>  <span class="c"># gzip</span>
        <span class="kn">import</span> <span class="nn">struct</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="kn">from</span> <span class="nn">.compat</span> <span class="kn">import</span> <span class="n">gzip</span>
            <span class="n">fileobj_new</span> <span class="o">=</span> <span class="n">gzip</span><span class="o">.</span><span class="n">GzipFile</span><span class="p">(</span><span class="n">fileobj</span><span class="o">=</span><span class="n">fileobj</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s">&#39;rb&#39;</span><span class="p">)</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>  <span class="c"># need to check that the file is really gzip</span>
        <span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">EOFError</span><span class="p">):</span>  <span class="c"># invalid gzip file</span>
            <span class="n">fileobj</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">except</span> <span class="n">struct</span><span class="o">.</span><span class="n">error</span><span class="p">:</span>  <span class="c"># invalid gzip file on Python 3</span>
            <span class="n">fileobj</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="n">fileobj</span> <span class="o">=</span> <span class="n">fileobj_new</span>
    <span class="k">elif</span> <span class="n">signature</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="n">b</span><span class="s">&#39;BZh&#39;</span><span class="p">:</span>  <span class="c"># bzip2</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c"># bz2.BZ2File does not support file objects, only filenames, so we</span>
            <span class="c"># need to write the data to a temporary file</span>
            <span class="n">tmp</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">NamedTemporaryFile</span><span class="p">(</span><span class="s">&quot;wb&quot;</span><span class="p">,</span> <span class="n">delete</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
            <span class="n">tmp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fileobj</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
            <span class="n">tmp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
            <span class="n">delete_fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
            <span class="kn">import</span> <span class="nn">bz2</span>
            <span class="n">fileobj_new</span> <span class="o">=</span> <span class="n">bz2</span><span class="o">.</span><span class="n">BZ2File</span><span class="p">(</span><span class="n">tmp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s">&#39;rb&#39;</span><span class="p">)</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>  <span class="c"># need to check that the file is really bzip2</span>
        <span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>  <span class="c"># invalid bzip2 file</span>
            <span class="n">fileobj</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">fileobj_new</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
            <span class="n">close_fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fileobj_new</span><span class="p">)</span>
            <span class="n">fileobj</span> <span class="o">=</span> <span class="n">fileobj_new</span>

    <span class="c"># By this point, we have a file, io.FileIO, gzip.GzipFile, or</span>
    <span class="c"># bz2.BZ2File instance opened in binary mode (that is, read</span>
    <span class="c"># returns bytes).  Now we need to, if requested, wrap it in a</span>
    <span class="c"># io.TextIOWrapper so read will return unicode based on the</span>
    <span class="c"># encoding parameter.</span>

    <span class="k">if</span> <span class="n">PY3K</span><span class="p">:</span>
        <span class="n">needs_textio_wrapper</span> <span class="o">=</span> <span class="n">encoding</span> <span class="o">!=</span> <span class="s">&#39;binary&#39;</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">needs_textio_wrapper</span> <span class="o">=</span> <span class="n">encoding</span> <span class="o">!=</span> <span class="s">&#39;binary&#39;</span> <span class="ow">and</span> <span class="n">encoding</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span>

    <span class="k">if</span> <span class="n">needs_textio_wrapper</span><span class="p">:</span>
        <span class="c"># A bz2.BZ2File can not be wrapped by a TextIOWrapper,</span>
        <span class="c"># so we decompress it to a temporary file and then</span>
        <span class="c"># return a handle to that.</span>
        <span class="kn">import</span> <span class="nn">bz2</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">fileobj</span><span class="p">,</span> <span class="n">bz2</span><span class="o">.</span><span class="n">BZ2File</span><span class="p">):</span>
            <span class="n">tmp</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">NamedTemporaryFile</span><span class="p">(</span><span class="s">&quot;wb&quot;</span><span class="p">,</span> <span class="n">delete</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
            <span class="n">data</span> <span class="o">=</span> <span class="n">fileobj</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
            <span class="n">tmp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
            <span class="n">tmp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
            <span class="n">delete_fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">PY3K</span><span class="p">:</span>
                <span class="n">fileobj</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">FileIO</span><span class="p">(</span><span class="n">tmp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">fileobj</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">tmp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
            <span class="n">close_fds</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fileobj</span><span class="p">)</span>

        <span class="c"># On Python 2.x, we need to first wrap the regular `file`</span>
        <span class="c"># instance in a `io.FileIO` object before it can be</span>
        <span class="c"># wrapped in a `TextIOWrapper`.  We don&#39;t just create an</span>
        <span class="c"># `io.FileIO` object in the first place, because we can&#39;t</span>
        <span class="c"># get a raw file descriptor out of it on Python 2.x, which</span>
        <span class="c"># is required for the XML iterparser.</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">PY3K</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">fileobj</span><span class="p">,</span> <span class="nb">file</span><span class="p">):</span>
            <span class="n">fileobj</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">FileIO</span><span class="p">(</span><span class="n">fileobj</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span>

        <span class="n">fileobj</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BufferedReader</span><span class="p">(</span><span class="n">fileobj</span><span class="p">)</span>
        <span class="n">fileobj</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">TextIOWrapper</span><span class="p">(</span><span class="n">fileobj</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">)</span>

        <span class="c"># Ensure that file is at the start - io.FileIO will for</span>
        <span class="c"># example not always be at the start:</span>
        <span class="c"># &gt;&gt;&gt; import io</span>
        <span class="c"># &gt;&gt;&gt; f = open(&#39;test.fits&#39;, &#39;rb&#39;)</span>
        <span class="c"># &gt;&gt;&gt; f.read(4)</span>
        <span class="c"># &#39;SIMP&#39;</span>
        <span class="c"># &gt;&gt;&gt; f.seek(0)</span>
        <span class="c"># &gt;&gt;&gt; fileobj = io.FileIO(f.fileno())</span>
        <span class="c"># &gt;&gt;&gt; fileobj.tell()</span>
        <span class="c"># 4096L</span>

        <span class="n">fileobj</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="k">yield</span> <span class="n">fileobj</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">close_fds</span><span class="p">:</span>
            <span class="n">fd</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">fd</span> <span class="ow">in</span> <span class="n">delete_fds</span><span class="p">:</span>
            <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">fd</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>

</div>
<div class="viewcode-block" id="get_file_contents"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_file_contents.html#astropy.utils.data.get_file_contents">[docs]</a><span class="k">def</span> <span class="nf">get_file_contents</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Retrieves the contents of a filename or file-like object.</span>

<span class="sd">    See  the `get_readable_fileobj` docstring for details on parameters.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    content</span>
<span class="sd">        The content of the file (as requested by `encoding`).</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">with</span> <span class="n">get_readable_fileobj</span><span class="p">(</span><span class="n">name_or_obj</span><span class="p">,</span> <span class="n">encoding</span><span class="p">,</span> <span class="n">cache</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>

</div>
<div class="viewcode-block" id="get_pkg_data_fileobj"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_pkg_data_fileobj.html#astropy.utils.data.get_pkg_data_fileobj">[docs]</a><span class="k">def</span> <span class="nf">get_pkg_data_fileobj</span><span class="p">(</span><span class="n">data_name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Retrieves a data file from the standard locations for the package and</span>
<span class="sd">    provides the file as a file-like object that reads bytes.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    data_name : str</span>
<span class="sd">        Name/location of the desired data file.  One of the following:</span>

<span class="sd">            * The name of a data file included in the source</span>
<span class="sd">              distribution.  The path is relative to the module</span>
<span class="sd">              calling this function.  For example, if calling from</span>
<span class="sd">              `astropy.pkname`, use ``&#39;data/file.dat&#39;`` to get the</span>
<span class="sd">              file in ``astropy/pkgname/data/file.dat``.  Double-dots</span>
<span class="sd">              can be used to go up a level.  In the same example, use</span>
<span class="sd">              ``&#39;../data/file.dat&#39;`` to get ``astropy/data/file.dat``.</span>
<span class="sd">            * If a matching local file does not exist, the Astropy</span>
<span class="sd">              data server will be queried for the file.</span>
<span class="sd">            * A hash like that produced by `compute_hash` can be</span>
<span class="sd">              requested, prefixed by &#39;hash/&#39;</span>
<span class="sd">              e.g. &#39;hash/395dd6493cc584df1e78b474fb150840&#39;.  The hash</span>
<span class="sd">              will first be searched for locally, and if not found,</span>
<span class="sd">              the Astropy data server will be queried.</span>

<span class="sd">    encoding : str, optional</span>
<span class="sd">        When `None` (default), returns a file-like object with a</span>
<span class="sd">        `read` method that on Python 2.x returns `bytes` objects and</span>
<span class="sd">        on Python 3.x returns `str` (`unicode`) objects, using</span>
<span class="sd">        `locale.getpreferredencoding()` as an encoding.  This matches</span>
<span class="sd">        the default behavior of the built-in `open` when no `mode`</span>
<span class="sd">        argument is provided.</span>

<span class="sd">        When `&#39;binary&#39;`, returns a file-like object where its `read`</span>
<span class="sd">        method returns `bytes` objects.</span>

<span class="sd">        When another string, it is the name of an encoding, and the</span>
<span class="sd">        file-like object&#39;s `read` method will return `str` (`unicode`)</span>
<span class="sd">        objects, decoded from binary using the given encoding.</span>

<span class="sd">    cache : bool</span>
<span class="sd">        If True, the file will be downloaded and saved locally or the</span>
<span class="sd">        already-cached local copy will be accessed. If False, the file-like</span>
<span class="sd">        object will directly access the resource (e.g. if a remote URL is</span>
<span class="sd">        accessed, an object like that from `urllib2.urlopen` is returned).</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    fileobj : file-like</span>
<span class="sd">        An object with the contents of the data file available via</span>
<span class="sd">        :func:`read`.  Can be used as part of a ``with`` statement,</span>
<span class="sd">        automatically closing itself after the ``with`` block.</span>

<span class="sd">    Raises</span>
<span class="sd">    ------</span>
<span class="sd">    urllib2.URLError</span>
<span class="sd">        If a remote file cannot be found.</span>
<span class="sd">    IOError</span>
<span class="sd">        If problems occur writing or reading a local file.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>

<span class="sd">    This will retrieve a data file and its contents for the `astropy.wcs`</span>
<span class="sd">    tests::</span>

<span class="sd">        from astropy.utils.data import get_pkg_data_fileobj</span>

<span class="sd">        with get_pkg_data_fileobj(&#39;data/3d_cd.hdr&#39;) as fobj:</span>
<span class="sd">            fcontents = fobj.read()</span>

<span class="sd">    This would download a data file from the astropy data server</span>
<span class="sd">    because the ``standards/vega.fits`` file is not present in the</span>
<span class="sd">    source distribution.  It will also save the file locally so the</span>
<span class="sd">    next time it is accessed it won&#39;t need to be downloaded.::</span>

<span class="sd">        from astropy.utils.data import get_pkg_data_fileobj</span>

<span class="sd">        with get_pkg_data_fileobj(&#39;standards/vega.fits&#39;) as fobj:</span>
<span class="sd">            fcontents = fobj.read()</span>

<span class="sd">    This does the same thing but does *not* cache it locally::</span>

<span class="sd">        with get_pkg_data_fileobj(&#39;standards/vega.fits&#39;, cache=False) as fobj:</span>
<span class="sd">            fcontents = fobj.read()</span>

<span class="sd">    See Also</span>
<span class="sd">    --------</span>
<span class="sd">    get_pkg_data_contents : returns the contents of a file or url as a bytes object</span>
<span class="sd">    get_pkg_data_filename : returns a local name for a file containing the data</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">datafn</span> <span class="o">=</span> <span class="n">_find_pkg_data_path</span><span class="p">(</span><span class="n">data_name</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">datafn</span><span class="p">):</span>
        <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s">&quot;Tried to access a data file that&#39;s actually &quot;</span>
                      <span class="s">&quot;a package data directory&quot;</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">datafn</span><span class="p">):</span>  <span class="c"># local file</span>
        <span class="k">return</span> <span class="n">get_readable_fileobj</span><span class="p">(</span><span class="n">datafn</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>  <span class="c"># remote file</span>
        <span class="k">return</span> <span class="n">get_readable_fileobj</span><span class="p">(</span><span class="n">DATAURL</span><span class="p">()</span> <span class="o">+</span> <span class="n">datafn</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">,</span>
                                    <span class="n">cache</span><span class="o">=</span><span class="n">cache</span><span class="p">)</span>

</div>
<div class="viewcode-block" id="get_pkg_data_filename"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_pkg_data_filename.html#astropy.utils.data.get_pkg_data_filename">[docs]</a><span class="k">def</span> <span class="nf">get_pkg_data_filename</span><span class="p">(</span><span class="n">data_name</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Retrieves a data file from the standard locations for the package and</span>
<span class="sd">    provides a local filename for the data.</span>

<span class="sd">    This function is similar to `get_pkg_data_fileobj` but returns the</span>
<span class="sd">    file *name* instead of a readable file-like object.  This means</span>
<span class="sd">    that this function must always cache remote files locally, unlike</span>
<span class="sd">    `get_pkg_data_fileobj`.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    data_name : str</span>
<span class="sd">        Name/location of the desired data file.  One of the following:</span>

<span class="sd">            * The name of a data file included in the source</span>
<span class="sd">              distribution.  The path is relative to the module</span>
<span class="sd">              calling this function.  For example, if calling from</span>
<span class="sd">              `astropy.pkname`, use ``&#39;data/file.dat&#39;`` to get the</span>
<span class="sd">              file in ``astropy/pkgname/data/file.dat``.  Double-dots</span>
<span class="sd">              can be used to go up a level.  In the same example, use</span>
<span class="sd">              ``&#39;../data/file.dat&#39;`` to get ``astropy/data/file.dat``.</span>
<span class="sd">            * If a matching local file does not exist, the Astropy</span>
<span class="sd">              data server will be queried for the file.</span>
<span class="sd">            * A hash like that produced by `compute_hash` can be</span>
<span class="sd">              requested, prefixed by &#39;hash/&#39;</span>
<span class="sd">              e.g. &#39;hash/395dd6493cc584df1e78b474fb150840&#39;.  The hash</span>
<span class="sd">              will first be searched for locally, and if not found,</span>
<span class="sd">              the Astropy data server will be queried.</span>

<span class="sd">    Raises</span>
<span class="sd">    ------</span>
<span class="sd">    urllib2.URLError</span>
<span class="sd">        If a remote file cannot be found.</span>
<span class="sd">    IOError</span>
<span class="sd">        If problems occur writing or reading a local file.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    filename : str</span>
<span class="sd">        A file path on the local file system corresponding to the data</span>
<span class="sd">        requested in `data_name`.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>

<span class="sd">    This will retrieve the contents of the data file for the `astropy.wcs`</span>
<span class="sd">    tests::</span>

<span class="sd">        from astropy.utils.data import get_pkg_data_filename</span>

<span class="sd">        fn = get_pkg_data_filename(&#39;data/3d_cd.hdr&#39;)</span>
<span class="sd">        with open(fn) as f:</span>
<span class="sd">            fcontents = f.read()</span>


<span class="sd">    This retrieves a data file by hash either locally or from the astropy data</span>
<span class="sd">    server::</span>

<span class="sd">        from astropy.utils.data import get_pkg_data_filename</span>

<span class="sd">        fn = get_pkg_data_filename(&#39;hash/da34a7b07ef153eede67387bf950bb32&#39;)</span>
<span class="sd">        with open(fn) as f:</span>
<span class="sd">            fcontents = f.read()</span>

<span class="sd">    See Also</span>
<span class="sd">    --------</span>
<span class="sd">    get_pkg_data_contents : returns the contents of a file or url as a bytes object</span>
<span class="sd">    get_pkg_data_fileobj : returns a file-like object with the data</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">if</span> <span class="n">data_name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;hash/&#39;</span><span class="p">):</span>
        <span class="c"># first try looking for a local version if a hash is specified</span>
        <span class="n">hashfn</span> <span class="o">=</span> <span class="n">_find_hash_fn</span><span class="p">(</span><span class="n">data_name</span><span class="p">[</span><span class="mi">5</span><span class="p">:])</span>
        <span class="k">if</span> <span class="n">hashfn</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">download_file</span><span class="p">(</span><span class="n">DATAURL</span><span class="p">()</span> <span class="o">+</span> <span class="n">data_name</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">hashfn</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">datafn</span> <span class="o">=</span> <span class="n">_find_pkg_data_path</span><span class="p">(</span><span class="n">data_name</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">datafn</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s">&quot;Tried to access a data file that&#39;s actually &quot;</span>
                          <span class="s">&quot;a package data directory&quot;</span><span class="p">)</span>
        <span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">datafn</span><span class="p">):</span>  <span class="c"># local file</span>
            <span class="k">return</span> <span class="n">datafn</span>
        <span class="k">else</span><span class="p">:</span>  <span class="c"># remote file</span>
            <span class="k">return</span> <span class="n">download_file</span><span class="p">(</span><span class="n">DATAURL</span><span class="p">()</span> <span class="o">+</span> <span class="n">data_name</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

</div>
<div class="viewcode-block" id="get_pkg_data_contents"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_pkg_data_contents.html#astropy.utils.data.get_pkg_data_contents">[docs]</a><span class="k">def</span> <span class="nf">get_pkg_data_contents</span><span class="p">(</span><span class="n">data_name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Retrieves a data file from the standard locations and returns its</span>
<span class="sd">    contents as a bytes object.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    data_name : str</span>
<span class="sd">        Name/location of the desired data file.  One of the following:</span>

<span class="sd">            * The name of a data file included in the source</span>
<span class="sd">              distribution.  The path is relative to the module</span>
<span class="sd">              calling this function.  For example, if calling from</span>
<span class="sd">              `astropy.pkname`, use ``&#39;data/file.dat&#39;`` to get the</span>
<span class="sd">              file in ``astropy/pkgname/data/file.dat``.  Double-dots</span>
<span class="sd">              can be used to go up a level.  In the same example, use</span>
<span class="sd">              ``&#39;../data/file.dat&#39;`` to get ``astropy/data/file.dat``.</span>
<span class="sd">            * If a matching local file does not exist, the Astropy</span>
<span class="sd">              data server will be queried for the file.</span>
<span class="sd">            * A hash like that produced by `compute_hash` can be</span>
<span class="sd">              requested, prefixed by &#39;hash/&#39;</span>
<span class="sd">              e.g. &#39;hash/395dd6493cc584df1e78b474fb150840&#39;.  The hash</span>
<span class="sd">              will first be searched for locally, and if not found,</span>
<span class="sd">              the Astropy data server will be queried.</span>
<span class="sd">            * A URL to some other file.</span>

<span class="sd">    encoding : str, optional</span>
<span class="sd">        When `None` (default), returns a file-like object with a</span>
<span class="sd">        `read` method that on Python 2.x returns `bytes` objects and</span>
<span class="sd">        on Python 3.x returns `str` (`unicode`) objects, using</span>
<span class="sd">        `locale.getpreferredencoding()` as an encoding.  This matches</span>
<span class="sd">        the default behavior of the built-in `open` when no `mode`</span>
<span class="sd">        argument is provided.</span>

<span class="sd">        When `&#39;binary&#39;`, returns a file-like object where its `read`</span>
<span class="sd">        method returns `bytes` objects.</span>

<span class="sd">        When another string, it is the name of an encoding, and the</span>
<span class="sd">        file-like object&#39;s `read` method will return `str` (`unicode`)</span>
<span class="sd">        objects, decoded from binary using the given encoding.</span>

<span class="sd">    cache : bool</span>
<span class="sd">        If True, the file will be downloaded and saved locally or the</span>
<span class="sd">        already-cached local copy will be accessed. If False, the file-like</span>
<span class="sd">        object will directly access the resource (e.g. if a remote URL is</span>
<span class="sd">        accessed, an object like that from `urllib2.urlopen` is returned).</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    contents : bytes</span>
<span class="sd">        The complete contents of the file as a bytes object.</span>

<span class="sd">    Raises</span>
<span class="sd">    ------</span>
<span class="sd">    urllib2.URLError</span>
<span class="sd">        If a remote file cannot be found.</span>
<span class="sd">    IOError</span>
<span class="sd">        If problems occur writing or reading a local file.</span>

<span class="sd">    See Also</span>
<span class="sd">    --------</span>
<span class="sd">    get_pkg_data_fileobj : returns a file-like object with the data</span>
<span class="sd">    get_pkg_data_filename : returns a local name for a file containing the data</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">with</span> <span class="n">get_pkg_data_fileobj</span><span class="p">(</span><span class="n">data_name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="n">cache</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
        <span class="n">contents</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">contents</span>

</div>
<div class="viewcode-block" id="get_pkg_data_filenames"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_pkg_data_filenames.html#astropy.utils.data.get_pkg_data_filenames">[docs]</a><span class="k">def</span> <span class="nf">get_pkg_data_filenames</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="s">&#39;*&#39;</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns the path of all of the data files in a given directory</span>
<span class="sd">    that match a given glob pattern.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    datadir : str</span>
<span class="sd">        Name/location of the desired data files.  One of the following:</span>

<span class="sd">            * The name of a directory included in the source</span>
<span class="sd">              distribution.  The path is relative to the module</span>
<span class="sd">              calling this function.  For example, if calling from</span>
<span class="sd">              `astropy.pkname`, use ``&#39;data&#39;`` to get the</span>
<span class="sd">              files in ``astropy/pkgname/data``.</span>
<span class="sd">            * Remote URLs are not currently supported.</span>

<span class="sd">    pattern : str, optional</span>
<span class="sd">        A UNIX-style filename glob pattern to match files.  See the</span>
<span class="sd">        `glob` module in the standard library for more information.</span>
<span class="sd">        By default, matches all files.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    filenames : iterator of str</span>
<span class="sd">        Paths on the local filesystem in *datadir* matching *pattern*.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>
<span class="sd">    This will retrieve the contents of the data file for the `astropy.wcs`</span>
<span class="sd">    tests::</span>

<span class="sd">        from astropy.utils.data import get_pkg_data_filenames</span>

<span class="sd">        for fn in get_pkg_data_filename(&#39;maps&#39;, &#39;*.hdr&#39;):</span>
<span class="sd">            with open(fn) as f:</span>
<span class="sd">                fcontents = f.read()</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">fnmatch</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">isdir</span><span class="p">,</span> <span class="n">isfile</span><span class="p">,</span> <span class="n">join</span>
    <span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">listdir</span>

    <span class="n">path</span> <span class="o">=</span> <span class="n">_find_pkg_data_path</span><span class="p">(</span><span class="n">datadir</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">isfile</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
        <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span>
            <span class="s">&quot;Tried to access a data directory that&#39;s actually &quot;</span>
            <span class="s">&quot;a package data file&quot;</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">isdir</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">listdir</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">fnmatch</span><span class="o">.</span><span class="n">fnmatch</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">pattern</span><span class="p">):</span>
                <span class="k">yield</span> <span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s">&quot;Path not found&quot;</span><span class="p">)</span>

</div>
<div class="viewcode-block" id="get_pkg_data_fileobjs"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_pkg_data_fileobjs.html#astropy.utils.data.get_pkg_data_fileobjs">[docs]</a><span class="k">def</span> <span class="nf">get_pkg_data_fileobjs</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="s">&#39;*&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Returns readable file objects for all of the data files in a given</span>
<span class="sd">    directory that match a given glob pattern.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    datadir : str</span>
<span class="sd">        Name/location of the desired data files.  One of the following:</span>

<span class="sd">            * The name of a directory included in the source</span>
<span class="sd">              distribution.  The path is relative to the module</span>
<span class="sd">              calling this function.  For example, if calling from</span>
<span class="sd">              `astropy.pkname`, use ``&#39;data&#39;`` to get the</span>
<span class="sd">              files in ``astropy/pkgname/data``</span>
<span class="sd">            * Remote URLs are not currently supported</span>

<span class="sd">    pattern : str, optional</span>
<span class="sd">        A UNIX-style filename glob pattern to match files.  See the</span>
<span class="sd">        `glob` module in the standard library for more information.</span>
<span class="sd">        By default, matches all files.</span>

<span class="sd">    encoding : str, optional</span>
<span class="sd">        When `None` (default), returns a file-like object with a</span>
<span class="sd">        `read` method that on Python 2.x returns `bytes` objects and</span>
<span class="sd">        on Python 3.x returns `str` (`unicode`) objects, using</span>
<span class="sd">        `locale.getpreferredencoding()` as an encoding.  This matches</span>
<span class="sd">        the default behavior of the built-in `open` when no `mode`</span>
<span class="sd">        argument is provided.</span>

<span class="sd">        When `&#39;binary&#39;`, returns a file-like object where its `read`</span>
<span class="sd">        method returns `bytes` objects.</span>

<span class="sd">        When another string, it is the name of an encoding, and the</span>
<span class="sd">        file-like object&#39;s `read` method will return `str` (`unicode`)</span>
<span class="sd">        objects, decoded from binary using the given encoding.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    fileobjs : iterator of file objects</span>
<span class="sd">        File objects for each of the files on the local filesystem in</span>
<span class="sd">        *datadir* matching *pattern*.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>
<span class="sd">    This will retrieve the contents of the data file for the `astropy.wcs`</span>
<span class="sd">    tests::</span>

<span class="sd">        from astropy.utils.data import get_pkg_data_filenames</span>

<span class="sd">        for fd in get_pkg_data_filename(&#39;maps&#39;, &#39;*.hdr&#39;):</span>
<span class="sd">            fcontents = fd.read()</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">for</span> <span class="n">fn</span> <span class="ow">in</span> <span class="n">get_pkg_data_filenames</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="n">pattern</span><span class="p">):</span>
        <span class="k">with</span> <span class="n">get_pkg_data_fileobj</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">encoding</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
            <span class="k">yield</span> <span class="n">fd</span>

</div>
<div class="viewcode-block" id="compute_hash"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.compute_hash.html#astropy.utils.data.compute_hash">[docs]</a><span class="k">def</span> <span class="nf">compute_hash</span><span class="p">(</span><span class="n">localfn</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Computes the MD5 hash for a file.</span>

<span class="sd">    The hash for a data file is used for looking up data files in a unique</span>
<span class="sd">    fashion. This is of particular use for tests; a test may require a</span>
<span class="sd">    particular version of a particular file, in which case it can be accessed</span>
<span class="sd">    via hash to get the appropriate version.</span>

<span class="sd">    Typically, if you wish to write a test that requires a particular data</span>
<span class="sd">    file, you will want to submit that file to the astropy data servers, and</span>
<span class="sd">    use e.g. ``get_pkg_data_filename(&#39;hash/a725fa6ba642587436612c2df0451956&#39;)``,</span>
<span class="sd">    but with the hash for your file in place of the hash in the example.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    localfn : str</span>
<span class="sd">        The path to the file for which the hash should be generated.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    md5hash : str</span>
<span class="sd">        The hex digest of the MD5 hash for the contents of the `localfn` file.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">hashlib</span>

    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">localfn</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
        <span class="n">h</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">()</span>
        <span class="n">block</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">COMPUTE_HASH_BLOCK_SIZE</span><span class="p">())</span>
        <span class="k">while</span> <span class="n">block</span><span class="p">:</span>
            <span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
            <span class="n">block</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">COMPUTE_HASH_BLOCK_SIZE</span><span class="p">())</span>

    <span class="k">return</span> <span class="n">h</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>

</div>
<span class="k">def</span> <span class="nf">_find_pkg_data_path</span><span class="p">(</span><span class="n">data_name</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Look for data in the source-included data directories and return the</span>
<span class="sd">    path.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">dirname</span><span class="p">,</span> <span class="n">join</span>
    <span class="kn">from</span> <span class="nn">..utils.misc</span> <span class="kn">import</span> <span class="n">find_current_module</span>

    <span class="n">module</span> <span class="o">=</span> <span class="n">find_current_module</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">module</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
        <span class="c"># not called from inside an astropy package.  So just pass name through</span>
        <span class="k">return</span> <span class="n">data_name</span>
    <span class="n">rootpkgname</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="n">__package__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;.&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>

    <span class="n">rootpkg</span> <span class="o">=</span> <span class="nb">__import__</span><span class="p">(</span><span class="n">rootpkgname</span><span class="p">)</span>

    <span class="n">module_path</span> <span class="o">=</span> <span class="n">dirname</span><span class="p">(</span><span class="n">module</span><span class="o">.</span><span class="n">__file__</span><span class="p">)</span>
    <span class="n">path</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">module_path</span><span class="p">,</span> <span class="n">data_name</span><span class="p">)</span>

    <span class="n">root_dir</span> <span class="o">=</span> <span class="n">dirname</span><span class="p">(</span><span class="n">rootpkg</span><span class="o">.</span><span class="n">__file__</span><span class="p">)</span>
    <span class="k">assert</span> <span class="n">_is_inside</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">root_dir</span><span class="p">),</span> \
           <span class="p">(</span><span class="s">&quot;attempted to get a local data file outside &quot;</span>
            <span class="s">&quot;of the &quot;</span> <span class="o">+</span> <span class="n">rootpkgname</span> <span class="o">+</span> <span class="s">&quot; tree&quot;</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">path</span>


<span class="k">def</span> <span class="nf">_find_hash_fn</span><span class="p">(</span><span class="nb">hash</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Looks for a local file by hash - returns file name if found and a valid</span>
<span class="sd">    file, otherwise returns None.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">isfile</span><span class="p">,</span> <span class="n">join</span>
    <span class="kn">from</span> <span class="nn">warnings</span> <span class="kn">import</span> <span class="n">warn</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">dldir</span><span class="p">,</span> <span class="n">urlmapfn</span> <span class="o">=</span> <span class="n">_get_download_cache_locs</span><span class="p">()</span>
    <span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">OSError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Could not access cache directory to search for data file: &#39;</span>
        <span class="n">warn</span><span class="p">(</span><span class="n">CacheMissingWarning</span><span class="p">(</span><span class="n">msg</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
        <span class="k">return</span> <span class="bp">None</span>
    <span class="n">hashfn</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">dldir</span><span class="p">,</span> <span class="nb">hash</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">isfile</span><span class="p">(</span><span class="n">hashfn</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">hashfn</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">None</span>


<div class="viewcode-block" id="get_free_space_in_dir"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.get_free_space_in_dir.html#astropy.utils.data.get_free_space_in_dir">[docs]</a><span class="k">def</span> <span class="nf">get_free_space_in_dir</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Given a path to a directory, returns the amount of free space (in</span>
<span class="sd">    bytes) on that filesystem.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    path : str</span>
<span class="sd">        The path to a directory</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    bytes : int</span>
<span class="sd">        The amount of free space on the partition that the directory</span>
<span class="sd">        is on.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">stat</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">statvfs</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">stat</span><span class="o">.</span><span class="n">f_bavail</span> <span class="o">*</span> <span class="n">stat</span><span class="o">.</span><span class="n">f_frsize</span>

</div>
<div class="viewcode-block" id="check_free_space_in_dir"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.check_free_space_in_dir.html#astropy.utils.data.check_free_space_in_dir">[docs]</a><span class="k">def</span> <span class="nf">check_free_space_in_dir</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">size</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Determines if a given directory has enough space to hold a file of</span>
<span class="sd">    a given size.  Raises an IOError if the file would be too large.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    path : str</span>
<span class="sd">        The path to a directory</span>

<span class="sd">    size : int</span>
<span class="sd">        A proposed filesize (in bytes)</span>

<span class="sd">    Raises</span>
<span class="sd">    -------</span>
<span class="sd">    IOError : There is not enough room on the filesystem</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">..utils.console</span> <span class="kn">import</span> <span class="n">human_file_size</span>

    <span class="n">space</span> <span class="o">=</span> <span class="n">get_free_space_in_dir</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">space</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span>
            <span class="s">&quot;Not enough free space in &#39;{0}&#39; &quot;</span>
            <span class="s">&quot;to download a {1} file&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
                <span class="n">path</span><span class="p">,</span> <span class="n">human_file_size</span><span class="p">(</span><span class="n">size</span><span class="p">)))</span>

</div>
<div class="viewcode-block" id="download_file"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.download_file.html#astropy.utils.data.download_file">[docs]</a><span class="k">def</span> <span class="nf">download_file</span><span class="p">(</span><span class="n">remote_url</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Accepts a URL, downloads and optionally caches the result</span>
<span class="sd">    returning the filename, with a name determined by the file&#39;s MD5</span>
<span class="sd">    hash. If ``cache=True`` and the file is present in the cache, just</span>
<span class="sd">    returns the filename.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    remote_url : str</span>
<span class="sd">        The URL of the file to download</span>
<span class="sd">    cache : bool, optional</span>
<span class="sd">        Whether to use the cache</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    local_path : str</span>
<span class="sd">        Returns the local path that the file was download to.</span>

<span class="sd">    Raises</span>
<span class="sd">    ------</span>
<span class="sd">    `urllib2.URLError`</span>
<span class="sd">        Whenever there&#39;s a problem getting the remote file.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="kn">import</span> <span class="nn">hashlib</span>
    <span class="kn">import</span> <span class="nn">socket</span>
    <span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">closing</span>
    <span class="kn">from</span> <span class="nn">tempfile</span> <span class="kn">import</span> <span class="n">NamedTemporaryFile</span><span class="p">,</span> <span class="n">gettempdir</span>
    <span class="kn">from</span> <span class="nn">shutil</span> <span class="kn">import</span> <span class="n">move</span>
    <span class="kn">from</span> <span class="nn">warnings</span> <span class="kn">import</span> <span class="n">warn</span>

    <span class="kn">from</span> <span class="nn">..utils.console</span> <span class="kn">import</span> <span class="n">ProgressBarOrSpinner</span>

    <span class="n">missing_cache</span> <span class="o">=</span> <span class="bp">False</span>

    <span class="k">if</span> <span class="n">cache</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">dldir</span><span class="p">,</span> <span class="n">urlmapfn</span> <span class="o">=</span> <span class="n">_get_download_cache_locs</span><span class="p">()</span>
        <span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">OSError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Remote data cache could not be accessed due to &#39;</span>
            <span class="n">estr</span> <span class="o">=</span> <span class="s">&#39;&#39;</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="p">(</span><span class="s">&#39;: &#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
            <span class="n">warn</span><span class="p">(</span><span class="n">CacheMissingWarning</span><span class="p">(</span><span class="n">msg</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span> <span class="o">+</span> <span class="n">estr</span><span class="p">))</span>
            <span class="n">cache</span> <span class="o">=</span> <span class="bp">False</span>
            <span class="n">missing_cache</span> <span class="o">=</span> <span class="bp">True</span>  <span class="c"># indicates that the cache is missing to raise a warning later</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">cache</span><span class="p">:</span>
            <span class="c"># We don&#39;t need to acquire the lock here, since we are only reading</span>
            <span class="k">with</span> <span class="n">_open_shelve</span><span class="p">(</span><span class="n">urlmapfn</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">url2hash</span><span class="p">:</span>
                <span class="k">if</span> <span class="nb">str</span><span class="p">(</span><span class="n">remote_url</span><span class="p">)</span> <span class="ow">in</span> <span class="n">url2hash</span><span class="p">:</span>
                    <span class="k">return</span> <span class="n">url2hash</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">remote_url</span><span class="p">)]</span>

        <span class="k">with</span> <span class="n">closing</span><span class="p">(</span><span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">remote_url</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">REMOTE_TIMEOUT</span><span class="p">()))</span> <span class="k">as</span> <span class="n">remote</span><span class="p">:</span>
            <span class="c">#keep a hash to rename the local file to the hashed name</span>
            <span class="nb">hash</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">()</span>

            <span class="n">info</span> <span class="o">=</span> <span class="n">remote</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
            <span class="k">if</span> <span class="s">&#39;Content-Length&#39;</span> <span class="ow">in</span> <span class="n">info</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">info</span><span class="p">[</span><span class="s">&#39;Content-Length&#39;</span><span class="p">])</span>
                <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
                    <span class="n">size</span> <span class="o">=</span> <span class="bp">None</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">size</span> <span class="o">=</span> <span class="bp">None</span>

            <span class="k">if</span> <span class="n">size</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
                <span class="n">check_free_space_in_dir</span><span class="p">(</span><span class="n">gettempdir</span><span class="p">(),</span> <span class="n">size</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">cache</span><span class="p">:</span>
                    <span class="n">check_free_space_in_dir</span><span class="p">(</span><span class="n">dldir</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>

            <span class="n">dlmsg</span> <span class="o">=</span> <span class="s">&quot;Downloading {0}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">remote_url</span><span class="p">)</span>
            <span class="k">with</span> <span class="n">ProgressBarOrSpinner</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">dlmsg</span><span class="p">)</span> <span class="k">as</span> <span class="n">p</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="k">with</span> <span class="n">NamedTemporaryFile</span><span class="p">(</span><span class="n">delete</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                        <span class="n">bytes_read</span> <span class="o">=</span> <span class="mi">0</span>
                        <span class="n">block</span> <span class="o">=</span> <span class="n">remote</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">DOWNLOAD_CACHE_BLOCK_SIZE</span><span class="p">())</span>
                        <span class="k">while</span> <span class="n">block</span><span class="p">:</span>
                            <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
                            <span class="nb">hash</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
                            <span class="n">bytes_read</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">block</span><span class="p">)</span>
                            <span class="n">p</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">bytes_read</span><span class="p">)</span>
                            <span class="n">block</span> <span class="o">=</span> <span class="n">remote</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">DOWNLOAD_CACHE_BLOCK_SIZE</span><span class="p">())</span>
                <span class="k">except</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">):</span>
                        <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
                    <span class="k">raise</span>

        <span class="k">if</span> <span class="n">cache</span><span class="p">:</span>
            <span class="n">_acquire_download_cache_lock</span><span class="p">()</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="k">with</span> <span class="n">_open_shelve</span><span class="p">(</span><span class="n">urlmapfn</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">url2hash</span><span class="p">:</span>
                    <span class="c"># We check now to see if another process has</span>
                    <span class="c"># inadvertently written the file underneath us</span>
                    <span class="c"># already</span>
                    <span class="k">if</span> <span class="nb">str</span><span class="p">(</span><span class="n">remote_url</span><span class="p">)</span> <span class="ow">in</span> <span class="n">url2hash</span><span class="p">:</span>
                        <span class="k">return</span> <span class="n">url2hash</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">remote_url</span><span class="p">)]</span>
                    <span class="n">local_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dldir</span><span class="p">,</span> <span class="nb">hash</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
                    <span class="n">move</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">local_path</span><span class="p">)</span>
                    <span class="n">url2hash</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">remote_url</span><span class="p">)]</span> <span class="o">=</span> <span class="n">local_path</span>
            <span class="k">finally</span><span class="p">:</span>
                <span class="n">_release_download_cache_lock</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">local_path</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">name</span>
            <span class="k">if</span> <span class="n">missing_cache</span><span class="p">:</span>
                <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;File downloaded to temporary location due to problem &#39;</span>
                       <span class="s">&#39;with cache directory and will not be cached.&#39;</span><span class="p">)</span>
                <span class="n">warn</span><span class="p">(</span><span class="n">CacheMissingWarning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">local_path</span><span class="p">))</span>
            <span class="k">if</span> <span class="n">DELETE_TEMPORARY_DOWNLOADS_AT_EXIT</span><span class="p">():</span>
                <span class="k">global</span> <span class="n">_tempfilestodel</span>
                <span class="n">_tempfilestodel</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">local_path</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">URLError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s">&#39;reason&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="p">,</span> <span class="s">&#39;errno&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="o">.</span><span class="n">errno</span> <span class="o">==</span> <span class="mi">8</span><span class="p">:</span>
            <span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="o">.</span><span class="n">strerror</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="o">.</span><span class="n">strerror</span> <span class="o">+</span> <span class="s">&#39;. requested URL: &#39;</span> <span class="o">+</span> <span class="n">remote_url</span>
            <span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="o">.</span><span class="n">errno</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">reason</span><span class="o">.</span><span class="n">strerror</span><span class="p">)</span>
        <span class="k">raise</span> <span class="n">e</span>
    <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">timeout</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="c"># this isn&#39;t supposed to happen, but occasionally a socket.timeout gets</span>
        <span class="c"># through.  It&#39;s supposed to be caught in `urrlib2` and raised in this</span>
        <span class="c"># way, but for some reason in mysterious circumstances it doesn&#39;t. So</span>
        <span class="c"># we&#39;ll just re-raise it here instead</span>
        <span class="k">raise</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">URLError</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">local_path</span>

</div>
<span class="k">def</span> <span class="nf">_do_download_files_in_parallel</span><span class="p">(</span><span class="n">args</span><span class="p">):</span>
    <span class="n">orig_stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">download_file</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">orig_stdout</span>


<div class="viewcode-block" id="download_files_in_parallel"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.download_files_in_parallel.html#astropy.utils.data.download_files_in_parallel">[docs]</a><span class="k">def</span> <span class="nf">download_files_in_parallel</span><span class="p">(</span><span class="n">urls</span><span class="p">,</span> <span class="n">cache</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Downloads multiple files in parallel from the given URLs.  Blocks until</span>
<span class="sd">    all files have downloaded.  The result is a list of local file paths</span>
<span class="sd">    corresponding to the given urls.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    urls : list of str</span>
<span class="sd">        The URLs to retrieve.</span>

<span class="sd">    cache : bool, optional</span>
<span class="sd">        Whether to use the cache</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    paths : list of str</span>
<span class="sd">        The local file paths corresponding to the downloaded URLs.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">.console</span> <span class="kn">import</span> <span class="n">ProgressBar</span>

    <span class="c"># Combine duplicate URLs</span>
    <span class="n">combined_urls</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">urls</span><span class="p">))</span>
    <span class="n">combined_paths</span> <span class="o">=</span> <span class="n">ProgressBar</span><span class="o">.</span><span class="n">map</span><span class="p">(</span>
        <span class="n">_do_download_files_in_parallel</span><span class="p">,</span>
        <span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="n">cache</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">combined_urls</span><span class="p">],</span>
        <span class="n">multiprocess</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">paths</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">url</span> <span class="ow">in</span> <span class="n">urls</span><span class="p">:</span>
        <span class="n">paths</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">combined_paths</span><span class="p">[</span><span class="n">combined_urls</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">url</span><span class="p">)])</span>
    <span class="k">return</span> <span class="n">paths</span>


<span class="c"># This is used by download_file and _deltemps to determine the files to delete</span>
<span class="c"># when the interpreter exits</span></div>
<span class="n">_tempfilestodel</span> <span class="o">=</span> <span class="p">[]</span>


<span class="nd">@atexit.register</span>
<span class="k">def</span> <span class="nf">_deltemps</span><span class="p">():</span>

    <span class="k">global</span> <span class="n">_tempfilestodel</span>

    <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">_tempfilestodel</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">fn</span> <span class="o">=</span> <span class="n">_tempfilestodel</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
            <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">fn</span><span class="p">)</span>


<div class="viewcode-block" id="clear_download_cache"><a class="viewcode-back" href="../../../_generated/astropy.utils.data.clear_download_cache.html#astropy.utils.data.clear_download_cache">[docs]</a><span class="k">def</span> <span class="nf">clear_download_cache</span><span class="p">(</span><span class="n">hashorurl</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Clears the data file cache by deleting the local file(s).</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    hashorurl : str or None</span>
<span class="sd">        If None, the whole cache is cleared.  Otherwise, either specifies a</span>
<span class="sd">        hash for the cached file that is supposed to be deleted, or a URL that</span>
<span class="sd">        has previously been downloaded to the cache.</span>

<span class="sd">    Raises</span>
<span class="sd">    ------</span>
<span class="sd">    OSEerror</span>
<span class="sd">        If the requested filename is not present in the data directory.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">unlink</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">join</span><span class="p">,</span> <span class="n">exists</span>
    <span class="kn">from</span> <span class="nn">shutil</span> <span class="kn">import</span> <span class="n">rmtree</span>
    <span class="kn">from</span> <span class="nn">warnings</span> <span class="kn">import</span> <span class="n">warn</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">dldir</span><span class="p">,</span> <span class="n">urlmapfn</span> <span class="o">=</span> <span class="n">_get_download_cache_locs</span><span class="p">()</span>
    <span class="k">except</span> <span class="p">(</span><span class="ne">IOError</span><span class="p">,</span> <span class="ne">OSError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Not clearing data cache - cache inacessable due to &#39;</span>
        <span class="n">estr</span> <span class="o">=</span> <span class="s">&#39;&#39;</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="p">(</span><span class="s">&#39;: &#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
        <span class="n">warn</span><span class="p">(</span><span class="n">CacheMissingWarning</span><span class="p">(</span><span class="n">msg</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span> <span class="o">+</span> <span class="n">estr</span><span class="p">))</span>
        <span class="k">return</span>

    <span class="n">_acquire_download_cache_lock</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">hashorurl</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">exists</span><span class="p">(</span><span class="n">dldir</span><span class="p">):</span>
                <span class="n">rmtree</span><span class="p">(</span><span class="n">dldir</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">exists</span><span class="p">(</span><span class="n">urlmapfn</span><span class="p">):</span>
                <span class="n">unlink</span><span class="p">(</span><span class="n">urlmapfn</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">with</span> <span class="n">_open_shelve</span><span class="p">(</span><span class="n">urlmapfn</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">url2hash</span><span class="p">:</span>
                <span class="n">filepath</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">dldir</span><span class="p">,</span> <span class="n">hashorurl</span><span class="p">)</span>
                <span class="k">assert</span> <span class="n">_is_inside</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="n">dldir</span><span class="p">),</span> \
                       <span class="p">(</span><span class="s">&quot;attempted to use clear_download_cache on a location&quot;</span> <span class="o">+</span>
                        <span class="s">&quot; that&#39;s not inside the data cache directory&quot;</span><span class="p">)</span>

                <span class="k">if</span> <span class="n">exists</span><span class="p">(</span><span class="n">filepath</span><span class="p">):</span>
                    <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">url2hash</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                        <span class="k">if</span> <span class="n">v</span> <span class="o">==</span> <span class="n">filepath</span><span class="p">:</span>
                            <span class="k">del</span> <span class="n">url2hash</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
                    <span class="n">unlink</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>

                <span class="k">elif</span> <span class="n">hashorurl</span> <span class="ow">in</span> <span class="n">url2hash</span><span class="p">:</span>
                    <span class="n">filepath</span> <span class="o">=</span> <span class="n">url2hash</span><span class="p">[</span><span class="n">hashorurl</span><span class="p">]</span>
                    <span class="k">del</span> <span class="n">url2hash</span><span class="p">[</span><span class="n">hashorurl</span><span class="p">]</span>
                    <span class="n">unlink</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>

                <span class="k">else</span><span class="p">:</span>
                    <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Could not find file or url {0}&#39;</span>
                    <span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">hashorurl</span><span class="p">))</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="c"># the lock will be gone if rmtree was used above, but release otherwise</span>
        <span class="k">if</span> <span class="n">exists</span><span class="p">(</span><span class="n">join</span><span class="p">(</span><span class="n">_get_download_cache_locs</span><span class="p">()[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&#39;lock&#39;</span><span class="p">)):</span>
            <span class="n">_release_download_cache_lock</span><span class="p">()</span>

</div>
<span class="k">def</span> <span class="nf">_get_download_cache_locs</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot; Finds the path to the data cache directory and makes them if</span>
<span class="sd">    they don&#39;t exist.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    datadir : str</span>
<span class="sd">        The path to the data cache directory.</span>
<span class="sd">    shelveloc : str</span>
<span class="sd">        The path to the shelve object that stores the cache info.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">..config.paths</span> <span class="kn">import</span> <span class="n">get_cache_dir</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">exists</span><span class="p">,</span> <span class="n">isdir</span><span class="p">,</span> <span class="n">join</span>
    <span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">mkdir</span>

    <span class="n">datadir</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">get_cache_dir</span><span class="p">(),</span> <span class="s">&#39;download&#39;</span><span class="p">)</span>
    <span class="n">shelveloc</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">get_cache_dir</span><span class="p">(),</span> <span class="s">&#39;download_urlmap&#39;</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">exists</span><span class="p">(</span><span class="n">datadir</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">mkdir</span><span class="p">(</span><span class="n">datadir</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">exists</span><span class="p">(</span><span class="n">datadir</span><span class="p">):</span>
                <span class="k">raise</span>
    <span class="k">elif</span> <span class="ow">not</span> <span class="n">isdir</span><span class="p">(</span><span class="n">datadir</span><span class="p">):</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Data cache directory {0} is not a directory&#39;</span>
        <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">datadir</span><span class="p">))</span>

    <span class="k">if</span> <span class="n">isdir</span><span class="p">(</span><span class="n">shelveloc</span><span class="p">):</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Data cache shelve object location {0} is a directory&#39;</span>
        <span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">shelveloc</span><span class="p">))</span>

    <span class="k">return</span> <span class="n">datadir</span><span class="p">,</span> <span class="n">shelveloc</span>


<span class="k">def</span> <span class="nf">_open_shelve</span><span class="p">(</span><span class="n">shelffn</span><span class="p">,</span> <span class="n">withclosing</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    opens a shelf in a way that is py3.x and py2.x compatible.  If</span>
<span class="sd">    `withclosing` is  True, it will be opened with closing, allowing use like:</span>

<span class="sd">        with _open_shelve(&#39;somefile&#39;,True) as s:</span>
<span class="sd">            ...</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">shelve</span>
    <span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">closing</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">PY3K</span><span class="p">:</span>  <span class="c"># pragma: py3</span>
        <span class="n">shelf</span> <span class="o">=</span> <span class="n">shelve</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">shelffn</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>  <span class="c"># pragma: py2</span>
        <span class="n">shelf</span> <span class="o">=</span> <span class="n">shelve</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">shelffn</span> <span class="o">+</span> <span class="s">&#39;.db&#39;</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">withclosing</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">closing</span><span class="p">(</span><span class="n">shelf</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">shelf</span>


<span class="c">#the cache directory must be locked before any writes are performed.  Same for</span>
<span class="c">#the hash shelve, so this should be used for both.</span>
<span class="k">def</span> <span class="nf">_acquire_download_cache_lock</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Uses the lock directory method.  This is good because `mkdir` is</span>
<span class="sd">    atomic at the system call level, so it&#39;s thread-safe.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">join</span>
    <span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">mkdir</span>
    <span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>

    <span class="n">lockdir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_get_download_cache_locs</span><span class="p">()[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&#39;lock&#39;</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">DOWNLOAD_CACHE_LOCK_ATTEMPTS</span><span class="p">()):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">mkdir</span><span class="p">(</span><span class="n">lockdir</span><span class="p">)</span>
            <span class="c">#write the pid of this process for informational purposes</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">join</span><span class="p">(</span><span class="n">lockdir</span><span class="p">,</span> <span class="s">&#39;pid&#39;</span><span class="p">),</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()))</span>

        <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
            <span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span>
    <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Unable to acquire lock for cache directory ({0} exists)&#39;</span>
    <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lockdir</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">_release_download_cache_lock</span><span class="p">():</span>
    <span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">join</span><span class="p">,</span> <span class="n">exists</span><span class="p">,</span> <span class="n">isdir</span>
    <span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">rmdir</span>

    <span class="n">lockdir</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">_get_download_cache_locs</span><span class="p">()[</span><span class="mi">0</span><span class="p">],</span> <span class="s">&#39;lock&#39;</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">isdir</span><span class="p">(</span><span class="n">lockdir</span><span class="p">):</span>
        <span class="c">#if the pid file is present, be sure to remove it</span>
        <span class="n">pidfn</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">lockdir</span><span class="p">,</span> <span class="s">&#39;pid&#39;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">exists</span><span class="p">(</span><span class="n">pidfn</span><span class="p">):</span>
            <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">pidfn</span><span class="p">)</span>
        <span class="n">rmdir</span><span class="p">(</span><span class="n">lockdir</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s">&#39;Error releasing lock. &quot;{0}&quot; either does not exist or is not &#39;</span> <span class="o">+</span>\
              <span class="s">&#39;a directory.&#39;</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lockdir</span><span class="p">))</span>
</pre></div>

          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper"><h3>Page Contents</h3>


        </div>
      </div>
      <div class="clearer"></div>
    </div>
<footer class="footer">
  <p class="pull-right"> &nbsp;
    <a href="#">Back to Top</a></p>
  <p>
    &copy; Copyright 2011-2013, The Astropy Developers.<br/>
    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. &nbsp;
    Last built 22 Oct 2013. <br/>
  </p>
</footer>
  </body>
</html>