Repository: pypa/pipenv

Issue:
package in a namespace from pip fails to lock

I checked the diagnose.

### Issue description

installing a package from pip with a namespace, i.e. fsc.export results in locking-failure, since (I assume) pipenv looks for `fsc-export` on https://pypi.org/simple and not for `fsc.export` (which is available). This package is not a pre-release.

### Expected result

That it would work just fine, like `pip install fsc.export`

### Actual result

```
Creating a Pipfile for this project…
Installing fsc.export…
⠋ Installing...Installing 'fsc.export'
$ ['/Users/mskoenz/.virtualenvs/hello-vT9ljSkH/bin/pip', 'install', '--verbose', '--upgrade', '"fsc.export"', '-i', 'https://pypi.org/simple']

Adding fsc.export to Pipfile's [packages]…
✔ Installation Succeeded
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✘ Locking Failed!
Using pip: -i https://pypi.org/simple
Using pip: -i https://pypi.org/simple
Using pip: -i https://pypi.org/simple

                          ROUND 1
Current constraints:
  fsc-export

Finding the best candidates:
Traceback (most recent call last):
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 385, in resolve
    results = self.resolver.resolve(max_rounds=environments.PIPENV_MAX_ROUNDS)
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 102, in resolve
    has_changed, best_matches = self._resolve_one_round()
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 198, in _resolve_one_round
    best_matches = {self.get_best_match(ireq) for ireq in constraints}
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 198, in <setcomp>
    best_matches = {self.get_best_match(ireq) for ireq in constraints}
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 263, in get_best_match
    best_match = self.repository.find_best_match(ireq, prereleases=self.prereleases)
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/repositories/pypi.py", line 175, in find_best_match
    raise NoCandidateFound(ireq, all_candidates, self.finder)
pipenv.patched.piptools.exceptions.NoCandidateFound: Could not find a version that matches fsc-export
No versions found
Was https://pypi.org/simple reachable?

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 126, in <module>
    main()
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 119, in main

    parsed.requirements_dir, parsed.packages)
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 85, in _main
    requirements_dir=requirements_dir,
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 69, in resolve
    req_dir=requirements_dir
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 726, in resolve_deps
    req_dir=req_dir,
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 480, in actually_resolve_deps
    resolved_tree = resolver.resolve()
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 395, in resolve
    raise ResolutionFailure(message=str(e))
pipenv.exceptions.ResolutionFailure: ERROR: ERROR: Could not find a version that matches fsc-export
No versions found
Was https://pypi.org/simple reachable?
Using pip: -i https://pypi.org/simple
Using pip: -i https://pypi.org/simple

                          ROUND 1
Current constraints:
  fsc-export
Finding the best candidates:
Traceback (most recent call last):
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 385, in resolve
    results = self.resolver.resolve(max_rounds=environments.PIPENV_MAX_ROUNDS)

  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 102, in resolve
    has_changed, best_matches = self._resolve_one_round()
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 198, in _resolve_one_round
    best_matches = {self.get_best_match(ireq) for ireq in constraints}
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 198, in <setcomp>
    best_matches = {self.get_best_match(ireq) for ireq in constraints}
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/resolver.py", line 263, in get_best_match
    best_match = self.repository.find_best_match(ireq, prereleases=self.prereleases)
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/patched/piptools/repositories/pypi.py", line 175, in find_best_match
    raise NoCandidateFound(ireq, all_candidates, self.finder)
pipenv.patched.piptools.exceptions.NoCandidateFound: Could not find a version that matches fsc-export
No versions found
Was https://pypi.org/simple reachable?

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 126, in <module>
    main()
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 119, in main
    parsed.requirements_dir, parsed.packages)
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 85, in _main
    requirements_dir=requirements_dir,
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/resolver.py", line 69, in resolve
    req_dir=requirements_dir
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 726, in resolve_deps
    req_dir=req_dir,
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 480, in actually_resolve_deps
    resolved_tree = resolver.resolve()
  File "/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv/utils.py", line 395, in resolve
    raise ResolutionFailure(message=str(e))
pipenv.exceptions.ResolutionFailure: ERROR: ERROR: Could not find a version that matches fsc-export
No versions found
Was https://pypi.org/simple reachable?
```

### Steps to replicate

in a completely fresh folder (no Pipfile), run:
`pipenv install fsc.export`

-------------------------------------------------------------------------------
<details><summary>$ pipenv --support</summary>

Pipenv version: `'2018.11.26'`

Pipenv location: `'/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/lib/python3.7/site-packages/pipenv'`

Python location: `'/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/bin/python3.7'`

Python installations found:

  - `3.7.0`: `/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/bin/python3`
  - `3.7.0`: `/Users/mskoenz/.pyenv/versions/3.7.0/bin/python3`
  - `3.7.0`: `/Users/mskoenz/.pyenv/versions/3.7.0/bin/python3.7m`
  - `3.7.0`: `/usr/local/bin/python3`
  - `3.7.0`: `/usr/local/bin/python3.7m`
  - `3.6.6`: `/Users/mskoenz/.pyenv/versions/3.6.6/bin/python3`
  - `3.6.6`: `/Users/mskoenz/.pyenv/versions/3.6.6/bin/python3.6m`
  - `3.5.6`: `/Users/mskoenz/.pyenv/versions/3.5.6/bin/python3`
  - `3.5.6`: `/Users/mskoenz/.pyenv/versions/3.5.6/bin/python3.5m`
  - `3.4.9`: `/Users/mskoenz/.pyenv/versions/3.4.9/bin/python3`
  - `3.4.9`: `/Users/mskoenz/.pyenv/versions/3.4.9/bin/python3.4m`
  - `2.7.15`: `/Users/mskoenz/.pyenv/versions/2.7.15/bin/python`
  - `2.7.15`: `/usr/local/bin/python`
  - `2.7.15`: `/usr/local/bin/pythonw`
  - `2.7.10`: `/Users/mskoenz/.pyenv/versions/2.7.10/bin/python`
  - `2.7.10`: `/usr/bin/python`
  - `2.7.10`: `/usr/bin/pythonw`
  - `2.7.10`: `/usr/bin/python2.7`

PEP 508 Information:

```
{'implementation_name': 'cpython',
 'implementation_version': '3.7.0',
 'os_name': 'posix',
 'platform_machine': 'x86_64',
 'platform_python_implementation': 'CPython',
 'platform_release': '18.2.0',
 'platform_system': 'Darwin',
 'platform_version': 'Darwin Kernel Version 18.2.0: Fri Oct  5 19:41:49 PDT '
                     '2018; root:xnu-4903.221.2~2/RELEASE_X86_64',
 'python_full_version': '3.7.0',
 'python_version': '3.7',
 'sys_platform': 'darwin'}
```

System environment variables:

  - `CPLUS_INCLUDE_PATH`
  - `LDFLAGS`
  - `SSH_AGENT_PID`
  - `TERM_PROGRAM`
  - `VIRTUALENVWRAPPER_PROJECT_FILENAME`
  - `VIRTUALENVWRAPPER_SCRIPT`
  - `PYENV_ROOT`
  - `PIP_PYTHON_PATH`
  - `TERM`
  - `SHELL`
  - `TMPDIR`
  - `CPPFLAGS`
  - `Apple_PubSub_Socket_Render`
  - `PERL5LIB`
  - `OLDPWD`
  - `PERL_MB_OPT`
  - `PYENV_VERSION`
  - `USER`
  - `COMMAND_MODE`
  - `PYENV_DIR`
  - `SSH_AUTH_SOCK`
  - `__CF_USER_TEXT_ENCODING`
  - `VIRTUAL_ENV`
  - `WORKON_HOME`
  - `VIRTUALENVWRAPPER_PYTHON`
  - `PIPENV_ACTIVE`
  - `PATH`
  - `VIRTUALENVWRAPPER_HOOK_DIR`
  - `C_INCLUDE_PATH`
  - `PWD`
  - `LANG`
  - `PYENV_HOOK_PATH`
  - `XPC_FLAGS`
  - `PS1`
  - `PYTHONDONTWRITEBYTECODE`
  - `XPC_SERVICE_NAME`
  - `HOME`
  - `SHLVL`
  - `PYENV_SHELL`
  - `PERL_LOCAL_LIB_ROOT`
  - `PIP_SHIMS_BASE_MODULE`
  - `LOGNAME`
  - `VIRTUALENVWRAPPER_WORKON_CD`
  - `SECURITYSESSIONID`
  - `PYENV_VIRTUALENVWRAPPER_PREFER_PYVENV`
  - `PERL_MM_OPT`
  - `_`
  - `PIP_DISABLE_PIP_VERSION_CHECK`
  - `PYTHONFINDER_IGNORE_UNSUPPORTED`

Pipenv–specific environment variables:

 - `PIPENV_ACTIVE`: `1`

Debug–specific environment variables:

  - `PATH`: `/Users/mskoenz/.virtualenvs/tmp-92509552f3b388/bin:/Users/mskoenz/perl5/bin:/Users/mskoenz/.pyenv/shims:/usr/local/opt/sqlite/bin:/usr/local/opt/coreutils/libexec/gnubin:/Users/mskoenz/.pyenv/versions/3.7.0/bin:/usr/local/Cellar/pyenv/1.2.7/libexec:/Users/mskoenz/.pyenv/plugins/pyenv-install-latest/bin:/Users/mskoenz/perl5/bin:/Users/mskoenz/.pyenv/shims:/usr/local/opt/sqlite/bin:/usr/local/opt/coreutils/libexec/gnubin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/Users/mskoenz/perl5/bin:/Users/mskoenz/.pyenv/shims:/usr/local/opt/sqlite/bin:/usr/local/opt/coreutils/libexec/gnubin`
  - `SHELL`: `/bin/bash`
  - `LANG`: `en_US.UTF-8`
  - `PWD`: `/Users/mskoenz/hello`
  - `VIRTUAL_ENV`: `/Users/mskoenz/.virtualenvs/tmp-92509552f3b388`


---------------------------

Contents of `Pipfile` ('/Users/mskoenz/hello/Pipfile'):

```toml
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
fsc-export = "*"

[requires]
python_version = "3.7"

[pipenv]
allow_prereleases = true

```

</details>


Discussion:
### Workaround

Change the package name in `Pipfile` from `fsc-export` to `"fsc.export"`, note the quotes can't be omitted.

```toml
[packages]
"fsc.export" = "*"
```
And do `pipenv lock`, everything works fine.
Alright, that worked, thx!

But I would assume that every package that uses . instead of - on pipy has the same issue, and there are many such projects. If convenient and possible, it would be nice to have that deduction automatically done.

Thx for your project!
@mskoenz That requires upstream fix https://github.com/pypa/pip/issues/5870
We used to quote this on write, we need to restore that behavior

Resolving patch:
diff --git a/pipenv/project.py b/pipenv/project.py
--- a/pipenv/project.py
+++ b/pipenv/project.py
@@ -940,7 +940,7 @@ def add_package_to_pipfile(self, package, dev=False):
             # Skip for wildcard version
             return
         # Add the package to the group.
-        p[key][name or package.normalized_name] = converted
+        p[key][name or pep423_name(package.name)] = converted
         # Write Pipfile.
         self.write_toml(p)
 


Test patch:
diff --git a/tests/integration/test_install_basic.py b/tests/integration/test_install_basic.py
--- a/tests/integration/test_install_basic.py
+++ b/tests/integration/test_install_basic.py
@@ -438,3 +438,11 @@ def test_install_non_exist_dep(PipenvInstance, pypi):
         c = p.pipenv("install dateutil")
         assert not c.ok
         assert "dateutil" not in p.pipfile["packages"]
+
+
+@pytest.mark.install
+def test_install_package_with_dots(PipenvInstance, pypi):
+    with PipenvInstance(pypi=pypi, chdir=True) as p:
+        c = p.pipenv("install backports.html")
+        assert c.ok
+        assert "backports.html" in p.pipfile["packages"]
diff --git a/tests/pypi/backports-html/backports.html-1.1.0.tar.gz b/tests/pypi/backports-html/backports.html-1.1.0.tar.gz
new file mode 100644
Binary files /dev/null and b/tests/pypi/backports-html/backports.html-1.1.0.tar.gz differ