mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-10-29 19:17:26 +00:00 
			
		
		
		
	uv run supports python package (#7281)
				
					
				
			## Summary Allow `uv run ./package` runs a Python package with a `__main__.py` script. Resolves #7275
This commit is contained in:
		
							parent
							
								
									77d278f68a
								
							
						
					
					
						commit
						38c7c5fdd1
					
				
					 2 changed files with 31 additions and 3 deletions
				
			
		|  | @ -777,6 +777,8 @@ pub(crate) enum RunCommand { | ||||||
|     PythonScript(PathBuf, Vec<OsString>), |     PythonScript(PathBuf, Vec<OsString>), | ||||||
|     /// Execute a `pythonw` script (Windows only).
 |     /// Execute a `pythonw` script (Windows only).
 | ||||||
|     PythonGuiScript(PathBuf, Vec<OsString>), |     PythonGuiScript(PathBuf, Vec<OsString>), | ||||||
|  |     /// Execute a Python package containing a `__main__.py` file.
 | ||||||
|  |     PythonPackage(PathBuf, Vec<OsString>), | ||||||
|     /// Execute a `python` script provided via `stdin`.
 |     /// Execute a `python` script provided via `stdin`.
 | ||||||
|     PythonStdin(Vec<u8>), |     PythonStdin(Vec<u8>), | ||||||
|     /// Execute an external command.
 |     /// Execute an external command.
 | ||||||
|  | @ -790,7 +792,9 @@ impl RunCommand { | ||||||
|     fn display_executable(&self) -> Cow<'_, str> { |     fn display_executable(&self) -> Cow<'_, str> { | ||||||
|         match self { |         match self { | ||||||
|             Self::Python(_) => Cow::Borrowed("python"), |             Self::Python(_) => Cow::Borrowed("python"), | ||||||
|             Self::PythonScript(_, _) | Self::Empty => Cow::Borrowed("python"), |             Self::PythonScript(_, _) | Self::PythonPackage(_, _) | Self::Empty => { | ||||||
|  |                 Cow::Borrowed("python") | ||||||
|  |             } | ||||||
|             Self::PythonGuiScript(_, _) => Cow::Borrowed("pythonw"), |             Self::PythonGuiScript(_, _) => Cow::Borrowed("pythonw"), | ||||||
|             Self::PythonStdin(_) => Cow::Borrowed("python -c"), |             Self::PythonStdin(_) => Cow::Borrowed("python -c"), | ||||||
|             Self::External(executable, _) => executable.to_string_lossy(), |             Self::External(executable, _) => executable.to_string_lossy(), | ||||||
|  | @ -805,7 +809,7 @@ impl RunCommand { | ||||||
|                 process.args(args); |                 process.args(args); | ||||||
|                 process |                 process | ||||||
|             } |             } | ||||||
|             Self::PythonScript(target, args) => { |             Self::PythonScript(target, args) | Self::PythonPackage(target, args) => { | ||||||
|                 let mut process = Command::new(interpreter.sys_executable()); |                 let mut process = Command::new(interpreter.sys_executable()); | ||||||
|                 process.arg(target); |                 process.arg(target); | ||||||
|                 process.args(args); |                 process.args(args); | ||||||
|  | @ -868,7 +872,7 @@ impl std::fmt::Display for RunCommand { | ||||||
|                 } |                 } | ||||||
|                 Ok(()) |                 Ok(()) | ||||||
|             } |             } | ||||||
|             Self::PythonScript(target, args) => { |             Self::PythonScript(target, args) | Self::PythonPackage(target, args) => { | ||||||
|                 write!(f, "python {}", target.display())?; |                 write!(f, "python {}", target.display())?; | ||||||
|                 for arg in args { |                 for arg in args { | ||||||
|                     write!(f, " {}", arg.to_string_lossy())?; |                     write!(f, " {}", arg.to_string_lossy())?; | ||||||
|  | @ -931,6 +935,8 @@ impl TryFrom<&ExternalCommand> for RunCommand { | ||||||
|             && target_path.exists() |             && target_path.exists() | ||||||
|         { |         { | ||||||
|             Ok(Self::PythonGuiScript(target_path, args.to_vec())) |             Ok(Self::PythonGuiScript(target_path, args.to_vec())) | ||||||
|  |         } else if target_path.is_dir() && target_path.join("__main__.py").exists() { | ||||||
|  |             Ok(Self::PythonPackage(target_path, args.to_vec())) | ||||||
|         } else { |         } else { | ||||||
|             Ok(Self::External( |             Ok(Self::External( | ||||||
|                 target.clone(), |                 target.clone(), | ||||||
|  |  | ||||||
|  | @ -1634,6 +1634,28 @@ fn run_stdin() -> Result<()> { | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[test] | ||||||
|  | fn run_package() -> Result<()> { | ||||||
|  |     let context = TestContext::new("3.12"); | ||||||
|  | 
 | ||||||
|  |     let main_script = context.temp_dir.child("__main__.py"); | ||||||
|  |     main_script.write_str(indoc! { r#" | ||||||
|  |         print("Hello, world!") | ||||||
|  |        "#
 | ||||||
|  |     })?; | ||||||
|  | 
 | ||||||
|  |     uv_snapshot!(context.filters(), context.run().arg("."), @r###" | ||||||
|  |     success: true | ||||||
|  |     exit_code: 0 | ||||||
|  |     ----- stdout ----- | ||||||
|  |     Hello, world! | ||||||
|  | 
 | ||||||
|  |     ----- stderr ----- | ||||||
|  |     "###);
 | ||||||
|  | 
 | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// When the `pyproject.toml` file is invalid.
 | /// When the `pyproject.toml` file is invalid.
 | ||||||
| #[test] | #[test] | ||||||
| fn run_project_toml_error() -> Result<()> { | fn run_project_toml_error() -> Result<()> { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jo
						Jo