summaryrefslogtreecommitdiff
path: root/Lib/packaging/pypi/mirrors.py
blob: a646acff3cdd91999bf5413108df337969f264f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"""Utilities related to the mirror infrastructure defined in PEP 381."""

from string import ascii_lowercase
import socket

DEFAULT_MIRROR_URL = "last.pypi.python.org"


def get_mirrors(hostname=None):
    """Return the list of mirrors from the last record found on the DNS
    entry::

    >>> from packaging.pypi.mirrors import get_mirrors
    >>> get_mirrors()
    ['a.pypi.python.org', 'b.pypi.python.org', 'c.pypi.python.org',
    'd.pypi.python.org']

    """
    if hostname is None:
        hostname = DEFAULT_MIRROR_URL

    # return the last mirror registered on PyPI.
    try:
        hostname = socket.gethostbyname_ex(hostname)[0]
    except socket.gaierror:
        return []
    end_letter = hostname.split(".", 1)

    # determine the list from the last one.
    return ["%s.%s" % (s, end_letter[1]) for s in string_range(end_letter[0])]


def string_range(last):
    """Compute the range of string between "a" and last.

    This works for simple "a to z" lists, but also for "a to zz" lists.
    """
    for k in range(len(last)):
        for x in product(ascii_lowercase, repeat=(k + 1)):
            result = ''.join(x)
            yield result
            if result == last:
                return


def product(*args, **kwds):
    pools = [tuple(arg) for arg in args] * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x + [y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)