Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential bug in "tests.lib.create_basic_wheel_for_package" #8064

Closed
deveshks opened this issue Apr 16, 2020 · 7 comments · Fixed by #8067
Closed

Potential bug in "tests.lib.create_basic_wheel_for_package" #8064

deveshks opened this issue Apr 16, 2020 · 7 comments · Fixed by #8067
Labels
auto-locked Outdated issues that have been locked by automation C: tests Testing and related things type: bug A confirmed bug or unintended behavior

Comments

@deveshks
Copy link
Contributor

deveshks commented Apr 16, 2020

Environment

  • pip version: 20.1.dev0
  • Python version: 3.8.2
  • OS: OSX 10.15.4

Description

When the helper tests.lib.create_basic_wheel_for_package is utilized in a unit test to create a wheel with name containing a -, e.g. simple-package, and then the wheel is installed, the package name is taken as simple and the version is taken as package

Expected behavior

Seems like according to PEP-491 file name convention, the package name cannot contain a -, so such package names shouldn't be allowed while creating wheels for testing purposes. (My understanding of the PEP might also be wrong here)

How to Reproduce

Execute the following unit test

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)

Output

The test fails with an assertion error because the output of pip list --format=json lists the package name as simple and version as package

 assert 'simple-package' in [{'name': 'pip', 'version': '20.1.dev0'}, 
{'name': 'setuptools', 'version': '46.1.3'}, {'name': 'simple', 'version': 'package'}]
@deveshks deveshks changed the title Potential bug in tests.lib.create_basic_wheel_for_package Potential bug in "tests.lib.create_basic_wheel_for_package" Apr 16, 2020
@pradyunsg pradyunsg added the S: needs triage Issues/PRs that need to be triaged label Apr 16, 2020
@uranusjr
Copy link
Member

Ah, this makes sense. The culprit is this line:

archive_name = "{}-{}-py2.py3-none-any.whl".format(name, version)

which would give simple-package-1.0-py2.py3-none-any.whl, but the wheel spec expects simple_package-1.0-py2.py3-none-any.whl.

The fix should be straightforward as well:

archive_name = "{}-{}-py2.py3-none-any.whl".format(
    canonicalize_name(name).replace('-', '_'),
    version,
)

@deveshks
Copy link
Contributor Author

deveshks commented Apr 16, 2020

I think that's the right approach, to canonicalize the name and replace - with _ before making the wheel file. Let me create a fix for it right away and use the same test which I wrote in the ticket to verify that it's been fixed :)

@pradyunsg pradyunsg added C: tests Testing and related things type: bug A confirmed bug or unintended behavior and removed S: needs triage Issues/PRs that need to be triaged labels Apr 16, 2020
@uranusjr
Copy link
Member

I just realised PEP 491 actually includes a regex to canonically transform a package name for a wheel’s file name. Maybe we should use that instead (with a link to the PEP); it would be much easier to understand for a future reader.

@deveshks
Copy link
Contributor Author

I think you mean re.sub("[^\w\d.]+", "_", distribution, re.UNICODE) present at PEP-491 Escaping and Unicode ?

So we would create a correct wheel file name using that regex? Also do we want to do anything with the folder name of the package as well for this change?

package_init_py = "{name}/__init__.py".format(name=name)

Also will the unit test for this be similar to what we discussed in #8054 ? (Note that the below might not work due to the quirk we found with pkg_resources.safe_name until we start using canonicalize_name as #8054 (comment))

@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

@uranusjr
Copy link
Member

Yes, that’s it. The same name can be used for the package as well (I don’t think the package is actually used by a lot of tests anyway).

@pradyunsg Does this need a test?

@pradyunsg
Copy link
Member

Yea, I think adding a test in test_lib.py is a good idea.

@deveshks
Copy link
Contributor Author

Yea, I think adding a test in test_lib.py is a good idea.

So what will that test do ? Is it enough to just try out variants of package names with dot, dash and underscore, and verify that the wheel file name is correct according to the spec for all 3 cases?

@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Jun 24, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Jun 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation C: tests Testing and related things type: bug A confirmed bug or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants