Unable to install python package via pip from pypi repository if package has period in its name
Summary
When a Python package contains a period character in its name, it cannot be installed via pip, as pip fails to locate the package.
Steps to reproduce
- Upload a package to the pypi repository with a period in its title
- Attempt to install the package as a dependency via pip
Example Project
https://gitlab.com/Xeonian/MyPyPiPackage
The above project is an implementation of the example project provided at https://gitlab.com/help/user/packages/pypi_repository/index. Two packages are uploaded, both containing the same code, one with a period in its name, and one without. The package without the period in its name can be installed as a dependency; the other cannot.
What is the current bug behavior?
Pip fails to install the dependency, citing that no matching candidate is available.
What is the expected correct behavior?
Pip locates and installs the dependency.
Relevant logs and/or screenshots
Successful install without period in name
$ pip install mypypipackage --index-url https://__token__:<token>@gitlab.com/api/v4/projects/20767841/packages/pypi/simple -v
Non-user install because user site-packages disabled
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-ephem-wheel-cache-qqyrfioi
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-hbj5b749
Initialized build tracking at C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-hbj5b749
Created build tracker: C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-hbj5b749
Entered build tracker: C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-hbj5b749
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-install-ucw9d3pn
Looking in indexes: https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple
1 location(s) to search for versions of mypypipackage:
* https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/mypypipackage/
Fetching project page and analyzing links: https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/mypypipackage/
Getting page https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/mypypipackage/
Found credentials in url for gitlab.com
Looking up "https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/mypypipackage/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): gitlab.com:443
https://gitlab.com:443 "GET /api/v4/projects/20767841/packages/pypi/simple/mypypipackage/ HTTP/1.1" 200 None
Updating cache with response from "https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/mypypipackage/"
Found link https://gitlab.com/api/v4/projects/20767841/packages/pypi/files/24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7/mypypipackage-0.0.1-py3-none-any.whl#sha256=24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7 (from https://gitlab.com/api/v4/projects/20767841/packages/py
pi/simple/mypypipackage/) (requires-python:>=3.6), version: 0.0.1
Found link https://gitlab.com/api/v4/projects/20767841/packages/pypi/files/6a91db1d5bf2ae7fb734b6b713357143a26763918ca2d0430550c43fcb437b29/mypypipackage-0.0.1.tar.gz#sha256=6a91db1d5bf2ae7fb734b6b713357143a26763918ca2d0430550c43fcb437b29 (from https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/
mypypipackage/) (requires-python:>=3.6), version: 0.0.1
Given no hashes to check 2 links for project 'mypypipackage': discarding no candidates
Using version 0.0.1 (newest of versions: 0.0.1)
Collecting mypypipackage
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-unpack-goe44o3n
Looking up "https://gitlab.com/api/v4/projects/20767841/packages/pypi/files/24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7/mypypipackage-0.0.1-py3-none-any.whl" in the cache
Current age based on date: 2620
Freshness lifetime from max-age: 0
https://gitlab.com:443 "GET /api/v4/projects/20767841/packages/pypi/files/24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7/mypypipackage-0.0.1-py3-none-any.whl HTTP/1.1" 304 0
Using cached https://gitlab.com/api/v4/projects/20767841/packages/pypi/files/24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7/mypypipackage-0.0.1-py3-none-any.whl (1.6 kB)
Added mypypipackage from https://gitlab.com/api/v4/projects/20767841/packages/pypi/files/24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7/mypypipackage-0.0.1-py3-none-any.whl#sha256=24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7 to build tracker 'C:\\Users\\Wes\\AppData\\Loca
l\\Temp\\pip-req-tracker-hbj5b749'
Removed mypypipackage from https://gitlab.com/api/v4/projects/20767841/packages/pypi/files/24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7/mypypipackage-0.0.1-py3-none-any.whl#sha256=24608d428276da3940b8769126fbe544b4b48eda25737c489e544bca6dde47a7 from build tracker 'C:\\Users\\Wes\\AppData\\
Local\\Temp\\pip-req-tracker-hbj5b749'
Installing collected packages: mypypipackage
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-unpacked-wheel-fjecaxnb
Successfully installed mypypipackage-0.0.1
1 location(s) to search for versions of pip:
* https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/
Fetching project page and analyzing links: https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/
Getting page https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/
Found credentials in url for gitlab.com
Looking up "https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): gitlab.com:443
https://gitlab.com:443 "GET /api/v4/projects/20767841/packages/pypi/simple/pip/ HTTP/1.1" 404 35
Status code 404 not in (200, 203, 300, 301)
Could not fetch URL https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/: 404 Client Error: Not Found for url: https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/ - skipping
Given no hashes to check 0 links for project 'pip': discarding no candidates
Removed build tracker: 'C:\\Users\\Wes\\AppData\\Local\\Temp\\pip-req-tracker-hbj5b749'
Unsuccessful install with period in name
$ pip install my.pypipackage --index-url https://__token__:<token>@gitlab.com/api/v4/projects/20767841/packages/pypi/simple -v
Non-user install because user site-packages disabled
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-ephem-wheel-cache-g5yuj5jt
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-zjl1oc8s
Initialized build tracking at C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-zjl1oc8s
Created build tracker: C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-zjl1oc8s
Entered build tracker: C:\Users\Wes\AppData\Local\Temp\pip-req-tracker-zjl1oc8s
Created temporary directory: C:\Users\Wes\AppData\Local\Temp\pip-install-fd4g9waq
Looking in indexes: https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple
1 location(s) to search for versions of my.pypipackage:
* https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/
Fetching project page and analyzing links: https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/
Getting page https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/
Found credentials in url for gitlab.com
Looking up "https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): gitlab.com:443
https://gitlab.com:443 "GET /api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/ HTTP/1.1" 404 35
Status code 404 not in (200, 203, 300, 301)
Could not fetch URL https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/: 404 Client Error: Not Found for url: https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my-pypipackage/ - skipping
Given no hashes to check 0 links for project 'my.pypipackage': discarding no candidates
ERROR: Could not find a version that satisfies the requirement my.pypipackage (from versions: none)
ERROR: No matching distribution found for my.pypipackage
Exception information:
Traceback (most recent call last):
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\cli\base_command.py", line 188, in _main
status = self.run(options, args)
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\cli\req_command.py", line 185, in wrapper
return func(self, options, args)
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\commands\install.py", line 332, in run
requirement_set = resolver.resolve(
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\resolution\legacy\resolver.py", line 179, in resolve
discovered_reqs.extend(self._resolve_one(requirement_set, req))
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\resolution\legacy\resolver.py", line 362, in _resolve_one
abstract_dist = self._get_abstract_dist_for(req_to_install)
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\resolution\legacy\resolver.py", line 313, in _get_abstract_dist_for
self._populate_link(req)
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\resolution\legacy\resolver.py", line 279, in _populate_link
req.link = self.finder.find_requirement(req, upgrade)
File "C:\Users\Wes\.virtualenvs\xeona-website-blog-handlers-I7xkWx01\lib\site-packages\pip\_internal\index\package_finder.py", line 928, in find_requirement
raise DistributionNotFound(
pip._internal.exceptions.DistributionNotFound: No matching distribution found for my.pypipackage
1 location(s) to search for versions of pip:
* https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/
Fetching project page and analyzing links: https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/
Getting page https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/
Found credentials in url for gitlab.com
Looking up "https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): gitlab.com:443
https://gitlab.com:443 "GET /api/v4/projects/20767841/packages/pypi/simple/pip/ HTTP/1.1" 404 35
Status code 404 not in (200, 203, 300, 301)
Could not fetch URL https://__token__:****@gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/: 404 Client Error: Not Found for url: https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/pip/ - skipping
Given no hashes to check 0 links for project 'pip': discarding no candidates
Removed build tracker: 'C:\\Users\\Wes\\AppData\\Local\\Temp\\pip-req-tracker-zjl1oc8s'
Output of checks
This bug happens on GitLab.com
Possible fixes
The verbose pip output demonstrates that pip replaces the periods in the package name with dashes when searching for the package. This is compliant behaviour with PEP-503: https://www.python.org/dev/peps/pep-0503/#normalized-names Pip has expected compliance with PEP-503 since the release of pip 8.1.2, back in 2016. Attempting to access the package directly, retaining the period in the name, resolves as expected: https://gitlab.com/api/v4/projects/20767841/packages/pypi/simple/my.pypipackage/ It therefore appears that the Gitlab pypi repository is not PEP-503 compliant, and the required resolution would be to normalize package names on upload. Periods in package names are both permissible (https://packaging.python.org/guides/distributing-packages-using-setuptools/#name), and advised for namespace packages, as per PEP-423 (https://www.python.org/dev/peps/pep-0423/).