Repository: pypa/pip
File: src/pip/_internal/index/collector.py (Python)

Code before:
# dropped. mypy does not appear to understand `except ImportError`, so this
# polyfill is used everywhere.
def _lru_cache(
        *args,                  # type: Any
        **kwargs                # type: Any
):
    # type: (...) -> Any
    cache = {}                  # type: Dict[Any, Any]

    def wrapper(fn):
        # type: (Any) -> Any

        def wrapped(
                *args,          # type: Any
                **kwargs        # type: Any
        ):
            # type: (...) -> Any
            cache_key = tuple(args) + tuple(kwargs.items())
            value = cache.get(cache_key, None)
            if value is not None:
                return value
            value = fn(*args, **kwargs)
            cache[cache_key] = value
            return value
        return wrapped
    return wrapper


def _match_vcs_scheme(url):
    # type: (str) -> Optional[str]
    """Look for VCS schemes in the URL.

    Returns the matched VCS scheme, or None if there's no match.
    """
    for scheme in vcs.schemes:
        if url.lower().startswith(scheme) and url[len(scheme)] in '+:':
            return scheme
    return None


def _is_url_like_archive(url):
    # type: (str) -> bool
    """Return whether the URL looks like an archive.
    """
    filename = Link(url).filename
    for bad_ext in ARCHIVE_EXTENSIONS:
        if filename.endswith(bad_ext):
            return True
    return False



Review comment (performance):
I wonder whether we should simply make the cache a no-op on Python 2. Something like:

```python
F = TypeVar('F', Callable)

def stub_lru_cache(maxsize=None):
    # type: (Optional[int]) -> Callable[[F], F]
    def _wrapper(f):
        # type: (F) -> F
        return f
    return _wrapper
try:
    from functools import lru_cache as real_lru_cache
except ImportError:
    _lru_cache = stub_lru_cache
else:
    _lru_cache = real_lru_cache
```

There are probably a couple of typing hoops we need to jump through, but the point is not avoid vendoring a duplicated `lru_cache` altogether.

Code after:
            # type: (Optional[int]) -> Callable[[F], F]
            raise NotImplementedError


logger = logging.getLogger(__name__)


# Fallback to noop_lru_cache in Python 2
# TODO: this can be removed when python 2 support is dropped!
def noop_lru_cache(maxsize=None):
    # type: (Optional[int]) -> Callable[[F], F]
    def _wrapper(f):
        # type: (F) -> F
        return f
    return _wrapper


_lru_cache = getattr(functools, "lru_cache", noop_lru_cache)  # type: LruCache


def _match_vcs_scheme(url):
    # type: (str) -> Optional[str]
    """Look for VCS schemes in the URL.

    Returns the matched VCS scheme, or None if there's no match.
    """
    for scheme in vcs.schemes:
        if url.lower().startswith(scheme) and url[len(scheme)] in '+:':
            return scheme
    return None


def _is_url_like_archive(url):
    # type: (str) -> bool
    """Return whether the URL looks like an archive.
    """
    filename = Link(url).filename
    for bad_ext in ARCHIVE_EXTENSIONS:
        if filename.endswith(bad_ext):
            return True
    return False


class _NotHTML(Exception):
    def __init__(self, content_type, request_desc):
        # type: (str, str) -> None
        super(_NotHTML, self).__init__(content_type, request_desc)
        self.content_type = content_type
        self.request_desc = request_desc