@@ -79,8 +79,8 @@ static DEFAULT_BACKEND: LazyLock<Pep517Backend> = LazyLock::new(|| Pep517Backend
79
79
pub enum Error {
80
80
#[ error( transparent) ]
81
81
Io ( #[ from] io:: Error ) ,
82
- #[ error( "Invalid source distribution: {0}" ) ]
83
- InvalidSourceDist ( String ) ,
82
+ #[ error( "{} does not appear to be a Python project, as neither `pyproject.toml` nor `setup.py` is present in the directory" , _0 . simplified_display ( ) ) ]
83
+ InvalidSourceDist ( PathBuf ) ,
84
84
#[ error( "Invalid `pyproject.toml`" ) ]
85
85
InvalidPyprojectToml ( #[ from] toml:: de:: Error ) ,
86
86
#[ error( "Editable installs with setup.py legacy builds are unsupported, please specify a build backend in pyproject.toml" ) ]
@@ -595,8 +595,7 @@ impl SourceBuild {
595
595
// We require either a `pyproject.toml` or a `setup.py` file at the top level.
596
596
if !source_tree. join ( "setup.py" ) . is_file ( ) {
597
597
return Err ( Box :: new ( Error :: InvalidSourceDist (
598
- "The archive contains neither a `pyproject.toml` nor a `setup.py` file at the top level"
599
- . to_string ( ) ,
598
+ source_tree. to_path_buf ( ) ,
600
599
) ) ) ;
601
600
}
602
601
@@ -723,7 +722,7 @@ impl SourceBuild {
723
722
#[ instrument( skip_all, fields( version_id = self . version_id) ) ]
724
723
pub async fn build_wheel ( & self , wheel_dir : & Path ) -> Result < String , Error > {
725
724
// The build scripts run with the extracted root as cwd, so they need the absolute path.
726
- let wheel_dir = fs :: canonicalize ( wheel_dir) ?;
725
+ let wheel_dir = std :: path :: absolute ( wheel_dir) ?;
727
726
728
727
// Prevent clashes from two uv processes building wheels in parallel.
729
728
let tmp_dir = tempdir_in ( & wheel_dir) ?;
@@ -737,86 +736,159 @@ impl SourceBuild {
737
736
Ok ( filename)
738
737
}
739
738
739
+ /// Perform a PEP 517 build for a wheel or source distribution (sdist).
740
740
async fn pep517_build (
741
741
& self ,
742
742
wheel_dir : & Path ,
743
743
pep517_backend : & Pep517Backend ,
744
744
) -> Result < String , Error > {
745
- let metadata_directory = self
746
- . metadata_directory
747
- . as_deref ( )
748
- . map_or ( "None" . to_string ( ) , |path| {
749
- format ! ( r#""{}""# , path. escape_for_python( ) )
750
- } ) ;
751
-
752
- // Write the hook output to a file so that we can read it back reliably.
753
- let outfile = self
754
- . temp_dir
755
- . path ( )
756
- . join ( format ! ( "build_{}.txt" , self . build_kind) ) ;
757
-
758
- debug ! (
759
- r#"Calling `{}.build_{}("{}", {}, {})`"# ,
760
- pep517_backend. backend,
761
- self . build_kind,
762
- wheel_dir. escape_for_python( ) ,
763
- self . config_settings. escape_for_python( ) ,
764
- metadata_directory,
765
- ) ;
766
- let script = formatdoc ! {
767
- r#"
768
- {}
745
+ match self . build_kind {
746
+ BuildKind :: Sdist => {
747
+ // Write the hook output to a file so that we can read it back reliably.
748
+ let outfile = self
749
+ . temp_dir
750
+ . path ( )
751
+ . join ( format ! ( "build_{}.txt" , self . build_kind) ) ;
752
+
753
+ debug ! (
754
+ r#"Calling `{}.build_{}("{}", {})`"# ,
755
+ pep517_backend. backend,
756
+ self . build_kind,
757
+ wheel_dir. escape_for_python( ) ,
758
+ self . config_settings. escape_for_python( ) ,
759
+ ) ;
760
+ let script = formatdoc ! {
761
+ r#"
762
+ {}
763
+
764
+ sdist_filename = backend.build_{}("{}", {})
765
+ with open("{}", "w") as fp:
766
+ fp.write(sdist_filename)
767
+ "# ,
768
+ pep517_backend. backend_import( ) ,
769
+ self . build_kind,
770
+ wheel_dir. escape_for_python( ) ,
771
+ self . config_settings. escape_for_python( ) ,
772
+ outfile. escape_for_python( )
773
+ } ;
774
+ let span = info_span ! (
775
+ "run_python_script" ,
776
+ script=format!( "build_{}" , self . build_kind) ,
777
+ python_version = %self . venv. interpreter( ) . python_version( )
778
+ ) ;
779
+ let output = self
780
+ . runner
781
+ . run_script (
782
+ & self . venv ,
783
+ & script,
784
+ & self . source_tree ,
785
+ & self . environment_variables ,
786
+ & self . modified_path ,
787
+ )
788
+ . instrument ( span)
789
+ . await ?;
790
+ if !output. status . success ( ) {
791
+ return Err ( Error :: from_command_output (
792
+ format ! (
793
+ "Build backend failed to build sdist through `build_{}()`" ,
794
+ self . build_kind
795
+ ) ,
796
+ & output,
797
+ & self . version_id ,
798
+ ) ) ;
799
+ }
769
800
770
- wheel_filename = backend.build_{}("{}", {}, {})
771
- with open("{}", "w") as fp:
772
- fp.write(wheel_filename)
773
- "# ,
774
- pep517_backend. backend_import( ) ,
775
- self . build_kind,
776
- wheel_dir. escape_for_python( ) ,
777
- self . config_settings. escape_for_python( ) ,
778
- metadata_directory,
779
- outfile. escape_for_python( )
780
- } ;
781
- let span = info_span ! (
782
- "run_python_script" ,
783
- script=format!( "build_{}" , self . build_kind) ,
784
- python_version = %self . venv. interpreter( ) . python_version( )
785
- ) ;
786
- let output = self
787
- . runner
788
- . run_script (
789
- & self . venv ,
790
- & script,
791
- & self . source_tree ,
792
- & self . environment_variables ,
793
- & self . modified_path ,
794
- )
795
- . instrument ( span)
796
- . await ?;
797
- if !output. status . success ( ) {
798
- return Err ( Error :: from_command_output (
799
- format ! (
800
- "Build backend failed to build wheel through `build_{}()`" ,
801
- self . build_kind
802
- ) ,
803
- & output,
804
- & self . version_id ,
805
- ) ) ;
806
- }
801
+ let distribution_filename = fs:: read_to_string ( & outfile) ?;
802
+ if !wheel_dir. join ( & distribution_filename) . is_file ( ) {
803
+ return Err ( Error :: from_command_output (
804
+ format ! (
805
+ "Build backend failed to produce sdist through `build_{}()`: `{distribution_filename}` not found" ,
806
+ self . build_kind
807
+ ) ,
808
+ & output,
809
+ & self . version_id ,
810
+ ) ) ;
811
+ }
812
+ Ok ( distribution_filename)
813
+ }
814
+ BuildKind :: Wheel | BuildKind :: Editable => {
815
+ let metadata_directory = self
816
+ . metadata_directory
817
+ . as_deref ( )
818
+ . map_or ( "None" . to_string ( ) , |path| {
819
+ format ! ( r#""{}""# , path. escape_for_python( ) )
820
+ } ) ;
821
+
822
+ // Write the hook output to a file so that we can read it back reliably.
823
+ let outfile = self
824
+ . temp_dir
825
+ . path ( )
826
+ . join ( format ! ( "build_{}.txt" , self . build_kind) ) ;
827
+
828
+ debug ! (
829
+ r#"Calling `{}.build_{}("{}", {}, {})`"# ,
830
+ pep517_backend. backend,
831
+ self . build_kind,
832
+ wheel_dir. escape_for_python( ) ,
833
+ self . config_settings. escape_for_python( ) ,
834
+ metadata_directory,
835
+ ) ;
836
+ let script = formatdoc ! {
837
+ r#"
838
+ {}
839
+
840
+ wheel_filename = backend.build_{}("{}", {}, {})
841
+ with open("{}", "w") as fp:
842
+ fp.write(wheel_filename)
843
+ "# ,
844
+ pep517_backend. backend_import( ) ,
845
+ self . build_kind,
846
+ wheel_dir. escape_for_python( ) ,
847
+ self . config_settings. escape_for_python( ) ,
848
+ metadata_directory,
849
+ outfile. escape_for_python( )
850
+ } ;
851
+ let span = info_span ! (
852
+ "run_python_script" ,
853
+ script=format!( "build_{}" , self . build_kind) ,
854
+ python_version = %self . venv. interpreter( ) . python_version( )
855
+ ) ;
856
+ let output = self
857
+ . runner
858
+ . run_script (
859
+ & self . venv ,
860
+ & script,
861
+ & self . source_tree ,
862
+ & self . environment_variables ,
863
+ & self . modified_path ,
864
+ )
865
+ . instrument ( span)
866
+ . await ?;
867
+ if !output. status . success ( ) {
868
+ return Err ( Error :: from_command_output (
869
+ format ! (
870
+ "Build backend failed to build wheel through `build_{}()`" ,
871
+ self . build_kind
872
+ ) ,
873
+ & output,
874
+ & self . version_id ,
875
+ ) ) ;
876
+ }
807
877
808
- let distribution_filename = fs:: read_to_string ( & outfile) ?;
809
- if !wheel_dir. join ( & distribution_filename) . is_file ( ) {
810
- return Err ( Error :: from_command_output (
811
- format ! (
812
- "Build backend failed to produce wheel through `build_{}()`: `{distribution_filename}` not found" ,
813
- self . build_kind
814
- ) ,
815
- & output,
816
- & self . version_id ,
817
- ) ) ;
878
+ let distribution_filename = fs:: read_to_string ( & outfile) ?;
879
+ if !wheel_dir. join ( & distribution_filename) . is_file ( ) {
880
+ return Err ( Error :: from_command_output (
881
+ format ! (
882
+ "Build backend failed to produce through `build_{}()`: `{distribution_filename}` not found" ,
883
+ self . build_kind
884
+ ) ,
885
+ & output,
886
+ & self . version_id ,
887
+ ) ) ;
888
+ }
889
+ Ok ( distribution_filename)
890
+ }
818
891
}
819
- Ok ( distribution_filename)
820
892
}
821
893
}
822
894
0 commit comments