Skip to content

Commit e640ffd

Browse files
authored
[Python] Keep deprecated fields in Python code (#3384)
## Changes Python code generation doesn't remove deprecated fields anymore unless they were deprecated during Private Preview. A few fields are manually excluded because they have been deprecated for many years and have never functioned. Remove `ForceNotDeprecated` annotation because it isn't needed anymore. ## Why During updates, removing deprecated fields immediately can be surprising because there is no prior notice. There are also bundles that rely on the usage of deprecated fields. ## Tests By looking at diffs in the generated code
1 parent 40e31a1 commit e640ffd

22 files changed

+211
-28
lines changed

bundle/docsgen/main.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,6 @@ func assignAnnotation(s *jsonschema.Schema, a annotation.Descriptor) {
137137
s.Deprecated = true
138138
s.DeprecationMessage = a.DeprecationMessage
139139
}
140-
if a.ForceNotDeprecated {
141-
s.Deprecated = false
142-
s.DeprecationMessage = ""
143-
}
144140
if a.Preview == "PRIVATE" {
145141
s.DoNotSuggest = true
146142
s.Preview = a.Preview

bundle/internal/annotation/descriptor.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ type Descriptor struct {
99
MarkdownExamples string `json:"markdown_examples,omitempty"`
1010
DeprecationMessage string `json:"deprecation_message,omitempty"`
1111
Preview string `json:"x-databricks-preview,omitempty"`
12-
13-
// If true, takes priority over 'DeprecationMessage'
14-
ForceNotDeprecated bool `json:"force_not_deprecated,omitempty"`
1512
}
1613

1714
const Placeholder = "PLACEHOLDER"

bundle/internal/schema/annotations.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ func assignAnnotation(s *jsonschema.Schema, a annotation.Descriptor) {
138138
s.Preview = a.Preview
139139
}
140140

141-
if a.ForceNotDeprecated {
142-
s.Deprecated = false
143-
s.DeprecationMessage = ""
144-
}
145-
146141
s.MarkdownDescription = convertLinksToAbsoluteUrl(a.MarkdownDescription)
147142
s.Title = a.Title
148143
s.Enum = a.Enum

bundle/internal/schema/annotations_openapi_overrides.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,6 @@ github.com/databricks/cli/bundle/config/resources.Pipeline:
353353
"run_as":
354354
"description": |-
355355
PLACEHOLDER
356-
"target":
357-
"force_not_deprecated": |-
358-
true
359356
"trigger":
360357
"deprecation_message": |-
361358
Use continuous instead

bundle/schema/jsonschema.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

experimental/python/codegen/codegen/generated_dataclass.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ class GeneratedField:
102102
be marked as experimental in docstring.
103103
"""
104104

105+
deprecated: bool
106+
"""
107+
If true, the field is deprecated and should be marked as deprecated in docstring.
108+
"""
109+
105110
def __post_init__(self):
106111
if self.default_factory is not None and self.default is not None:
107112
raise ValueError("Can't have both default and default_factory", self)
@@ -131,6 +136,7 @@ class GeneratedDataclass:
131136
fields: list[GeneratedField]
132137
extends: list[GeneratedType]
133138
experimental: bool
139+
deprecated: bool
134140

135141

136142
def generate_field(
@@ -156,6 +162,7 @@ def generate_field(
156162
default_factory="dict",
157163
create_func_default="None",
158164
experimental=prop.stage == Stage.PRIVATE,
165+
deprecated=prop.deprecated or False,
159166
)
160167
elif field_type.name == "VariableOrList":
161168
return GeneratedField(
@@ -168,6 +175,7 @@ def generate_field(
168175
default_factory="list",
169176
create_func_default="None",
170177
experimental=prop.stage == Stage.PRIVATE,
178+
deprecated=prop.deprecated or False,
171179
)
172180
elif is_required:
173181
return GeneratedField(
@@ -180,6 +188,7 @@ def generate_field(
180188
default_factory=None,
181189
create_func_default=None,
182190
experimental=prop.stage == Stage.PRIVATE,
191+
deprecated=prop.deprecated or False,
183192
)
184193
else:
185194
return GeneratedField(
@@ -192,6 +201,7 @@ def generate_field(
192201
default_factory=None,
193202
create_func_default="None",
194203
experimental=prop.stage == Stage.PRIVATE,
204+
deprecated=prop.deprecated or False,
195205
)
196206

197207

@@ -326,6 +336,7 @@ def generate_dataclass(
326336
fields=fields,
327337
extends=extends,
328338
experimental=schema.stage == Stage.PRIVATE,
339+
deprecated=schema.deprecated or False,
329340
)
330341

331342

@@ -365,10 +376,19 @@ def _append_dataclass(b: CodeBuilder, generated: GeneratedDataclass):
365376
b.append(":").newline()
366377

367378
# FIXME should contain class docstring
368-
if not generated.description and not generated.experimental:
379+
if (
380+
not generated.description
381+
and not generated.experimental
382+
and not generated.deprecated
383+
):
369384
b.indent().append_triple_quote().append_triple_quote().newline().newline()
370385
else:
371-
_append_description(b, generated.description, generated.experimental)
386+
_append_description(
387+
b,
388+
generated.description,
389+
experimental=generated.experimental,
390+
deprecated=generated.deprecated,
391+
)
372392

373393

374394
def _append_field(b: CodeBuilder, field: GeneratedField):
@@ -446,7 +466,12 @@ def _append_typed_dict(b: CodeBuilder, generated: GeneratedDataclass):
446466
b.indent().append_triple_quote().append_triple_quote().newline().newline()
447467

448468

449-
def _append_description(b: CodeBuilder, description: Optional[str], experimental: bool):
469+
def _append_description(
470+
b: CodeBuilder, description: Optional[str], *, experimental: bool, deprecated: bool
471+
):
472+
if deprecated:
473+
description = "[DEPRECATED] " + (description or "")
474+
450475
if description or experimental:
451476
b.indent().append_triple_quote().newline()
452477
if experimental:
@@ -472,7 +497,12 @@ def get_code(generated: GeneratedDataclass) -> str:
472497

473498
for field in generated.fields:
474499
_append_field(b, field)
475-
_append_description(b, field.description, field.experimental)
500+
_append_description(
501+
b,
502+
field.description,
503+
experimental=field.experimental,
504+
deprecated=field.deprecated,
505+
)
476506

477507
b.newline()
478508

@@ -485,7 +515,12 @@ def get_code(generated: GeneratedDataclass) -> str:
485515

486516
for field in generated.fields:
487517
_append_typed_dict_field(b, field)
488-
_append_description(b, field.description, field.experimental)
518+
_append_description(
519+
b,
520+
field.description,
521+
experimental=field.experimental,
522+
deprecated=field.deprecated,
523+
)
489524

490525
b.newline()
491526

experimental/python/codegen/codegen/generated_enum.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class GeneratedEnum:
1515
values: dict[str, str]
1616
description: Optional[str]
1717
experimental: bool
18+
deprecated: bool
1819

1920

2021
def generate_enum(namespace: str, schema_name: str, schema: Schema) -> GeneratedEnum:
@@ -35,6 +36,7 @@ def generate_enum(namespace: str, schema_name: str, schema: Schema) -> Generated
3536
values=values,
3637
description=schema.description,
3738
experimental=schema.stage == Stage.PRIVATE,
39+
deprecated=schema.deprecated or False,
3840
)
3941

4042

@@ -48,7 +50,12 @@ def get_code(generated: GeneratedEnum) -> str:
4850
b.append(f"class {generated.class_name}(Enum):")
4951
b.newline()
5052

51-
_append_description(b, generated.description, generated.experimental)
53+
_append_description(
54+
b,
55+
generated.description,
56+
experimental=generated.experimental,
57+
deprecated=generated.deprecated,
58+
)
5259

5360
# Example:
5461
#

experimental/python/codegen/codegen/jsonschema_patch.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
# doesn't work, openapi schema needs to be updated to be enum
88
"kind",
99
},
10+
# fields that were deprecated a long time ago
11+
"resources.Pipeline": {
12+
# 'trigger' is deprecated, use 'continuous' or schedule pipeline refresh using job instead
13+
"trigger",
14+
},
15+
"pipelines.PipelineLibrary": [
16+
# 'whl' is deprecated, install libraries through notebooks and %pip command
17+
"whl",
18+
],
1019
}
1120

1221
EXTRA_REQUIRED_FIELDS: dict[str, list[str]] = {

experimental/python/codegen/codegen/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,17 @@ def _transitively_mark_deprecated_and_private(
7777
def _remove_deprecated_fields(
7878
schemas: dict[str, openapi.Schema],
7979
) -> dict[str, openapi.Schema]:
80+
"""
81+
Remove fields that were deprecated during Private Preview.
82+
"""
83+
8084
new_schemas = {}
8185

8286
for name, schema in schemas.items():
8387
if schema.type == openapi.SchemaType.OBJECT:
8488
new_properties = {}
8589
for field_name, field in schema.properties.items():
86-
if field.deprecated:
90+
if field.deprecated and field.stage == openapi.Stage.PRIVATE:
8791
continue
8892

8993
new_properties[field_name] = field

experimental/python/codegen/codegen_tests/test_generated_dataclass.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ def test_generate_dataclass():
6969
param_type_name=variable_or_type(str_type(), is_required=True),
7070
type_name=variable_or_type(str_type(), is_required=True),
7171
experimental=False,
72+
deprecated=False,
7273
),
7374
],
7475
experimental=False,
76+
deprecated=False,
7577
)
7678

7779

0 commit comments

Comments
 (0)