localstack-core 4.6.1.dev60__py3-none-any.whl → 4.10.1.dev12__py3-none-any.whl

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 (672) hide show
  1. localstack/aws/api/apigateway/__init__.py +87 -110
  2. localstack/aws/api/cloudformation/__init__.py +18 -4
  3. localstack/aws/api/cloudwatch/__init__.py +41 -1
  4. localstack/aws/api/config/__init__.py +4 -0
  5. localstack/aws/api/core.py +8 -5
  6. localstack/aws/api/dynamodb/__init__.py +30 -0
  7. localstack/aws/api/ec2/__init__.py +1545 -66
  8. localstack/aws/api/events/__init__.py +12 -16
  9. localstack/aws/api/iam/__init__.py +7 -0
  10. localstack/aws/api/kinesis/__init__.py +19 -0
  11. localstack/aws/api/kms/__init__.py +6 -0
  12. localstack/aws/api/lambda_/__init__.py +36 -23
  13. localstack/aws/api/logs/__init__.py +20 -8
  14. localstack/aws/api/opensearch/__init__.py +16 -0
  15. localstack/aws/api/pipes/__init__.py +24 -32
  16. localstack/aws/api/redshift/__init__.py +9 -3
  17. localstack/aws/api/route53/__init__.py +5 -0
  18. localstack/aws/api/s3/__init__.py +12 -0
  19. localstack/aws/api/s3control/__init__.py +56 -0
  20. localstack/aws/api/scheduler/__init__.py +14 -16
  21. localstack/aws/api/ssm/__init__.py +2 -0
  22. localstack/aws/api/stepfunctions/__init__.py +88 -114
  23. localstack/aws/api/support/__init__.py +8 -9
  24. localstack/aws/api/transcribe/__init__.py +17 -0
  25. localstack/aws/chain.py +2 -2
  26. localstack/aws/client.py +14 -11
  27. localstack/aws/connect.py +42 -41
  28. localstack/aws/forwarder.py +57 -9
  29. localstack/aws/gateway.py +1 -3
  30. localstack/aws/handlers/analytics.py +2 -3
  31. localstack/aws/handlers/cors.py +4 -5
  32. localstack/aws/handlers/internal_requests.py +6 -1
  33. localstack/aws/handlers/logging.py +13 -4
  34. localstack/aws/handlers/metric_handler.py +44 -5
  35. localstack/aws/handlers/service.py +48 -28
  36. localstack/aws/mocking.py +18 -27
  37. localstack/aws/patches.py +2 -2
  38. localstack/aws/protocol/op_router.py +11 -10
  39. localstack/aws/protocol/parser.py +475 -49
  40. localstack/aws/protocol/serializer.py +723 -106
  41. localstack/aws/protocol/service_router.py +133 -33
  42. localstack/aws/protocol/validate.py +6 -6
  43. localstack/aws/scaffold.py +9 -10
  44. localstack/aws/serving/edge.py +5 -6
  45. localstack/aws/serving/hypercorn.py +2 -2
  46. localstack/aws/serving/twisted.py +1 -2
  47. localstack/aws/serving/werkzeug.py +2 -2
  48. localstack/aws/skeleton.py +12 -11
  49. localstack/aws/spec-patches.json +58 -0
  50. localstack/aws/spec.py +66 -46
  51. localstack/cli/exceptions.py +1 -1
  52. localstack/cli/localstack.py +11 -11
  53. localstack/cli/lpm.py +4 -5
  54. localstack/cli/plugins.py +1 -1
  55. localstack/cli/profiles.py +1 -2
  56. localstack/config.py +44 -30
  57. localstack/constants.py +4 -29
  58. localstack/deprecations.py +5 -5
  59. localstack/dev/kubernetes/__main__.py +130 -7
  60. localstack/dev/run/__main__.py +5 -5
  61. localstack/dev/run/configurators.py +1 -4
  62. localstack/dev/run/paths.py +6 -6
  63. localstack/dns/models.py +2 -1
  64. localstack/dns/plugins.py +5 -1
  65. localstack/dns/server.py +16 -6
  66. localstack/http/dispatcher.py +1 -2
  67. localstack/http/response.py +2 -2
  68. localstack/http/router.py +1 -1
  69. localstack/http/trace.py +2 -1
  70. localstack/logging/format.py +6 -6
  71. localstack/packages/api.py +13 -12
  72. localstack/packages/core.py +4 -4
  73. localstack/packages/debugpy.py +1 -3
  74. localstack/packages/ffmpeg.py +1 -2
  75. localstack/packages/java.py +38 -12
  76. localstack/packages/plugins.py +0 -8
  77. localstack/runtime/analytics.py +3 -0
  78. localstack/runtime/hooks.py +1 -1
  79. localstack/runtime/init.py +8 -9
  80. localstack/runtime/main.py +5 -5
  81. localstack/runtime/patches.py +2 -2
  82. localstack/runtime/shutdown.py +2 -1
  83. localstack/services/apigateway/exporter.py +1 -2
  84. localstack/services/apigateway/helpers.py +7 -10
  85. localstack/services/apigateway/legacy/context.py +21 -21
  86. localstack/services/apigateway/legacy/helpers.py +27 -28
  87. localstack/services/apigateway/legacy/integration.py +11 -10
  88. localstack/services/apigateway/legacy/invocations.py +6 -5
  89. localstack/services/apigateway/legacy/provider.py +148 -68
  90. localstack/services/apigateway/legacy/router_asf.py +2 -2
  91. localstack/services/apigateway/legacy/templates.py +6 -6
  92. localstack/services/apigateway/models.py +16 -16
  93. localstack/services/apigateway/next_gen/execute_api/api.py +2 -2
  94. localstack/services/apigateway/next_gen/execute_api/context.py +25 -25
  95. localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py +2 -5
  96. localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
  97. localstack/services/apigateway/next_gen/execute_api/handlers/parse.py +1 -2
  98. localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +2 -3
  99. localstack/services/apigateway/next_gen/execute_api/header_utils.py +1 -1
  100. localstack/services/apigateway/next_gen/execute_api/helpers.py +2 -2
  101. localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +9 -6
  102. localstack/services/apigateway/next_gen/execute_api/integrations/http.py +12 -12
  103. localstack/services/apigateway/next_gen/execute_api/router.py +31 -0
  104. localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
  105. localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
  106. localstack/services/apigateway/next_gen/execute_api/variables.py +63 -63
  107. localstack/services/apigateway/next_gen/provider.py +5 -0
  108. localstack/services/apigateway/resource_providers/aws_apigateway_account.py +3 -3
  109. localstack/services/apigateway/resource_providers/aws_apigateway_account_plugin.py +1 -3
  110. localstack/services/apigateway/resource_providers/aws_apigateway_apikey.py +14 -14
  111. localstack/services/apigateway/resource_providers/aws_apigateway_apikey_plugin.py +1 -3
  112. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping.py +5 -5
  113. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping_plugin.py +1 -3
  114. localstack/services/apigateway/resource_providers/aws_apigateway_deployment.py +46 -46
  115. localstack/services/apigateway/resource_providers/aws_apigateway_deployment_plugin.py +1 -3
  116. localstack/services/apigateway/resource_providers/aws_apigateway_domainname.py +18 -18
  117. localstack/services/apigateway/resource_providers/aws_apigateway_domainname_plugin.py +1 -3
  118. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse.py +7 -7
  119. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse_plugin.py +1 -3
  120. localstack/services/apigateway/resource_providers/aws_apigateway_method.py +36 -36
  121. localstack/services/apigateway/resource_providers/aws_apigateway_method_plugin.py +1 -3
  122. localstack/services/apigateway/resource_providers/aws_apigateway_model.py +6 -6
  123. localstack/services/apigateway/resource_providers/aws_apigateway_model_plugin.py +1 -3
  124. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator.py +6 -6
  125. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator_plugin.py +1 -3
  126. localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +6 -6
  127. localstack/services/apigateway/resource_providers/aws_apigateway_resource_plugin.py +1 -3
  128. localstack/services/apigateway/resource_providers/aws_apigateway_restapi.py +26 -26
  129. localstack/services/apigateway/resource_providers/aws_apigateway_restapi_plugin.py +1 -3
  130. localstack/services/apigateway/resource_providers/aws_apigateway_stage.py +33 -33
  131. localstack/services/apigateway/resource_providers/aws_apigateway_stage_plugin.py +1 -3
  132. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan.py +18 -18
  133. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan_plugin.py +1 -3
  134. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey.py +5 -5
  135. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey_plugin.py +1 -3
  136. localstack/services/cdk/resource_providers/cdk_metadata.py +4 -3
  137. localstack/services/cdk/resource_providers/cdk_metadata_plugin.py +1 -3
  138. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.py +14 -14
  139. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py +1 -3
  140. localstack/services/cloudformation/api_utils.py +4 -8
  141. localstack/services/cloudformation/cfn_utils.py +2 -2
  142. localstack/services/cloudformation/deployment_utils.py +14 -12
  143. localstack/services/cloudformation/engine/changes.py +3 -3
  144. localstack/services/cloudformation/engine/entities.py +27 -17
  145. localstack/services/cloudformation/engine/parameters.py +4 -4
  146. localstack/services/cloudformation/engine/template_deployer.py +15 -14
  147. localstack/services/cloudformation/engine/template_utils.py +34 -12
  148. localstack/services/cloudformation/engine/transformers.py +11 -8
  149. localstack/services/cloudformation/engine/types.py +5 -4
  150. localstack/services/cloudformation/engine/v2/change_set_model.py +336 -39
  151. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +96 -17
  152. localstack/services/cloudformation/engine/v2/change_set_model_executor.py +289 -136
  153. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +315 -146
  154. localstack/services/cloudformation/engine/v2/change_set_model_transform.py +380 -105
  155. localstack/services/cloudformation/engine/v2/change_set_model_validator.py +183 -0
  156. localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +6 -0
  157. localstack/services/cloudformation/engine/v2/resolving.py +102 -0
  158. localstack/services/cloudformation/engine/yaml_parser.py +9 -2
  159. localstack/services/cloudformation/provider.py +11 -6
  160. localstack/services/cloudformation/provider_utils.py +34 -4
  161. localstack/services/cloudformation/resource_provider.py +31 -21
  162. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py +7 -7
  163. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro_plugin.py +1 -3
  164. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack.py +9 -9
  165. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack_plugin.py +1 -3
  166. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition.py +6 -6
  167. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition_plugin.py +1 -3
  168. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle.py +2 -2
  169. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle_plugin.py +1 -3
  170. localstack/services/cloudformation/resources.py +24149 -0
  171. localstack/services/cloudformation/scaffolding/__main__.py +13 -12
  172. localstack/services/cloudformation/scaffolding/propgen.py +2 -2
  173. localstack/services/cloudformation/service_models.py +2 -2
  174. localstack/services/cloudformation/stores.py +33 -22
  175. localstack/services/cloudformation/v2/entities.py +103 -88
  176. localstack/services/cloudformation/v2/provider.py +872 -131
  177. localstack/services/cloudformation/v2/types.py +38 -0
  178. localstack/services/cloudformation/v2/utils.py +4 -1
  179. localstack/services/cloudwatch/alarm_scheduler.py +11 -8
  180. localstack/services/cloudwatch/cloudwatch_database_helper.py +4 -5
  181. localstack/services/cloudwatch/models.py +5 -7
  182. localstack/services/cloudwatch/provider.py +30 -25
  183. localstack/services/cloudwatch/provider_v2.py +27 -32
  184. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py +40 -40
  185. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm_plugin.py +1 -3
  186. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm.py +12 -12
  187. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm_plugin.py +1 -3
  188. localstack/services/dynamodb/packages.py +3 -3
  189. localstack/services/dynamodb/provider.py +159 -18
  190. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable.py +63 -63
  191. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable_plugin.py +1 -3
  192. localstack/services/dynamodb/resource_providers/aws_dynamodb_table.py +57 -57
  193. localstack/services/dynamodb/resource_providers/aws_dynamodb_table_plugin.py +1 -3
  194. localstack/services/dynamodb/server.py +2 -2
  195. localstack/services/dynamodb/utils.py +13 -14
  196. localstack/services/dynamodb/v2/provider.py +157 -18
  197. localstack/services/dynamodbstreams/dynamodbstreams_api.py +2 -2
  198. localstack/services/dynamodbstreams/models.py +1 -3
  199. localstack/services/ec2/patches.py +26 -5
  200. localstack/services/ec2/provider.py +3 -3
  201. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions.py +10 -10
  202. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions_plugin.py +1 -3
  203. localstack/services/ec2/resource_providers/aws_ec2_instance.py +96 -96
  204. localstack/services/ec2/resource_providers/aws_ec2_instance_plugin.py +1 -3
  205. localstack/services/ec2/resource_providers/aws_ec2_internetgateway.py +5 -5
  206. localstack/services/ec2/resource_providers/aws_ec2_internetgateway_plugin.py +1 -3
  207. localstack/services/ec2/resource_providers/aws_ec2_keypair.py +10 -10
  208. localstack/services/ec2/resource_providers/aws_ec2_keypair_plugin.py +1 -3
  209. localstack/services/ec2/resource_providers/aws_ec2_natgateway.py +13 -13
  210. localstack/services/ec2/resource_providers/aws_ec2_natgateway_plugin.py +1 -3
  211. localstack/services/ec2/resource_providers/aws_ec2_networkacl.py +6 -6
  212. localstack/services/ec2/resource_providers/aws_ec2_networkacl_plugin.py +1 -3
  213. localstack/services/ec2/resource_providers/aws_ec2_prefixlist.py +14 -14
  214. localstack/services/ec2/resource_providers/aws_ec2_prefixlist_plugin.py +1 -3
  215. localstack/services/ec2/resource_providers/aws_ec2_route.py +15 -15
  216. localstack/services/ec2/resource_providers/aws_ec2_route_plugin.py +1 -3
  217. localstack/services/ec2/resource_providers/aws_ec2_routetable.py +6 -6
  218. localstack/services/ec2/resource_providers/aws_ec2_routetable_plugin.py +1 -3
  219. localstack/services/ec2/resource_providers/aws_ec2_securitygroup.py +29 -29
  220. localstack/services/ec2/resource_providers/aws_ec2_securitygroup_plugin.py +1 -3
  221. localstack/services/ec2/resource_providers/aws_ec2_subnet.py +19 -19
  222. localstack/services/ec2/resource_providers/aws_ec2_subnet_plugin.py +1 -3
  223. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation.py +4 -4
  224. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation_plugin.py +1 -3
  225. localstack/services/ec2/resource_providers/aws_ec2_transitgateway.py +16 -16
  226. localstack/services/ec2/resource_providers/aws_ec2_transitgateway_plugin.py +1 -3
  227. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment.py +9 -9
  228. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment_plugin.py +1 -3
  229. localstack/services/ec2/resource_providers/aws_ec2_vpc.py +15 -15
  230. localstack/services/ec2/resource_providers/aws_ec2_vpc_plugin.py +1 -3
  231. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint.py +29 -22
  232. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint_plugin.py +1 -3
  233. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment.py +5 -5
  234. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment_plugin.py +1 -3
  235. localstack/services/ecr/resource_providers/aws_ecr_repository.py +22 -19
  236. localstack/services/ecr/resource_providers/aws_ecr_repository_plugin.py +1 -3
  237. localstack/services/edge.py +6 -6
  238. localstack/services/es/provider.py +21 -21
  239. localstack/services/events/archive.py +2 -2
  240. localstack/services/events/connection.py +5 -5
  241. localstack/services/events/event_bus.py +9 -9
  242. localstack/services/events/event_rule_engine.py +31 -13
  243. localstack/services/events/models.py +29 -30
  244. localstack/services/events/provider.py +29 -26
  245. localstack/services/events/replay.py +3 -3
  246. localstack/services/events/resource_providers/aws_events_apidestination.py +8 -8
  247. localstack/services/events/resource_providers/aws_events_apidestination_plugin.py +1 -3
  248. localstack/services/events/resource_providers/aws_events_connection.py +27 -27
  249. localstack/services/events/resource_providers/aws_events_connection_plugin.py +1 -3
  250. localstack/services/events/resource_providers/aws_events_eventbus.py +9 -9
  251. localstack/services/events/resource_providers/aws_events_eventbus_plugin.py +1 -3
  252. localstack/services/events/resource_providers/aws_events_eventbuspolicy.py +11 -11
  253. localstack/services/events/resource_providers/aws_events_eventbuspolicy_plugin.py +1 -3
  254. localstack/services/events/resource_providers/aws_events_rule.py +82 -82
  255. localstack/services/events/resource_providers/aws_events_rule_plugin.py +1 -3
  256. localstack/services/events/rule.py +15 -15
  257. localstack/services/events/target.py +21 -13
  258. localstack/services/events/utils.py +7 -7
  259. localstack/services/events/v1/models.py +1 -3
  260. localstack/services/events/v1/provider.py +15 -15
  261. localstack/services/firehose/models.py +1 -3
  262. localstack/services/firehose/provider.py +25 -16
  263. localstack/services/iam/iam_patches.py +5 -6
  264. localstack/services/iam/provider.py +14 -119
  265. localstack/services/iam/resource_providers/aws_iam_accesskey.py +6 -6
  266. localstack/services/iam/resource_providers/aws_iam_accesskey_plugin.py +1 -3
  267. localstack/services/iam/resource_providers/aws_iam_group.py +9 -9
  268. localstack/services/iam/resource_providers/aws_iam_group_plugin.py +1 -3
  269. localstack/services/iam/resource_providers/aws_iam_instanceprofile.py +5 -5
  270. localstack/services/iam/resource_providers/aws_iam_instanceprofile_plugin.py +1 -3
  271. localstack/services/iam/resource_providers/aws_iam_managedpolicy.py +9 -9
  272. localstack/services/iam/resource_providers/aws_iam_managedpolicy_plugin.py +1 -3
  273. localstack/services/iam/resource_providers/aws_iam_policy.py +7 -7
  274. localstack/services/iam/resource_providers/aws_iam_policy_plugin.py +1 -3
  275. localstack/services/iam/resource_providers/aws_iam_role.py +16 -16
  276. localstack/services/iam/resource_providers/aws_iam_role_plugin.py +1 -3
  277. localstack/services/iam/resource_providers/aws_iam_servercertificate.py +10 -10
  278. localstack/services/iam/resource_providers/aws_iam_servercertificate_plugin.py +1 -3
  279. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole.py +5 -5
  280. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole_plugin.py +1 -3
  281. localstack/services/iam/resource_providers/aws_iam_user.py +17 -17
  282. localstack/services/iam/resource_providers/aws_iam_user_plugin.py +1 -3
  283. localstack/services/iam/resources/policy_simulator.py +133 -0
  284. localstack/services/kinesis/kinesis_mock_server.py +7 -8
  285. localstack/services/kinesis/models.py +17 -5
  286. localstack/services/kinesis/packages.py +3 -3
  287. localstack/services/kinesis/provider.py +86 -3
  288. localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +13 -13
  289. localstack/services/kinesis/resource_providers/aws_kinesis_stream_plugin.py +1 -3
  290. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer.py +7 -7
  291. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer_plugin.py +1 -3
  292. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream.py +191 -191
  293. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream_plugin.py +1 -3
  294. localstack/services/kms/models.py +21 -18
  295. localstack/services/kms/provider.py +62 -26
  296. localstack/services/kms/resource_providers/aws_kms_alias.py +3 -3
  297. localstack/services/kms/resource_providers/aws_kms_alias_plugin.py +1 -3
  298. localstack/services/kms/resource_providers/aws_kms_key.py +14 -14
  299. localstack/services/kms/resource_providers/aws_kms_key_plugin.py +1 -3
  300. localstack/services/kms/utils.py +4 -3
  301. localstack/services/lambda_/api_utils.py +19 -16
  302. localstack/services/lambda_/custom_endpoints.py +2 -2
  303. localstack/services/lambda_/event_source_mapping/esm_worker_factory.py +4 -7
  304. localstack/services/lambda_/event_source_mapping/pipe_utils.py +2 -2
  305. localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
  306. localstack/services/lambda_/event_source_mapping/senders/sender_utils.py +2 -1
  307. localstack/services/lambda_/hooks.py +6 -1
  308. localstack/services/lambda_/invocation/assignment.py +1 -2
  309. localstack/services/lambda_/invocation/docker_runtime_executor.py +7 -11
  310. localstack/services/lambda_/invocation/event_manager.py +1 -1
  311. localstack/services/lambda_/invocation/execution_environment.py +4 -4
  312. localstack/services/lambda_/invocation/executor_endpoint.py +8 -11
  313. localstack/services/lambda_/invocation/internal_sqs_queue.py +6 -10
  314. localstack/services/lambda_/invocation/lambda_models.py +33 -30
  315. localstack/services/lambda_/invocation/lambda_service.py +12 -5
  316. localstack/services/lambda_/invocation/logs.py +2 -3
  317. localstack/services/lambda_/invocation/runtime_executor.py +3 -3
  318. localstack/services/lambda_/invocation/version_manager.py +31 -8
  319. localstack/services/lambda_/ldm.py +14 -0
  320. localstack/services/lambda_/packages.py +3 -4
  321. localstack/services/lambda_/provider.py +9 -26
  322. localstack/services/lambda_/provider_utils.py +1 -1
  323. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig.py +8 -8
  324. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig_plugin.py +1 -3
  325. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig.py +11 -11
  326. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig_plugin.py +1 -3
  327. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py +39 -39
  328. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping_plugin.py +1 -3
  329. localstack/services/lambda_/resource_providers/aws_lambda_function.py +54 -54
  330. localstack/services/lambda_/resource_providers/aws_lambda_function_plugin.py +1 -3
  331. localstack/services/lambda_/resource_providers/aws_lambda_layerversion.py +11 -11
  332. localstack/services/lambda_/resource_providers/aws_lambda_layerversion_plugin.py +1 -3
  333. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission.py +6 -6
  334. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission_plugin.py +1 -3
  335. localstack/services/lambda_/resource_providers/aws_lambda_permission.py +10 -10
  336. localstack/services/lambda_/resource_providers/aws_lambda_permission_plugin.py +1 -3
  337. localstack/services/lambda_/resource_providers/aws_lambda_url.py +15 -15
  338. localstack/services/lambda_/resource_providers/aws_lambda_url_plugin.py +1 -3
  339. localstack/services/lambda_/resource_providers/aws_lambda_version.py +8 -8
  340. localstack/services/lambda_/resource_providers/aws_lambda_version_plugin.py +1 -3
  341. localstack/services/lambda_/resource_providers/lambda_alias.py +12 -12
  342. localstack/services/lambda_/resource_providers/lambda_alias_plugin.py +1 -3
  343. localstack/services/lambda_/runtimes.py +1 -3
  344. localstack/services/lambda_/urlrouter.py +14 -1
  345. localstack/services/logs/models.py +1 -3
  346. localstack/services/logs/provider.py +39 -22
  347. localstack/services/logs/resource_providers/aws_logs_loggroup.py +9 -9
  348. localstack/services/logs/resource_providers/aws_logs_loggroup_plugin.py +1 -3
  349. localstack/services/logs/resource_providers/aws_logs_logstream.py +4 -4
  350. localstack/services/logs/resource_providers/aws_logs_logstream_plugin.py +1 -3
  351. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter.py +7 -7
  352. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter_plugin.py +1 -3
  353. localstack/services/moto.py +5 -4
  354. localstack/services/opensearch/cluster.py +28 -20
  355. localstack/services/opensearch/cluster_manager.py +13 -14
  356. localstack/services/opensearch/models.py +1 -3
  357. localstack/services/opensearch/packages.py +27 -9
  358. localstack/services/opensearch/provider.py +15 -10
  359. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain.py +61 -61
  360. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain_plugin.py +1 -3
  361. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain.py +89 -89
  362. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain_plugin.py +1 -3
  363. localstack/services/opensearch/versions.py +57 -10
  364. localstack/services/plugins.py +37 -32
  365. localstack/services/providers.py +10 -2
  366. localstack/services/redshift/provider.py +0 -21
  367. localstack/services/redshift/resource_providers/aws_redshift_cluster.py +57 -57
  368. localstack/services/redshift/resource_providers/aws_redshift_cluster_plugin.py +1 -3
  369. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group.py +21 -21
  370. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group_plugin.py +1 -3
  371. localstack/services/route53/models.py +1 -3
  372. localstack/services/route53/provider.py +1 -2
  373. localstack/services/route53/resource_providers/aws_route53_healthcheck.py +6 -6
  374. localstack/services/route53/resource_providers/aws_route53_healthcheck_plugin.py +1 -3
  375. localstack/services/route53/resource_providers/aws_route53_recordset.py +27 -27
  376. localstack/services/route53/resource_providers/aws_route53_recordset_plugin.py +1 -3
  377. localstack/services/route53resolver/models.py +8 -10
  378. localstack/services/route53resolver/provider.py +12 -12
  379. localstack/services/s3/codec.py +2 -2
  380. localstack/services/s3/constants.py +5 -2
  381. localstack/services/s3/cors.py +8 -8
  382. localstack/services/s3/models.py +73 -73
  383. localstack/services/s3/notifications.py +74 -58
  384. localstack/services/s3/presigned_url.py +41 -59
  385. localstack/services/s3/provider.py +86 -29
  386. localstack/services/s3/resource_providers/aws_s3_bucket.py +180 -180
  387. localstack/services/s3/resource_providers/aws_s3_bucket_plugin.py +1 -3
  388. localstack/services/s3/resource_providers/aws_s3_bucketpolicy.py +4 -4
  389. localstack/services/s3/resource_providers/aws_s3_bucketpolicy_plugin.py +1 -3
  390. localstack/services/s3/storage/core.py +4 -3
  391. localstack/services/s3/storage/ephemeral.py +7 -6
  392. localstack/services/s3/utils.py +51 -31
  393. localstack/services/s3/validation.py +47 -33
  394. localstack/services/s3/website_hosting.py +9 -7
  395. localstack/services/scheduler/resource_providers/aws_scheduler_schedule.py +60 -60
  396. localstack/services/scheduler/resource_providers/aws_scheduler_schedule_plugin.py +1 -3
  397. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup.py +9 -9
  398. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup_plugin.py +1 -3
  399. localstack/services/secretsmanager/provider.py +10 -12
  400. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy.py +5 -5
  401. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy_plugin.py +1 -3
  402. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule.py +21 -21
  403. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule_plugin.py +1 -3
  404. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret.py +23 -23
  405. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret_plugin.py +1 -3
  406. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment.py +5 -5
  407. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment_plugin.py +1 -3
  408. localstack/services/ses/models.py +8 -1
  409. localstack/services/ses/provider.py +128 -55
  410. localstack/services/ses/resource_providers/aws_ses_emailidentity.py +21 -21
  411. localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py +1 -3
  412. localstack/services/sns/constants.py +7 -1
  413. localstack/services/sns/executor.py +9 -2
  414. localstack/services/sns/models.py +25 -25
  415. localstack/services/sns/provider.py +9 -7
  416. localstack/services/sns/publisher.py +37 -23
  417. localstack/services/sns/resource_providers/aws_sns_subscription.py +13 -13
  418. localstack/services/sns/resource_providers/aws_sns_subscription_plugin.py +1 -3
  419. localstack/services/sns/resource_providers/aws_sns_topic.py +16 -16
  420. localstack/services/sns/resource_providers/aws_sns_topic_plugin.py +1 -3
  421. localstack/services/sns/resource_providers/aws_sns_topicpolicy.py +4 -4
  422. localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py +1 -3
  423. localstack/services/sns/v2/models.py +167 -0
  424. localstack/services/sns/v2/provider.py +867 -0
  425. localstack/services/sns/v2/utils.py +130 -0
  426. localstack/services/sqs/constants.py +2 -2
  427. localstack/services/sqs/developer_api.py +205 -0
  428. localstack/services/sqs/models.py +71 -36
  429. localstack/services/sqs/provider.py +56 -332
  430. localstack/services/sqs/query_api.py +8 -5
  431. localstack/services/sqs/resource_providers/aws_sqs_queue.py +21 -21
  432. localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py +1 -3
  433. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py +7 -5
  434. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy_plugin.py +1 -3
  435. localstack/services/sqs/utils.py +123 -4
  436. localstack/services/ssm/provider.py +3 -4
  437. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow.py +15 -15
  438. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow_plugin.py +1 -3
  439. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget.py +10 -10
  440. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget_plugin.py +1 -3
  441. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask.py +48 -48
  442. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask_plugin.py +1 -3
  443. localstack/services/ssm/resource_providers/aws_ssm_parameter.py +10 -10
  444. localstack/services/ssm/resource_providers/aws_ssm_parameter_plugin.py +1 -3
  445. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py +29 -29
  446. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py +1 -3
  447. localstack/services/stepfunctions/asl/antlt4utils/antlr4utils.py +3 -4
  448. localstack/services/stepfunctions/asl/component/common/assign/assign_decl.py +1 -1
  449. localstack/services/stepfunctions/asl/component/common/assign/assign_decl_binding.py +1 -1
  450. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_array.py +1 -1
  451. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_object.py +1 -1
  452. localstack/services/stepfunctions/asl/component/common/catch/catcher_decl.py +9 -9
  453. localstack/services/stepfunctions/asl/component/common/error_name/custom_error_name.py +2 -2
  454. localstack/services/stepfunctions/asl/component/common/error_name/error_name.py +4 -4
  455. localstack/services/stepfunctions/asl/component/common/error_name/failure_event.py +8 -8
  456. localstack/services/stepfunctions/asl/component/common/error_name/states_error_name_type.py +1 -1
  457. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_binding.py +2 -2
  458. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_array.py +1 -1
  459. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_object.py +1 -1
  460. localstack/services/stepfunctions/asl/component/common/path/input_path.py +4 -4
  461. localstack/services/stepfunctions/asl/component/common/path/output_path.py +4 -4
  462. localstack/services/stepfunctions/asl/component/common/path/result_path.py +3 -3
  463. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadarr/payload_arr.py +1 -1
  464. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding.py +3 -3
  465. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadtmpl/payload_tmpl.py +1 -1
  466. localstack/services/stepfunctions/asl/component/common/retry/retrier_decl.py +8 -8
  467. localstack/services/stepfunctions/asl/component/common/string/string_expression.py +3 -3
  468. localstack/services/stepfunctions/asl/component/common/timeouts/timeout.py +3 -3
  469. localstack/services/stepfunctions/asl/component/eval_component.py +2 -3
  470. localstack/services/stepfunctions/asl/component/intrinsic/argument/argument.py +4 -4
  471. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/array/array_partition.py +1 -1
  472. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/generic/string_format.py +1 -1
  473. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_array.py +1 -1
  474. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_format.py +1 -1
  475. localstack/services/stepfunctions/asl/component/intrinsic/jsonata.py +3 -3
  476. localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
  477. localstack/services/stepfunctions/asl/component/program/program.py +9 -9
  478. localstack/services/stepfunctions/asl/component/program/states.py +1 -1
  479. localstack/services/stepfunctions/asl/component/state/state.py +10 -11
  480. localstack/services/stepfunctions/asl/component/state/state_choice/choice_rule.py +11 -11
  481. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
  482. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/operator/implementations/is_operator.py +2 -2
  483. localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +3 -5
  484. localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +9 -9
  485. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/item_reader_decl.py +7 -7
  486. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/reader_config/reader_config_decl.py +5 -5
  487. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_eval_s3.py +2 -1
  488. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_output_transformer/resource_output_transformer_csv.py +2 -2
  489. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/distributed_iteration_component.py +8 -8
  490. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/inline_iteration_component.py +7 -7
  491. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +4 -4
  492. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/inline_item_processor_worker.py +5 -5
  493. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/map_run_record.py +10 -10
  494. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_component.py +3 -3
  495. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_declaration.py +3 -3
  496. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_worker.py +2 -2
  497. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/distributed_iterator_worker.py +3 -5
  498. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator.py +1 -2
  499. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator_worker.py +5 -5
  500. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/job.py +9 -9
  501. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/result_writer/resource_eval/resource_eval_s3.py +2 -1
  502. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +12 -13
  503. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branch_worker.py +3 -3
  504. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branches_decl.py +7 -7
  505. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +2 -3
  506. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +7 -7
  507. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/resource.py +3 -3
  508. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +10 -10
  509. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_api_gateway.py +18 -18
  510. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_aws_sdk.py +1 -1
  511. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_batch.py +8 -7
  512. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +18 -17
  513. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_dynamodb.py +2 -2
  514. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_ecs.py +5 -4
  515. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_events.py +4 -4
  516. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_glue.py +7 -6
  517. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_lambda.py +4 -4
  518. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sfn.py +9 -8
  519. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sns.py +2 -2
  520. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sqs.py +4 -4
  521. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +5 -5
  522. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task_lambda.py +2 -2
  523. localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +3 -5
  524. localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +5 -7
  525. localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
  526. localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
  527. localstack/services/stepfunctions/asl/component/state/state_wait/wait_function/timestamp.py +2 -2
  528. localstack/services/stepfunctions/asl/eval/callback/callback.py +18 -18
  529. localstack/services/stepfunctions/asl/eval/environment.py +22 -24
  530. localstack/services/stepfunctions/asl/eval/evaluation_details.py +3 -5
  531. localstack/services/stepfunctions/asl/eval/event/event_manager.py +10 -10
  532. localstack/services/stepfunctions/asl/eval/event/logging.py +3 -3
  533. localstack/services/stepfunctions/asl/eval/program_state.py +8 -8
  534. localstack/services/stepfunctions/asl/eval/states.py +12 -12
  535. localstack/services/stepfunctions/asl/eval/test_state/environment.py +3 -5
  536. localstack/services/stepfunctions/asl/eval/variable_store.py +6 -6
  537. localstack/services/stepfunctions/asl/jsonata/jsonata.py +7 -6
  538. localstack/services/stepfunctions/asl/parse/asl_parser.py +1 -1
  539. localstack/services/stepfunctions/asl/parse/intrinsic/preprocessor.py +2 -3
  540. localstack/services/stepfunctions/asl/parse/preprocessor.py +44 -44
  541. localstack/services/stepfunctions/asl/parse/typed_props.py +2 -2
  542. localstack/services/stepfunctions/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py +1 -1
  543. localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py +2 -2
  544. localstack/services/stepfunctions/asl/utils/encoding.py +2 -2
  545. localstack/services/stepfunctions/asl/utils/json_path.py +2 -2
  546. localstack/services/stepfunctions/backend/activity.py +4 -4
  547. localstack/services/stepfunctions/backend/alias.py +8 -8
  548. localstack/services/stepfunctions/backend/execution.py +29 -30
  549. localstack/services/stepfunctions/backend/execution_worker.py +7 -7
  550. localstack/services/stepfunctions/backend/state_machine.py +28 -28
  551. localstack/services/stepfunctions/backend/test_state/execution.py +3 -4
  552. localstack/services/stepfunctions/backend/test_state/execution_worker.py +1 -3
  553. localstack/services/stepfunctions/mocking/mock_config.py +9 -9
  554. localstack/services/stepfunctions/mocking/mock_config_file.py +10 -10
  555. localstack/services/stepfunctions/packages.py +14 -5
  556. localstack/services/stepfunctions/provider.py +34 -44
  557. localstack/services/stepfunctions/quotas.py +2 -3
  558. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity.py +6 -6
  559. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity_plugin.py +1 -3
  560. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +25 -25
  561. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine_plugin.py +1 -3
  562. localstack/services/stepfunctions/stepfunctions_utils.py +1 -2
  563. localstack/services/stores.py +8 -8
  564. localstack/services/transcribe/packages.py +1 -3
  565. localstack/services/transcribe/provider.py +8 -3
  566. localstack/state/codecs.py +61 -0
  567. localstack/state/core.py +11 -5
  568. localstack/state/inspect.py +4 -4
  569. localstack/state/pickle.py +36 -23
  570. localstack/testing/aws/asf_utils.py +3 -2
  571. localstack/testing/aws/cloudformation_utils.py +1 -1
  572. localstack/testing/aws/lambda_utils.py +15 -14
  573. localstack/testing/aws/util.py +3 -2
  574. localstack/testing/pytest/cloudformation/fixtures.py +68 -18
  575. localstack/testing/pytest/container.py +5 -5
  576. localstack/testing/pytest/filters.py +1 -3
  577. localstack/testing/pytest/fixtures.py +188 -49
  578. localstack/testing/pytest/in_memory_localstack.py +1 -3
  579. localstack/testing/pytest/marking.py +42 -15
  580. localstack/testing/pytest/path_filter.py +1 -1
  581. localstack/testing/pytest/stepfunctions/fixtures.py +4 -4
  582. localstack/testing/pytest/stepfunctions/utils.py +11 -10
  583. localstack/testing/pytest/util.py +1 -1
  584. localstack/testing/pytest/validation_tracking.py +3 -4
  585. localstack/testing/scenario/provisioning.py +11 -10
  586. localstack/testing/snapshots/transformer_utility.py +8 -3
  587. localstack/testing/testselection/matching.py +2 -2
  588. localstack/testing/testselection/opt_out.py +1 -1
  589. localstack/testing/testselection/scripts/filter_by_test_selection.py +1 -1
  590. localstack/testing/testselection/scripts/generate_test_selection.py +1 -1
  591. localstack/testing/testselection/testselection.py +2 -2
  592. localstack/utils/analytics/cli.py +2 -3
  593. localstack/utils/analytics/client.py +5 -5
  594. localstack/utils/analytics/events.py +2 -2
  595. localstack/utils/analytics/metadata.py +6 -4
  596. localstack/utils/analytics/metrics/counter.py +11 -18
  597. localstack/utils/analytics/metrics/registry.py +2 -2
  598. localstack/utils/analytics/publisher.py +4 -5
  599. localstack/utils/analytics/service_providers.py +19 -0
  600. localstack/utils/analytics/service_request_aggregator.py +4 -4
  601. localstack/utils/archives.py +12 -12
  602. localstack/utils/asyncio.py +2 -2
  603. localstack/utils/aws/arns.py +26 -31
  604. localstack/utils/aws/aws_responses.py +21 -28
  605. localstack/utils/aws/aws_stack.py +7 -12
  606. localstack/utils/aws/dead_letter_queue.py +4 -9
  607. localstack/utils/aws/message_forwarding.py +8 -11
  608. localstack/utils/aws/request_context.py +5 -6
  609. localstack/utils/aws/resources.py +1 -1
  610. localstack/utils/aws/templating.py +4 -4
  611. localstack/utils/batch_policy.py +4 -4
  612. localstack/utils/bootstrap.py +37 -30
  613. localstack/utils/catalog/catalog.py +139 -0
  614. localstack/utils/catalog/catalog_loader.py +119 -0
  615. localstack/utils/catalog/common.py +58 -0
  616. localstack/utils/catalog/plugins.py +28 -0
  617. localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
  618. localstack/utils/collections.py +33 -27
  619. localstack/utils/config_listener.py +2 -2
  620. localstack/utils/container_networking.py +5 -6
  621. localstack/utils/container_utils/container_client.py +156 -160
  622. localstack/utils/container_utils/docker_cmd_client.py +97 -81
  623. localstack/utils/container_utils/docker_sdk_client.py +75 -72
  624. localstack/utils/crypto.py +12 -13
  625. localstack/utils/diagnose.py +11 -12
  626. localstack/utils/docker_utils.py +11 -7
  627. localstack/utils/files.py +34 -15
  628. localstack/utils/functions.py +5 -4
  629. localstack/utils/http.py +14 -14
  630. localstack/utils/iputils.py +2 -1
  631. localstack/utils/json.py +21 -7
  632. localstack/utils/kinesis/kinesis_connector.py +2 -1
  633. localstack/utils/net.py +25 -17
  634. localstack/utils/no_exit_argument_parser.py +2 -2
  635. localstack/utils/numbers.py +9 -2
  636. localstack/utils/objects.py +15 -14
  637. localstack/utils/patch.py +14 -7
  638. localstack/utils/platform.py +2 -2
  639. localstack/utils/run.py +15 -14
  640. localstack/utils/scheduler.py +13 -12
  641. localstack/utils/server/tcp_proxy.py +2 -2
  642. localstack/utils/serving.py +3 -4
  643. localstack/utils/strings.py +15 -16
  644. localstack/utils/sync.py +126 -1
  645. localstack/utils/tagging.py +10 -8
  646. localstack/utils/testutil.py +17 -17
  647. localstack/utils/threads.py +3 -3
  648. localstack/utils/time.py +12 -4
  649. localstack/utils/urls.py +1 -3
  650. localstack/utils/xml.py +1 -1
  651. localstack/utils/xray/traceid.py +1 -1
  652. localstack/version.py +16 -3
  653. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -13
  654. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +663 -655
  655. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
  656. localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
  657. localstack/packages/terraform.py +0 -47
  658. localstack/services/cloudformation/deploy.html +0 -144
  659. localstack/services/cloudformation/deploy_ui.py +0 -47
  660. localstack/services/cloudformation/plugins.py +0 -12
  661. localstack/services/lambda_/lambda_debug_mode/ldm.py +0 -375
  662. localstack/services/lambda_/lambda_debug_mode/ldm_config_file.py +0 -178
  663. localstack/services/lambda_/lambda_debug_mode/ldm_types.py +0 -11
  664. localstack/services/lambda_/lambda_debug_mode/ldm_utils.py +0 -43
  665. localstack_core-4.6.1.dev60.dist-info/plux.json +0 -1
  666. /localstack/{services/lambda_/lambda_debug_mode/__init__.py → testing/pytest/cloudformation/transformers.py} +0 -0
  667. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
  668. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
  669. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
  670. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
  671. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
  672. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
localstack/utils/http.py CHANGED
@@ -2,7 +2,6 @@ import logging
2
2
  import math
3
3
  import os
4
4
  import re
5
- from typing import Dict, Optional, Union
6
5
  from urllib.parse import parse_qs, parse_qsl, urlencode, urlparse, urlunparse
7
6
 
8
7
  import requests
@@ -43,18 +42,18 @@ def create_chunked_data(data, chunk_size: int = 80):
43
42
  dl = len(data)
44
43
  ret = ""
45
44
  for i in range(dl // chunk_size):
46
- ret += "%s\r\n" % (hex(chunk_size)[2:])
47
- ret += "%s\r\n\r\n" % (data[i * chunk_size : (i + 1) * chunk_size])
45
+ ret += f"{hex(chunk_size)[2:]}\r\n"
46
+ ret += f"{data[i * chunk_size : (i + 1) * chunk_size]}\r\n\r\n"
48
47
 
49
48
  if len(data) % chunk_size != 0:
50
- ret += "%s\r\n" % (hex(len(data) % chunk_size)[2:])
51
- ret += "%s\r\n" % (data[-(len(data) % chunk_size) :])
49
+ ret += f"{hex(len(data) % chunk_size)[2:]}\r\n"
50
+ ret += f"{data[-(len(data) % chunk_size) :]}\r\n"
52
51
 
53
52
  ret += "0\r\n\r\n"
54
53
  return ret
55
54
 
56
55
 
57
- def canonicalize_headers(headers: Union[Dict, CaseInsensitiveDict]) -> Dict:
56
+ def canonicalize_headers(headers: dict | CaseInsensitiveDict) -> dict:
58
57
  if not headers:
59
58
  return headers
60
59
 
@@ -76,7 +75,7 @@ def add_path_parameters_to_url(uri: str, path_params: list):
76
75
  return urlunparse(url._replace(path=new_path))
77
76
 
78
77
 
79
- def add_query_params_to_url(uri: str, query_params: Dict) -> str:
78
+ def add_query_params_to_url(uri: str, query_params: dict) -> str:
80
79
  """
81
80
  Add query parameters to the uri.
82
81
  :param uri: the base uri it can contains path arguments and query parameters
@@ -103,7 +102,7 @@ def add_query_params_to_url(uri: str, query_params: Dict) -> str:
103
102
 
104
103
 
105
104
  def make_http_request(
106
- url: str, data: Union[bytes, str] = None, headers: Dict[str, str] = None, method: str = "GET"
105
+ url: str, data: bytes | str = None, headers: dict[str, str] = None, method: str = "GET"
107
106
  ) -> Response:
108
107
  return requests.request(
109
108
  url=url, method=method, headers=headers, data=data, auth=NetrcBypassAuth(), verify=False
@@ -141,7 +140,7 @@ class _RequestsSafe:
141
140
  safe_requests = _RequestsSafe()
142
141
 
143
142
 
144
- def parse_request_data(method: str, path: str, data=None, headers=None) -> Dict:
143
+ def parse_request_data(method: str, path: str, data=None, headers=None) -> dict:
145
144
  """Extract request data either from query string as well as request body (e.g., for POST)."""
146
145
  result = {}
147
146
  headers = headers or {}
@@ -165,7 +164,7 @@ def parse_request_data(method: str, path: str, data=None, headers=None) -> Dict:
165
164
  return result
166
165
 
167
166
 
168
- def get_proxies() -> Dict[str, str]:
167
+ def get_proxies() -> dict[str, str]:
169
168
  proxy_map = {}
170
169
  if config.OUTBOUND_HTTP_PROXY:
171
170
  proxy_map["http"] = config.OUTBOUND_HTTP_PROXY
@@ -179,7 +178,7 @@ def download(
179
178
  path: str,
180
179
  verify_ssl: bool = True,
181
180
  timeout: float = None,
182
- request_headers: Optional[dict] = None,
181
+ request_headers: dict | None = None,
183
182
  quiet: bool = False,
184
183
  ) -> None:
185
184
  """Downloads file at url to the given path. Raises TimeoutError if the optional timeout (in secs) is reached.
@@ -202,7 +201,7 @@ def download(
202
201
  r = s.get(url, stream=True, verify=_verify, timeout=timeout, headers=request_headers)
203
202
  # check status code before attempting to read body
204
203
  if not r.ok:
205
- raise Exception("Failed to download %s, response code %s" % (url, r.status_code))
204
+ raise Exception(f"Failed to download {url}, response code {r.status_code}")
206
205
 
207
206
  total_size = 0
208
207
  if r.headers.get("Content-Length"):
@@ -291,18 +290,19 @@ def download_github_artifact(url: str, target_file: str, timeout: int = None):
291
290
  Optionally allows to define a timeout in seconds."""
292
291
 
293
292
  def do_download(
294
- download_url: str, request_headers: Optional[dict] = None, print_error: bool = False
293
+ download_url: str, request_headers: dict | None = None, print_error: bool = False
295
294
  ):
296
295
  try:
297
296
  download(download_url, target_file, timeout=timeout, request_headers=request_headers)
298
297
  return True
299
298
  except Exception as e:
300
299
  if print_error:
301
- LOG.exception(
300
+ LOG.error(
302
301
  "Unable to download Github artifact from %s to %s: %s %s",
303
302
  url,
304
303
  target_file,
305
304
  e,
305
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
306
306
  )
307
307
 
308
308
  # if a GitHub API token is set, use it to avoid rate limiting issues
@@ -6,7 +6,8 @@ some of its functionality.
6
6
  import ipaddress
7
7
  import json
8
8
  import subprocess as sp
9
- from typing import Any, Generator, TypedDict
9
+ from collections.abc import Generator
10
+ from typing import Any, TypedDict
10
11
 
11
12
  from cachetools import TTLCache, cached
12
13
 
localstack/utils/json.py CHANGED
@@ -5,7 +5,7 @@ import logging
5
5
  import os
6
6
  from datetime import date, datetime
7
7
  from json import JSONDecodeError
8
- from typing import Any, Union
8
+ from typing import Any
9
9
 
10
10
  from localstack.config import HostAndPort
11
11
 
@@ -42,7 +42,7 @@ class CustomEncoder(json.JSONEncoder):
42
42
  try:
43
43
  if isinstance(o, bytes):
44
44
  return to_str(o)
45
- return super(CustomEncoder, self).default(o)
45
+ return super().default(o)
46
46
  except Exception:
47
47
  return None
48
48
 
@@ -63,9 +63,9 @@ class FileMappedDocument(dict):
63
63
  concurrent writes, run load(). To save and overwrite the current document on disk, run save().
64
64
  """
65
65
 
66
- path: Union[str, os.PathLike]
66
+ path: str | os.PathLike
67
67
 
68
- def __init__(self, path: Union[str, os.PathLike], mode=0o664):
68
+ def __init__(self, path: str | os.PathLike, mode=0o664):
69
69
  super().__init__()
70
70
  self.path = path
71
71
  self.mode = mode
@@ -78,7 +78,7 @@ class FileMappedDocument(dict):
78
78
  if os.path.isdir(self.path):
79
79
  raise IsADirectoryError
80
80
 
81
- with open(self.path, "r") as fd:
81
+ with open(self.path) as fd:
82
82
  self.update(json.load(fd))
83
83
 
84
84
  def save(self):
@@ -169,10 +169,24 @@ def extract_jsonpath(value, path):
169
169
  return result
170
170
 
171
171
 
172
- def assign_to_path(target, path: str, value, delimiter: str = "."):
172
+ def assign_to_path(target: dict, path: str, value: any, delimiter: str = ".") -> dict:
173
+ """Assign the given value to a dict. If the path doesn't exist in the target dict, it will be created.
174
+ The delimiter can be used to provide a path with a different delimiter.
175
+
176
+ Examples:
177
+ - assign_to_path({}, "a", "b") => {"a": "b"}
178
+ - assign_to_path({}, "a.b.c", "d") => {"a": {"b": {"c": "d"}}}
179
+ - assign_to_path({}, "a.b/c", "d", delimiter="/") => {"a.b": {"c": "d"}}
180
+
181
+ """
173
182
  parts = path.strip(delimiter).split(delimiter)
183
+
184
+ if len(parts) == 1:
185
+ target[parts[0]] = value
186
+ return target
187
+
174
188
  path_to_parent = delimiter.join(parts[:-1])
175
- parent = extract_from_jsonpointer_path(target, path_to_parent, auto_create=True)
189
+ parent = extract_from_jsonpointer_path(target, path_to_parent, delimiter, auto_create=True)
176
190
  if not isinstance(parent, dict):
177
191
  LOG.debug(
178
192
  'Unable to find parent (type %s) for path "%s" in object: %s',
@@ -6,7 +6,8 @@ import re
6
6
  import socket
7
7
  import tempfile
8
8
  import threading
9
- from typing import Any, Callable
9
+ from collections.abc import Callable
10
+ from typing import Any
10
11
 
11
12
  from amazon_kclpy import kcl
12
13
  from amazon_kclpy.v2 import processor
localstack/utils/net.py CHANGED
@@ -3,8 +3,9 @@ import random
3
3
  import re
4
4
  import socket
5
5
  import threading
6
+ from collections.abc import MutableMapping
6
7
  from contextlib import closing
7
- from typing import Any, List, MutableMapping, NamedTuple, Optional, Union
8
+ from typing import Any, NamedTuple
8
9
  from urllib.parse import urlparse
9
10
 
10
11
  import dns.resolver
@@ -49,14 +50,14 @@ class Port(NamedTuple):
49
50
 
50
51
 
51
52
  # simple helper type to encapsulate int/Port argument types
52
- IntOrPort = Union[int, Port]
53
+ IntOrPort = int | Port
53
54
 
54
55
 
55
56
  def is_port_open(
56
- port_or_url: Union[int, str],
57
+ port_or_url: int | str,
57
58
  http_path: str = None,
58
59
  expect_success: bool = True,
59
- protocols: Optional[Union[str, List[str]]] = None,
60
+ protocols: str | list[str] | None = None,
60
61
  quiet: bool = True,
61
62
  ):
62
63
  from localstack.utils.http import safe_requests
@@ -92,11 +93,16 @@ def is_port_open(
92
93
  answers = resolver.query("google.com", "A")
93
94
  assert len(answers) > 0
94
95
  else:
95
- sock.sendto(bytes(), (host, port))
96
+ sock.sendto(b"", (host, port))
96
97
  sock.recvfrom(1024)
97
98
  except Exception:
98
99
  if not quiet:
99
- LOG.exception("Error connecting to UDP port %s:%s", host, port)
100
+ LOG.error(
101
+ "Error connecting to UDP port %s:%s",
102
+ host,
103
+ port,
104
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
105
+ )
100
106
  return False
101
107
  elif nw_protocol == socket.SOCK_STREAM:
102
108
  result = sock.connect_ex((host, port))
@@ -158,8 +164,9 @@ def wait_for_port_status(
158
164
  status = is_port_open(port, http_path=http_path, expect_success=expect_success)
159
165
  if bool(status) != (not expect_closed):
160
166
  raise Exception(
161
- "Port %s (path: %s) was not %s"
162
- % (port, http_path, "closed" if expect_closed else "open")
167
+ "Port {} (path: {}) was not {}".format(
168
+ port, http_path, "closed" if expect_closed else "open"
169
+ )
163
170
  )
164
171
 
165
172
  return retry(check, sleep=sleep_time, retries=retries)
@@ -190,7 +197,7 @@ def port_can_be_bound(port: IntOrPort, address: str = "") -> bool:
190
197
  return False
191
198
 
192
199
 
193
- def get_free_udp_port(blocklist: List[int] = None) -> int:
200
+ def get_free_udp_port(blocklist: list[int] = None) -> int:
194
201
  blocklist = blocklist or []
195
202
  for i in range(10):
196
203
  udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@@ -202,7 +209,7 @@ def get_free_udp_port(blocklist: List[int] = None) -> int:
202
209
  raise Exception(f"Unable to determine free UDP port with blocklist {blocklist}")
203
210
 
204
211
 
205
- def get_free_tcp_port(blocklist: List[int] = None) -> int:
212
+ def get_free_tcp_port(blocklist: list[int] = None) -> int:
206
213
  """
207
214
  Tries to bind a socket to port 0 and returns the port that was assigned by the system. If the port is
208
215
  in the given ``blocklist``, or the port is marked as reserved in ``dynamic_port_range``, the procedure
@@ -268,11 +275,11 @@ def get_free_tcp_port_range(num_ports: int, max_attempts: int = 50) -> "PortRang
268
275
  raise PortNotAvailableException("reached max_attempts when trying to find port range")
269
276
 
270
277
 
271
- def resolve_hostname(hostname: str) -> Optional[str]:
278
+ def resolve_hostname(hostname: str) -> str | None:
272
279
  """Resolve the given hostname and return its IP address, or None if it cannot be resolved."""
273
280
  try:
274
281
  return socket.gethostbyname(hostname)
275
- except socket.error:
282
+ except OSError:
276
283
  return None
277
284
 
278
285
 
@@ -280,7 +287,7 @@ def is_ip_address(addr: str) -> bool:
280
287
  try:
281
288
  socket.inet_aton(addr)
282
289
  return True
283
- except socket.error:
290
+ except OSError:
284
291
  return False
285
292
 
286
293
 
@@ -341,7 +348,8 @@ class PortRange:
341
348
  if end > self.end:
342
349
  raise ValueError(f"end not in range ({end} < {self.end})")
343
350
 
344
- port_range = PortRange(start, end)
351
+ # ensures that we return an instance of a subclass
352
+ port_range = type(self)(start, end)
345
353
  port_range._ports_cache = self._ports_cache
346
354
  port_range._ports_lock = self._ports_lock
347
355
  return port_range
@@ -354,7 +362,7 @@ class PortRange:
354
362
  """
355
363
  return range(self.start, self.end + 1)
356
364
 
357
- def reserve_port(self, port: Optional[IntOrPort] = None, duration: Optional[int] = None) -> int:
365
+ def reserve_port(self, port: IntOrPort | None = None, duration: int | None = None) -> int:
358
366
  """
359
367
  Reserves the given port (if it is still free). If the given port is None, it reserves a free port from the
360
368
  configured port range for external services. If a port is given, it has to be within the configured
@@ -468,9 +476,9 @@ def get_docker_host_from_container() -> str:
468
476
  if config.is_in_docker:
469
477
  try:
470
478
  result = socket.gethostbyname("host.docker.internal")
471
- except socket.error:
479
+ except OSError:
472
480
  result = socket.gethostbyname("host.containers.internal")
473
- except socket.error:
481
+ except OSError:
474
482
  # TODO if neither host resolves, we might be in linux. We could just use the default gateway then
475
483
  pass
476
484
  return result
@@ -1,6 +1,6 @@
1
1
  import argparse
2
2
  import logging
3
- from typing import NoReturn, Optional
3
+ from typing import NoReturn
4
4
 
5
5
  LOG = logging.getLogger(__name__)
6
6
 
@@ -12,7 +12,7 @@ class NoExitArgumentParser(argparse.ArgumentParser):
12
12
  * ArgumentParser subclassing example: https://stackoverflow.com/a/59072378/6875981
13
13
  """
14
14
 
15
- def exit(self, status: int = ..., message: Optional[str] = ...) -> NoReturn:
15
+ def exit(self, status: int = ..., message: str | None = ...) -> NoReturn:
16
16
  LOG.warning("Error in argument parser but preventing exit: %s", message)
17
17
 
18
18
  def error(self, message: str) -> NoReturn:
@@ -1,4 +1,4 @@
1
- from typing import Any, Union
1
+ from typing import Any
2
2
 
3
3
 
4
4
  def format_number(number: float, decimals: int = 2):
@@ -11,6 +11,13 @@ def format_number(number: float, decimals: int = 2):
11
11
 
12
12
 
13
13
  def is_number(s: Any) -> bool:
14
+ # booleans inherit from int
15
+ #
16
+ # >>> a.__class__.__mro__
17
+ # (<class 'bool'>, <class 'int'>, <class 'object'>)
18
+ if s is False or s is True:
19
+ return False
20
+
14
21
  try:
15
22
  float(s) # for int, long and float
16
23
  return True
@@ -18,7 +25,7 @@ def is_number(s: Any) -> bool:
18
25
  return False
19
26
 
20
27
 
21
- def to_number(s: Any) -> Union[int, float]:
28
+ def to_number(s: Any) -> int | float:
22
29
  """Cast the string representation of the given object to a number (int or float), or raise ValueError."""
23
30
  try:
24
31
  return int(str(s))
@@ -1,12 +1,13 @@
1
1
  import functools
2
2
  import re
3
3
  import threading
4
- from typing import Any, Callable, Dict, Generic, List, Optional, Set, Type, TypeVar, Union
4
+ from collections.abc import Callable
5
+ from typing import Any, Generic, TypeVar
5
6
 
6
7
  from .collections import ensure_list
7
8
  from .strings import first_char_to_lower, first_char_to_upper
8
9
 
9
- ComplexType = Union[List, Dict, object]
10
+ ComplexType = list | dict | object
10
11
 
11
12
  _T = TypeVar("_T")
12
13
 
@@ -16,7 +17,7 @@ class Value(Generic[_T]):
16
17
  Simple value container.
17
18
  """
18
19
 
19
- value: Optional[_T]
20
+ value: _T | None
20
21
 
21
22
  def __init__(self, value: _T = None) -> None:
22
23
  self.value = value
@@ -30,7 +31,7 @@ class Value(Generic[_T]):
30
31
  def is_set(self) -> bool:
31
32
  return self.value is not None
32
33
 
33
- def get(self) -> Optional[_T]:
34
+ def get(self) -> _T | None:
34
35
  return self.value
35
36
 
36
37
  def __bool__(self):
@@ -83,7 +84,7 @@ class SubtypesInstanceManager:
83
84
  """Simple instance manager base class that scans the subclasses of a base type for concrete named
84
85
  implementations, and lazily creates and returns (singleton) instances on demand."""
85
86
 
86
- _instances: Dict[str, "SubtypesInstanceManager"]
87
+ _instances: dict[str, "SubtypesInstanceManager"]
87
88
 
88
89
  @classmethod
89
90
  def get(cls, subtype_name: str, raise_if_missing: bool = True):
@@ -104,7 +105,7 @@ class SubtypesInstanceManager:
104
105
  return instance
105
106
 
106
107
  @classmethod
107
- def instances(cls) -> Dict[str, "SubtypesInstanceManager"]:
108
+ def instances(cls) -> dict[str, "SubtypesInstanceManager"]:
108
109
  base_type = cls.get_base_type()
109
110
  if not hasattr(base_type, "_instances"):
110
111
  base_type._instances = {}
@@ -116,13 +117,13 @@ class SubtypesInstanceManager:
116
117
  raise NotImplementedError
117
118
 
118
119
  @classmethod
119
- def get_base_type(cls) -> Type:
120
+ def get_base_type(cls) -> type:
120
121
  """Get the base class for which instances are being managed - can be customized by subtypes."""
121
122
  return cls
122
123
 
123
124
 
124
125
  # this requires that all subclasses have been imported before(!)
125
- def get_all_subclasses(clazz: Type) -> Set[Type]:
126
+ def get_all_subclasses(clazz: type) -> set[type]:
126
127
  """Recursively get all subclasses of the given class."""
127
128
  result = set()
128
129
  subs = clazz.__subclasses__()
@@ -132,11 +133,11 @@ def get_all_subclasses(clazz: Type) -> Set[Type]:
132
133
  return result
133
134
 
134
135
 
135
- def fully_qualified_class_name(klass: Type) -> str:
136
+ def fully_qualified_class_name(klass: type) -> str:
136
137
  return f"{klass.__module__}.{klass.__name__}"
137
138
 
138
139
 
139
- def not_none_or(value: Optional[Any], alternative: Any) -> Any:
140
+ def not_none_or(value: Any | None, alternative: Any) -> Any:
140
141
  """Return 'value' if it is not None, or 'alternative' otherwise."""
141
142
  return value if value is not None else alternative
142
143
 
@@ -156,14 +157,14 @@ def recurse_object(obj: ComplexType, func: Callable, path: str = "") -> ComplexT
156
157
 
157
158
 
158
159
  def keys_to(
159
- obj: ComplexType, op: Callable[[str], str], skip_children_of: List[str] = None
160
+ obj: ComplexType, op: Callable[[str], str], skip_children_of: list[str] = None
160
161
  ) -> ComplexType:
161
162
  """Recursively changes all dict keys to apply op. Skip children
162
163
  of any elements whose names are contained in skip_children_of (e.g., ['Tags'])"""
163
164
  skip_children_of = ensure_list(skip_children_of or [])
164
165
 
165
166
  def fix_keys(o, path="", **kwargs):
166
- if any(re.match(r"(^|.*\.)%s($|[.\[].*)" % k, path) for k in skip_children_of):
167
+ if any(re.match(rf"(^|.*\.){k}($|[.\[].*)", path) for k in skip_children_of):
167
168
  return o
168
169
  if isinstance(o, dict):
169
170
  for k, v in dict(o).items():
@@ -175,11 +176,11 @@ def keys_to(
175
176
  return result
176
177
 
177
178
 
178
- def keys_to_lower(obj: ComplexType, skip_children_of: List[str] = None) -> ComplexType:
179
+ def keys_to_lower(obj: ComplexType, skip_children_of: list[str] = None) -> ComplexType:
179
180
  return keys_to(obj, first_char_to_lower, skip_children_of)
180
181
 
181
182
 
182
- def keys_to_upper(obj: ComplexType, skip_children_of: List[str] = None) -> ComplexType:
183
+ def keys_to_upper(obj: ComplexType, skip_children_of: list[str] = None) -> ComplexType:
183
184
  return keys_to(obj, first_char_to_upper, skip_children_of)
184
185
 
185
186
 
localstack/utils/patch.py CHANGED
@@ -1,7 +1,8 @@
1
1
  import functools
2
2
  import inspect
3
3
  import types
4
- from typing import Any, Callable, List, Type
4
+ from collections.abc import Callable
5
+ from typing import Any
5
6
 
6
7
 
7
8
  def get_defining_object(method):
@@ -71,7 +72,7 @@ def create_patch_proxy(target: Callable, new: Callable):
71
72
 
72
73
 
73
74
  class Patch:
74
- applied_patches: List["Patch"] = []
75
+ applied_patches: list["Patch"] = []
75
76
  """Bookkeeping for patches that are applied. You can use this to debug patches. For instance,
76
77
  you could write something like::
77
78
 
@@ -97,19 +98,25 @@ class Patch:
97
98
  self.is_applied = False
98
99
 
99
100
  def apply(self):
101
+ if self.is_applied:
102
+ return
103
+
100
104
  if self.old and self.name == "__getattr__":
101
105
  raise Exception("You can't patch class types implementing __getattr__")
102
106
  if not self.old and self.name != "__getattr__":
103
107
  raise AttributeError(f"`{self.obj.__name__}` object has no attribute `{self.name}`")
104
108
  setattr(self.obj, self.name, self.new)
105
- self.is_applied = True
106
109
  Patch.applied_patches.append(self)
110
+ self.is_applied = True
107
111
 
108
112
  def undo(self):
113
+ if not self.is_applied:
114
+ return
115
+
109
116
  # If we added a method to a class type, we don't have a self.old. We just delete __getattr__
110
117
  setattr(self.obj, self.name, self.old) if self.old else delattr(self.obj, self.name)
111
- self.is_applied = False
112
118
  Patch.applied_patches.remove(self)
119
+ self.is_applied = False
113
120
 
114
121
  def __enter__(self):
115
122
  self.apply()
@@ -120,7 +127,7 @@ class Patch:
120
127
  return self
121
128
 
122
129
  @staticmethod
123
- def extend_class(target: Type, fn: Callable):
130
+ def extend_class(target: type, fn: Callable):
124
131
  def _getattr(obj, name):
125
132
  if name != fn.__name__:
126
133
  raise AttributeError(f"`{target.__name__}` object has no attribute `{name}`")
@@ -164,9 +171,9 @@ class Patch:
164
171
 
165
172
 
166
173
  class Patches:
167
- patches: List[Patch]
174
+ patches: list[Patch]
168
175
 
169
- def __init__(self, patches: List[Patch] = None) -> None:
176
+ def __init__(self, patches: list[Patch] = None) -> None:
170
177
  super().__init__()
171
178
 
172
179
  self.patches = []
@@ -14,14 +14,14 @@ def is_windows() -> bool:
14
14
  return "windows" == platform.system().lower()
15
15
 
16
16
 
17
- @lru_cache()
17
+ @lru_cache
18
18
  def is_debian() -> bool:
19
19
  from localstack.utils.files import load_file
20
20
 
21
21
  return "Debian" in load_file("/etc/issue", "")
22
22
 
23
23
 
24
- @lru_cache()
24
+ @lru_cache
25
25
  def is_redhat() -> bool:
26
26
  from localstack.utils.files import load_file
27
27
 
localstack/utils/run.py CHANGED
@@ -7,9 +7,10 @@ import subprocess
7
7
  import sys
8
8
  import threading
9
9
  import time
10
+ from collections.abc import Callable
10
11
  from functools import lru_cache
11
12
  from queue import Queue
12
- from typing import Any, AnyStr, Callable, Dict, List, Optional, Union
13
+ from typing import Any, AnyStr
13
14
 
14
15
  from localstack import config
15
16
 
@@ -23,19 +24,19 @@ LOG = logging.getLogger(__name__)
23
24
 
24
25
 
25
26
  def run(
26
- cmd: Union[str, List[str]],
27
+ cmd: str | list[str],
27
28
  print_error=True,
28
29
  asynchronous=False,
29
30
  stdin=False,
30
31
  stderr=subprocess.STDOUT,
31
32
  outfile=None,
32
- env_vars: Optional[Dict[AnyStr, AnyStr]] = None,
33
+ env_vars: dict[AnyStr, AnyStr] | None = None,
33
34
  inherit_cwd=False,
34
35
  inherit_env=True,
35
36
  tty=False,
36
37
  shell=True,
37
38
  cwd: str = None,
38
- ) -> Union[str, subprocess.Popen]:
39
+ ) -> str | subprocess.Popen:
39
40
  LOG.debug("Executing command: %s", cmd)
40
41
  env_dict = os.environ.copy() if inherit_env else {}
41
42
  if env_vars:
@@ -114,7 +115,7 @@ def run(
114
115
  return process
115
116
  except subprocess.CalledProcessError as e:
116
117
  if print_error:
117
- print("ERROR: '%s': exit code %s; output: %s" % (cmd, e.returncode, e.output))
118
+ print(f"ERROR: '{cmd}': exit code {e.returncode}; output: {e.output}")
118
119
  sys.stdout.flush()
119
120
  raise e
120
121
 
@@ -151,7 +152,7 @@ def run_for_max_seconds(max_secs, _function, *args, **kwargs):
151
152
  time.sleep(0.5)
152
153
 
153
154
 
154
- def run_interactive(command: List[str]):
155
+ def run_interactive(command: list[str]):
155
156
  """
156
157
  Run an interactive command in a subprocess. This blocks the current thread and attaches sys.stdin to
157
158
  the process. Copied from https://stackoverflow.com/a/43012138/804840
@@ -196,13 +197,13 @@ def is_root() -> bool:
196
197
  return get_os_user() == "root"
197
198
 
198
199
 
199
- @lru_cache()
200
+ @lru_cache
200
201
  def get_os_user() -> str:
201
202
  # using getpass.getuser() seems to be reporting a different/invalid user in Docker/macOS
202
203
  return run("whoami").strip()
203
204
 
204
205
 
205
- def to_str(obj: Union[str, bytes], errors="strict"):
206
+ def to_str(obj: str | bytes, errors="strict"):
206
207
  return obj.decode(config.DEFAULT_ENCODING, errors) if isinstance(obj, bytes) else obj
207
208
 
208
209
 
@@ -211,10 +212,10 @@ class ShellCommandThread(FuncThread):
211
212
 
212
213
  def __init__(
213
214
  self,
214
- cmd: Union[str, List[str]],
215
+ cmd: str | list[str],
215
216
  params: Any = None,
216
- outfile: Union[str, int] = None,
217
- env_vars: Dict[str, str] = None,
217
+ outfile: str | int = None,
218
+ env_vars: dict[str, str] = None,
218
219
  stdin: bool = False,
219
220
  auto_restart: bool = False,
220
221
  quiet: bool = True,
@@ -223,8 +224,8 @@ class ShellCommandThread(FuncThread):
223
224
  log_listener: Callable = None,
224
225
  stop_listener: Callable = None,
225
226
  strip_color: bool = False,
226
- name: Optional[str] = None,
227
- cwd: Optional[str] = None,
227
+ name: str | None = None,
228
+ cwd: str | None = None,
228
229
  ):
229
230
  params = params if params is not None else {}
230
231
  env_vars = env_vars if env_vars is not None else {}
@@ -268,7 +269,7 @@ class ShellCommandThread(FuncThread):
268
269
  if self.strip_color:
269
270
  # strip color codes
270
271
  line = re.sub(r"\x1b(\[.*?[@-~]|\].*?(\x07|\x1b\\))", "", line)
271
- return "%s\r\n" % line.strip()
272
+ return f"{line.strip()}\r\n"
272
273
 
273
274
  def filter_line(line):
274
275
  """Return True if this line should be filtered, i.e., not printed"""