aws-lambda-builders 1.57.0__tar.gz → 1.59.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. {aws_lambda_builders-1.57.0/aws_lambda_builders.egg-info → aws_lambda_builders-1.59.0}/PKG-INFO +5 -4
  2. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/__init__.py +1 -1
  3. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/builder.py +1 -1
  4. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/validator.py +2 -0
  5. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflow.py +1 -1
  6. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/DESIGN.md +45 -1
  7. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/actions.py +49 -0
  8. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/packager.py +53 -4
  9. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/workflow.py +29 -7
  10. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0/aws_lambda_builders.egg-info}/PKG-INFO +5 -4
  11. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders.egg-info/requires.txt +3 -3
  12. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/pyproject.toml +1 -1
  13. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/requirements/dev.txt +3 -3
  14. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/setup.py +1 -0
  15. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/LICENSE +0 -0
  16. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/MANIFEST.in +0 -0
  17. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/NOTICE +0 -0
  18. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/README.md +0 -0
  19. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/__main__.py +0 -0
  20. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/actions.py +0 -0
  21. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/architecture.py +0 -0
  22. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/binary_path.py +0 -0
  23. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/exceptions.py +0 -0
  24. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/path_resolver.py +0 -0
  25. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/registry.py +0 -0
  26. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/utils.py +0 -0
  27. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/__init__.py +0 -0
  28. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/DESIGN.md +0 -0
  29. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/__init__.py +0 -0
  30. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/actions.py +0 -0
  31. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/exceptions.py +0 -0
  32. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/make.py +0 -0
  33. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/utils.py +0 -0
  34. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/validator.py +0 -0
  35. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/custom_make/workflow.py +0 -0
  36. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/DESIGN.md +0 -0
  37. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/__init__.py +0 -0
  38. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/actions.py +0 -0
  39. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/dotnetcli.py +0 -0
  40. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/dotnetcli_resolver.py +0 -0
  41. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/utils.py +0 -0
  42. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/dotnet_clipackage/workflow.py +0 -0
  43. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/DESIGN.md +0 -0
  44. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/__init__.py +0 -0
  45. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/actions.py +0 -0
  46. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/builder.py +0 -0
  47. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/utils.py +0 -0
  48. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/validator.py +0 -0
  49. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/go_modules/workflow.py +0 -0
  50. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java/__init__.py +0 -0
  51. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java/actions.py +0 -0
  52. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java/utils.py +0 -0
  53. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/DESIGN.md +0 -0
  54. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/__init__.py +0 -0
  55. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/actions.py +0 -0
  56. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/gradle.py +0 -0
  57. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/gradle_resolver.py +0 -0
  58. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/gradle_validator.py +0 -0
  59. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/resources/lambda-build-init.gradle +0 -0
  60. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_gradle/workflow.py +0 -0
  61. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/DESIGN.md +0 -0
  62. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/__init__.py +0 -0
  63. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/actions.py +0 -0
  64. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/maven.py +0 -0
  65. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/maven_resolver.py +0 -0
  66. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/maven_validator.py +0 -0
  67. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/java_maven/workflow.py +0 -0
  68. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/DESIGN.md +0 -0
  69. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/__init__.py +0 -0
  70. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/actions.py +0 -0
  71. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/exceptions.py +0 -0
  72. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/npm.py +0 -0
  73. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/utils.py +0 -0
  74. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm/workflow.py +0 -0
  75. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/DESIGN.md +0 -0
  76. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/__init__.py +0 -0
  77. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/actions.py +0 -0
  78. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/esbuild.py +0 -0
  79. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/exceptions.py +0 -0
  80. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/nodejs_npm_esbuild/workflow.py +0 -0
  81. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/__init__.py +0 -0
  82. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/compat.py +0 -0
  83. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/exceptions.py +0 -0
  84. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/utils.py +0 -0
  85. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/python_pip/validator.py +0 -0
  86. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/ruby_bundler/DESIGN.md +0 -0
  87. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/ruby_bundler/__init__.py +0 -0
  88. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/ruby_bundler/actions.py +0 -0
  89. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/ruby_bundler/bundler.py +0 -0
  90. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/ruby_bundler/utils.py +0 -0
  91. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/ruby_bundler/workflow.py +0 -0
  92. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/DESIGN.md +0 -0
  93. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/__init__.py +0 -0
  94. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/actions.py +0 -0
  95. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/cargo_lambda.py +0 -0
  96. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/exceptions.py +0 -0
  97. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/feature_flag.py +0 -0
  98. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/utils.py +0 -0
  99. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders/workflows/rust_cargo/workflow.py +0 -0
  100. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders.egg-info/SOURCES.txt +0 -0
  101. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders.egg-info/dependency_links.txt +0 -0
  102. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders.egg-info/entry_points.txt +0 -0
  103. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/aws_lambda_builders.egg-info/top_level.txt +0 -0
  104. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/requirements/base.txt +0 -0
  105. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/requirements/python_pip.txt +0 -0
  106. {aws_lambda_builders-1.57.0 → aws_lambda_builders-1.59.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws_lambda_builders
3
- Version: 1.57.0
3
+ Version: 1.59.0
4
4
  Summary: Python library to compile, build & package AWS Lambda functions for several runtimes & frameworks.
5
5
  Home-page: https://github.com/awslabs/aws-lambda-builders
6
6
  Author: Amazon Web Services
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
23
  Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
24
25
  Classifier: Topic :: Internet
25
26
  Classifier: Topic :: Software Development :: Build Tools
26
27
  Classifier: Topic :: Utilities
@@ -30,15 +31,15 @@ License-File: NOTICE
30
31
  Requires-Dist: setuptools
31
32
  Requires-Dist: wheel
32
33
  Provides-Extra: dev
33
- Requires-Dist: coverage==7.9.2; python_version >= "3.9" and extra == "dev"
34
+ Requires-Dist: coverage==7.10.7; python_version >= "3.9" and extra == "dev"
34
35
  Requires-Dist: coverage==7.6.1; python_version < "3.9" and extra == "dev"
35
36
  Requires-Dist: flake8==3.8.4; extra == "dev"
36
- Requires-Dist: pytest-cov==6.2.1; python_version >= "3.9" and extra == "dev"
37
+ Requires-Dist: pytest-cov==6.3.0; python_version >= "3.9" and extra == "dev"
37
38
  Requires-Dist: pytest-cov==5.0.0; python_version < "3.9" and extra == "dev"
38
39
  Requires-Dist: pytest>=6.1.1; extra == "dev"
39
40
  Requires-Dist: parameterized==0.9.0; extra == "dev"
40
41
  Requires-Dist: pyelftools~=0.32; extra == "dev"
41
- Requires-Dist: black==25.1.0; python_version >= "3.9" and extra == "dev"
42
+ Requires-Dist: black==25.9.0; python_version >= "3.9" and extra == "dev"
42
43
  Requires-Dist: black==24.8.0; python_version < "3.9" and extra == "dev"
43
44
  Requires-Dist: ruff==0.11.13; extra == "dev"
44
45
  Dynamic: author
@@ -5,5 +5,5 @@ AWS Lambda Builder Library
5
5
  # Changing version will trigger a new release!
6
6
  # Please make the version change as the last step of your development.
7
7
 
8
- __version__ = "1.57.0"
8
+ __version__ = "1.59.0"
9
9
  RPC_PROTOCOL_VERSION = "0.3"
@@ -105,7 +105,7 @@ class LambdaBuilder(object):
105
105
 
106
106
  :type options: dict
107
107
  :param options:
108
- Optional dictionary of options ot pass to build action. **Not supported**.
108
+ Optional dictionary of options to pass to build action.
109
109
 
110
110
  :type executable_search_paths: list
111
111
  :param executable_search_paths:
@@ -20,6 +20,7 @@ SUPPORTED_RUNTIMES = {
20
20
  "python3.11": [ARM64, X86_64],
21
21
  "python3.12": [ARM64, X86_64],
22
22
  "python3.13": [ARM64, X86_64],
23
+ "python3.14": [ARM64, X86_64],
23
24
  "ruby3.2": [ARM64, X86_64],
24
25
  "ruby3.3": [ARM64, X86_64],
25
26
  "ruby3.4": [ARM64, X86_64],
@@ -27,6 +28,7 @@ SUPPORTED_RUNTIMES = {
27
28
  "java11": [ARM64, X86_64],
28
29
  "java17": [ARM64, X86_64],
29
30
  "java21": [ARM64, X86_64],
31
+ "java25": [ARM64, X86_64],
30
32
  "go1.x": [ARM64, X86_64],
31
33
  "dotnet6": [ARM64, X86_64],
32
34
  "dotnet8": [ARM64, X86_64],
@@ -227,7 +227,7 @@ class BaseWorkflow(object, metaclass=_WorkflowMetaClass):
227
227
  optimizations : dict, optional
228
228
  dictionary of optimization flags to pass to the build action. **Not supported**, by default None
229
229
  options : dict, optional
230
- dictionary of options ot pass to build action. **Not supported**., by default None
230
+ dictionary of options to pass to build action. By default None
231
231
  mode : str, optional
232
232
  Mode the build should produce, by default BuildMode.RELEASE
233
233
  download_dependencies: bool, optional
@@ -49,7 +49,7 @@ def build_dependencies(artifacts_dir_path,
49
49
 
50
50
  :type runtime: str
51
51
  :param runtime: Python version to build dependencies for. This can
52
- either be python3.8, python3.9, python3.10, python3.11, python3.12 or python3.13. These are
52
+ either be python3.8, python3.9, python3.10, python3.11, python3.12, python3.13 or python3.14. These are
53
53
  currently the only supported values.
54
54
 
55
55
  :type ui: :class:`lambda_builders.actions.python_pip.utils.UI`
@@ -147,3 +147,47 @@ bundle has an `__init__.py` and is on the `PYTHONPATH`.
147
147
  The dependencies should now be succesfully installed in the target directory.
148
148
  All the temporary/intermediate files can now be deleting including all the
149
149
  wheel files and sdists.
150
+
151
+ ### Configuring the builder
152
+
153
+ The Lambda builder supports the following optional sub-properties of the `aws_sam` configuration property.
154
+
155
+ #### `parent_python_packages`
156
+
157
+ `parent_python_packages` must be a string, corresponding to a dot-separated list of parent packages to create in the destination directory. This is useful when the source code has a package structure that needs to be preserved in the built artifacts.
158
+
159
+ For example, if your source code is structured like this:
160
+
161
+ ```
162
+ ├── app
163
+ | ├── main.py
164
+ | └── utils
165
+ | └── logger.py
166
+ └── tests
167
+ └── unit/test_handler.py
168
+ ```
169
+
170
+ Then the SAM build output will look like this:
171
+
172
+ ```
173
+ └── .aws-sam
174
+ └── build
175
+ └── AppLogicalId
176
+ ├── main.py
177
+ └── utils
178
+ └── logger.py
179
+ ```
180
+
181
+ The tests would break because `main.py` is importing `logger` as `from .utils import logger`, but the built artifacts would not have the `app` package.
182
+
183
+ To fix this, you can set the `parent_python_packages` property to `app` and the SAM build output will look like this:
184
+
185
+ ```
186
+ └── .aws-sam
187
+ └── build
188
+ └── AppLogicalId
189
+ └── app
190
+ ├── main.py
191
+ └── utils
192
+ └── logger.py
193
+ ```
@@ -3,6 +3,7 @@ Action to resolve Python dependencies using PIP
3
3
  """
4
4
 
5
5
  import logging
6
+ from pathlib import Path
6
7
  from typing import Optional, Tuple
7
8
 
8
9
  from aws_lambda_builders.actions import ActionFailedError, BaseAction, Purpose
@@ -21,6 +22,8 @@ from aws_lambda_builders.workflows.python_pip.utils import OSUtils
21
22
 
22
23
  LOG = logging.getLogger(__name__)
23
24
 
25
+ PARENT_PYTHON_PKGS_KEY = "parent_python_packages"
26
+
24
27
 
25
28
  class PythonPipBuildAction(BaseAction):
26
29
  NAME = "ResolveDependencies"
@@ -115,3 +118,49 @@ class PythonPipBuildAction(BaseAction):
115
118
  LOG.debug(f"Python runtime path '{python_path}' does not contain pip")
116
119
 
117
120
  raise ActionFailedError("Failed to find a Python runtime containing pip on the PATH.")
121
+
122
+
123
+ class PythonCreateParentPackagesAction(BaseAction):
124
+ NAME = "CreateParentPackages"
125
+ DESCRIPTION = "Creating parent Python packages"
126
+ PURPOSE = Purpose.COPY_SOURCE
127
+ LANGUAGE = "python"
128
+
129
+ def __init__(self, source_dir, dest_dir, options=None):
130
+ self.source_dir = source_dir
131
+ self.dest_dir = dest_dir
132
+ self.options = options or {}
133
+
134
+ def execute(self):
135
+ pkg_parts = self._get_parent_python_packages()
136
+ if not pkg_parts:
137
+ return
138
+
139
+ source_path = Path(self.source_dir)
140
+ dest_path = Path(self.dest_dir)
141
+
142
+ target_pkg_path = dest_path.joinpath(*pkg_parts)
143
+ try:
144
+ target_pkg_path.mkdir(parents=True, exist_ok=False)
145
+ except FileExistsError:
146
+ LOG.warning("Skipping creating package %s as it would overwrite existing folder", target_pkg_path)
147
+ return
148
+
149
+ for item in source_path.glob(pattern="*"):
150
+ if (dest_path / item.name).exists():
151
+ (dest_path / item.name).rename(target_pkg_path / item.name)
152
+ else:
153
+ LOG.debug(f"{item} does not exist in the build path, skipping.")
154
+
155
+ def _get_parent_python_packages(self) -> Optional[list]:
156
+ """
157
+ Returns the parent Python packages to be created.
158
+ """
159
+ if not isinstance(self.options, dict):
160
+ return None
161
+
162
+ parent_python_pkgs = self.options.get(PARENT_PYTHON_PKGS_KEY)
163
+ if isinstance(parent_python_pkgs, str) and len(parent_python_pkgs) > 0:
164
+ return parent_python_pkgs.split(".")
165
+
166
+ return None
@@ -88,6 +88,7 @@ def get_lambda_abi(runtime):
88
88
  "python3.11": "cp311",
89
89
  "python3.12": "cp312",
90
90
  "python3.13": "cp313",
91
+ "python3.14": "cp314",
91
92
  }
92
93
 
93
94
  if runtime not in supported:
@@ -102,8 +103,8 @@ class PythonPipDependencyBuilder(object):
102
103
 
103
104
  :type runtime: str
104
105
  :param runtime: Python version to build dependencies for. This can
105
- either be python3.8, python3.9, python3.10, python3.11, python3.12 or python3.13. These are currently the
106
- only supported values.
106
+ either be python3.8, python3.9, python3.10, python3.11, python3.12, python3.13 or python3.14.
107
+ These are currently the only supported values.
107
108
 
108
109
  :type osutils: :class:`lambda_builders.utils.OSUtils`
109
110
  :param osutils: A class used for all interactions with the
@@ -215,6 +216,7 @@ class DependencyBuilder(object):
215
216
  "cp311": (2, 26),
216
217
  "cp312": (2, 34),
217
218
  "cp313": (2, 34),
219
+ "cp314": (2, 34),
218
220
  }
219
221
  # Fallback version if we're on an unknown python version
220
222
  # not in _RUNTIME_GLIBC.
@@ -664,8 +666,22 @@ class SDistMetadataFetcher(object):
664
666
 
665
667
  def _get_pkg_info_filepath(self, package_dir):
666
668
  setup_py = self._osutils.joinpath(package_dir, "setup.py")
667
- script = self._SETUPTOOLS_SHIM % setup_py
668
669
 
670
+ # First, try to ensure setuptools is available for the subprocess
671
+ # In Python 3.12+, setuptools might not be available by default
672
+ try:
673
+ # Check if setuptools is available in the current environment
674
+ check_cmd = [self.python_exe, "-c", "import setuptools"]
675
+ result = subprocess.run(check_cmd, capture_output=True, timeout=10, check=False)
676
+ if result.returncode != 0:
677
+ LOG.debug(
678
+ "setuptools not available in Python environment. "
679
+ "PKG-INFO fallback will be used if setup.py fails."
680
+ )
681
+ except Exception as e:
682
+ LOG.debug("Could not check setuptools availability: %s", e)
683
+
684
+ script = self._SETUPTOOLS_SHIM % setup_py
669
685
  cmd = [self.python_exe, "-c", script, "--no-user-cfg", "egg_info", "--egg-base", "egg-info"]
670
686
  egg_info_dir = self._osutils.joinpath(package_dir, "egg-info")
671
687
  self._osutils.makedirs(egg_info_dir)
@@ -676,6 +692,13 @@ class SDistMetadataFetcher(object):
676
692
  info_contents = self._osutils.get_directory_contents(egg_info_dir)
677
693
  if p.returncode != 0:
678
694
  LOG.debug("Non zero rc (%s) from the setup.py egg_info command: %s", p.returncode, stderr)
695
+ # Check if the error is due to missing setuptools/distutils in Python 3.12+
696
+ if b"setuptools" in stderr or b"distutils" in stderr:
697
+ LOG.debug(
698
+ "Setup.py failed likely due to missing setuptools/distutils in Python 3.12+. "
699
+ "Trying fallback PKG-INFO."
700
+ )
701
+
679
702
  if info_contents:
680
703
  pkg_info_path = self._osutils.joinpath(egg_info_dir, info_contents[0], "PKG-INFO")
681
704
  else:
@@ -683,8 +706,34 @@ class SDistMetadataFetcher(object):
683
706
  # should be available right in the top level directory of the sdist
684
707
  # in the case where the egg_info command fails.
685
708
  pkg_info_path = self._get_fallback_pkg_info_filepath(package_dir)
709
+ LOG.debug("Using fallback PKG-INFO path: %s", pkg_info_path)
710
+
686
711
  if not self._osutils.file_exists(pkg_info_path):
687
- raise UnsupportedPackageError(self._osutils.basename(package_dir))
712
+ LOG.debug("PKG-INFO file not found at: %s", pkg_info_path)
713
+
714
+ # Look for any .egg-info directories that might already exist
715
+ try:
716
+ package_contents = self._osutils.get_directory_contents(package_dir)
717
+ for item in package_contents:
718
+ if item.endswith(".egg-info") and self._osutils.directory_exists(
719
+ self._osutils.joinpath(package_dir, item)
720
+ ):
721
+ potential_pkg_info = self._osutils.joinpath(package_dir, item, "PKG-INFO")
722
+ if self._osutils.file_exists(potential_pkg_info):
723
+ LOG.debug("Found PKG-INFO in existing .egg-info directory: %s", potential_pkg_info)
724
+ pkg_info_path = potential_pkg_info
725
+ break
726
+ except Exception as e:
727
+ LOG.debug("Error while searching for existing .egg-info directories: %s", e)
728
+
729
+ if not self._osutils.file_exists(pkg_info_path):
730
+ LOG.warning(
731
+ "Unable to find PKG-INFO file for package in %s. "
732
+ "This may be due to missing setuptools/distutils in Python 3.12+ "
733
+ "or an incomplete sdist package.",
734
+ package_dir,
735
+ )
736
+ raise UnsupportedPackageError(self._osutils.basename(package_dir))
688
737
  return pkg_info_path
689
738
 
690
739
  def _get_fallback_pkg_info_filepath(self, package_dir: str) -> str:
@@ -9,7 +9,7 @@ from aws_lambda_builders.path_resolver import PathResolver
9
9
  from aws_lambda_builders.workflow import BaseWorkflow, BuildDirectory, BuildInSourceSupport, Capability
10
10
  from aws_lambda_builders.workflows.python_pip.validator import PythonRuntimeValidator
11
11
 
12
- from .actions import PythonPipBuildAction
12
+ from .actions import PARENT_PYTHON_PKGS_KEY, PythonCreateParentPackagesAction, PythonPipBuildAction
13
13
  from .utils import OSUtils, is_experimental_build_improvements_enabled
14
14
 
15
15
  LOG = logging.getLogger(__name__)
@@ -87,15 +87,15 @@ class PythonPipWorkflow(BaseWorkflow):
87
87
  self.actions = []
88
88
  if not osutils.file_exists(manifest_path):
89
89
  LOG.warning("requirements.txt file not found. Continuing the build without dependencies.")
90
- self.actions.append(CopySourceAction(source_dir, artifacts_dir, excludes=self.EXCLUDED_FILES))
90
+ self._actions.append(CopySourceAction(source_dir, artifacts_dir, excludes=self.EXCLUDED_FILES))
91
91
  return
92
92
 
93
93
  # If a requirements.txt exists, run pip builder before copy action.
94
94
  if self.download_dependencies:
95
95
  if self.dependencies_dir:
96
96
  # clean up the dependencies folder before installing
97
- self.actions.append(CleanUpAction(self.dependencies_dir))
98
- self.actions.append(
97
+ self._actions.append(CleanUpAction(self.dependencies_dir))
98
+ self._actions.append(
99
99
  PythonPipBuildAction(
100
100
  artifacts_dir,
101
101
  scratch_dir,
@@ -113,11 +113,25 @@ class PythonPipWorkflow(BaseWorkflow):
113
113
  # when copying downloaded dependencies back to artifacts folder, don't exclude anything
114
114
  # symlinking python dependencies is disabled for now since it is breaking sam local commands
115
115
  if False and is_experimental_build_improvements_enabled(self.experimental_flags):
116
- self.actions.append(LinkSourceAction(self.dependencies_dir, artifacts_dir))
116
+ self._actions.append(LinkSourceAction(self.dependencies_dir, artifacts_dir))
117
117
  else:
118
- self.actions.append(CopySourceAction(self.dependencies_dir, artifacts_dir))
118
+ self._actions.append(CopySourceAction(self.dependencies_dir, artifacts_dir))
119
119
 
120
- self.actions.append(CopySourceAction(source_dir, artifacts_dir, excludes=self.EXCLUDED_FILES))
120
+ self._actions.append(CopySourceAction(source_dir, artifacts_dir, excludes=self.EXCLUDED_FILES))
121
+
122
+ @property
123
+ def actions(self):
124
+ """
125
+ Returns the list of actions to be executed in this workflow.
126
+ If required, creating the parent package(s) must be executed last.
127
+ """
128
+ if self._should_create_parent_packages():
129
+ return self._actions + [PythonCreateParentPackagesAction(self.source_dir, self.artifacts_dir, self.options)]
130
+ return self._actions
131
+
132
+ @actions.setter
133
+ def actions(self, value):
134
+ self._actions = value
121
135
 
122
136
  def get_resolvers(self):
123
137
  """
@@ -138,5 +152,13 @@ class PythonPipWorkflow(BaseWorkflow):
138
152
  major, _ = self.runtime.replace(self.CAPABILITY.language, "").split(".")
139
153
  return [f"{self.CAPABILITY.language}{major}"] if major == self.PYTHON_VERSION_THREE else None
140
154
 
155
+ def _should_create_parent_packages(self):
156
+ """
157
+ Determines if the parent package(s) should be created based on the options provided.
158
+ """
159
+ if isinstance(self.options, dict):
160
+ return PARENT_PYTHON_PKGS_KEY in self.options
161
+ return False
162
+
141
163
  def get_validators(self):
142
164
  return [PythonRuntimeValidator(runtime=self.runtime, architecture=self.architecture)]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws_lambda_builders
3
- Version: 1.57.0
3
+ Version: 1.59.0
4
4
  Summary: Python library to compile, build & package AWS Lambda functions for several runtimes & frameworks.
5
5
  Home-page: https://github.com/awslabs/aws-lambda-builders
6
6
  Author: Amazon Web Services
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
23
  Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
24
25
  Classifier: Topic :: Internet
25
26
  Classifier: Topic :: Software Development :: Build Tools
26
27
  Classifier: Topic :: Utilities
@@ -30,15 +31,15 @@ License-File: NOTICE
30
31
  Requires-Dist: setuptools
31
32
  Requires-Dist: wheel
32
33
  Provides-Extra: dev
33
- Requires-Dist: coverage==7.9.2; python_version >= "3.9" and extra == "dev"
34
+ Requires-Dist: coverage==7.10.7; python_version >= "3.9" and extra == "dev"
34
35
  Requires-Dist: coverage==7.6.1; python_version < "3.9" and extra == "dev"
35
36
  Requires-Dist: flake8==3.8.4; extra == "dev"
36
- Requires-Dist: pytest-cov==6.2.1; python_version >= "3.9" and extra == "dev"
37
+ Requires-Dist: pytest-cov==6.3.0; python_version >= "3.9" and extra == "dev"
37
38
  Requires-Dist: pytest-cov==5.0.0; python_version < "3.9" and extra == "dev"
38
39
  Requires-Dist: pytest>=6.1.1; extra == "dev"
39
40
  Requires-Dist: parameterized==0.9.0; extra == "dev"
40
41
  Requires-Dist: pyelftools~=0.32; extra == "dev"
41
- Requires-Dist: black==25.1.0; python_version >= "3.9" and extra == "dev"
42
+ Requires-Dist: black==25.9.0; python_version >= "3.9" and extra == "dev"
42
43
  Requires-Dist: black==24.8.0; python_version < "3.9" and extra == "dev"
43
44
  Requires-Dist: ruff==0.11.13; extra == "dev"
44
45
  Dynamic: author
@@ -14,6 +14,6 @@ pytest-cov==5.0.0
14
14
  black==24.8.0
15
15
 
16
16
  [dev:python_version >= "3.9"]
17
- coverage==7.9.2
18
- pytest-cov==6.2.1
19
- black==25.1.0
17
+ coverage==7.10.7
18
+ pytest-cov==6.3.0
19
+ black==25.9.0
@@ -9,7 +9,7 @@ select = [
9
9
  "PL", # pylint
10
10
  "I", # isort
11
11
  ]
12
- ignore = ["PLR0913"]
12
+ ignore = ["PLR0913", "PLC0415"]
13
13
 
14
14
  [tool.ruff.lint.pylint]
15
15
  max-branches = 13
@@ -1,7 +1,7 @@
1
- coverage==7.9.2; python_version>="3.9"
1
+ coverage==7.10.7; python_version>="3.9"
2
2
  coverage==7.6.1; python_version<"3.9"
3
3
  flake8==3.8.4
4
- pytest-cov==6.2.1; python_version>="3.9"
4
+ pytest-cov==6.3.0; python_version>="3.9"
5
5
  pytest-cov==5.0.0; python_version<"3.9"
6
6
 
7
7
  # Test requirements
@@ -10,6 +10,6 @@ parameterized==0.9.0
10
10
  pyelftools~=0.32 # Used to verify the generated Go binary architecture in integration tests (utils.py)
11
11
 
12
12
  # formatter
13
- black==25.1.0; python_version>="3.9"
13
+ black==25.9.0; python_version>="3.9"
14
14
  black==24.8.0; python_version<"3.9"
15
15
  ruff==0.11.13
@@ -64,6 +64,7 @@ setup(
64
64
  "Programming Language :: Python :: 3.11",
65
65
  "Programming Language :: Python :: 3.12",
66
66
  "Programming Language :: Python :: 3.13",
67
+ "Programming Language :: Python :: 3.14",
67
68
  "Topic :: Internet",
68
69
  "Topic :: Software Development :: Build Tools",
69
70
  "Topic :: Utilities",