Merge "Add flag to not add directory of entrypoint to sys.path"

This commit is contained in:
Cole Faust
2022-09-26 22:42:21 +00:00
committed by Gerrit Code Review
6 changed files with 96 additions and 16 deletions

View File

@@ -124,6 +124,14 @@ type BinaryProperties struct {
// to support it. When using embedded_launcher: true, this is already the
// behavior. The default is currently false.
Dont_add_top_level_directories_to_path *bool
// Setting this to true will mimic Python 3.11+'s PYTHON_SAFE_PATH environment
// variable or -P flag, even on older python versions. This is a temporary
// flag while modules are changed to support it, eventually true will be the
// default and the flag will be removed. The default is currently false. It
// is only applicable when embedded_launcher is false, when embedded_launcher
// is true this is already implied.
Dont_add_entrypoint_folder_to_path *bool
}
type binaryDecorator struct {
@@ -185,11 +193,12 @@ func (binary *binaryDecorator) bootstrap(ctx android.ModuleContext, actualVersio
}
addTopDirectoriesToPath := !proptools.BoolDefault(binary.binaryProperties.Dont_add_top_level_directories_to_path, false)
dontAddEntrypointFolderToPath := proptools.BoolDefault(binary.binaryProperties.Dont_add_entrypoint_folder_to_path, false)
binFile := registerBuildActionForParFile(ctx, embeddedLauncher, launcherPath,
binary.getHostInterpreterName(ctx, actualVersion),
main, binary.getStem(ctx), append(android.Paths{srcsZip}, depsSrcsZips...),
addTopDirectoriesToPath)
addTopDirectoriesToPath, dontAddEntrypointFolderToPath)
return android.OptionalPathForPath(binFile)
}

View File

@@ -20,7 +20,6 @@ import (
"strings"
"android/soong/android"
"github.com/google/blueprint"
_ "github.com/google/blueprint/bootstrap"
)
@@ -52,13 +51,25 @@ var (
},
"interp", "main", "srcsZips", "addTopDirectoriesToPath")
hostParWithoutAddingEntrypointFolderToPath = pctx.AndroidStaticRule("hostParWithoutAddingEntrypointFolderToPath",
blueprint.RuleParams{
Command: `sed -e 's/%interpreter%/$interp/g' -e 's/%main%/__soong_entrypoint_redirector__.py/g' -e 's/ADD_TOP_DIRECTORIES_TO_PATH/$addTopDirectoriesToPath/g' build/soong/python/scripts/stub_template_host.txt > $out.main && ` +
"sed -e 's/ENTRY_POINT/$main/g' build/soong/python/scripts/main_non_embedded.py >`dirname $out`/__soong_entrypoint_redirector__.py && " +
"$parCmd -o $out.entrypoint_zip -C `dirname $out` -f `dirname $out`/__soong_entrypoint_redirector__.py && " +
`echo "#!/usr/bin/env $interp" >${out}.prefix &&` +
`$mergeParCmd -p --prefix ${out}.prefix -pm $out.main $out $srcsZips $out.entrypoint_zip && ` +
"chmod +x $out && (rm -f $out.main; rm -f ${out}.prefix; rm -f $out.entrypoint_zip; rm -f `dirname $out`/__soong_entrypoint_redirector__.py)",
CommandDeps: []string{"$mergeParCmd", "$parCmd", "build/soong/python/scripts/stub_template_host.txt", "build/soong/python/scripts/main_non_embedded.py"},
},
"interp", "main", "srcsZips", "addTopDirectoriesToPath")
embeddedPar = pctx.AndroidStaticRule("embeddedPar",
blueprint.RuleParams{
Command: `rm -f $out.main && ` +
`sed 's/ENTRY_POINT/$main/' build/soong/python/scripts/main.py >$out.main &&` +
`$mergeParCmd -p -pm $out.main --prefix $launcher $out $srcsZips && ` +
`chmod +x $out && rm -rf $out.main`,
CommandDeps: []string{"$mergeParCmd", "$parCmd", "build/soong/python/scripts/main.py"},
CommandDeps: []string{"$mergeParCmd", "build/soong/python/scripts/main.py"},
},
"main", "srcsZips", "launcher")
@@ -81,7 +92,7 @@ func init() {
func registerBuildActionForParFile(ctx android.ModuleContext, embeddedLauncher bool,
launcherPath android.OptionalPath, interpreter, main, binName string,
srcsZips android.Paths, addTopDirectoriesToPath bool) android.Path {
srcsZips android.Paths, addTopDirectoriesToPath bool, dontAddEntrypointFolderToPath bool) android.Path {
// .intermediate output path for bin executable.
binFile := android.PathForModuleOut(ctx, binName)
@@ -94,18 +105,33 @@ func registerBuildActionForParFile(ctx android.ModuleContext, embeddedLauncher b
if addTopDirectoriesToPath {
addDirsString = "True"
}
ctx.Build(pctx, android.BuildParams{
Rule: hostPar,
Description: "host python archive",
Output: binFile,
Implicits: implicits,
Args: map[string]string{
"interp": strings.Replace(interpreter, "/", `\/`, -1),
"main": strings.Replace(main, "/", `\/`, -1),
"srcsZips": strings.Join(srcsZips.Strings(), " "),
"addTopDirectoriesToPath": addDirsString,
},
})
if dontAddEntrypointFolderToPath {
ctx.Build(pctx, android.BuildParams{
Rule: hostParWithoutAddingEntrypointFolderToPath,
Description: "host python archive",
Output: binFile,
Implicits: implicits,
Args: map[string]string{
"interp": strings.Replace(interpreter, "/", `\/`, -1),
"main": strings.Replace(strings.TrimSuffix(main, pyExt), "/", ".", -1),
"srcsZips": strings.Join(srcsZips.Strings(), " "),
"addTopDirectoriesToPath": addDirsString,
},
})
} else {
ctx.Build(pctx, android.BuildParams{
Rule: hostPar,
Description: "host python archive",
Output: binFile,
Implicits: implicits,
Args: map[string]string{
"interp": strings.Replace(interpreter, "/", `\/`, -1),
"main": strings.Replace(main, "/", `\/`, -1),
"srcsZips": strings.Join(srcsZips.Strings(), " "),
"addTopDirectoriesToPath": addDirsString,
},
})
}
} else if launcherPath.Valid() {
// added launcherPath to the implicits Ninja dependencies.
implicits = append(implicits, launcherPath.Path())

View File

@@ -0,0 +1,6 @@
import runpy
# The purpose of this file is to implement python 3.11+'s
# PYTHON_SAFE_PATH / -P option on older python versions.
runpy._run_module_as_main("ENTRY_POINT", alter_argv=False)

View File

@@ -0,0 +1,24 @@
python_test_host {
name: "py_dont_import_folder_of_entrypoint_test",
main: "mypkg/main.py",
srcs: [
"mypkg/main.py",
"mypkg/mymodule.py",
],
dont_add_entrypoint_folder_to_path: true,
dont_add_top_level_directories_to_path: true,
}
python_test_host {
name: "py_dont_import_folder_of_entrypoint_test_embedded_launcher",
main: "mypkg/main.py",
srcs: [
"mypkg/main.py",
"mypkg/mymodule.py",
],
version: {
py3: {
embedded_launcher: true,
},
},
}

View File

@@ -0,0 +1,15 @@
import unittest
import sys
class TestProtoWithPkgPath(unittest.TestCase):
def test_cant_import_mymodule_directly(self):
with self.assertRaises(ImportError):
import mymodule
def test_can_import_mymodule_by_parent_package(self):
import mypkg.mymodule
if __name__ == '__main__':
unittest.main()