Repository: conda/conda

Issue:
assertion error when loading package cache

```
{
  "command":"D:\\Anaconda3\\Scripts\\conda-script.py install -c anaconda pillow",
  "conda_info":{
    "_channels":"https://conda.anaconda.org/anaconda/win-64
                          https://conda.anaconda.org/anaconda/noarch
                          https://repo.continuum.io/pkgs/free/win-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/win-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/win-64
                          https://repo.continuum.io/pkgs/pro/noarch
                          https://repo.continuum.io/pkgs/msys2/win-64
                          https://repo.continuum.io/pkgs/msys2/noarch",
    "_config_files":"",
    "_envs_dirs":"D:\\Anaconda3\\envs
                          C:\\Users\\username\\AppData\\Local\\conda\\conda\\envs
                          C:\\Users\\username\\.conda\\envs",
    "_pkgs_dirs":"D:\\Anaconda3\\pkgs
                          C:\\Users\\username\\AppData\\Local\\conda\\conda\\pkgs",
    "_rtwro":"writable",
    "active_prefix":null,
    "active_prefix_name":null,
    "channels":[
      "https://conda.anaconda.org/anaconda/win-64",
      "https://conda.anaconda.org/anaconda/noarch",
      "https://repo.continuum.io/pkgs/free/win-64",
      "https://repo.continuum.io/pkgs/free/noarch",
      "https://repo.continuum.io/pkgs/r/win-64",
      "https://repo.continuum.io/pkgs/r/noarch",
      "https://repo.continuum.io/pkgs/pro/win-64",
      "https://repo.continuum.io/pkgs/pro/noarch",
      "https://repo.continuum.io/pkgs/msys2/win-64",
      "https://repo.continuum.io/pkgs/msys2/noarch"
    ],
    "conda_build_version":"3.0.6",
    "conda_env_version":"4.4.0rc0",
    "conda_location":"D:\\Anaconda3\\lib\\site-packages\\conda",
    "conda_prefix":"D:\\Anaconda3",
    "conda_private":false,
    "conda_shlvl":-1,
    "conda_version":"4.4.0rc0",
    "config_files":[

    ],
    "default_prefix":"D:\\Anaconda3",
    "envs":[

    ],
    "envs_dirs":[
      "D:\\Anaconda3\\envs",
      "C:\\Users\\username\\AppData\\Local\\conda\\conda\\envs",
      "C:\\Users\\username\\.conda\\envs"
    ],
    "is_windows_admin":false,
    "netrc_file":null,
    "offline":false,
    "pkgs_dirs":[
      "D:\\Anaconda3\\pkgs",
      "C:\\Users\\username\\AppData\\Local\\conda\\conda\\pkgs"
    ],
    "platform":"win-64",
    "python_version":"3.5.3.final.0",
    "rc_path":"C:\\Users\\username\\.condarc",
    "requests_version":"2.14.2",
    "root_prefix":"D:\\Anaconda3",
    "root_writable":true,
    "sys_rc_path":"D:\\Anaconda3\\.condarc",
    "user_agent":"conda/4.4.0rc0 requests/2.14.2 CPython/3.5.3 Windows/10 Windows/10.0.15063",
    "user_rc_path":"C:\\Users\\username\\.condarc"
  },
  "error":"AssertionError('D:\\\\Anaconda3\\\\pkgs\\\\numpy-1.10.1-py35_0',)",
  "exception_name":"AssertionError",
  "exception_type":"<class 'AssertionError'>",
  "traceback":"Traceback (most recent call last):
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 262, in _make_single_record
    repodata_record = read_repodata_json(extracted_package_dir)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\gateways\\disk\\read.py\", line 123, in read_repodata_json
    with open(join(extracted_package_directory, 'info', 'repodata_record.json')) as fi:
FileNotFoundError: [Errno 2] No such file or directory: 'D:\\\\Anaconda3\\\\pkgs\\\\numpy-1.10.1-py35_0\\\\info\\\\repodata_record.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 270, in _make_single_record
    index_json_record = read_index_json(extracted_package_dir)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\gateways\\disk\\read.py\", line 111, in read_index_json
    with open(join(extracted_package_directory, 'info', 'index.json')) as fi:
FileNotFoundError: [Errno 2] No such file or directory: 'D:\\\\Anaconda3\\\\pkgs\\\\numpy-1.10.1-py35_0\\\\info\\\\index.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\exceptions.py\", line 653, in __call__
    return func(*args, **kwargs)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\cli\\main.py\", line 136, in _main
    exit_code = args.func(args, p)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\cli\\main_install.py\", line 80, in execute
    install(args, parser, 'install')
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\cli\\install.py\", line 220, in install
    handle_txn(progressive_fetch_extract, unlink_link_transaction, prefix, args, newenv)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\cli\\install.py\", line 237, in handle_txn
    unlink_link_transaction.display_actions(progressive_fetch_extract)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\link.py\", line 698, in display_actions
    legacy_action_groups = self.make_legacy_action_groups(pfe)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\link.py\", line 681, in make_legacy_action_groups
    pfe.prepare()
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 479, in prepare
    for prec in self.link_precs)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 479, in <genexpr>
    for prec in self.link_precs)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 375, in make_actions_for_record
    ), None)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 372, in <genexpr>
    pcrec for pcrec in concat(PackageCache(pkgs_dir).query(pref_or_spec)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 373, in <genexpr>
    for pkgs_dir in context.pkgs_dirs)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 116, in query
    return (pcrec for pcrec in itervalues(self._package_cache_records) if pcrec == param)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 208, in _package_cache_records
    return self.__package_cache_records or self.load() or self.__package_cache_records
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 88, in load
    package_cache_record = self._make_single_record(base_name)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\core\\package_cache.py\", line 274, in _make_single_record
    extract_tarball(package_tarball_full_path, extracted_package_dir)
  File \"D:\\Anaconda3\\lib\\site-packages\\conda\\gateways\\disk\\create.py\", line 133, in extract_tarball
    assert not lexists(destination_directory), destination_directory
AssertionError: D:\\Anaconda3\\pkgs\\numpy-1.10.1-py35_0
"
}
```


Discussion:

Resolving patch:
diff --git a/conda/core/package_cache.py b/conda/core/package_cache.py
--- a/conda/core/package_cache.py
+++ b/conda/core/package_cache.py
@@ -265,12 +265,26 @@ def _make_single_record(self, package_filename):
                 package_tarball_full_path=package_tarball_full_path,
                 extracted_package_dir=extracted_package_dir,
             )
+            return package_cache_record
         except (IOError, OSError):
+            # no info/repodata_record.json exists
+            # try reading info/index.json
             try:
                 index_json_record = read_index_json(extracted_package_dir)
             except (IOError, OSError):
+                # info/index.json doesn't exist either
+                if isdir(extracted_package_dir) and not isfile(package_tarball_full_path):
+                    # We have a directory that looks like a conda package, but without
+                    # (1) info/repodata_record.json or info/index.json, and (2) a conda package
+                    # tarball, there's not much we can do.  We'll just ignore it.
+                    return None
+
                 try:
                     if self.is_writable:
+                        if isdir(extracted_package_dir):
+                            # We have a partially unpacked conda package directory. Best thing
+                            # to do is remove it and try extracting.
+                            rm_rf(extracted_package_dir)
                         extract_tarball(package_tarball_full_path, extracted_package_dir)
                         index_json_record = read_index_json(extracted_package_dir)
                     else:
@@ -294,7 +308,14 @@ def _make_single_record(self, package_filename):
                 package_tarball_full_path=package_tarball_full_path,
                 extracted_package_dir=extracted_package_dir,
             )
-        return package_cache_record
+
+            # write the info/repodata_record.json file so we can short-circuit this next time
+            if self.is_writable:
+                repodata_record = PackageRecord.from_objects(package_cache_record)
+                repodata_record_path = join(extracted_package_dir, 'info', 'repodata_record.json')
+                write_as_json_to_file(repodata_record_path, repodata_record)
+
+            return package_cache_record
 
     @staticmethod
     def _dedupe_pkgs_dir_contents(pkgs_dir_contents):


Test patch: