Environnement
La description
Lorsque l'assistant tests.lib.create_basic_wheel_for_package
est utilisé dans un test unitaire pour créer une roue avec un nom contenant un -
, par exemple simple-package
, puis que la roue est installée, le nom du paquet est pris comme simple
et la version est prise comme package
Comportement prévisible
Il semble que selon la convention de nom de fichier PEP-491, le nom du package ne peut pas contenir de -
, donc de tels noms de package ne devraient pas être autorisés lors de la création de roues à des fins de test. (Ma compréhension du PEP peut également être erronée ici)
Comment reproduire
Exécutez le test unitaire suivant
def test_create_wheel_bug(script):
package = create_basic_wheel_for_package(script, 'simple-package', '1.0')
script.pip("install", "--no-cache-dir", "--no-index", package)
result = script.pip('list', '--format=json')
assert 'simple-package' in json.loads(result.stdout)
Production
Le test échoue avec une erreur d'assertion car la sortie de pip list --format=json
répertorie le nom du package comme simple
et la version comme package
assert 'simple-package' in [{'name': 'pip', 'version': '20.1.dev0'},
{'name': 'setuptools', 'version': '46.1.3'}, {'name': 'simple', 'version': 'package'}]
Ah, cela a du sens. Le coupable est cette ligne:
archive_name = "{}-{}-py2.py3-none-any.whl".format(name, version)
ce qui donnerait simple-package-1.0-py2.py3-none-any.whl
, mais la spécification de roue attend simple_package-1.0-py2.py3-none-any.whl
.
Le correctif devrait également être simple:
archive_name = "{}-{}-py2.py3-none-any.whl".format(
canonicalize_name(name).replace('-', '_'),
version,
)
Je pense que c'est la bonne approche, pour canoniser le nom et remplacer -
par _
avant de créer le fichier wheel. Laissez-moi créer un correctif pour cela tout de suite et utiliser le même test que j'ai écrit dans le ticket pour vérifier qu'il a été corrigé :)
Je viens de réaliser que PEP 491 inclut en fait une regex pour transformer canoniquement un nom de package pour le nom de fichier d'une roue. Peut-être devrions-nous utiliser cela à la place (avec un lien vers le PEP); ce serait beaucoup plus facile à comprendre pour un futur lecteur.
Je pense que vous voulez dire re.sub("[^\w\d.]+", "_", distribution, re.UNICODE)
présent à PEP-491 Escaping et Unicode ?
Nous créerions donc un nom de fichier de roue correct en utilisant cette expression régulière? Souhaitons-nous également faire quelque chose avec le nom de dossier du package pour ce changement?
Le test unitaire pour cela sera-t-il également similaire à ce que nous avons discuté dans https://github.com/pypa/pip/pull/8054 ? (Notez que ce qui suit peut ne pas fonctionner en raison de la bizarrerie que nous avons trouvée avec pkg_resources.safe_name
jusqu'à ce que nous commencions à utiliser canonicalize_name
comme https://github.com/pypa/pip/pull/8054#discussion_r409654545)
@pytest.mark.parametrize(
'package_name',
['simple-package', 'simple_package', 'simple.package'],
)
def test_create_wheel_bug(script):
package = create_basic_wheel_for_package(script, package_name, '1.0')
script.pip("install", "--no-cache-dir", "--no-index", package)
result = script.pip('list', '--format=freeze')
assert package_name in result.stdout
Oui c'est ça. Le même nom peut également être utilisé pour le paquet (je ne pense pas que le paquet soit réellement utilisé par beaucoup de tests de toute façon).
@pradyunsg Cela nécessite-t-il un test?
Oui, je pense que l'ajout d'un test dans test_lib.py est une bonne idée.
Oui, je pense que l'ajout d'un test dans test_lib.py est une bonne idée.
Alors, que fera ce test? Est-il suffisant d'essayer simplement des variantes de noms de packages avec un point, un tiret et un trait de soulignement, et de vérifier que le nom du fichier de roue est correct selon les spécifications pour les 3 cas?
Commentaire le plus utile
Ah, cela a du sens. Le coupable est cette ligne:
ce qui donnerait
simple-package-1.0-py2.py3-none-any.whl
, mais la spécification de roue attendsimple_package-1.0-py2.py3-none-any.whl
.Le correctif devrait également être simple: