@@ -86,17 +86,25 @@ def _set_requirement_extras(req: Requirement, new_extras: set[str]) -> Requireme
8686    return  get_requirement (f"{ pre } { extras } { post }  )
8787
8888
89- def  parse_editable (editable_req : str ) ->  tuple [str  |  None , str , set [str ]]:
90-     """Parses an editable requirement into: 
91-         - a requirement name 
92-         - an URL 
93-         - extras 
94-         - editable options 
95-     Accepted requirements: 
96-         svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir 
97-         .[some_extra] 
98-     """ 
89+ def  _parse_direct_url_editable (editable_req : str ) ->  tuple [str  |  None , str , set [str ]]:
90+     try :
91+         req  =  Requirement (editable_req )
92+     except  InvalidRequirement :
93+         pass 
94+     else :
95+         if  req .url  and  "://"  in  req .url :
96+             # Join the marker back into the name part. This will be parsed out 
97+             # later into a Requirement again. 
98+             if  req .marker :
99+                 name  =  f"{ req .name } { req .marker }  
100+             else :
101+                 name  =  req .name 
102+             return  (name , req .url , req .extras )
103+ 
104+     raise  ValueError 
99105
106+ 
107+ def  _parse_pip_syntax_editable (editable_req : str ) ->  tuple [str  |  None , str , set [str ]]:
100108    url  =  editable_req 
101109
102110    # 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]]:
122130            url  =  f"{ version_control } { url }  
123131            break 
124132
133+     return  Link (url ).egg_fragment , url , set ()
134+ 
135+ 
136+ def  parse_editable (editable_req : str ) ->  tuple [str  |  None , str , set [str ]]:
137+     """Parses an editable requirement into: 
138+         - a requirement name 
139+         - an URL 
140+         - extras 
141+     Accepted requirements: 
142+         - svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir 
143+         - local_path[some_extra] 
144+         - Foobar[extra] @ svn+http://blahblah@rev#subdirectory=subdir ; markers 
145+     """ 
146+     try :
147+         package_name , url , extras  =  _parse_direct_url_editable (editable_req )
148+     except  ValueError :
149+         package_name , url , extras  =  _parse_pip_syntax_editable (editable_req )
150+ 
125151    link  =  Link (url )
126152
127-     if  not  link .is_vcs :
153+     if  not  link .is_vcs   and   not   link . is_file :
128154        backends  =  ", " .join (vcs .all_schemes )
129155        raise  InstallationError (
130156            f"{ editable_req }  
131157            f"It should either be a path to a local project or a VCS URL " 
132158            f"(beginning with { backends }  
133159        )
134160
135-     package_name   =   link . egg_fragment 
136-     if  not  package_name :
161+     # The project name can be inferred from local file URIs easily. 
162+     if  not  package_name   and   not   link . is_file :
137163        raise  InstallationError (
138164            f"Could not detect requirement name for '{ editable_req }  
139-             "please specify one with #egg= your_package_name" 
165+             "please specify one with your_package_name @ URL " 
140166        )
141-     return  package_name , url , set () 
167+     return  package_name , url , extras 
142168
143169
144170def  check_first_requirement_in_file (filename : str ) ->  None :
0 commit comments