We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix/5147
Suppress the output of the stack trace when `pip install` is called with an invalid requirement.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pip/_internal/req/constructors.py`
Content:
```
1 """Backing implementation for InstallRequirement's various constructors
2 
3 The idea here is that these formed a major chunk of InstallRequirement's size
4 so, moving them and support code dedicated to them outside of that class
5 helps creates for better understandability for the rest of the code.
6 
7 These are meant to be used elsewhere within pip to create instances of
8 InstallRequirement.
9 """
10 
11 import logging
12 import os
13 import re
14 import traceback
15 
16 from pip._vendor.packaging.markers import Marker
17 from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
18 from pip._vendor.packaging.specifiers import Specifier
19 from pip._vendor.pkg_resources import RequirementParseError, parse_requirements
20 
21 from pip._internal.download import (
22     is_archive_file, is_url, path_to_url, url_to_path,
23 )
24 from pip._internal.exceptions import InstallationError
25 from pip._internal.models.index import PyPI, TestPyPI
26 from pip._internal.models.link import Link
27 from pip._internal.req.req_install import InstallRequirement
28 from pip._internal.utils.misc import is_installable_dir
29 from pip._internal.vcs import vcs
30 from pip._internal.wheel import Wheel
31 
32 __all__ = [
33     "install_req_from_editable", "install_req_from_line",
34     "parse_editable"
35 ]
36 
37 logger = logging.getLogger(__name__)
38 operators = Specifier._operators.keys()
39 
40 
41 def _strip_extras(path):
42     m = re.match(r'^(.+)(\[[^\]]+\])$', path)
43     extras = None
44     if m:
45         path_no_extras = m.group(1)
46         extras = m.group(2)
47     else:
48         path_no_extras = path
49 
50     return path_no_extras, extras
51 
52 
53 def parse_editable(editable_req):
54     """Parses an editable requirement into:
55         - a requirement name
56         - an URL
57         - extras
58         - editable options
59     Accepted requirements:
60         svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir
61         .[some_extra]
62     """
63 
64     url = editable_req
65 
66     # If a file path is specified with extras, strip off the extras.
67     url_no_extras, extras = _strip_extras(url)
68 
69     if os.path.isdir(url_no_extras):
70         if not os.path.exists(os.path.join(url_no_extras, 'setup.py')):
71             raise InstallationError(
72                 "Directory %r is not installable. File 'setup.py' not found." %
73                 url_no_extras
74             )
75         # Treating it as code that has already been checked out
76         url_no_extras = path_to_url(url_no_extras)
77 
78     if url_no_extras.lower().startswith('file:'):
79         package_name = Link(url_no_extras).egg_fragment
80         if extras:
81             return (
82                 package_name,
83                 url_no_extras,
84                 Requirement("placeholder" + extras.lower()).extras,
85             )
86         else:
87             return package_name, url_no_extras, None
88 
89     for version_control in vcs:
90         if url.lower().startswith('%s:' % version_control):
91             url = '%s+%s' % (version_control, url)
92             break
93 
94     if '+' not in url:
95         raise InstallationError(
96             '%s should either be a path to a local project or a VCS url '
97             'beginning with svn+, git+, hg+, or bzr+' %
98             editable_req
99         )
100 
101     vc_type = url.split('+', 1)[0].lower()
102 
103     if not vcs.get_backend(vc_type):
104         error_message = 'For --editable=%s only ' % editable_req + \
105             ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \
106             ' is currently supported'
107         raise InstallationError(error_message)
108 
109     package_name = Link(url).egg_fragment
110     if not package_name:
111         raise InstallationError(
112             "Could not detect requirement name for '%s', please specify one "
113             "with #egg=your_package_name" % editable_req
114         )
115     return package_name, url, None
116 
117 
118 def deduce_helpful_msg(req):
119     """Returns helpful msg in case requirements file does not exist,
120     or cannot be parsed.
121 
122     :params req: Requirements file path
123     """
124     msg = ""
125     if os.path.exists(req):
126         msg = " It does exist."
127         # Try to parse and check if it is a requirements file.
128         try:
129             with open(req, 'r') as fp:
130                 # parse first line only
131                 next(parse_requirements(fp.read()))
132                 msg += " The argument you provided " + \
133                     "(%s) appears to be a" % (req) + \
134                     " requirements file. If that is the" + \
135                     " case, use the '-r' flag to install" + \
136                     " the packages specified within it."
137         except RequirementParseError:
138             logger.debug("Cannot parse '%s' as requirements \
139             file" % (req), exc_info=1)
140     else:
141         msg += " File '%s' does not exist." % (req)
142     return msg
143 
144 
145 # ---- The actual constructors follow ----
146 
147 
148 def install_req_from_editable(
149     editable_req, comes_from=None, isolated=False, options=None,
150     wheel_cache=None, constraint=False
151 ):
152     name, url, extras_override = parse_editable(editable_req)
153     if url.startswith('file:'):
154         source_dir = url_to_path(url)
155     else:
156         source_dir = None
157 
158     if name is not None:
159         try:
160             req = Requirement(name)
161         except InvalidRequirement:
162             raise InstallationError("Invalid requirement: '%s'" % name)
163     else:
164         req = None
165     return InstallRequirement(
166         req, comes_from, source_dir=source_dir,
167         editable=True,
168         link=Link(url),
169         constraint=constraint,
170         isolated=isolated,
171         options=options if options else {},
172         wheel_cache=wheel_cache,
173         extras=extras_override or (),
174     )
175 
176 
177 def install_req_from_line(
178     name, comes_from=None, isolated=False, options=None, wheel_cache=None,
179     constraint=False
180 ):
181     """Creates an InstallRequirement from a name, which might be a
182     requirement, directory containing 'setup.py', filename, or URL.
183     """
184     if is_url(name):
185         marker_sep = '; '
186     else:
187         marker_sep = ';'
188     if marker_sep in name:
189         name, markers = name.split(marker_sep, 1)
190         markers = markers.strip()
191         if not markers:
192             markers = None
193         else:
194             markers = Marker(markers)
195     else:
196         markers = None
197     name = name.strip()
198     req = None
199     path = os.path.normpath(os.path.abspath(name))
200     link = None
201     extras = None
202 
203     if is_url(name):
204         link = Link(name)
205     else:
206         p, extras = _strip_extras(path)
207         looks_like_dir = os.path.isdir(p) and (
208             os.path.sep in name or
209             (os.path.altsep is not None and os.path.altsep in name) or
210             name.startswith('.')
211         )
212         if looks_like_dir:
213             if not is_installable_dir(p):
214                 raise InstallationError(
215                     "Directory %r is not installable. Neither 'setup.py' "
216                     "nor 'pyproject.toml' found." % name
217                 )
218             link = Link(path_to_url(p))
219         elif is_archive_file(p):
220             if not os.path.isfile(p):
221                 logger.warning(
222                     'Requirement %r looks like a filename, but the '
223                     'file does not exist',
224                     name
225                 )
226             link = Link(path_to_url(p))
227 
228     # it's a local file, dir, or url
229     if link:
230         # Handle relative file URLs
231         if link.scheme == 'file' and re.search(r'\.\./', link.url):
232             link = Link(
233                 path_to_url(os.path.normpath(os.path.abspath(link.path))))
234         # wheel file
235         if link.is_wheel:
236             wheel = Wheel(link.filename)  # can raise InvalidWheelFilename
237             req = "%s==%s" % (wheel.name, wheel.version)
238         else:
239             # set the req to the egg fragment.  when it's not there, this
240             # will become an 'unnamed' requirement
241             req = link.egg_fragment
242 
243     # a requirement specifier
244     else:
245         req = name
246 
247     if extras:
248         extras = Requirement("placeholder" + extras.lower()).extras
249     else:
250         extras = ()
251     if req is not None:
252         try:
253             req = Requirement(req)
254         except InvalidRequirement:
255             if os.path.sep in req:
256                 add_msg = "It looks like a path."
257                 add_msg += deduce_helpful_msg(req)
258             elif '=' in req and not any(op in req for op in operators):
259                 add_msg = "= is not a valid operator. Did you mean == ?"
260             else:
261                 add_msg = traceback.format_exc()
262             raise InstallationError(
263                 "Invalid requirement: '%s'\n%s" % (req, add_msg)
264             )
265 
266     return InstallRequirement(
267         req, comes_from, link=link, markers=markers,
268         isolated=isolated,
269         options=options if options else {},
270         wheel_cache=wheel_cache,
271         constraint=constraint,
272         extras=extras,
273     )
274 
275 
276 def install_req_from_req(
277     req, comes_from=None, isolated=False, wheel_cache=None
278 ):
279     try:
280         req = Requirement(req)
281     except InvalidRequirement:
282         raise InstallationError("Invalid requirement: '%s'" % req)
283 
284     domains_not_allowed = [
285         PyPI.file_storage_domain,
286         TestPyPI.file_storage_domain,
287     ]
288     if req.url and comes_from.link.netloc in domains_not_allowed:
289         # Explicitly disallow pypi packages that depend on external urls
290         raise InstallationError(
291             "Packages installed from PyPI cannot depend on packages "
292             "which are not also hosted on PyPI.\n"
293             "%s depends on %s " % (comes_from.name, req)
294         )
295 
296     return InstallRequirement(
297         req, comes_from, isolated=isolated, wheel_cache=wheel_cache
298     )
299
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/pip/_internal/req/constructors.py b/src/pip/_internal/req/constructors.py
--- a/src/pip/_internal/req/constructors.py
+++ b/src/pip/_internal/req/constructors.py
@@ -11,7 +11,6 @@
 import logging
 import os
 import re
-import traceback
 
 from pip._vendor.packaging.markers import Marker
 from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
@@ -258,7 +257,7 @@
             elif '=' in req and not any(op in req for op in operators):
                 add_msg = "= is not a valid operator. Did you mean == ?"
             else:
-                add_msg = traceback.format_exc()
+                add_msg = ""
             raise InstallationError(
                 "Invalid requirement: '%s'\n%s" % (req, add_msg)
             )

{"golden_diff": "diff --git a/src/pip/_internal/req/constructors.py b/src/pip/_internal/req/constructors.py\n--- a/src/pip/_internal/req/constructors.py\n+++ b/src/pip/_internal/req/constructors.py\n@@ -11,7 +11,6 @@\n import logging\n import os\n import re\n-import traceback\n \n from pip._vendor.packaging.markers import Marker\n from pip._vendor.packaging.requirements import InvalidRequirement, Requirement\n@@ -258,7 +257,7 @@\n             elif '=' in req and not any(op in req for op in operators):\n                 add_msg = \"= is not a valid operator. Did you mean == ?\"\n             else:\n-                add_msg = traceback.format_exc()\n+                add_msg = \"\"\n             raise InstallationError(\n                 \"Invalid requirement: '%s'\\n%s\" % (req, add_msg)\n             )\n", "issue": "Fix/5147\nSuppress the output of the stack trace when `pip install` is called with an invalid requirement.\r\n\n", "before_files": [{"content": "\"\"\"Backing implementation for InstallRequirement's various constructors\n\nThe idea here is that these formed a major chunk of InstallRequirement's size\nso, moving them and support code dedicated to them outside of that class\nhelps creates for better understandability for the rest of the code.\n\nThese are meant to be used elsewhere within pip to create instances of\nInstallRequirement.\n\"\"\"\n\nimport logging\nimport os\nimport re\nimport traceback\n\nfrom pip._vendor.packaging.markers import Marker\nfrom pip._vendor.packaging.requirements import InvalidRequirement, Requirement\nfrom pip._vendor.packaging.specifiers import Specifier\nfrom pip._vendor.pkg_resources import RequirementParseError, parse_requirements\n\nfrom pip._internal.download import (\n    is_archive_file, is_url, path_to_url, url_to_path,\n)\nfrom pip._internal.exceptions import InstallationError\nfrom pip._internal.models.index import PyPI, TestPyPI\nfrom pip._internal.models.link import Link\nfrom pip._internal.req.req_install import InstallRequirement\nfrom pip._internal.utils.misc import is_installable_dir\nfrom pip._internal.vcs import vcs\nfrom pip._internal.wheel import Wheel\n\n__all__ = [\n    \"install_req_from_editable\", \"install_req_from_line\",\n    \"parse_editable\"\n]\n\nlogger = logging.getLogger(__name__)\noperators = Specifier._operators.keys()\n\n\ndef _strip_extras(path):\n    m = re.match(r'^(.+)(\\[[^\\]]+\\])$', path)\n    extras = None\n    if m:\n        path_no_extras = m.group(1)\n        extras = m.group(2)\n    else:\n        path_no_extras = path\n\n    return path_no_extras, extras\n\n\ndef parse_editable(editable_req):\n    \"\"\"Parses an editable requirement into:\n        - a requirement name\n        - an URL\n        - extras\n        - editable options\n    Accepted requirements:\n        svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir\n        .[some_extra]\n    \"\"\"\n\n    url = editable_req\n\n    # If a file path is specified with extras, strip off the extras.\n    url_no_extras, extras = _strip_extras(url)\n\n    if os.path.isdir(url_no_extras):\n        if not os.path.exists(os.path.join(url_no_extras, 'setup.py')):\n            raise InstallationError(\n                \"Directory %r is not installable. File 'setup.py' not found.\" %\n                url_no_extras\n            )\n        # Treating it as code that has already been checked out\n        url_no_extras = path_to_url(url_no_extras)\n\n    if url_no_extras.lower().startswith('file:'):\n        package_name = Link(url_no_extras).egg_fragment\n        if extras:\n            return (\n                package_name,\n                url_no_extras,\n                Requirement(\"placeholder\" + extras.lower()).extras,\n            )\n        else:\n            return package_name, url_no_extras, None\n\n    for version_control in vcs:\n        if url.lower().startswith('%s:' % version_control):\n            url = '%s+%s' % (version_control, url)\n            break\n\n    if '+' not in url:\n        raise InstallationError(\n            '%s should either be a path to a local project or a VCS url '\n            'beginning with svn+, git+, hg+, or bzr+' %\n            editable_req\n        )\n\n    vc_type = url.split('+', 1)[0].lower()\n\n    if not vcs.get_backend(vc_type):\n        error_message = 'For --editable=%s only ' % editable_req + \\\n            ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \\\n            ' is currently supported'\n        raise InstallationError(error_message)\n\n    package_name = Link(url).egg_fragment\n    if not package_name:\n        raise InstallationError(\n            \"Could not detect requirement name for '%s', please specify one \"\n            \"with #egg=your_package_name\" % editable_req\n        )\n    return package_name, url, None\n\n\ndef deduce_helpful_msg(req):\n    \"\"\"Returns helpful msg in case requirements file does not exist,\n    or cannot be parsed.\n\n    :params req: Requirements file path\n    \"\"\"\n    msg = \"\"\n    if os.path.exists(req):\n        msg = \" It does exist.\"\n        # Try to parse and check if it is a requirements file.\n        try:\n            with open(req, 'r') as fp:\n                # parse first line only\n                next(parse_requirements(fp.read()))\n                msg += \" The argument you provided \" + \\\n                    \"(%s) appears to be a\" % (req) + \\\n                    \" requirements file. If that is the\" + \\\n                    \" case, use the '-r' flag to install\" + \\\n                    \" the packages specified within it.\"\n        except RequirementParseError:\n            logger.debug(\"Cannot parse '%s' as requirements \\\n            file\" % (req), exc_info=1)\n    else:\n        msg += \" File '%s' does not exist.\" % (req)\n    return msg\n\n\n# ---- The actual constructors follow ----\n\n\ndef install_req_from_editable(\n    editable_req, comes_from=None, isolated=False, options=None,\n    wheel_cache=None, constraint=False\n):\n    name, url, extras_override = parse_editable(editable_req)\n    if url.startswith('file:'):\n        source_dir = url_to_path(url)\n    else:\n        source_dir = None\n\n    if name is not None:\n        try:\n            req = Requirement(name)\n        except InvalidRequirement:\n            raise InstallationError(\"Invalid requirement: '%s'\" % name)\n    else:\n        req = None\n    return InstallRequirement(\n        req, comes_from, source_dir=source_dir,\n        editable=True,\n        link=Link(url),\n        constraint=constraint,\n        isolated=isolated,\n        options=options if options else {},\n        wheel_cache=wheel_cache,\n        extras=extras_override or (),\n    )\n\n\ndef install_req_from_line(\n    name, comes_from=None, isolated=False, options=None, wheel_cache=None,\n    constraint=False\n):\n    \"\"\"Creates an InstallRequirement from a name, which might be a\n    requirement, directory containing 'setup.py', filename, or URL.\n    \"\"\"\n    if is_url(name):\n        marker_sep = '; '\n    else:\n        marker_sep = ';'\n    if marker_sep in name:\n        name, markers = name.split(marker_sep, 1)\n        markers = markers.strip()\n        if not markers:\n            markers = None\n        else:\n            markers = Marker(markers)\n    else:\n        markers = None\n    name = name.strip()\n    req = None\n    path = os.path.normpath(os.path.abspath(name))\n    link = None\n    extras = None\n\n    if is_url(name):\n        link = Link(name)\n    else:\n        p, extras = _strip_extras(path)\n        looks_like_dir = os.path.isdir(p) and (\n            os.path.sep in name or\n            (os.path.altsep is not None and os.path.altsep in name) or\n            name.startswith('.')\n        )\n        if looks_like_dir:\n            if not is_installable_dir(p):\n                raise InstallationError(\n                    \"Directory %r is not installable. Neither 'setup.py' \"\n                    \"nor 'pyproject.toml' found.\" % name\n                )\n            link = Link(path_to_url(p))\n        elif is_archive_file(p):\n            if not os.path.isfile(p):\n                logger.warning(\n                    'Requirement %r looks like a filename, but the '\n                    'file does not exist',\n                    name\n                )\n            link = Link(path_to_url(p))\n\n    # it's a local file, dir, or url\n    if link:\n        # Handle relative file URLs\n        if link.scheme == 'file' and re.search(r'\\.\\./', link.url):\n            link = Link(\n                path_to_url(os.path.normpath(os.path.abspath(link.path))))\n        # wheel file\n        if link.is_wheel:\n            wheel = Wheel(link.filename)  # can raise InvalidWheelFilename\n            req = \"%s==%s\" % (wheel.name, wheel.version)\n        else:\n            # set the req to the egg fragment.  when it's not there, this\n            # will become an 'unnamed' requirement\n            req = link.egg_fragment\n\n    # a requirement specifier\n    else:\n        req = name\n\n    if extras:\n        extras = Requirement(\"placeholder\" + extras.lower()).extras\n    else:\n        extras = ()\n    if req is not None:\n        try:\n            req = Requirement(req)\n        except InvalidRequirement:\n            if os.path.sep in req:\n                add_msg = \"It looks like a path.\"\n                add_msg += deduce_helpful_msg(req)\n            elif '=' in req and not any(op in req for op in operators):\n                add_msg = \"= is not a valid operator. Did you mean == ?\"\n            else:\n                add_msg = traceback.format_exc()\n            raise InstallationError(\n                \"Invalid requirement: '%s'\\n%s\" % (req, add_msg)\n            )\n\n    return InstallRequirement(\n        req, comes_from, link=link, markers=markers,\n        isolated=isolated,\n        options=options if options else {},\n        wheel_cache=wheel_cache,\n        constraint=constraint,\n        extras=extras,\n    )\n\n\ndef install_req_from_req(\n    req, comes_from=None, isolated=False, wheel_cache=None\n):\n    try:\n        req = Requirement(req)\n    except InvalidRequirement:\n        raise InstallationError(\"Invalid requirement: '%s'\" % req)\n\n    domains_not_allowed = [\n        PyPI.file_storage_domain,\n        TestPyPI.file_storage_domain,\n    ]\n    if req.url and comes_from.link.netloc in domains_not_allowed:\n        # Explicitly disallow pypi packages that depend on external urls\n        raise InstallationError(\n            \"Packages installed from PyPI cannot depend on packages \"\n            \"which are not also hosted on PyPI.\\n\"\n            \"%s depends on %s \" % (comes_from.name, req)\n        )\n\n    return InstallRequirement(\n        req, comes_from, isolated=isolated, wheel_cache=wheel_cache\n    )\n", "path": "src/pip/_internal/req/constructors.py"}], "after_files": [{"content": "\"\"\"Backing implementation for InstallRequirement's various constructors\n\nThe idea here is that these formed a major chunk of InstallRequirement's size\nso, moving them and support code dedicated to them outside of that class\nhelps creates for better understandability for the rest of the code.\n\nThese are meant to be used elsewhere within pip to create instances of\nInstallRequirement.\n\"\"\"\n\nimport logging\nimport os\nimport re\n\nfrom pip._vendor.packaging.markers import Marker\nfrom pip._vendor.packaging.requirements import InvalidRequirement, Requirement\nfrom pip._vendor.packaging.specifiers import Specifier\nfrom pip._vendor.pkg_resources import RequirementParseError, parse_requirements\n\nfrom pip._internal.download import (\n    is_archive_file, is_url, path_to_url, url_to_path,\n)\nfrom pip._internal.exceptions import InstallationError\nfrom pip._internal.models.index import PyPI, TestPyPI\nfrom pip._internal.models.link import Link\nfrom pip._internal.req.req_install import InstallRequirement\nfrom pip._internal.utils.misc import is_installable_dir\nfrom pip._internal.vcs import vcs\nfrom pip._internal.wheel import Wheel\n\n__all__ = [\n    \"install_req_from_editable\", \"install_req_from_line\",\n    \"parse_editable\"\n]\n\nlogger = logging.getLogger(__name__)\noperators = Specifier._operators.keys()\n\n\ndef _strip_extras(path):\n    m = re.match(r'^(.+)(\\[[^\\]]+\\])$', path)\n    extras = None\n    if m:\n        path_no_extras = m.group(1)\n        extras = m.group(2)\n    else:\n        path_no_extras = path\n\n    return path_no_extras, extras\n\n\ndef parse_editable(editable_req):\n    \"\"\"Parses an editable requirement into:\n        - a requirement name\n        - an URL\n        - extras\n        - editable options\n    Accepted requirements:\n        svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir\n        .[some_extra]\n    \"\"\"\n\n    url = editable_req\n\n    # If a file path is specified with extras, strip off the extras.\n    url_no_extras, extras = _strip_extras(url)\n\n    if os.path.isdir(url_no_extras):\n        if not os.path.exists(os.path.join(url_no_extras, 'setup.py')):\n            raise InstallationError(\n                \"Directory %r is not installable. File 'setup.py' not found.\" %\n                url_no_extras\n            )\n        # Treating it as code that has already been checked out\n        url_no_extras = path_to_url(url_no_extras)\n\n    if url_no_extras.lower().startswith('file:'):\n        package_name = Link(url_no_extras).egg_fragment\n        if extras:\n            return (\n                package_name,\n                url_no_extras,\n                Requirement(\"placeholder\" + extras.lower()).extras,\n            )\n        else:\n            return package_name, url_no_extras, None\n\n    for version_control in vcs:\n        if url.lower().startswith('%s:' % version_control):\n            url = '%s+%s' % (version_control, url)\n            break\n\n    if '+' not in url:\n        raise InstallationError(\n            '%s should either be a path to a local project or a VCS url '\n            'beginning with svn+, git+, hg+, or bzr+' %\n            editable_req\n        )\n\n    vc_type = url.split('+', 1)[0].lower()\n\n    if not vcs.get_backend(vc_type):\n        error_message = 'For --editable=%s only ' % editable_req + \\\n            ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \\\n            ' is currently supported'\n        raise InstallationError(error_message)\n\n    package_name = Link(url).egg_fragment\n    if not package_name:\n        raise InstallationError(\n            \"Could not detect requirement name for '%s', please specify one \"\n            \"with #egg=your_package_name\" % editable_req\n        )\n    return package_name, url, None\n\n\ndef deduce_helpful_msg(req):\n    \"\"\"Returns helpful msg in case requirements file does not exist,\n    or cannot be parsed.\n\n    :params req: Requirements file path\n    \"\"\"\n    msg = \"\"\n    if os.path.exists(req):\n        msg = \" It does exist.\"\n        # Try to parse and check if it is a requirements file.\n        try:\n            with open(req, 'r') as fp:\n                # parse first line only\n                next(parse_requirements(fp.read()))\n                msg += \" The argument you provided \" + \\\n                    \"(%s) appears to be a\" % (req) + \\\n                    \" requirements file. If that is the\" + \\\n                    \" case, use the '-r' flag to install\" + \\\n                    \" the packages specified within it.\"\n        except RequirementParseError:\n            logger.debug(\"Cannot parse '%s' as requirements \\\n            file\" % (req), exc_info=1)\n    else:\n        msg += \" File '%s' does not exist.\" % (req)\n    return msg\n\n\n# ---- The actual constructors follow ----\n\n\ndef install_req_from_editable(\n    editable_req, comes_from=None, isolated=False, options=None,\n    wheel_cache=None, constraint=False\n):\n    name, url, extras_override = parse_editable(editable_req)\n    if url.startswith('file:'):\n        source_dir = url_to_path(url)\n    else:\n        source_dir = None\n\n    if name is not None:\n        try:\n            req = Requirement(name)\n        except InvalidRequirement:\n            raise InstallationError(\"Invalid requirement: '%s'\" % name)\n    else:\n        req = None\n    return InstallRequirement(\n        req, comes_from, source_dir=source_dir,\n        editable=True,\n        link=Link(url),\n        constraint=constraint,\n        isolated=isolated,\n        options=options if options else {},\n        wheel_cache=wheel_cache,\n        extras=extras_override or (),\n    )\n\n\ndef install_req_from_line(\n    name, comes_from=None, isolated=False, options=None, wheel_cache=None,\n    constraint=False\n):\n    \"\"\"Creates an InstallRequirement from a name, which might be a\n    requirement, directory containing 'setup.py', filename, or URL.\n    \"\"\"\n    if is_url(name):\n        marker_sep = '; '\n    else:\n        marker_sep = ';'\n    if marker_sep in name:\n        name, markers = name.split(marker_sep, 1)\n        markers = markers.strip()\n        if not markers:\n            markers = None\n        else:\n            markers = Marker(markers)\n    else:\n        markers = None\n    name = name.strip()\n    req = None\n    path = os.path.normpath(os.path.abspath(name))\n    link = None\n    extras = None\n\n    if is_url(name):\n        link = Link(name)\n    else:\n        p, extras = _strip_extras(path)\n        looks_like_dir = os.path.isdir(p) and (\n            os.path.sep in name or\n            (os.path.altsep is not None and os.path.altsep in name) or\n            name.startswith('.')\n        )\n        if looks_like_dir:\n            if not is_installable_dir(p):\n                raise InstallationError(\n                    \"Directory %r is not installable. Neither 'setup.py' \"\n                    \"nor 'pyproject.toml' found.\" % name\n                )\n            link = Link(path_to_url(p))\n        elif is_archive_file(p):\n            if not os.path.isfile(p):\n                logger.warning(\n                    'Requirement %r looks like a filename, but the '\n                    'file does not exist',\n                    name\n                )\n            link = Link(path_to_url(p))\n\n    # it's a local file, dir, or url\n    if link:\n        # Handle relative file URLs\n        if link.scheme == 'file' and re.search(r'\\.\\./', link.url):\n            link = Link(\n                path_to_url(os.path.normpath(os.path.abspath(link.path))))\n        # wheel file\n        if link.is_wheel:\n            wheel = Wheel(link.filename)  # can raise InvalidWheelFilename\n            req = \"%s==%s\" % (wheel.name, wheel.version)\n        else:\n            # set the req to the egg fragment.  when it's not there, this\n            # will become an 'unnamed' requirement\n            req = link.egg_fragment\n\n    # a requirement specifier\n    else:\n        req = name\n\n    if extras:\n        extras = Requirement(\"placeholder\" + extras.lower()).extras\n    else:\n        extras = ()\n    if req is not None:\n        try:\n            req = Requirement(req)\n        except InvalidRequirement:\n            if os.path.sep in req:\n                add_msg = \"It looks like a path.\"\n                add_msg += deduce_helpful_msg(req)\n            elif '=' in req and not any(op in req for op in operators):\n                add_msg = \"= is not a valid operator. Did you mean == ?\"\n            else:\n                add_msg = \"\"\n            raise InstallationError(\n                \"Invalid requirement: '%s'\\n%s\" % (req, add_msg)\n            )\n\n    return InstallRequirement(\n        req, comes_from, link=link, markers=markers,\n        isolated=isolated,\n        options=options if options else {},\n        wheel_cache=wheel_cache,\n        constraint=constraint,\n        extras=extras,\n    )\n\n\ndef install_req_from_req(\n    req, comes_from=None, isolated=False, wheel_cache=None\n):\n    try:\n        req = Requirement(req)\n    except InvalidRequirement:\n        raise InstallationError(\"Invalid requirement: '%s'\" % req)\n\n    domains_not_allowed = [\n        PyPI.file_storage_domain,\n        TestPyPI.file_storage_domain,\n    ]\n    if req.url and comes_from.link.netloc in domains_not_allowed:\n        # Explicitly disallow pypi packages that depend on external urls\n        raise InstallationError(\n            \"Packages installed from PyPI cannot depend on packages \"\n            \"which are not also hosted on PyPI.\\n\"\n            \"%s depends on %s \" % (comes_from.name, req)\n        )\n\n    return InstallRequirement(\n        req, comes_from, isolated=isolated, wheel_cache=wheel_cache\n    )\n", "path": "src/pip/_internal/req/constructors.py"}]}