88import urllib .request
99from pathlib import Path
1010from shutil import which
11- from typing import List , NoReturn , Optional
11+ from typing import List , NoReturn , Optional , Union
1212
1313from packaging .requirements import InvalidRequirement , Requirement
1414
4242 {app_lines}"""
4343
4444
45- def maybe_script_content (app : str , is_path : bool ) -> Optional [str ]:
45+ def maybe_script_content (app : str , is_path : bool ) -> Optional [Union [ str , Path ] ]:
4646 # If the app is a script, return its content.
4747 # Return None if it should be treated as a package name.
4848
4949 # Look for a local file first.
5050 app_path = Path (app )
5151 if app_path .is_file ():
52- return app_path . read_text ( encoding = "utf-8" )
52+ return app_path
5353 elif is_path :
5454 raise PipxError (f"The specified path { app } does not exist" )
5555
@@ -71,7 +71,7 @@ def maybe_script_content(app: str, is_path: bool) -> Optional[str]:
7171
7272
7373def run_script (
74- content : str ,
74+ content : Union [ str , Path ] ,
7575 app_args : List [str ],
7676 python : str ,
7777 pip_args : List [str ],
@@ -81,7 +81,7 @@ def run_script(
8181) -> NoReturn :
8282 requirements = _get_requirements_from_script (content )
8383 if requirements is None :
84- exec_app ([ python , "-c" , content , * app_args ] )
84+ python_path = Path ( python )
8585 else :
8686 # Note that the environment name is based on the identified
8787 # requirements, and *not* on the script name. This is deliberate, as
@@ -99,7 +99,12 @@ def run_script(
9999 venv = Venv (venv_dir , python = python , verbose = verbose )
100100 venv .create_venv (venv_args , pip_args )
101101 venv .install_unmanaged_packages (requirements , pip_args )
102- exec_app ([venv .python_path , "-c" , content , * app_args ])
102+ python_path = venv .python_path
103+
104+ if isinstance (content , Path ):
105+ exec_app ([python_path , content , * app_args ])
106+ else :
107+ exec_app ([python_path , "-c" , content , * app_args ])
103108
104109
105110def run_package (
@@ -323,11 +328,14 @@ def _http_get_request(url: str) -> str:
323328INLINE_SCRIPT_METADATA = re .compile (r"(?m)^# /// (?P<type>[a-zA-Z0-9-]+)$\s(?P<content>(^#(| .*)$\s)+)^# ///$" )
324329
325330
326- def _get_requirements_from_script (content : str ) -> Optional [List [str ]]:
331+ def _get_requirements_from_script (content : Union [ str , Path ] ) -> Optional [List [str ]]:
327332 """
328333 Supports inline script metadata.
329334 """
330335
336+ if isinstance (content , Path ):
337+ content = content .read_text (encoding = "utf-8" )
338+
331339 name = "script"
332340
333341 # Windows is currently getting un-normalized line endings, so normalize
0 commit comments