Given a requirement, return its cache key.

        This behavior is a little weird in order to allow backwards
        compatibility with cache files. For a requirement without extras, this
        will return, for example::

            ("ipython", "2.1.0")

        For a requirement with extras, the extras will be comma-separated and
        appended to the version, inside brackets, like so::

            ("ipython", "2.1.0[nbconvert,notebook]")

def as_cache_key(self, ireq):
        """Given a requirement, return its cache key.

        This behavior is a little weird in order to allow backwards
        compatibility with cache files. For a requirement without extras, this
        will return, for example::

            ("ipython", "2.1.0")

        For a requirement with extras, the extras will be comma-separated and
        appended to the version, inside brackets, like so::

            ("ipython", "2.1.0[nbconvert,notebook]")
        """
        extras = tuple(sorted(ireq.extras))
        if not extras:
            extras_string = ""
        else:
            extras_string = "[{}]".format(",".join(extras))
        name = key_from_req(ireq.req)
        version = get_pinned_version(ireq)
        return name, "{}{}".format(version, extras_string)