Repository: pypa/pipenv

Issue:
Last default dependency being marked as local and editable
Checked out [diagnose documentation](https://pipenv.pypa.io/en/latest/diagnose/) for common issues. I outlined my (possibly flawed) workflow in the steps to reproduce below. I've been fussing around with this for a couple weeks blaming myself, and would love for this to be a me-bug.

### Issue description

Last external package listed in the default section of Pipfile.lock is incorrectly being marked as local and editable

### Expected result

Last external package listed is still provided from pypi

### Actual result

My Pipfile.lock get this diff included in it, which breaks CI and other users for obvious reasons:
```
             "version": "==1.25.10"
         },
         "wrapt": {
-            "hashes": [
-                "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
-            ],
-            "version": "==1.12.1"
+            "editable": true,
+            "path": "."
         }
     },
     "develop": {
```

### Steps to replicate
```
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
flake8 = "3.8.3"
pytest = "5.4.3"
pytest-cov = "2.10.0"
termcolor = "1.1.0"

[packages]
mycli = {editable = true, path = "."}

[requires]
python_version = "3.7"
```
(mycli has a setup.py to facilitate creating an entrypoint for python click and defines non-dev dependencies)

The project is a CLI utility and we clone the repository and install via:
`PIPENV_IGNORE_VIRTUALENVS=1 PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy`

As a developer adding a new dependency, I edit the `setup.py` and run:
`pipenv lock`

This generates a Pipfile.lock file that does include my new dependency, but also a malformed last default dependency (I've had the issue with multiple packages that are near the end of the alphabet in that position, specifically `wrapt` and `zipp`)

I am able to workaround the issue and generate a correct Pipfile.lock by:
`rm -rf Pipfile.lock .venv`
and
`pipenv lock`

-------------------------------------------------------------------------------

I am purposefully omitting the `pipenv --support` output because the application I'm working on is proprietary and I worry about leaking details of our environment (or our security team yelling at me :laughing:). If there are specific snippets i can scrub and provide I would be glad to, just didn't want to scrub the whole thing up front.


Thank you for reading and again, hope I'm just being dumb.
Thanks!


Discussion:
@patelamol and I can reproduce this with pipenv 2020.08.13.
I experienced this bug in all the latest version until `2018.11.26`. So `2018.11.26` doesn't have this issue.

As @jmehnle and @patelamol commented, I've been experiencing a similar issue with some of my packages in this case
```json
       "zipp": {
            "editable": true,
            "path": "."
        },
```

My solution was to manually edit the pipfile lock, which is unsafe/unhealthy to the latest version
```json
"zipp": {
            "hashes": [
                "sha256:43f4fa8d8bb313e65d8323a3952ef8756bf40f9a5c3ea7334be23ee4ec8278b6",
                "sha256:b52f22895f4cfce194bc8172f3819ee8de7540aa6d873535a8668b730b8b411f"
            ],
            "version": "==3.2.0"
        }
```
I wonder if there's a pipenv update coming out soon with this bugfix
@gregflynn @patelamol So does this issue exist on the master branch? I can't reproduce with the given steps
> @gregflynn @patelamol So does this issue exist on the master branch? I can't reproduce with the given steps

Surely! I have not run pipenv from github before and didn't see instructions in the README so I'll be verbose about the steps:
1. git cloned down
1. `pyenv virtualenv 3.7.9 pipenv` && `pyenv local pipenv` && `pip install -e .`
1. verification:
    ```
    $ pipenv --version
    pipenv, version 2020.8.13

    $ ~/.pyenv/versions/pipenv/bin/pipenv --version 
    pipenv, version 2020.8.13.dev0
    ```
1. made a fresh venv with 2020.8.13
1. added `stockquotes == 2.0.0` to my setup.py
1. ran `~/.pyenv/versions/pipenv/bin/pipenv lock`
1. No dice, seeing the error with
```diff
         "wrapt": {
-            "hashes": [
-                "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
-            ],
-            "version": "==1.12.1"
+            "editable": true,
+            "path": "."
         }
     },
```

@frostming thank you for the suggestion and taking a look, happy to do more testing or correct this test if I've gone astray.
@gregflynn 
> 4. made a fresh venv with 2020.8.13

Is this step critical to reproduce the bug? I create with master Pipenv and can't reproduce. A docker image would be of great help if possible
> @gregflynn
> 
> > 1. made a fresh venv with 2020.8.13
> 
> Is this step critical to reproduce the bug? I create with master Pipenv and can't reproduce. A docker image would be of great help if possible

Good eye but I made the following changes and was still able to reproduce with latest master version. For step 4 I updated my install script:
```diff
-PIPENV_IGNORE_VIRTUALENVS=1 PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy
+PIPENV_IGNORE_VIRTUALENVS=1 PIPENV_VENV_IN_PROJECT=1 $HOME/.pyenv/versions/pipenv/bin/pipenv install --deploy
```

and still got:
```diff
         "wrapt": {
-            "hashes": [
-                "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
-            ],
-            "version": "==1.12.1"
+            "editable": true,
+            "path": "."
         }
     },
```

Happy to try more things! Thanks
Oh, I managed to reproduce it! I didn't notice the critical factor is VENV_IN_PROJECT.

Resolving patch:
diff --git a/pipenv/vendor/requirementslib/__init__.py b/pipenv/vendor/requirementslib/__init__.py
--- a/pipenv/vendor/requirementslib/__init__.py
+++ b/pipenv/vendor/requirementslib/__init__.py
@@ -10,7 +10,7 @@
 from .models.pipfile import Pipfile
 from .models.requirements import Requirement
 
-__version__ = "1.5.13"
+__version__ = "1.5.14"
 
 
 logger = logging.getLogger(__name__)
diff --git a/pipenv/vendor/requirementslib/models/setup_info.py b/pipenv/vendor/requirementslib/models/setup_info.py
--- a/pipenv/vendor/requirementslib/models/setup_info.py
+++ b/pipenv/vendor/requirementslib/models/setup_info.py
@@ -465,6 +465,18 @@ def close(self):
             pass
 
 
+def _is_venv_dir(path):
+    # type: (AnyStr) -> bool
+    if os.name == "nt":
+        return os.path.isfile(os.path.join(path, "Scripts/python.exe")) or os.path.isfile(
+            os.path.join(path, "Scripts/activate")
+        )
+    else:
+        return os.path.isfile(os.path.join(path, "bin/python")) or os.path.isfile(
+            os.path.join(path, "bin/activate")
+        )
+
+
 def iter_metadata(path, pkg_name=None, metadata_type="egg-info"):
     # type: (AnyStr, Optional[AnyStr], AnyStr) -> Generator
     if pkg_name is not None:
@@ -472,6 +484,9 @@ def iter_metadata(path, pkg_name=None, metadata_type="egg-info"):
     dirs_to_search = [path]
     while dirs_to_search:
         p = dirs_to_search.pop(0)
+        # Skip when the directory is like a venv
+        if _is_venv_dir(p):
+            continue
         with contextlib.closing(ScandirCloser(p)) as path_iterator:
             for entry in path_iterator:
                 if entry.is_dir():


Test patch: