Skip to content

Commit

Permalink
Fix the "safe_name" attribute of PackageFile for backwards compatibility
Browse files Browse the repository at this point in the history
Commit 0bd26af introduced a regression
that was causing some namespace packages with dots in them fail to
upload to PyPI. The reason is because
`packaging.utils.canonicalize_name()` is not equivalent to
`pkg_resources.safe_name()` as the former transforms the "." into "-",
while the later only does it for non-alphanumeric/. characters.

Closes: #743
  • Loading branch information
pablogsal committed Mar 16, 2021
1 parent 2dab479 commit 0027889
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog/745.bugfix.rst
@@ -0,0 +1 @@
Fixed a regression that was causing some namespace packages with dots in them fail to upload to PyPI.
22 changes: 22 additions & 0 deletions tests/test_package.py
Expand Up @@ -110,6 +110,28 @@ def test_package_signed_name_is_correct():
assert package.signed_filename == (filename + ".asc")


def test_package_safe_name_is_correct():
package = package_file.PackageFile(
filename="tests/fixtures/deprecated-pypirc",
comment=None,
metadata=pretend.stub(name="mosaik.SimConfig"),
python_version=None,
filetype=None,
)

assert package.safe_name == "mosaik.SimConfig"

package = package_file.PackageFile(
filename="tests/fixtures/deprecated-pypirc",
comment=None,
metadata=pretend.stub(name="mosaik$$$$.SimConfig"),
python_version=None,
filetype=None,
)

assert package.safe_name == "mosaik-.SimConfig"


@pytest.mark.parametrize("gpg_signature", [(None), (pretend.stub())])
def test_metadata_dictionary(gpg_signature):
meta = pretend.stub(
Expand Down
12 changes: 10 additions & 2 deletions twine/package.py
Expand Up @@ -14,11 +14,11 @@
import hashlib
import io
import os
import re
import subprocess
from typing import Dict, NamedTuple, Optional, Sequence, Tuple, Union

import importlib_metadata
import packaging.utils
import pkginfo

from twine import exceptions
Expand All @@ -44,6 +44,14 @@
MetadataValue = Union[str, Sequence[str]]


def _safe_name(name: str) -> str:
"""Convert an arbitrary string to a standard distribution name.
Any runs of non-alphanumeric/. characters are replaced with a single '-'.
"""
return re.sub("[^A-Za-z0-9.]+", "-", name)


class PackageFile:
def __init__(
self,
Expand All @@ -59,7 +67,7 @@ def __init__(
self.metadata = metadata
self.python_version = python_version
self.filetype = filetype
self.safe_name = packaging.utils.canonicalize_name(metadata.name)
self.safe_name = _safe_name(metadata.name)
self.signed_filename = self.filename + ".asc"
self.signed_basefilename = self.basefilename + ".asc"
self.gpg_signature: Optional[Tuple[str, bytes]] = None
Expand Down

0 comments on commit 0027889

Please sign in to comment.