This is an automated email from the ASF dual-hosted git repository.

shunping pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new 7052f01e45a Add an experiment to disable pip build isolation  (#37331)
7052f01e45a is described below

commit 7052f01e45a55507f5e5a9271296d2fd1da89c15
Author: Shunping Huang <[email protected]>
AuthorDate: Mon Feb 2 16:44:29 2026 -0500

    Add an experiment to disable pip build isolation  (#37331)
    
    * Disable build isolation for workflow tarball by default. Add an env var 
to enable it if needed.
    
    * Apply build isolation setting to all pip install commands. Use experiment 
to control.
    
    * Only search experiment in experiment options.
---
 sdks/python/container/boot.go    | 39 +++++++++++++++++++++++++++++++++++++++
 sdks/python/container/piputil.go | 14 ++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/sdks/python/container/boot.go b/sdks/python/container/boot.go
index 847325d4f83..572dbf01113 100644
--- a/sdks/python/container/boot.go
+++ b/sdks/python/container/boot.go
@@ -30,6 +30,7 @@ import (
        "os/signal"
        "path/filepath"
        "regexp"
+       "slices"
        "strings"
        "sync"
        "syscall"
@@ -116,6 +117,37 @@ func main() {
        }
 }
 
+// The json string of pipeline options is in the following format.
+// We only focus on experiments here.
+//
+//     {
+//              "display_data": [
+//                     {...},
+//              ],
+//              "options": {
+//                     ...
+//                       "experiments": [
+//                             ...
+//                      ],
+//              }
+//     }
+type PipelineOptionsData struct {
+       Options OptionsData `json:"options"`
+}
+
+type OptionsData struct {
+       Experiments []string `json:"experiments"`
+}
+
+func getExperiments(options string) []string {
+       var opts PipelineOptionsData
+       err := json.Unmarshal([]byte(options), &opts)
+       if err != nil {
+               return nil
+       }
+       return opts.Options.Experiments
+}
+
 func launchSDKProcess() error {
        ctx := grpcx.WriteWorkerID(context.Background(), *id)
 
@@ -155,6 +187,13 @@ func launchSDKProcess() error {
                logger.Fatalf(ctx, "Failed to convert pipeline options: %v", 
err)
        }
 
+       experiments := getExperiments(options)
+       pipNoBuildIsolation = false
+       if slices.Contains(experiments, "pip_no_build_isolation") {
+               pipNoBuildIsolation = true
+               logger.Printf(ctx, "Disabled build isolation when installing 
packages with pip")
+       }
+
        // (2) Retrieve and install the staged packages.
        //
        // No log.Fatalf() from here on, otherwise deferred cleanups will not 
be called!
diff --git a/sdks/python/container/piputil.go b/sdks/python/container/piputil.go
index d6250ad2fdc..1faf8421a02 100644
--- a/sdks/python/container/piputil.go
+++ b/sdks/python/container/piputil.go
@@ -32,6 +32,11 @@ import (
        "github.com/apache/beam/sdks/v2/go/pkg/beam/util/execx"
 )
 
+var (
+       // Whether to append "--no-build-isolation" flag to pip install command
+       pipNoBuildIsolation bool
+)
+
 const pipLogFlushInterval time.Duration = 15 * time.Second
 const unrecoverableURL string = 
"https://beam.apache.org/documentation/sdks/python-unrecoverable-errors/index.html#pip-dependency-resolution-failures";
 
@@ -112,6 +117,9 @@ func pipInstallPackage(ctx context.Context, logger 
*tools.Logger, files []string
                                // installed if necessary.  This achieves our 
goal outlined above.
                                args := []string{"-m", "pip", "install", 
"--no-cache-dir", "--disable-pip-version-check", "--upgrade", 
"--force-reinstall", "--no-deps",
                                        filepath.Join(dir, packageSpec)}
+                               if pipNoBuildIsolation {
+                                       args = append(args, 
"--no-build-isolation")
+                               }
                                err := execx.ExecuteEnvWithIO(nil, os.Stdin, 
bufLogger, bufLogger, pythonVersion, args...)
                                if err != nil {
                                        bufLogger.FlushAtError(ctx)
@@ -120,6 +128,9 @@ func pipInstallPackage(ctx context.Context, logger 
*tools.Logger, files []string
                                        bufLogger.FlushAtDebug(ctx)
                                }
                                args = []string{"-m", "pip", "install", 
"--no-cache-dir", "--disable-pip-version-check", filepath.Join(dir, 
packageSpec)}
+                               if pipNoBuildIsolation {
+                                       args = append(args, 
"--no-build-isolation")
+                               }
                                err = execx.ExecuteEnvWithIO(nil, os.Stdin, 
bufLogger, bufLogger, pythonVersion, args...)
                                if err != nil {
                                        bufLogger.FlushAtError(ctx)
@@ -131,6 +142,9 @@ func pipInstallPackage(ctx context.Context, logger 
*tools.Logger, files []string
 
                        // Case when we do not perform a forced reinstall.
                        args := []string{"-m", "pip", "install", 
"--no-cache-dir", "--disable-pip-version-check", filepath.Join(dir, 
packageSpec)}
+                       if pipNoBuildIsolation {
+                               args = append(args, "--no-build-isolation")
+                       }
                        err := execx.ExecuteEnvWithIO(nil, os.Stdin, bufLogger, 
bufLogger, pythonVersion, args...)
                        if err != nil {
                                bufLogger.FlushAtError(ctx)

Reply via email to