-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Support Direct URL editable requirements #13495
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
8850376
f241d83
71e5a12
ddfc4d5
d3e377c
8a4d049
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add support installing an editable requirement written as a Direct URL (``PackageName @ URL``). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,17 +86,25 @@ def _set_requirement_extras(req: Requirement, new_extras: set[str]) -> Requireme | |
| return get_requirement(f"{pre}{extras}{post}") | ||
|
|
||
|
|
||
| def parse_editable(editable_req: str) -> tuple[str | None, str, set[str]]: | ||
| """Parses an editable requirement into: | ||
| - a requirement name | ||
| - an URL | ||
| - extras | ||
| - editable options | ||
| Accepted requirements: | ||
| svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir | ||
| .[some_extra] | ||
| """ | ||
| def _parse_direct_url_editable(editable_req: str) -> tuple[str | None, str, set[str]]: | ||
| try: | ||
| req = Requirement(editable_req) | ||
| except InvalidRequirement: | ||
| pass | ||
| else: | ||
| if req.url: | ||
| # Join the marker back into the name part. This will be parsed out | ||
| # later into a Requirement again. | ||
| if req.marker: | ||
| name = f"{req.name} ; {req.marker}" | ||
| else: | ||
| name = req.name | ||
| return (name, req.url, req.extras) | ||
|
|
||
| raise ValueError | ||
|
|
||
|
|
||
| def _parse_pip_syntax_editable(editable_req: str) -> tuple[str | None, str, set[str]]: | ||
| url = editable_req | ||
|
|
||
| # If a file path is specified with extras, strip off the extras. | ||
|
|
@@ -122,23 +130,41 @@ def parse_editable(editable_req: str) -> tuple[str | None, str, set[str]]: | |
| url = f"{version_control}+{url}" | ||
| break | ||
|
|
||
| return Link(url).egg_fragment, url, set() | ||
|
|
||
|
|
||
| def parse_editable(editable_req: str) -> tuple[str | None, str, set[str]]: | ||
| """Parses an editable requirement into: | ||
| - a requirement name with environment markers | ||
| - an URL | ||
| - extras | ||
| Accepted requirements: | ||
| - svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir | ||
| - local_path[some_extra] | ||
| - Foobar[extra] @ svn+http://blahblah@rev#subdirectory=subdir ; markers | ||
| """ | ||
| try: | ||
| package_name, url, extras = _parse_direct_url_editable(editable_req) | ||
| except ValueError: | ||
| package_name, url, extras = _parse_pip_syntax_editable(editable_req) | ||
|
|
||
| link = Link(url) | ||
|
|
||
| if not link.is_vcs: | ||
| if not link.is_vcs and not link.url.startswith("file:"): | ||
| backends = ", ".join(vcs.all_schemes) | ||
| raise InstallationError( | ||
| f"{editable_req} is not a valid editable requirement. " | ||
| f"It should either be a path to a local project or a VCS URL " | ||
| f"(beginning with {backends})." | ||
| ) | ||
|
|
||
| package_name = link.egg_fragment | ||
| if not package_name: | ||
| # The project name can be inferred from local file URIs easily. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean with this comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the extraction of |
||
| if not package_name and not link.url.startswith("file:"): | ||
| raise InstallationError( | ||
| f"Could not detect requirement name for '{editable_req}', " | ||
| "please specify one with #egg=your_package_name" | ||
| "please specify one with your_package_name @ URL" | ||
| ) | ||
| return package_name, url, set() | ||
| return package_name, url, extras | ||
|
|
||
|
|
||
| def check_first_requirement_in_file(filename: str) -> None: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: it could be convenient to support
pkgname[extras] @ ./localdiras an alternative to./localdir[extras]. But that can be discussed separately.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not add extensions to standard requirement syntax, but yes, this would be a follow up.