fix: allow url fragments in requirements file (#1195)

This commit addresses issue #1194 (see issue for details).

It brings the `comment` detection of `requirements_parser.bzl` closer to
the spec described here:
-
https://pip.pypa.io/en/stable/reference/requirements-file-format/#comments

1. Lines that begin with `#` are comments.
2. Content after (and including) ` #` is a comment.

Prior to this commit, a dependency like this would result in invalid
`pip wheel` arguments:

```
requests @ https://github.com/psf/requests/releases/download/v2.29.0/requests-2.29.0.tar.gz#sha1=3897c249b51a1a405d615a8c9cb92e5fdbf0dd49
```
diff --git a/python/pip_install/private/test/requirements_parser_tests.bzl b/python/pip_install/private/test/requirements_parser_tests.bzl
index c13ec20..5ea742e 100644
--- a/python/pip_install/private/test/requirements_parser_tests.bzl
+++ b/python/pip_install/private/test/requirements_parser_tests.bzl
@@ -63,6 +63,9 @@
 # Comment
 BarProject==2.0.0 #Comment
 """).requirements)
+    asserts.equals(env, [("requests", "requests @ https://github.com/psf/requests/releases/download/v2.29.0/requests-2.29.0.tar.gz#sha1=3897c249b51a1a405d615a8c9cb92e5fdbf0dd49")], parse("""\
+requests @ https://github.com/psf/requests/releases/download/v2.29.0/requests-2.29.0.tar.gz#sha1=3897c249b51a1a405d615a8c9cb92e5fdbf0dd49
+""").requirements)
 
     # Multiline
     asserts.equals(env, [("certifi", "certifi==2021.10.8     --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872     --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569")], parse("""\
@@ -71,6 +74,11 @@
     --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
     # via requests
 """).requirements)
+    asserts.equals(env, [("requests", "requests @ https://github.com/psf/requests/releases/download/v2.29.0/requests-2.29.0.tar.gz#sha1=3897c249b51a1a405d615a8c9cb92e5fdbf0dd49     --hash=sha256:eca58eb564b134e4ff521a02aa6f566c653835753e1fc8a50a20cb6bee4673cd")], parse("""\
+requests @ https://github.com/psf/requests/releases/download/v2.29.0/requests-2.29.0.tar.gz#sha1=3897c249b51a1a405d615a8c9cb92e5fdbf0dd49 \
+    --hash=sha256:eca58eb564b134e4ff521a02aa6f566c653835753e1fc8a50a20cb6bee4673cd
+    # via requirements.txt
+""").requirements)
 
     # Options
     asserts.equals(env, ["--pre"], parse("--pre\n").options)
diff --git a/python/pip_install/requirements_parser.bzl b/python/pip_install/requirements_parser.bzl
index ac90b95..3b49fdf 100644
--- a/python/pip_install/requirements_parser.bzl
+++ b/python/pip_install/requirements_parser.bzl
@@ -116,7 +116,7 @@
     elif input == "\n" or input == EOF:
         result.options.append(buffer.rstrip("\n"))
         return (_STATE.ConsumeSpace, "")
-    elif input == "#":
+    elif input == "#" and (len(buffer) == 0 or buffer[-1].isspace()):
         return (_STATE.ConsumeComment, buffer)
 
     return (_STATE.ParseOption, buffer + input)
@@ -127,7 +127,7 @@
     elif input == "\n" or input == EOF:
         result.requirements[-1] = (result.requirements[-1][0], buffer.rstrip(" \n"))
         return (_STATE.ConsumeSpace, "")
-    elif input == "#":
+    elif input == "#" and (len(buffer) == 0 or buffer[-1].isspace()):
         return (_STATE.ConsumeComment, buffer)
 
     return (_STATE.ParseRequirement, buffer + input)