# Buggy code
def _make_single_record(self, package_filename):
    if not package_filename.endswith(CONDA_TARBALL_EXTENSION):
        package_filename += CONDA_TARBALL_EXTENSION

    package_tarball_full_path = join(self.pkgs_dir, package_filename)
    log.trace("adding to package cache %s", package_tarball_full_path)
    extracted_package_dir = package_tarball_full_path[: -len(CONDA_TARBALL_EXTENSION)]

    # try reading info/repodata_record.json
    try:
        repodata_record = read_repodata_json(extracted_package_dir)
        package_cache_record = PackageCacheRecord.from_objects(
            repodata_record,
            package_tarball_full_path=package_tarball_full_path,
            extracted_package_dir=extracted_package_dir,
        )
        return package_cache_record
    except (IOError, OSError, JSONDecodeError) as e:
        # IOError / OSError if info/repodata_record.json doesn't exists
        # JsonDecodeError if info/repodata_record.json is partially extracted or corrupted
        #   python 2.7 raises ValueError instead of JsonDecodeError
        #   ValueError("No JSON object could be decoded")
        log.debug(
            "unable to read %s\n  because %r",
            join(extracted_package_dir, "info", "repodata_record.json"),
            e,
        )

        # try reading info/index.json
        try:
            index_json_record = read_index_json(extracted_package_dir)
        except (IOError, OSError, JSONDecodeError) as e:
            # IOError / OSError if info/index.json doesn't exist
            # JsonDecodeError if info/index.json is partially extracted or corrupted
            #   python 2.7 raises ValueError instead of JsonDecodeError
            #   ValueError("No JSON object could be decoded")
            log.debug(
                "unable to read %s\n  because",
                join(extracted_package_dir, "info", "index.json"),
                e,
            )

            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)
                    try:
                        index_json_record = read_index_json(extracted_package_dir)
                    except (IOError, OSError, JSONDecodeError):
                        # At this point, we can assume the package tarball is bad.
                        # Remove everything and move on.
                        rm_rf(package_tarball_full_path)
                        rm_rf(extracted_package_dir)
                        return None
                else:
                    index_json_record = read_index_json_from_tarball(
                        package_tarball_full_path
                    )
            except (EOFError, ReadError) as e:
                # EOFError: Compressed file ended before the end-of-stream marker was reached
                # tarfile.ReadError: file could not be opened successfully
                # We have a corrupted tarball. Remove the tarball so it doesn't affect
                # anything, and move on.
                log.debug(
                    "unable to extract info/index.json from %s\n  because %r",
                    package_tarball_full_path,
                    e,
                )
                rm_rf(package_tarball_full_path)
                return None

        # we were able to read info/index.json, so let's continue
        if isfile(package_tarball_full_path):
            md5 = compute_md5sum(package_tarball_full_path)
        else:
            md5 = None

        url = first(self._urls_data, lambda x: basename(x) == package_filename)
        package_cache_record = PackageCacheRecord.from_objects(
            index_json_record,
            url=url,
            md5=md5,
            package_tarball_full_path=package_tarball_full_path,
            extracted_package_dir=extracted_package_dir,
        )

        # 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


# Traceback (FileNotFoundError)
error: PermissionError(13, 'Permission denied')
command: /home/jing/anaconda3/bin/conda upgrade Requests
user_agent: conda/4.4.3 requests/2.18.4 CPython/3.6.1 Linux/4.13.0-21-generic ubuntu/17.10 glibc/2.26
_messageid: -9223372036845975622
_messagetime: 1513948198000 / 2017-12-22 07:09:58
_receipttime: 1513993708752 / 2017-12-22 19:48:28

Traceback (most recent call last):
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 268, in _make_single_record
repodata_record = read_repodata_json(extracted_package_dir)
File "/home/jing/anaconda3/lib/python3.6/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:
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/common/compat.py", line 120, in open
closefd=closefd)
FileNotFoundError: [Errno 2] No such file or directory: '/home/jing/anaconda3/pkgs/conda-4.3.31-py36_0/info/repodata_record.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/exceptions.py", line 722, in __call__
return func(*args, **kwargs)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/main.py", line 78, in _main
exit_code = do_call(args, p)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/conda_argparse.py", line 75, in do_call
exit_code = getattr(module, func_name)(args, parser)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/main_update.py", line 14, in execute
install(args, parser, 'update')
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/install.py", line 239, in install
handle_txn(progressive_fetch_extract, unlink_link_transaction, prefix, args, newenv)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/cli/install.py", line 256, in handle_txn
unlink_link_transaction.display_actions(progressive_fetch_extract)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/link.py", line 706, in display_actions
legacy_action_groups = self.make_legacy_action_groups(pfe)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/link.py", line 689, in make_legacy_action_groups
pfe.prepare()
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/common/io.py", line 415, in decorated
return f(*args, **kwds)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 525, in prepare
for prec in self.link_precs)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 525, in <genexpr>
for prec in self.link_precs)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 419, in make_actions_for_record
), None)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 416, in <genexpr>
pcrec for pcrec in concat(PackageCache(pkgs_dir).query(pref_or_spec)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 417, in <genexpr>
for pkgs_dir in context.pkgs_dirs)
File "/home/jing/anaconda3/lib/python3.6/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 "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 209, in _package_cache_records
self.load()
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 88, in load
package_cache_record = self._make_single_record(base_name)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/core/package_cache.py", line 339, in _make_single_record
write_as_json_to_file(repodata_record_path, repodata_record)
File "/home/jing/anaconda3/lib/python3.6/site-packages/conda/gateways/disk/create.py", line 61, in write_as_json_to_file
with open(file_path, str('wb')) as fo:
PermissionError: [Errno 13] Permission denied: '/home/jing/anaconda3/pkgs/conda-4.3.31-py36_0/info/repodata_record.json'

# Fixed code
def _make_single_record(self, package_filename):
    if not package_filename.endswith(CONDA_TARBALL_EXTENSION):
        package_filename += CONDA_TARBALL_EXTENSION

    package_tarball_full_path = join(self.pkgs_dir, package_filename)
    log.trace("adding to package cache %s", package_tarball_full_path)
    extracted_package_dir = package_tarball_full_path[: -len(CONDA_TARBALL_EXTENSION)]

    # try reading info/repodata_record.json
    try:
        repodata_record = read_repodata_json(extracted_package_dir)
        package_cache_record = PackageCacheRecord.from_objects(
            repodata_record,
            package_tarball_full_path=package_tarball_full_path,
            extracted_package_dir=extracted_package_dir,
        )
        return package_cache_record
    except (IOError, OSError, JSONDecodeError) as e:
        # IOError / OSError if info/repodata_record.json doesn't exists
        # JsonDecodeError if info/repodata_record.json is partially extracted or corrupted
        #   python 2.7 raises ValueError instead of JsonDecodeError
        #   ValueError("No JSON object could be decoded")
        log.debug(
            "unable to read %s\n  because %r",
            join(extracted_package_dir, "info", "repodata_record.json"),
            e,
        )

        # try reading info/index.json
        try:
            index_json_record = read_index_json(extracted_package_dir)
        except (IOError, OSError, JSONDecodeError) as e:
            # IOError / OSError if info/index.json doesn't exist
            # JsonDecodeError if info/index.json is partially extracted or corrupted
            #   python 2.7 raises ValueError instead of JsonDecodeError
            #   ValueError("No JSON object could be decoded")
            log.debug(
                "unable to read %s\n  because",
                join(extracted_package_dir, "info", "index.json"),
                e,
            )

            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)
                    try:
                        index_json_record = read_index_json(extracted_package_dir)
                    except (IOError, OSError, JSONDecodeError):
                        # At this point, we can assume the package tarball is bad.
                        # Remove everything and move on.
                        rm_rf(package_tarball_full_path)
                        rm_rf(extracted_package_dir)
                        return None
                else:
                    index_json_record = read_index_json_from_tarball(
                        package_tarball_full_path
                    )
            except (EOFError, ReadError) as e:
                # EOFError: Compressed file ended before the end-of-stream marker was reached
                # tarfile.ReadError: file could not be opened successfully
                # We have a corrupted tarball. Remove the tarball so it doesn't affect
                # anything, and move on.
                log.debug(
                    "unable to extract info/index.json from %s\n  because %r",
                    package_tarball_full_path,
                    e,
                )
                rm_rf(package_tarball_full_path)
                return None

        # we were able to read info/index.json, so let's continue
        if isfile(package_tarball_full_path):
            md5 = compute_md5sum(package_tarball_full_path)
        else:
            md5 = None

        url = first(self._urls_data, lambda x: basename(x) == package_filename)
        package_cache_record = PackageCacheRecord.from_objects(
            index_json_record,
            url=url,
            md5=md5,
            package_tarball_full_path=package_tarball_full_path,
            extracted_package_dir=extracted_package_dir,
        )

        # 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"
            )
            try:
                write_as_json_to_file(repodata_record_path, repodata_record)
            except (IOError, OSError) as e:
                if e.errno in (EACCES, EPERM) and isdir(dirname(repodata_record_path)):
                    raise NotWritableError(repodata_record_path, e.errno, caused_by=e)
                else:
                    raise

        return package_cache_record