Medio ambiente
Descripción
Cuando el ayudante tests.lib.create_basic_wheel_for_package
se utiliza en una prueba unitaria para crear una rueda con un nombre que contenga un -
, por ejemplo, simple-package
, y luego se instala la rueda, se toma el nombre del paquete como simple
y la versión se toma como package
Comportamiento esperado
Parece que de acuerdo con la convención de nombre de archivo PEP-491 , el nombre del paquete no puede contener un -
, por lo que dichos nombres de paquetes no deben permitirse al crear ruedas con fines de prueba. (Mi comprensión del PEP también puede estar equivocada aquí)
Cómo reproducir
Ejecute la siguiente prueba unitaria
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)
Salida
La prueba falla con un error de afirmación porque la salida de pip list --format=json
enumera el nombre del paquete como simple
y la versión como package
assert 'simple-package' in [{'name': 'pip', 'version': '20.1.dev0'},
{'name': 'setuptools', 'version': '46.1.3'}, {'name': 'simple', 'version': 'package'}]
Ah, esto tiene sentido. El culpable es esta línea:
archive_name = "{}-{}-py2.py3-none-any.whl".format(name, version)
lo que daría simple-package-1.0-py2.py3-none-any.whl
, pero la especificación de la rueda espera simple_package-1.0-py2.py3-none-any.whl
.
La solución también debería ser sencilla:
archive_name = "{}-{}-py2.py3-none-any.whl".format(
canonicalize_name(name).replace('-', '_'),
version,
)
Creo que ese es el enfoque correcto, canonicalizar el nombre y reemplazar -
con _
antes de hacer el archivo de rueda. Permítame crear una solución para él de inmediato y usar la misma prueba que escribí en el ticket para verificar que se haya solucionado :)
Me acabo de dar cuenta de que PEP 491 en realidad incluye una expresión regular para transformar canónicamente un nombre de paquete para el nombre de archivo de una rueda. Quizás deberíamos usar eso en su lugar (con un enlace al PEP); sería mucho más fácil de entender para un futuro lector.
Creo que te refieres a re.sub("[^\w\d.]+", "_", distribution, re.UNICODE)
presente en PEP-491 Escaping y Unicode .
Entonces, ¿crearíamos un nombre de archivo de rueda correcto usando esa expresión regular? Además, ¿queremos hacer algo con el nombre de la carpeta del paquete para este cambio?
Además, ¿la prueba unitaria para esto será similar a lo que discutimos en https://github.com/pypa/pip/pull/8054 ? (Tenga en cuenta que lo siguiente podría no funcionar debido a la peculiaridad que encontramos con pkg_resources.safe_name
hasta que comencemos a usar canonicalize_name
como 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
Si eso es. También se puede usar el mismo nombre para el paquete (de todos modos, no creo que el paquete sea usado por muchas pruebas).
@pradyunsg ¿Esto necesita una prueba?
Sí, creo que agregar una prueba en test_lib.py es una buena idea.
Sí, creo que agregar una prueba en test_lib.py es una buena idea.
Entonces, ¿qué hará esa prueba? ¿Es suficiente probar las variantes de los nombres de los paquetes con puntos, guiones y guiones bajos, y verificar que el nombre del archivo de la rueda sea correcto de acuerdo con las especificaciones para los 3 casos?
Comentario más útil
Ah, esto tiene sentido. El culpable es esta línea:
lo que daría
simple-package-1.0-py2.py3-none-any.whl
, pero la especificación de la rueda esperasimple_package-1.0-py2.py3-none-any.whl
.La solución también debería ser sencilla: