Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement layout="zip" for Lambda/GCF, skipping lambdex #19022

Merged
merged 10 commits into from
May 20, 2023
Prev Previous commit
Next Next commit
refactor: track module/func separately in ResolvedPythonFaaSHandler
  • Loading branch information
huonw committed May 17, 2023
commit 6ff0d4866e91a6d90ee9f62997b56402a2ad39f7
14 changes: 7 additions & 7 deletions src/python/pants/backend/python/util_rules/faas.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def filespec(self) -> Filespec:

@dataclass(frozen=True)
class ResolvedPythonFaaSHandler:
val: str
module: str
func: str
file_name_used: bool


Expand All @@ -118,7 +119,7 @@ async def resolve_python_faas_handler(
# If it's already a module, simply use that. Otherwise, convert the file name into a module
# path.
if not path.endswith(".py"):
return ResolvedPythonFaaSHandler(handler_val, file_name_used=False)
return ResolvedPythonFaaSHandler(module=path, func=func, file_name_used=False)

# Use the engine to validate that the file exists and that it resolves to only one file.
full_glob = os.path.join(address.spec_path, path)
Expand Down Expand Up @@ -147,7 +148,7 @@ async def resolve_python_faas_handler(
stripped_source_path = os.path.relpath(handler_path, source_root.path)
module_base, _ = os.path.splitext(stripped_source_path)
normalized_path = module_base.replace(os.path.sep, ".")
return ResolvedPythonFaaSHandler(f"{normalized_path}:{func}", file_name_used=True)
return ResolvedPythonFaaSHandler(module=normalized_path, func=func, file_name_used=True)


class PythonFaaSDependencies(Dependencies):
Expand Down Expand Up @@ -187,7 +188,6 @@ async def infer_faas_handler_dependency(
ResolvePythonFaaSHandlerRequest(request.field_set.handler),
),
)
module, _, _func = handler.val.partition(":")

# Only set locality if needed, to avoid unnecessary rule graph memoization misses.
# When set, use the source root, which is useful in practice, but incurs fewer memoization
Expand All @@ -202,7 +202,7 @@ async def infer_faas_handler_dependency(
owners = await Get(
PythonModuleOwners,
PythonModuleOwnersRequest(
module,
handler.module,
resolve=request.field_set.resolve.normalized_value(python_setup),
locality=locality,
),
Expand All @@ -218,7 +218,7 @@ async def infer_faas_handler_dependency(
context=(
f"The target {address} has the field "
f"`handler={repr(request.field_set.handler.value)}`, which maps "
f"to the Python module `{module}`"
f"to the Python module `{handler.module}`"
),
)
maybe_disambiguated = explicitly_provided_deps.disambiguated(
Expand Down Expand Up @@ -359,7 +359,7 @@ async def build_lambdex(
f"\n\nFiles targets dependencies: {files_addresses}"
)

lambdex_args = ["build", "-e", handler.val, output_filename]
lambdex_args = ["build", "-e", f"{handler.module}:{handler.func}", output_filename]
if request.script_handler:
lambdex_args.extend(("-H", request.script_handler))
if request.script_module:
Expand Down
23 changes: 17 additions & 6 deletions src/python/pants/backend/python/util_rules/faas_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ def test_handler_filespec(handler: str, expected: List[str]) -> None:


def test_resolve_handler(rule_runner: RuleRunner) -> None:
def assert_resolved(handler: str, *, expected: str, is_file: bool) -> None:
def assert_resolved(
handler: str, *, expected_module: str, expected_func: str, is_file: bool
) -> None:
addr = Address("src/python/project")
rule_runner.write_files(
{"src/python/project/lambda.py": "", "src/python/project/f2.py": ""}
Expand All @@ -75,17 +77,26 @@ def assert_resolved(handler: str, *, expected: str, is_file: bool) -> None:
result = rule_runner.request(
ResolvedPythonFaaSHandler, [ResolvePythonFaaSHandlerRequest(field)]
)
assert result.val == expected
assert result.module == expected_module
assert result.func == expected_func
assert result.file_name_used == is_file

assert_resolved("path.to.lambda:func", expected="path.to.lambda:func", is_file=False)
assert_resolved("lambda.py:func", expected="project.lambda:func", is_file=True)
assert_resolved(
"path.to.lambda:func", expected_module="path.to.lambda", expected_func="func", is_file=False
)
assert_resolved(
"lambda.py:func", expected_module="project.lambda", expected_func="func", is_file=True
)

with engine_error(contains="Unmatched glob"):
assert_resolved("doesnt_exist.py:func", expected="doesnt matter", is_file=True)
assert_resolved(
"doesnt_exist.py:func", expected_module="doesnt matter", expected_func="", is_file=True
)
# Resolving >1 file is an error.
with engine_error(InvalidFieldException):
assert_resolved("*.py:func", expected="doesnt matter", is_file=True)
assert_resolved(
"*.py:func", expected_module="doesnt matter", expected_func="", is_file=True
)


def test_infer_handler_dependency(rule_runner: RuleRunner, caplog) -> None:
Expand Down