snowflake-cli-labs 3.0.0rc1__py3-none-any.whl → 3.0.0rc3__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 (92) hide show
  1. snowflake/cli/__about__.py +1 -1
  2. snowflake/cli/_app/cli_app.py +10 -1
  3. snowflake/cli/_app/commands_registration/builtin_plugins.py +2 -0
  4. snowflake/cli/_app/secret.py +9 -0
  5. snowflake/cli/_app/snow_connector.py +110 -51
  6. snowflake/cli/_app/telemetry.py +8 -4
  7. snowflake/cli/_app/version_check.py +74 -0
  8. snowflake/cli/_plugins/git/commands.py +55 -14
  9. snowflake/cli/_plugins/git/manager.py +53 -7
  10. snowflake/cli/_plugins/helpers/commands.py +57 -0
  11. snowflake/cli/{api/commands/typer_pre_execute.py → _plugins/helpers/plugin_spec.py} +14 -10
  12. snowflake/cli/_plugins/nativeapp/application_entity.py +651 -0
  13. snowflake/cli/{api/project/schemas/entities → _plugins/nativeapp}/application_entity_model.py +2 -2
  14. snowflake/cli/_plugins/nativeapp/application_package_entity.py +1107 -0
  15. snowflake/cli/{api/project/schemas/entities → _plugins/nativeapp}/application_package_entity_model.py +3 -3
  16. snowflake/cli/_plugins/nativeapp/artifacts.py +10 -9
  17. snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
  18. snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
  19. snowflake/cli/_plugins/nativeapp/codegen/compiler.py +1 -1
  20. snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +1 -1
  21. snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +1 -1
  22. snowflake/cli/_plugins/nativeapp/codegen/snowpark/models.py +1 -1
  23. snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +3 -6
  24. snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +50 -32
  25. snowflake/cli/_plugins/nativeapp/commands.py +84 -16
  26. snowflake/cli/_plugins/nativeapp/exceptions.py +0 -9
  27. snowflake/cli/_plugins/nativeapp/manager.py +56 -92
  28. snowflake/cli/_plugins/nativeapp/policy.py +3 -0
  29. snowflake/cli/_plugins/nativeapp/project_model.py +2 -2
  30. snowflake/cli/_plugins/nativeapp/run_processor.py +65 -272
  31. snowflake/cli/_plugins/nativeapp/same_account_install_method.py +70 -0
  32. snowflake/cli/_plugins/nativeapp/teardown_processor.py +11 -154
  33. snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +150 -40
  34. snowflake/cli/_plugins/nativeapp/version/commands.py +6 -24
  35. snowflake/cli/_plugins/nativeapp/version/version_processor.py +35 -235
  36. snowflake/cli/_plugins/snowpark/commands.py +5 -5
  37. snowflake/cli/_plugins/snowpark/common.py +4 -4
  38. snowflake/cli/_plugins/snowpark/models.py +2 -1
  39. snowflake/cli/{api/entities → _plugins/snowpark}/snowpark_entity.py +2 -2
  40. snowflake/cli/{api/project/schemas/entities/snowpark_entity.py → _plugins/snowpark/snowpark_entity_model.py} +3 -6
  41. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +1 -1
  42. snowflake/cli/_plugins/stage/manager.py +9 -4
  43. snowflake/cli/_plugins/streamlit/commands.py +4 -4
  44. snowflake/cli/_plugins/streamlit/manager.py +17 -4
  45. snowflake/cli/{api/entities → _plugins/streamlit}/streamlit_entity.py +2 -2
  46. snowflake/cli/{api/project/schemas/entities → _plugins/streamlit}/streamlit_entity_model.py +5 -12
  47. snowflake/cli/_plugins/workspace/action_context.py +2 -1
  48. snowflake/cli/_plugins/workspace/commands.py +127 -48
  49. snowflake/cli/_plugins/workspace/manager.py +1 -0
  50. snowflake/cli/_plugins/workspace/plugin_spec.py +1 -1
  51. snowflake/cli/api/cli_global_context.py +136 -313
  52. snowflake/cli/api/commands/flags.py +76 -91
  53. snowflake/cli/api/commands/snow_typer.py +7 -5
  54. snowflake/cli/api/config.py +1 -1
  55. snowflake/cli/api/connections.py +214 -0
  56. snowflake/cli/api/console/abc.py +4 -2
  57. snowflake/cli/api/entities/common.py +4 -0
  58. snowflake/cli/api/entities/utils.py +41 -31
  59. snowflake/cli/api/errno.py +1 -0
  60. snowflake/cli/api/identifiers.py +7 -3
  61. snowflake/cli/api/project/definition.py +11 -0
  62. snowflake/cli/api/project/definition_conversion.py +175 -16
  63. snowflake/cli/api/project/schemas/entities/common.py +15 -14
  64. snowflake/cli/api/project/schemas/entities/entities.py +13 -10
  65. snowflake/cli/api/project/schemas/project_definition.py +107 -45
  66. snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
  67. snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +0 -7
  68. snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
  69. snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
  70. snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
  71. snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
  72. snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
  73. snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
  74. snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
  75. snowflake/cli/api/rendering/project_definition_templates.py +4 -0
  76. snowflake/cli/api/rendering/sql_templates.py +7 -0
  77. snowflake/cli/api/sql_execution.py +6 -15
  78. snowflake/cli/api/utils/definition_rendering.py +3 -1
  79. {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/METADATA +9 -9
  80. {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/RECORD +88 -81
  81. snowflake/cli/api/entities/application_entity.py +0 -12
  82. snowflake/cli/api/entities/application_package_entity.py +0 -553
  83. snowflake/cli/api/project/schemas/snowpark/__init__.py +0 -13
  84. snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
  85. /snowflake/cli/{api/project/schemas/native_app → _plugins/helpers}/__init__.py +0 -0
  86. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +0 -0
  87. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +0 -0
  88. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
  89. /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
  90. {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/WHEEL +0 -0
  91. {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/entry_points.txt +0 -0
  92. {snowflake_cli_labs-3.0.0rc1.dist-info → snowflake_cli_labs-3.0.0rc3.dist-info}/licenses/LICENSE +0 -0
@@ -19,29 +19,29 @@ from typing import Any, Dict, List, Optional, Union
19
19
 
20
20
  from packaging.version import Version
21
21
  from pydantic import Field, ValidationError, field_validator, model_validator
22
- from snowflake.cli.api.project.errors import SchemaValidationError
23
- from snowflake.cli.api.project.schemas.entities.application_entity_model import (
22
+ from snowflake.cli._plugins.nativeapp.application_entity_model import (
24
23
  ApplicationEntityModel,
25
24
  )
25
+ from snowflake.cli.api.project.errors import SchemaValidationError
26
26
  from snowflake.cli.api.project.schemas.entities.common import (
27
- DefaultsField,
28
27
  TargetField,
29
28
  )
30
29
  from snowflake.cli.api.project.schemas.entities.entities import (
31
30
  EntityModel,
32
31
  v2_entity_model_types_map,
33
32
  )
34
- from snowflake.cli.api.project.schemas.native_app.native_app import (
33
+ from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
34
+ from snowflake.cli.api.project.schemas.v1.native_app.native_app import (
35
35
  NativeApp,
36
36
  NativeAppV11,
37
37
  )
38
- from snowflake.cli.api.project.schemas.snowpark.snowpark import Snowpark
39
- from snowflake.cli.api.project.schemas.streamlit.streamlit import Streamlit
40
- from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
38
+ from snowflake.cli.api.project.schemas.v1.snowpark.snowpark import Snowpark
39
+ from snowflake.cli.api.project.schemas.v1.streamlit.streamlit import Streamlit
41
40
  from snowflake.cli.api.utils.types import Context
42
41
  from typing_extensions import Annotated
43
42
 
44
43
  AnnotatedEntity = Annotated[EntityModel, Field(discriminator="type")]
44
+ scalar = str | int | float | bool
45
45
 
46
46
 
47
47
  @dataclass
@@ -62,6 +62,11 @@ class ProjectProperties:
62
62
  project_context: Context
63
63
 
64
64
 
65
+ @dataclass
66
+ class YamlOverride:
67
+ data: dict | list
68
+
69
+
65
70
  class _ProjectDefinitionBase(UpdatableModel):
66
71
  def __init__(self, *args, **kwargs):
67
72
  try:
@@ -114,31 +119,12 @@ class DefinitionV11(DefinitionV10):
114
119
  class DefinitionV20(_ProjectDefinitionBase):
115
120
  entities: Dict[str, AnnotatedEntity] = Field(title="Entity definitions.")
116
121
 
117
- @model_validator(mode="before")
118
- @classmethod
119
- def apply_defaults(cls, data: Dict) -> Dict:
120
- """
121
- Applies default values that exist on the model but not specified in yml
122
- """
123
- if "defaults" in data and "entities" in data:
124
- for key, entity in data["entities"].items():
125
- entity_fields = get_allowed_fields_for_entity(entity)
126
- if not entity_fields:
127
- continue
128
- for default_key, default_value in data["defaults"].items():
129
- if default_key in entity_fields and default_key not in entity:
130
- entity[default_key] = default_value
131
- return data
132
-
133
- @field_validator("entities", mode="after")
134
- @classmethod
135
- def validate_entities_identifiers(
136
- cls, entities: Dict[str, EntityModel]
137
- ) -> Dict[str, EntityModel]:
138
- for key, entity in entities.items():
122
+ @model_validator(mode="after")
123
+ def validate_entities_identifiers(self):
124
+ for key, entity in self.entities.items():
139
125
  entity.set_entity_id(key)
140
126
  entity.validate_identifier()
141
- return entities
127
+ return self
142
128
 
143
129
  @field_validator("entities", mode="after")
144
130
  @classmethod
@@ -179,11 +165,6 @@ class DefinitionV20(_ProjectDefinitionBase):
179
165
  f"Target type mismatch. Expected {target_type.__name__}, got {actual_target_type.__name__}"
180
166
  )
181
167
 
182
- defaults: Optional[DefaultsField] = Field(
183
- title="Default key/value entity values that are merged recursively for each entity.",
184
- default=None,
185
- )
186
-
187
168
  env: Optional[Dict[str, Union[str, int, bool]]] = Field(
188
169
  title="Default environment specification for this project.",
189
170
  default=None,
@@ -203,22 +184,92 @@ class DefinitionV20(_ProjectDefinitionBase):
203
184
  if "mixins" not in data or "entities" not in data:
204
185
  return data
205
186
 
206
- for entity in data["entities"].values():
187
+ entities = data["entities"]
188
+ for entity_name, entity in entities.items():
207
189
  entity_mixins = entity_mixins_to_list(
208
190
  entity.get("meta", {}).get("use_mixins")
209
191
  )
210
192
 
211
- entity_fields = get_allowed_fields_for_entity(entity)
212
- if entity_fields and entity_mixins:
213
- for mixin_name in entity_mixins:
214
- if mixin_name in data["mixins"]:
215
- for key, value in data["mixins"][mixin_name].items():
216
- if key in entity_fields:
217
- entity[key] = value
218
- else:
219
- raise ValueError(f"Mixin {mixin_name} not found in mixins")
193
+ merged_values = cls._merge_mixins_with_entity(
194
+ entity_id=entity_name,
195
+ entity=entity,
196
+ entity_mixins_names=entity_mixins,
197
+ mixin_defs=data["mixins"],
198
+ )
199
+ entities[entity_name] = merged_values
200
+ return data
201
+
202
+ @classmethod
203
+ def _merge_mixins_with_entity(
204
+ cls,
205
+ entity_id: str,
206
+ entity: dict,
207
+ entity_mixins_names: list,
208
+ mixin_defs: dict,
209
+ ) -> dict:
210
+ # Validate mixins
211
+ for mixin_name in entity_mixins_names:
212
+ if mixin_name not in mixin_defs:
213
+ raise ValueError(f"Mixin {mixin_name} not defined")
214
+
215
+ # Build object override data from mixins
216
+ data: dict = {}
217
+ for mx_name in entity_mixins_names:
218
+ data = cls._merge_data(data, mixin_defs[mx_name])
219
+
220
+ for key, override_value in data.items():
221
+ if key not in get_allowed_fields_for_entity(entity):
222
+ raise ValueError(
223
+ f"Unsupported key '{key}' for entity {entity_id} of type {entity['type']} "
224
+ )
225
+
226
+ entity_value = entity.get(key)
227
+ if (
228
+ entity_value is not None
229
+ and not isinstance(entity_value, YamlOverride)
230
+ and not isinstance(entity_value, type(override_value))
231
+ ):
232
+ raise ValueError(
233
+ f"Value from mixins for property {key} is of type '{type(override_value).__name__}' "
234
+ f"while entity {entity_id} expects value of type '{type(entity_value).__name__}'"
235
+ )
236
+
237
+ # Apply entity data on top of mixins
238
+ data = cls._merge_data(data, entity)
220
239
  return data
221
240
 
241
+ @classmethod
242
+ def _merge_data(
243
+ cls,
244
+ left: dict | list | scalar | None,
245
+ right: dict | list | scalar | None | YamlOverride,
246
+ ):
247
+ """
248
+ Merges right data into left. Right and left is expected to be of the same type, if not right is returned.
249
+ If left is sequence then missing elements from right are appended.
250
+ If left is dictionary then we update it with data from right. The update is done recursively key by key.
251
+ """
252
+ if isinstance(right, YamlOverride):
253
+ return right.data
254
+
255
+ if left is None:
256
+ return right
257
+
258
+ # At that point left and right are of the same type
259
+ if isinstance(left, dict) and isinstance(right, dict):
260
+ data = dict(left)
261
+ for key in right:
262
+ data[key] = cls._merge_data(left=data.get(key), right=right[key])
263
+ return data
264
+
265
+ if isinstance(left, list) and isinstance(right, list):
266
+ return _unique_extend(left, right)
267
+
268
+ if not isinstance(right, type(left)):
269
+ raise ValueError(f"Could not merge {type(right)} and {type(left)}.")
270
+
271
+ return right
272
+
222
273
  def get_entities_by_type(self, entity_type: str):
223
274
  return {i: e for i, e in self.entities.items() if e.get_type() == entity_type}
224
275
 
@@ -263,8 +314,19 @@ def get_allowed_fields_for_entity(entity: Dict[str, Any]) -> List[str]:
263
314
  Get the allowed fields for the given entity.
264
315
  """
265
316
  entity_type = entity.get("type")
317
+ if entity_type is None:
318
+ raise ValueError("Entity is missing type declaration.")
319
+
266
320
  if entity_type not in v2_entity_model_types_map:
267
321
  return []
268
322
 
269
323
  entity_model = v2_entity_model_types_map[entity_type]
270
324
  return entity_model.model_fields
325
+
326
+
327
+ def _unique_extend(list_a: List, list_b: List) -> List:
328
+ new_list = list(list_a)
329
+ for item in list_b:
330
+ if item not in list_a:
331
+ new_list.append(item)
332
+ return new_list
File without changes
@@ -19,16 +19,9 @@ from typing import Optional, cast
19
19
  from pydantic import Field
20
20
  from snowflake.cli.api.project.schemas.updatable_model import (
21
21
  IdentifierField,
22
- UpdatableModel,
23
22
  )
24
23
 
25
24
 
26
- class Identifier(UpdatableModel):
27
- name: str = Field(title="Entity name")
28
- schema_: str = Field(title="Entity schema", alias="schema", default=None)
29
- database: str = Field(title="Entity database", default=None)
30
-
31
-
32
25
  class ObjectIdentifierBaseModel:
33
26
  """
34
27
  Type representing a base class defining object that can be identified by fully qualified name (db.schema.name).
@@ -18,13 +18,13 @@ import re
18
18
  from typing import List, Optional, Union
19
19
 
20
20
  from pydantic import Field, field_validator
21
- from snowflake.cli.api.project.schemas.native_app.application import (
21
+ from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
22
+ from snowflake.cli.api.project.schemas.v1.native_app.application import (
22
23
  Application,
23
24
  ApplicationV11,
24
25
  )
25
- from snowflake.cli.api.project.schemas.native_app.package import Package, PackageV11
26
- from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
27
- from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
26
+ from snowflake.cli.api.project.schemas.v1.native_app.package import Package, PackageV11
27
+ from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
28
28
  from snowflake.cli.api.project.util import (
29
29
  SCHEMA_AND_NAME,
30
30
  )
@@ -17,9 +17,9 @@ from __future__ import annotations
17
17
  from typing import Dict, List, Optional, Union
18
18
 
19
19
  from pydantic import Field, field_validator
20
- from snowflake.cli.api.project.schemas.identifier_model import ObjectIdentifierModel
21
- from snowflake.cli.api.project.schemas.snowpark.argument import Argument
22
20
  from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
21
+ from snowflake.cli.api.project.schemas.v1.identifier_model import ObjectIdentifierModel
22
+ from snowflake.cli.api.project.schemas.v1.snowpark.argument import Argument
23
23
 
24
24
 
25
25
  class _CallableBase(UpdatableModel):
@@ -17,11 +17,11 @@ from __future__ import annotations
17
17
  from typing import List, Optional
18
18
 
19
19
  from pydantic import Field
20
- from snowflake.cli.api.project.schemas.snowpark.callable import (
20
+ from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
21
+ from snowflake.cli.api.project.schemas.v1.snowpark.callable import (
21
22
  FunctionSchema,
22
23
  ProcedureSchema,
23
24
  )
24
- from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
25
25
 
26
26
 
27
27
  class Snowpark(UpdatableModel):
@@ -18,8 +18,8 @@ from pathlib import Path
18
18
  from typing import List, Optional
19
19
 
20
20
  from pydantic import Field
21
- from snowflake.cli.api.project.schemas.identifier_model import ObjectIdentifierModel
22
21
  from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
22
+ from snowflake.cli.api.project.schemas.v1.identifier_model import ObjectIdentifierModel
23
23
 
24
24
 
25
25
  class Streamlit(UpdatableModel, ObjectIdentifierModel(object_name="Streamlit")): # type: ignore
@@ -44,3 +44,4 @@ class Streamlit(UpdatableModel, ObjectIdentifierModel(object_name="Streamlit")):
44
44
  title: Optional[str] = Field(
45
45
  title="Human-readable title for the Streamlit dashboard", default=None
46
46
  )
47
+ comment: Optional[str] = Field(title="Comment for the Streamlit app", default=None)
@@ -24,6 +24,10 @@ _YML_TEMPLATE_START = "<%"
24
24
  _YML_TEMPLATE_END = "%>"
25
25
 
26
26
 
27
+ def has_client_side_templates(template_content: str) -> bool:
28
+ return _YML_TEMPLATE_START in template_content
29
+
30
+
27
31
  def get_client_side_jinja_env() -> Environment:
28
32
  _random_block = "___very___unique___block___to___disable___logic___blocks___"
29
33
  return env_bootstrap(
@@ -55,6 +55,13 @@ def _does_template_have_env_syntax(env: Environment, template_content: str) -> b
55
55
  return bool(meta.find_undeclared_variables(template))
56
56
 
57
57
 
58
+ def has_sql_templates(template_content: str) -> bool:
59
+ return (
60
+ _OLD_SQL_TEMPLATE_START in template_content
61
+ or _SQL_TEMPLATE_START in template_content
62
+ )
63
+
64
+
58
65
  def choose_sql_jinja_env_based_on_template_syntax(
59
66
  template_content: str, reference_name: Optional[str] = None
60
67
  ) -> Environment:
@@ -98,11 +98,7 @@ class SqlExecutor:
98
98
  )
99
99
 
100
100
  def current_role(self) -> str:
101
- *_, cursor = self._execute_string(
102
- "select current_role()", cursor_class=DictCursor
103
- )
104
- role_result = cursor.fetchone()
105
- return role_result["CURRENT_ROLE()"]
101
+ return self._execute_query(f"select current_role()").fetchone()[0]
106
102
 
107
103
  @contextmanager
108
104
  def use_role(self, new_role: str):
@@ -110,10 +106,7 @@ class SqlExecutor:
110
106
  Switches to a different role for a while, then switches back.
111
107
  This is a no-op if the requested role is already active.
112
108
  """
113
- role_result = self._execute_query(
114
- f"select current_role()", cursor_class=DictCursor
115
- ).fetchone()
116
- prev_role = role_result["CURRENT_ROLE()"]
109
+ prev_role = self.current_role()
117
110
  is_different_role = new_role.lower() != prev_role.lower()
118
111
  if is_different_role:
119
112
  self._log.debug("Assuming different role: %s", new_role)
@@ -126,9 +119,9 @@ class SqlExecutor:
126
119
 
127
120
  def session_has_warehouse(self) -> bool:
128
121
  result = self._execute_query(
129
- "select current_warehouse() is not null as result", cursor_class=DictCursor
122
+ "select current_warehouse() is not null"
130
123
  ).fetchone()
131
- return bool(result.get("RESULT"))
124
+ return bool(result[0])
132
125
 
133
126
  @contextmanager
134
127
  def use_warehouse(self, new_wh: str):
@@ -138,12 +131,10 @@ class SqlExecutor:
138
131
  If there is no default warehouse in the account, it will throw an error.
139
132
  """
140
133
 
141
- wh_result = self._execute_query(
142
- f"select current_warehouse()", cursor_class=DictCursor
143
- ).fetchone()
134
+ wh_result = self._execute_query(f"select current_warehouse()").fetchone()
144
135
  # If user has an assigned default warehouse, prev_wh will contain a value even if the warehouse is suspended.
145
136
  try:
146
- prev_wh = wh_result["CURRENT_WAREHOUSE()"]
137
+ prev_wh = wh_result[0]
147
138
  except:
148
139
  prev_wh = None
149
140
 
@@ -277,7 +277,9 @@ def _add_defaults_to_definition(original_definition: Definition) -> Definition:
277
277
  with context({"skip_validation_on_templates": True}):
278
278
  # pass a flag to Pydantic to skip validation for templated scalars
279
279
  # populate the defaults
280
- project_definition = build_project_definition(**original_definition)
280
+ project_definition = build_project_definition(
281
+ **copy.deepcopy(original_definition)
282
+ )
281
283
 
282
284
  definition_with_defaults = project_definition.model_dump(
283
285
  exclude_none=True, warnings=False, by_alias=True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: snowflake-cli-labs
3
- Version: 3.0.0rc1
3
+ Version: 3.0.0rc3
4
4
  Summary: Snowflake CLI
5
5
  Project-URL: Source code, https://github.com/snowflakedb/snowflake-cli
6
6
  Project-URL: Bug Tracker, https://github.com/snowflakedb/snowflake-cli/issues
@@ -222,14 +222,14 @@ Requires-Dist: jinja2==3.1.4
222
222
  Requires-Dist: packaging
223
223
  Requires-Dist: pip
224
224
  Requires-Dist: pluggy==1.5.0
225
- Requires-Dist: pydantic==2.8.2
226
- Requires-Dist: pyyaml==6.0.1
225
+ Requires-Dist: pydantic==2.9.1
226
+ Requires-Dist: pyyaml==6.0.2
227
227
  Requires-Dist: requests==2.32.3
228
228
  Requires-Dist: requirements-parser==0.11.0
229
- Requires-Dist: rich==13.7.1
230
- Requires-Dist: setuptools==74.1.0
231
- Requires-Dist: snowflake-connector-python[secure-local-storage]==3.12.1
232
- Requires-Dist: snowflake-core==0.8.0; python_version < '3.12'
229
+ Requires-Dist: rich==13.8.1
230
+ Requires-Dist: setuptools==75.1.0
231
+ Requires-Dist: snowflake-connector-python[secure-local-storage]==3.12.2
232
+ Requires-Dist: snowflake-core==0.12.1; python_version < '3.12'
233
233
  Requires-Dist: snowflake-snowpark-python>=1.15.0; python_version < '3.12'
234
234
  Requires-Dist: tomlkit==0.13.2
235
235
  Requires-Dist: typer==0.12.5
@@ -238,8 +238,8 @@ Provides-Extra: development
238
238
  Requires-Dist: coverage==7.6.1; extra == 'development'
239
239
  Requires-Dist: pre-commit>=3.5.0; extra == 'development'
240
240
  Requires-Dist: pytest-randomly==3.15.0; extra == 'development'
241
- Requires-Dist: pytest==8.3.2; extra == 'development'
242
- Requires-Dist: syrupy==4.6.1; extra == 'development'
241
+ Requires-Dist: pytest==8.3.3; extra == 'development'
242
+ Requires-Dist: syrupy==4.7.1; extra == 'development'
243
243
  Description-Content-Type: text/markdown
244
244
 
245
245
  <!--