Repository: sarugaku/requirementslib (python)

Issue:
Fix support for parsing VCS uris with an @ sign
As of #310, this fails to output the correct reference.  

Example:

```python
>>> from requirementslib import __version__
>>> __version__
'1.6.4'
>>> from requirementslib.models.requirements import Line
>>> Line("-e git+ssh://git@github.com/mycomp/our_repo.git@release/v318#egg=our_package")
<Line (editable=True, name=our_package, path=None, uri=git+ssh://git@github.com/mycomp/our_repo.git, extras=(), markers=None, vcs=git, specifier=None, pyproject=None, pyproject_requires=None, pyproject_backend=None, ireq=None)>
```

```python
>>> from requirementslib import __version__
>>> __version__
'1.6.6'
>>> from requirementslib.models.requirements import Line
>>> Line("-e git+ssh://git@github.com/mycomp/our_repo.git@release/v318#egg=our_package")
<Line (editable=True, name=our_package, path=None, uri=git+ssh://git@github.com/mycomp/our_repo.git@release/v318, extras=(), markers=None, vcs=git, specifier=None, pyproject=None, pyproject_requires=None, pyproject_backend=None, ireq=None)>
```

Related to https://github.com/pypa/pipenv/issues/5179

Pull request:
Fix bug to parse VCS URIs with references
This fixes a bug introduced in #310.

In addition, I opted to make the test more data-driven to make it easier to add additional test cases.  I'm sure I've missed some. 

- Make split ref test data driven
- Add failing test case for VCS with ref and user
- Fix handling non-file-like uris with @ signs
- Add news issue

Fixes #330

Related to https://github.com/pypa/pipenv/issues/5179

Patch:
diff --git a/news/330.bugfix.rst b/news/330.bugfix.rst
new file mode 100644
index 0000000..714a3f7
--- /dev/null
+++ b/news/330.bugfix.rst
@@ -0,0 +1,1 @@
+Resolved an issue introduced in 1.6.5 that failed to parse refs in VCS uris
diff --git a/src/requirementslib/models/utils.py b/src/requirementslib/models/utils.py
index 5b11f26..77569c0 100644
--- a/src/requirementslib/models/utils.py
+++ b/src/requirementslib/models/utils.py
@@ -567,7 +567,10 @@ def split_ref_from_uri(uri):
     path = parsed.path if parsed.path else ""
     scheme = parsed.scheme if parsed.scheme else ""
     ref = None
-    if scheme != "file" and (re.match("^.*@[^/@]*$", path) or path.count("@") >= 2):
+    schema_is_filelike = scheme in ("", "file")
+    if (not schema_is_filelike and "@" in path) or (
+        schema_is_filelike and (re.match("^.*@[^/@]*$", path) or path.count("@") >= 2)
+    ):
         path, _, ref = path.rpartition("@")
     parsed = parsed._replace(path=path)
     return (parsed.url, ref)


Test patch:
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
index fb16961..93c2018 100644
--- a/tests/unit/test_utils.py
+++ b/tests/unit/test_utils.py
@@ -100,33 +100,61 @@ def test_split_vcs_method_from_uri():
     )
 
 
-def test_split_ref_from_uri():
-    assert utils.split_ref_from_uri("https://github.com/sarugaku/plette.git") == (
-        "https://github.com/sarugaku/plette.git",
-        None,
-    )
-    assert utils.split_ref_from_uri("/Users/some.user@acme.com/dev/myproject") == (
-        "/Users/some.user@acme.com/dev/myproject",
-        None,
-    )
-    assert utils.split_ref_from_uri(
-        "https://user:password@github.com/sarugaku/plette.git"
-    ) == (
-        "https://user:password@github.com/sarugaku/plette.git",
-        None,
-    )
-    assert utils.split_ref_from_uri(
-        "git+https://github.com/pypa/pipenv.git@master#egg=pipenv"
-    ) == (
-        "git+https://github.com/pypa/pipenv.git#egg=pipenv",
-        "master",
-    )
-    assert utils.split_ref_from_uri(
-        "/Users/some.user@acme.com/dev/myproject@bugfix/309"
-    ) == (
-        "/Users/some.user@acme.com/dev/myproject",
-        "bugfix/309",
-    )
+@pytest.mark.parametrize(
+    "uri,expected_output",
+    [
+        pytest.param(
+            "https://github.com/sarugaku/plette.git",
+            (
+                "https://github.com/sarugaku/plette.git",
+                None,
+            ),
+            id="https VCS, no ref",
+        ),
+        pytest.param(
+            "/Users/some.user@acme.com/dev/myproject",
+            (
+                "/Users/some.user@acme.com/dev/myproject",
+                None,
+            ),
+            id="Local path with @",
+        ),
+        pytest.param(
+            "https://user:password@github.com/sarugaku/plette.git",
+            (
+                "https://user:password@github.com/sarugaku/plette.git",
+                None,
+            ),
+            id="https VCS, with user@, no ref",
+        ),
+        pytest.param(
+            "git+https://github.com/pypa/pipenv.git@master#egg=pipenv",
+            (
+                "git+https://github.com/pypa/pipenv.git#egg=pipenv",
+                "master",
+            ),
+            id="https VCS, no user, master ref",
+        ),
+        pytest.param(
+            "/Users/some.user@acme.com/dev/myproject@bugfix/309",
+            (
+                "/Users/some.user@acme.com/dev/myproject",
+                "bugfix/309",
+            ),
+            id="Local path with @ ref",
+        ),
+        pytest.param(
+            "git+ssh://git@github.com/mycomp/our_repo.git@release/v318#egg=our_package",
+            (
+                "git+ssh://git@github.com/mycomp/our_repo.git#egg=our_package",
+                "release/v318",
+            ),
+            id="git/ssh VCS with user name, @ ref, egg",
+        ),
+    ],
+)
+def test_split_ref_from_uri(uri: str, expected_output):
+    assert utils.split_ref_from_uri(uri) == expected_output
 
 
 # tests from pip-tools