コード例 #1
0
ファイル: test_utils.py プロジェクト: twm/twine
def test_get_config_no_distutils(tmpdir):
    """
    Even if the user hasn't set PyPI has an index server
    in 'index-servers', default to uploading to PyPI.
    """
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(
            textwrap.dedent("""
            [pypi]
            username = testuser
            password = testpassword
        """))

    assert utils.get_config(pypirc) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
        "testpypi": {
            "repository": utils.TEST_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #2
0
ファイル: test_utils.py プロジェクト: pypa/twine
def test_get_config_no_distutils(tmpdir):
    """
    Even if the user hasn't set PyPI has an index server
    in 'index-servers', default to uploading to PyPI.
    """
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(textwrap.dedent("""
            [pypi]
            username = testuser
            password = testpassword
        """))

    assert utils.get_config(pypirc) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
        "testpypi": {
            "repository": utils.TEST_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #3
0
def test_get_config_no_distutils(tmpdir):
    """Upload by default to PyPI if an index server is not set in .pypirc."""
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(
            textwrap.dedent(
                """
            [pypi]
            username = testuser
            password = testpassword
        """
            )
        )

    assert utils.get_config(pypirc) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
        "testpypi": {
            "repository": utils.TEST_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #4
0
def _pypirc_section_for_repo(repo):
    from twine import utils
    config = utils.get_config()
    for section in config:
        if config[section].get("repository") == repo:
            return section
    return None
コード例 #5
0
ファイル: test_utils.py プロジェクト: hugovk/twine
def test_get_config_override_pypi_url(write_config_file):
    config_file = write_config_file(
        """
        [pypi]
        repository = http://pypiproxy
        """
    )

    assert utils.get_config(config_file)["pypi"]["repository"] == "http://pypiproxy"
コード例 #6
0
def test_get_config_missing(tmpdir):
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    assert get_config(pypirc) == {
        "pypi": {
            "repository": DEFAULT_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #7
0
ファイル: test_utils.py プロジェクト: yuhonghong7035/twine
def test_get_config_override_pypi_url(tmpdir):
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(textwrap.dedent("""
            [pypi]
            repository = http://pypiproxy
        """))

    assert utils.get_config(pypirc)['pypi']['repository'] == 'http://pypiproxy'
コード例 #8
0
ファイル: test_utils.py プロジェクト: pypa/twine
def test_get_config_override_pypi_url(tmpdir):
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(textwrap.dedent("""
            [pypi]
            repository = http://pypiproxy
        """))

    assert utils.get_config(pypirc)['pypi']['repository'] == 'http://pypiproxy'
コード例 #9
0
ファイル: test_utils.py プロジェクト: msabramo/twine
def test_get_config_missing(tmpdir):
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    assert get_config(pypirc) == {
        "pypi": {
            "repository": DEFAULT_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #10
0
def test_get_config_deprecated_pypirc():
    tests_dir = os.path.dirname(os.path.abspath(__file__))
    deprecated_pypirc_path = os.path.join(tests_dir, 'fixtures',
                                          'deprecated-pypirc')

    assert utils.get_config(deprecated_pypirc_path) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": '******',
            "password": '******',
        },
    }
コード例 #11
0
ファイル: test_utils.py プロジェクト: Brightcells/twine
def test_get_config_deprecated_pypirc():
    tests_dir = os.path.dirname(os.path.abspath(__file__))
    deprecated_pypirc_path = os.path.join(tests_dir, 'fixtures',
                                          'deprecated-pypirc')

    assert get_config(deprecated_pypirc_path) == {
        "pypi": {
            "repository": DEFAULT_REPOSITORY,
            "username": '******',
            "password": '******',
        },
    }
コード例 #12
0
ファイル: test_utils.py プロジェクト: hugovk/twine
def test_get_config_missing(config_file):
    assert utils.get_config(config_file) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": None,
            "password": None,
        },
        "testpypi": {
            "repository": utils.TEST_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #13
0
ファイル: pypi.py プロジェクト: mkwon0/docker-compose-swap
def check_pypirc():
    try:
        config = get_config()
    except Error as e:
        raise ScriptError('Failed to parse .pypirc file: {}'.format(e))

    if config is None:
        raise ScriptError('Failed to parse .pypirc file')

    if 'pypi' not in config:
        raise ScriptError('Missing [pypi] section in .pypirc file')

    if not (config['pypi'].get('username') and config['pypi'].get('password')):
        raise ScriptError('Missing login/password pair for pypi repo')
コード例 #14
0
ファイル: test_utils.py プロジェクト: hugovk/twine
def test_empty_userpass(write_config_file):
    """Suppress prompts if empty username and password are provided in .pypirc."""
    config_file = write_config_file(
        """
        [pypi]
        username=
        password=
        """
    )

    config = utils.get_config(config_file)
    pypi = config["pypi"]

    assert pypi["username"] == pypi["password"] == ""
コード例 #15
0
ファイル: pypi.py プロジェクト: docker/compose
def check_pypirc():
    try:
        config = get_config()
    except Error as e:
        raise ScriptError('Failed to parse .pypirc file: {}'.format(e))

    if config is None:
        raise ScriptError('Failed to parse .pypirc file')

    if 'pypi' not in config:
        raise ScriptError('Missing [pypi] section in .pypirc file')

    if not (config['pypi'].get('username') and config['pypi'].get('password')):
        raise ScriptError('Missing login/password pair for pypi repo')
コード例 #16
0
def test_empty_userpass(tmpdir):
    """Suppress prompts if empty username and password are provided in .pypirc."""
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(
            textwrap.dedent("""
            [pypi]
            username=
            password=
        """))

    config = utils.get_config(pypirc)
    pypi = config["pypi"]

    assert pypi["username"] == pypi["password"] == ""
コード例 #17
0
def test_get_config_no_distutils(tmpdir):
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(textwrap.dedent("""
            [pypi]
            username = testuser
            password = testpassword
        """))

    assert utils.get_config(pypirc) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
    }
コード例 #18
0
ファイル: test_utils.py プロジェクト: msabramo/twine
def test_get_config_no_distutils(tmpdir):
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(textwrap.dedent("""
            [pypi]
            username = testuser
            password = testpassword
        """))

    assert get_config(pypirc) == {
        "pypi": {
            "repository": DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
    }
コード例 #19
0
ファイル: test_utils.py プロジェクト: timgates42/twine
def test_empty_userpass(tmpdir):
    """
    Empty username and password may be supplied to suppress
    prompts. See #426.
    """
    pypirc = os.path.join(str(tmpdir), ".pypirc")

    with open(pypirc, "w") as fp:
        fp.write(textwrap.dedent("""
            [pypi]
            username=
            password=
        """))

    config = utils.get_config(pypirc)
    pypi = config['pypi']

    assert pypi['username'] == pypi['password'] == ''
コード例 #20
0
ファイル: test_utils.py プロジェクト: hugovk/twine
def test_get_config_no_section(write_config_file):
    config_file = write_config_file(
        """
        [distutils]
        index-servers = pypi foo

        [pypi]
        username = testuser
        password = testpassword
        """
    )

    assert utils.get_config(config_file) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
    }
コード例 #21
0
ファイル: test_utils.py プロジェクト: hugovk/twine
def test_get_config_no_distutils(write_config_file):
    """Upload by default to PyPI if an index server is not set in .pypirc."""
    config_file = write_config_file(
        """
        [pypi]
        username = testuser
        password = testpassword
        """
    )

    assert utils.get_config(config_file) == {
        "pypi": {
            "repository": utils.DEFAULT_REPOSITORY,
            "username": "******",
            "password": "******",
        },
        "testpypi": {
            "repository": utils.TEST_REPOSITORY,
            "username": None,
            "password": None,
        },
    }
コード例 #22
0
def upload(dists, repository, sign, identity, username, password, comment,
           sign_with, config_file):
    # Check that a nonsensical option wasn't given
    if not sign and identity:
        raise ValueError("sign must be given along with identity")

    # Determine if the user has passed in pre-signed distributions
    signatures = dict(
        (os.path.basename(d), d) for d in dists if d.endswith(".asc"))
    dists = [i for i in dists if not i.endswith(".asc")]

    # Get our config from the .pypirc file
    try:
        config = get_config(config_file)[repository]
    except KeyError:
        raise KeyError(
            "Missing '{0}' section from the configuration file".format(
                repository, ), )

    parsed = urlparse(config["repository"])
    if parsed.netloc in ["pypi.python.org", "testpypi.python.org"]:
        config["repository"] = urlunparse(("https", ) + parsed[1:])

    print("Uploading distributions to {0}".format(config["repository"]))

    username = get_username(username, config)
    password = get_password(password, config)

    session = requests.session()

    uploads = find_dists(dists)

    for filename in uploads:
        # Sign the dist if requested
        if sign:
            sign_file(sign_with, filename, identity)

        # Extract the metadata from the package
        for ext, dtype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):
                meta = DIST_TYPES[dtype](filename)
                break
        else:
            raise ValueError("Unknown distribution format: '%s'" %
                             os.path.basename(filename))

        if dtype == "bdist_egg":
            pkgd = pkg_resources.Distribution.from_filename(filename)
            py_version = pkgd.py_version
        elif dtype == "bdist_wheel":
            py_version = meta.py_version
        elif dtype == "bdist_wininst":
            py_version = meta.py_version
        else:
            py_version = None

        # Fill in the data - send all the meta-data in case we need to
        # register a new release
        data = {
            # action
            ":action": "file_upload",
            "protcol_version": "1",

            # identify release
            "name": pkg_resources.safe_name(meta.name),
            "version": meta.version,

            # file content
            "filetype": dtype,
            "pyversion": py_version,

            # additional meta-data
            "metadata_version": meta.metadata_version,
            "summary": meta.summary,
            "home_page": meta.home_page,
            "author": meta.author,
            "author_email": meta.author_email,
            "maintainer": meta.maintainer,
            "maintainer_email": meta.maintainer_email,
            "license": meta.license,
            "description": meta.description,
            "keywords": meta.keywords,
            "platform": meta.platforms,
            "classifiers": meta.classifiers,
            "download_url": meta.download_url,
            "supported_platform": meta.supported_platforms,
            "comment": comment,

            # PEP 314
            "provides": meta.provides,
            "requires": meta.requires,
            "obsoletes": meta.obsoletes,

            # Metadata 1.2
            "project_urls": meta.project_urls,
            "provides_dist": meta.provides_dist,
            "obsoletes_dist": meta.obsoletes_dist,
            "requires_dist": meta.requires_dist,
            "requires_external": meta.requires_external,
            "requires_python": meta.requires_python,
        }

        md5_hash = hashlib.md5()
        with open(filename, "rb") as fp:
            content = fp.read(4096)
            while content:
                md5_hash.update(content)
                content = fp.read(4096)

        data["md5_digest"] = md5_hash.hexdigest()

        signed_name = os.path.basename(filename) + ".asc"
        if signed_name in signatures:
            with open(signatures[signed_name], "rb") as gpg:
                data["gpg_signature"] = (signed_name, gpg.read())
        elif sign:
            with open(filename + ".asc", "rb") as gpg:
                data["gpg_signature"] = (signed_name, gpg.read())

        print("Uploading {0}".format(os.path.basename(filename)))

        data_to_send = []
        for key, value in data.items():
            if isinstance(value, (list, tuple)):
                for item in value:
                    data_to_send.append((key, item))
            else:
                data_to_send.append((key, value))

        with open(filename, "rb") as fp:
            data_to_send.append((
                "content",
                (os.path.basename(filename), fp, "application/octet-stream"),
            ))
            encoder = MultipartEncoder(data_to_send)
            resp = session.post(
                config["repository"],
                data=encoder,
                auth=(username, password),
                allow_redirects=False,
                headers={'Content-Type': encoder.content_type},
            )
        # Bug 28. Try to silence a ResourceWarning by releasing the socket and
        # clearing the connection pool.
        resp.close()
        session.close()

        # Bug 92. If we get a redirect we should abort because something seems
        # funky. The behaviour is not well defined and redirects being issued
        # by PyPI should never happen in reality. This should catch malicious
        # redirects as well.
        if resp.is_redirect:
            raise exc.RedirectDetected(
                ('"{0}" attempted to redirect to "{1}" during upload.'
                 ' Aborting...').format(config["respository"],
                                        resp.headers["location"]))
        # Otherwise, raise an HTTPError based on the status code.
        resp.raise_for_status()
コード例 #23
0
ファイル: upload.py プロジェクト: asfaltboy/twine
def upload(dists, repository, sign, identity, username, password, comment,
           sign_with, config_file):
    # Check that a nonsensical option wasn't given
    if not sign and identity:
        raise ValueError("sign must be given along with identity")

    # Determine if the user has passed in pre-signed distributions
    signatures = dict(
        (os.path.basename(d), d) for d in dists if d.endswith(".asc")
    )
    dists = [i for i in dists if not i.endswith(".asc")]

    # Get our config from the .pypirc file
    try:
        config = get_config(config_file)[repository]
    except KeyError:
        msg = (
            "Missing '{repo}' section from the configuration file.\n"
            "Maybe you have a out-dated '{cfg}' format?\n"
            "more info: "
            "https://docs.python.org/distutils/packageindex.html#pypirc\n"
        ).format(
            repo=repository,
            cfg=config_file
        )
        raise KeyError(msg)

    parsed = urlparse(config["repository"])
    if parsed.netloc in ["pypi.python.org", "testpypi.python.org"]:
        config["repository"] = urlunparse(
            ("https",) + parsed[1:]
        )

    print("Uploading distributions to {0}".format(config["repository"]))

    username = get_username(username, config)
    password = get_password(password, config)

    session = requests.session()

    uploads = find_dists(dists)

    for filename in uploads:
        # Sign the dist if requested
        if sign:
            sign_file(sign_with, filename, identity)

        # Extract the metadata from the package
        for ext, dtype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):
                meta = DIST_TYPES[dtype](filename)
                break
        else:
            raise ValueError(
                "Unknown distribution format: '%s'" %
                os.path.basename(filename)
            )

        if dtype == "bdist_egg":
            pkgd = pkg_resources.Distribution.from_filename(filename)
            py_version = pkgd.py_version
        elif dtype == "bdist_wheel":
            py_version = meta.py_version
        elif dtype == "bdist_wininst":
            py_version = meta.py_version
        else:
            py_version = None

        # Fill in the data - send all the meta-data in case we need to
        # register a new release
        data = {
            # action
            ":action": "file_upload",
            "protcol_version": "1",

            # identify release
            "name": pkg_resources.safe_name(meta.name),
            "version": meta.version,

            # file content
            "filetype": dtype,
            "pyversion": py_version,

            # additional meta-data
            "metadata_version": meta.metadata_version,
            "summary": meta.summary,
            "home_page": meta.home_page,
            "author": meta.author,
            "author_email": meta.author_email,
            "maintainer": meta.maintainer,
            "maintainer_email": meta.maintainer_email,
            "license": meta.license,
            "description": meta.description,
            "keywords": meta.keywords,
            "platform": meta.platforms,
            "classifiers": meta.classifiers,
            "download_url": meta.download_url,
            "supported_platform": meta.supported_platforms,
            "comment": comment,

            # PEP 314
            "provides": meta.provides,
            "requires": meta.requires,
            "obsoletes": meta.obsoletes,

            # Metadata 1.2
            "project_urls": meta.project_urls,
            "provides_dist": meta.provides_dist,
            "obsoletes_dist": meta.obsoletes_dist,
            "requires_dist": meta.requires_dist,
            "requires_external": meta.requires_external,
            "requires_python": meta.requires_python,

        }

        md5_hash = hashlib.md5()
        with open(filename, "rb") as fp:
            content = fp.read(4096)
            while content:
                md5_hash.update(content)
                content = fp.read(4096)

        data["md5_digest"] = md5_hash.hexdigest()

        signed_name = os.path.basename(filename) + ".asc"
        if signed_name in signatures:
            with open(signatures[signed_name], "rb") as gpg:
                data["gpg_signature"] = (signed_name, gpg.read())
        elif sign:
            with open(filename + ".asc", "rb") as gpg:
                data["gpg_signature"] = (signed_name, gpg.read())

        print("Uploading {0}".format(os.path.basename(filename)))

        data_to_send = []
        for key, value in data.items():
            if isinstance(value, (list, tuple)):
                for item in value:
                    data_to_send.append((key, item))
            else:
                data_to_send.append((key, value))

        with open(filename, "rb") as fp:
            data_to_send.append((
                "content",
                (os.path.basename(filename), fp, "application/octet-stream"),
            ))
            encoder = MultipartEncoder(data_to_send)
            resp = session.post(
                config["repository"],
                data=encoder,
                auth=(username, password),
                allow_redirects=False,
                headers={'Content-Type': encoder.content_type},
            )
        # Bug 28. Try to silence a ResourceWarning by releasing the socket and
        # clearing the connection pool.
        resp.close()
        session.close()

        # Bug 92. If we get a redirect we should abort because something seems
        # funky. The behaviour is not well defined and redirects being issued
        # by PyPI should never happen in reality. This should catch malicious
        # redirects as well.
        if resp.is_redirect:
            raise exc.RedirectDetected(
                ('"{0}" attempted to redirect to "{1}" during upload.'
                 ' Aborting...').format(config["respository"],
                                        resp.headers["location"]))
        # Otherwise, raise an HTTPError based on the status code.
        resp.raise_for_status()
コード例 #24
0
ファイル: upload.py プロジェクト: dundeemt/twine
def upload(dists, repository, sign, identity, username, password, comment):
    # Check that a nonsensical option wasn't given
    if not sign and identity:
        raise ValueError("sign must be given along with identity")

    # Determine if the user has passed in pre-signed distributions
    signatures = dict(
        (os.path.basename(d), d) for d in dists if d.endswith(".asc")
    )
    dists = [i for i in dists if not i.endswith(".asc")]

    # Get our config from ~/.pypirc
    try:
        config = get_config()[repository]
    except KeyError:
        raise KeyError(
            "Missing '{0}' section from the configuration file".format(
                repository,
            ),
        )

    parsed = urlparse(config["repository"])
    if parsed.netloc in ["pypi.python.org", "testpypi.python.org"]:
        config["repository"] = urlunparse(
            ("https",) + parsed[1:]
        )

    print("Uploading distributions to {0}".format(config["repository"]))

    session = requests.session()

    for filename in dists:
        # Sign the dist if requested
        if sign:
            print("Signing {0}".format(os.path.basename(filename)))
            gpg_args = ["gpg", "--detach-sign", "-a", filename]
            if identity:
                gpg_args[2:2] = ["--local-user", identity]
            subprocess.check_call(gpg_args)

        # Extract the metadata from the package
        for ext, dtype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):
                meta = DIST_TYPES[dtype](filename)
                break
        else:
            raise ValueError(
                "Unknown distribution format: '%s'" %
                os.path.basename(filename)
            )

        if dtype == "bdist_egg":
            pkgd = pkg_resources.Distribution.from_filename(filename)
            py_version = pkgd.py_version
        elif dtype == "bdist_wheel":
            py_version = meta.py_version
        else:
            py_version = None

        # Fill in the data - send all the meta-data in case we need to
        # register a new release
        data = {
            # action
            ":action": "file_upload",
            "protcol_version": "1",

            # identify release
            "name": meta.name,
            "version": meta.version,

            # file content
            "filetype": dtype,
            "pyversion": py_version,

            # additional meta-data
            "metadata_version": meta.metadata_version,
            "summary": meta.summary,
            "home_page": meta.home_page,
            "author": meta.author,
            "author_email": meta.author_email,
            "maintainer": meta.maintainer,
            "maintainer_email": meta.maintainer_email,
            "license": meta.license,
            "description": meta.description,
            "keywords": meta.keywords,
            "platform": meta.platforms,
            "classifiers": meta.classifiers,
            "download_url": meta.download_url,
            "supported_platform": meta.supported_platforms,
            "comment": comment,

            # PEP 314
            "provides": meta.provides,
            "requires": meta.requires,
            "obsoletes": meta.obsoletes,

            # Metadata 1.2
            "project_urls": meta.project_urls,
            "provides_dist": meta.provides_dist,
            "obsoletes_dist": meta.obsoletes_dist,
            "requires_dist": meta.requires_dist,
            "requires_external": meta.requires_external,
            "requires_python": meta.requires_python,

        }

        with open(filename, "rb") as fp:
            content = fp.read()
            filedata = {
                "content": (os.path.basename(filename), content),
            }
            data["md5_digest"] = hashlib.md5(content).hexdigest()

        signed_name = os.path.basename(filename) + ".asc"
        if signed_name in signatures:
            with open(signatures[signed_name], "rb") as gpg:
                filedata["gpg_signature"] = (signed_name, gpg.read())
        elif sign:
            with open(filename + ".asc", "rb") as gpg:
                filedata["gpg_signature"] = (signed_name, gpg.read())

        print("Uploading {0}".format(os.path.basename(filename)))

        resp = session.post(
            config["repository"],
            data=dict((k, v) for k, v in data.items() if v),
            files=filedata,
            auth=(
                username or config.get("username"),
                password or config.get("password"),
            ),
        )
        resp.raise_for_status()
コード例 #25
0
def upload(dists, repository, sign, identity, username, password, comment):
    # Check that a nonsensical option wasn't given
    if not sign and identity:
        raise ValueError("sign must be given along with identity")

    # Determine if the user has passed in pre-signed distributions
    signatures = dict(
        (os.path.basename(d), d) for d in dists if d.endswith(".asc"))
    dists = [i for i in dists if not i.endswith(".asc")]

    # Get our config from ~/.pypirc
    try:
        config = get_config()[repository]
    except KeyError:
        raise KeyError(
            "Missing '{0}' section from the configuration file".format(
                repository, ), )

    parsed = urlparse(config["repository"])
    if parsed.netloc in ["pypi.python.org", "testpypi.python.org"]:
        config["repository"] = urlunparse(("https", ) + parsed[1:])

    print("Uploading distributions to {0}".format(config["repository"]))

    session = requests.session()

    for filename in dists:
        # Sign the dist if requested
        if sign:
            print("Signing {0}".format(os.path.basename(filename)))
            gpg_args = ["gpg", "--detach-sign", "-a", filename]
            if identity:
                gpg_args[2:2] = ["--local-user", identity]
            subprocess.check_call(gpg_args)

        # Extract the metadata from the package
        for ext, dtype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):
                meta = DIST_TYPES[dtype](filename)
                break
        else:
            raise ValueError("Unknown distribution format: '%s'" %
                             os.path.basename(filename))

        if dtype == "bdist_egg":
            pkgd = pkg_resources.Distribution.from_filename(filename)
            py_version = pkgd.py_version
        elif dtype == "bdist_wheel":
            py_version = meta.py_version
        else:
            py_version = None

        # Fill in the data - send all the meta-data in case we need to
        # register a new release
        data = {
            # action
            ":action": "file_upload",
            "protcol_version": "1",

            # identify release
            "name": meta.name,
            "version": meta.version,

            # file content
            "filetype": dtype,
            "pyversion": py_version,

            # additional meta-data
            "metadata_version": meta.metadata_version,
            "summary": meta.summary,
            "home_page": meta.home_page,
            "author": meta.author,
            "author_email": meta.author_email,
            "maintainer": meta.maintainer,
            "maintainer_email": meta.maintainer_email,
            "license": meta.license,
            "description": meta.description,
            "keywords": meta.keywords,
            "platform": meta.platforms,
            "classifiers": meta.classifiers,
            "download_url": meta.download_url,
            "supported_platform": meta.supported_platforms,
            "comment": comment,

            # PEP 314
            "provides": meta.provides,
            "requires": meta.requires,
            "obsoletes": meta.obsoletes,

            # Metadata 1.2
            "project_urls": meta.project_urls,
            "provides_dist": meta.provides_dist,
            "obsoletes_dist": meta.obsoletes_dist,
            "requires_dist": meta.requires_dist,
            "requires_external": meta.requires_external,
            "requires_python": meta.requires_python,
        }

        with open(filename, "rb") as fp:
            content = fp.read()
            filedata = {
                "content": (os.path.basename(filename), content),
            }
            data["md5_digest"] = hashlib.md5(content).hexdigest()

        signed_name = os.path.basename(filename) + ".asc"
        if signed_name in signatures:
            with open(signatures[signed_name], "rb") as gpg:
                filedata["gpg_signature"] = (signed_name, gpg.read())
        elif sign:
            with open(filename + ".asc", "rb") as gpg:
                filedata["gpg_signature"] = (signed_name, gpg.read())

        print("Uploading {0}".format(os.path.basename(filename)))

        resp = session.post(
            config["repository"],
            data=dict((k, v) for k, v in data.items() if v),
            files=filedata,
            auth=(
                username or config.get("username"),
                password or config.get("password"),
            ),
        )
        resp.raise_for_status()