Skip to content

Commit b3c7976

Browse files
authored
chore(python): Upgrade to IRv57 (#6476)
1 parent c4f4655 commit b3c7976

File tree

452 files changed

+12933
-7955
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

452 files changed

+12933
-7955
lines changed
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 0.56.25
2+
**`(internal):`** The CLI now recognizes that the latest Python SDK uses IRv57.
3+
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 1.6.3
2+
**`(internal):`** Update the IR to v57.
3+
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 1.4.8
2+
**`(internal):`** Update the IR to v57.
3+
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 4.3.19
2+
**`(internal):`** Update the IR to v57.
3+
4+

generators/python/fastapi/versions.yml

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
# For unreleased changes, use unreleased.yml
2+
- version: 1.6.3
3+
irVersion: 57
4+
changelogEntry:
5+
- type: internal
6+
summary: |
7+
Update the IR to v57.
8+
29
- version: 1.6.2
310
irVersion: 53
411
changelogEntry:

generators/python/poetry.lock

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generators/python/pydantic/versions.yml

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
# For unreleased changes, use unreleased.yml
2+
- version: 1.4.8
3+
irVersion: 57
4+
changelogEntry:
5+
- type: internal
6+
summary: |
7+
Update the IR to v57.
8+
29
- version: 1.4.7
310
irVersion: 53
411
changelogEntry:

generators/python/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ordered-set = "^4.1.0"
1313
pydantic-core = "^2.18.2"
1414
fern-fern-fdr-sdk = { version = "0.98.20", source = "fern-prod" }
1515
fern-fern-generator-cli-sdk = { version = "0.0.18", source = "fern-prod" }
16-
fern_fern_ir_v53 = "53.12.0"
16+
fern_fern_ir_v57 = "57.0.0"
1717

1818
[tool.poetry.dev-dependencies]
1919
pytest = "^7.4.2"

generators/python/sdk/versions.yml

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
# For unreleased changes, use unreleased.yml
2+
- version: 4.3.19
3+
irVersion: 57
4+
changelogEntry:
5+
- type: internal
6+
summary: |
7+
Update the IR to v57.
8+
29
- version: 4.3.18
310
irVersion: 53
411
changelogEntry:

generators/python/src/fern_python/generator_cli/reference_config_builder.py

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def _visit_type_reference(self, type_reference: ir_types.TypeReference) -> Optio
5151
list_=lambda tr: self._visit_type_reference(tr),
5252
map_=lambda _: None,
5353
optional=lambda tr: self._visit_type_reference(tr),
54+
nullable=lambda tr: self._visit_type_reference(tr),
5455
set_=lambda tr: self._visit_type_reference(tr),
5556
literal=lambda _: None,
5657
),

generators/python/src/fern_python/generators/context/pydantic_generator_context_impl.py

+7
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ def get_initializer_for_type_reference(
144144
set_=lambda _: None,
145145
# Ignore literal defaults when the wrapping type is optional
146146
optional=lambda opt: self.get_initializer_for_type_reference(opt, ignore_literals=True),
147+
nullable=lambda nullable: self.get_initializer_for_type_reference(nullable, ignore_literals=True),
147148
map_=lambda _: None,
148149
)
149150

@@ -247,6 +248,7 @@ def get_referenced_types_of_type_reference(self, type_reference: ir_types.TypeRe
247248
list_=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
248249
set_=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
249250
optional=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
251+
nullable=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
250252
map_=lambda map_type: (
251253
self.get_referenced_types_of_type_reference(map_type.key_type).union(
252254
self.get_referenced_types_of_type_reference(map_type.value_type)
@@ -267,6 +269,7 @@ def get_type_names_in_type_reference(self, type_reference: ir_types.TypeReferenc
267269
list_=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
268270
set_=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
269271
optional=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
272+
nullable=lambda item_type: self.get_referenced_types_of_type_reference(item_type),
270273
map_=lambda map_type: (
271274
self.get_referenced_types_of_type_reference(map_type.key_type).union(
272275
self.get_referenced_types_of_type_reference(map_type.value_type)
@@ -288,6 +291,7 @@ def maybe_get_type_ids_for_type_reference(
288291
map_=lambda mt: (self.maybe_get_type_ids_for_type_reference(mt.key_type) or []).extend(
289292
self.maybe_get_type_ids_for_type_reference(mt.value_type) or []
290293
),
294+
nullable=lambda nullable_tr: self.maybe_get_type_ids_for_type_reference(nullable_tr),
291295
optional=lambda optional_tr: self.maybe_get_type_ids_for_type_reference(optional_tr),
292296
set_=lambda set_tr: self.maybe_get_type_ids_for_type_reference(set_tr),
293297
literal=lambda _: None,
@@ -316,6 +320,9 @@ def unwrap_example_type_reference(
316320
optional=lambda optional: self.unwrap_example_type_reference(optional.optional)
317321
if optional.optional is not None
318322
else example_type_reference,
323+
nullable=lambda nullable: self.unwrap_example_type_reference(nullable.nullable)
324+
if nullable.nullable is not None
325+
else example_type_reference,
319326
map_=lambda _: example_type_reference,
320327
literal=lambda _: example_type_reference,
321328
),

generators/python/src/fern_python/generators/context/type_reference_to_type_hint_converter.py

+43-1
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,33 @@ def _get_type_hint_for_container(
147147
),
148148
unknown=lambda: AST.TypeHint.list(AST.TypeHint.any()),
149149
),
150-
optional=lambda wrapped_type: AST.TypeHint.optional(
150+
nullable=lambda wrapped_type: AST.TypeHint.optional(
151+
self.get_type_hint_for_type_reference(
152+
type_reference=self._unbox_type_reference(wrapped_type),
153+
must_import_after_current_declaration=must_import_after_current_declaration,
154+
as_if_type_checking_import=as_if_type_checking_import,
155+
in_endpoint=in_endpoint,
156+
for_typeddict=for_typeddict,
157+
)
158+
)
159+
if not for_typeddict
160+
else AST.TypeHint.not_required(
151161
self.get_type_hint_for_type_reference(
152162
type_reference=wrapped_type,
153163
must_import_after_current_declaration=must_import_after_current_declaration,
154164
as_if_type_checking_import=as_if_type_checking_import,
155165
in_endpoint=in_endpoint,
156166
for_typeddict=for_typeddict,
157167
)
168+
),
169+
optional=lambda wrapped_type: AST.TypeHint.optional(
170+
self.get_type_hint_for_type_reference(
171+
type_reference=self._unbox_type_reference(wrapped_type),
172+
must_import_after_current_declaration=must_import_after_current_declaration,
173+
as_if_type_checking_import=as_if_type_checking_import,
174+
in_endpoint=in_endpoint,
175+
for_typeddict=for_typeddict,
176+
)
158177
)
159178
if not for_typeddict
160179
else AST.TypeHint.not_required(
@@ -209,3 +228,26 @@ def _get_type_hint_for_primitive(self, primitive: ir_types.PrimitiveType) -> AST
209228
float_=AST.TypeHint.float_,
210229
)
211230
return to_return
231+
232+
def _unbox_type_reference(self, type_reference: ir_types.TypeReference) -> ir_types.TypeReference:
233+
return type_reference.visit(
234+
container=lambda container: self._unbox_type_reference_container(
235+
type_reference=type_reference,
236+
container=container,
237+
),
238+
named=lambda _: type_reference,
239+
primitive=lambda _: type_reference,
240+
unknown=lambda: type_reference,
241+
)
242+
243+
def _unbox_type_reference_container(
244+
self, type_reference: ir_types.TypeReference, container: ir_types.ContainerType
245+
) -> ir_types.TypeReference:
246+
return container.visit(
247+
list_=lambda _: type_reference,
248+
map_=lambda _: type_reference,
249+
set_=lambda _: type_reference,
250+
nullable=lambda nullable: self._unbox_type_reference(type_reference=nullable),
251+
optional=lambda optional: self._unbox_type_reference(type_reference=optional),
252+
literal=lambda _: type_reference,
253+
)

generators/python/src/fern_python/generators/fastapi/service_generator/endpoint_generator.py

+6
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def _get_is_return_type_pydantic_model(self) -> bool:
105105
json=lambda json_response: True,
106106
streaming=lambda _: True,
107107
stream_parameter=lambda _: True,
108+
bytes=lambda _: False,
108109
)
109110

110111
def _get_return_type(self) -> AST.TypeHint:
@@ -368,6 +369,7 @@ def _get_response_body_type(self, response_body: ir_types.HttpResponseBody) -> A
368369
text=lambda _: AST.TypeHint.str_(),
369370
streaming=lambda _: raise_streaming_unsupported(),
370371
stream_parameter=lambda _: raise_stream_parameter_unsupported(),
372+
bytes=lambda _: raise_bytes_response_unsupported(),
371373
)
372374

373375
def _get_json_response_body_type(
@@ -405,5 +407,9 @@ def raise_bytes_unsupported() -> Never:
405407
raise RuntimeError("bytes request is not supported")
406408

407409

410+
def raise_bytes_response_unsupported() -> Never:
411+
raise RuntimeError("bytes response is not supported")
412+
413+
408414
def raise_json_nested_property_as_response_unsupported() -> Never:
409415
raise RuntimeError("nested property json response is unsupported")

generators/python/src/fern_python/generators/fastapi/service_generator/endpoint_parameters/convert_to_singular_type.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ def convert_to_singular_type(context: FastApiGeneratorContext, type: ir_types.Ty
1515
elif union.type == "container":
1616
container_union = union.container.get_as_union()
1717
if container_union.type == "optional":
18-
return AST.TypeHint.optional(wrapped_type=convert_to_singular_type(context, container_union.optional))
18+
return AST.TypeHint.optional(
19+
wrapped_type=convert_to_singular_type(context, _unbox_type_reference(container_union.optional))
20+
)
21+
elif container_union.type == "nullable":
22+
return AST.TypeHint.optional(
23+
wrapped_type=convert_to_singular_type(context, _unbox_type_reference(container_union.nullable))
24+
)
1925
elif union.type == "named":
2026
declaration = context.pydantic_generator_context.get_declaration_for_type_id(union.type_id)
2127
shape_union = declaration.shape.get_as_union()
@@ -46,3 +52,28 @@ def convert_to_singular_type(context: FastApiGeneratorContext, type: ir_types.Ty
4652
elif union.type != "void":
4753
assert_never(union)
4854
raise ValueError(f"Provided type is not a singular type: {type}")
55+
56+
57+
def _unbox_type_reference(type_reference: ir_types.TypeReference) -> ir_types.TypeReference:
58+
return type_reference.visit(
59+
container=lambda container: _unbox_type_reference_container(
60+
type_reference=type_reference,
61+
container=container,
62+
),
63+
named=lambda _: type_reference,
64+
primitive=lambda _: type_reference,
65+
unknown=lambda: type_reference,
66+
)
67+
68+
69+
def _unbox_type_reference_container(
70+
type_reference: ir_types.TypeReference, container: ir_types.ContainerType
71+
) -> ir_types.TypeReference:
72+
return container.visit(
73+
list_=lambda _: type_reference,
74+
map_=lambda _: type_reference,
75+
set_=lambda _: type_reference,
76+
nullable=lambda nullable: _unbox_type_reference(type_reference=nullable),
77+
optional=lambda optional: _unbox_type_reference(type_reference=optional),
78+
literal=lambda _: type_reference,
79+
)

generators/python/src/fern_python/generators/fastapi/service_generator/endpoint_parameters/header_endpoint_parameter.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ def get_type(self) -> AST.TypeHint:
2121

2222
def get_default(self) -> AST.Expression:
2323
value_type = self._header.value_type.get_as_union()
24-
is_optional = value_type.type == "container" and value_type.container.get_as_union().type == "optional"
24+
is_optional = value_type.type == "container" and (
25+
value_type.container.get_as_union().type == "optional"
26+
or value_type.container.get_as_union().type == "nullable"
27+
)
2528
return FastAPI.Header(is_optional=is_optional, wire_value=self._header.name.wire_value)
2629

2730
@staticmethod

generators/python/src/fern_python/generators/fastapi/service_generator/endpoint_parameters/query_endpoint_parameter.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ def get_type(self) -> AST.TypeHint:
2323

2424
def get_default(self) -> AST.Expression:
2525
value_type = self._query_parameter.value_type.get_as_union()
26-
is_optional = value_type.type == "container" and value_type.container.get_as_union().type == "optional"
26+
is_optional = value_type.type == "container" and (
27+
value_type.container.get_as_union().type == "optional"
28+
or value_type.container.get_as_union().type == "nullable"
29+
)
2730
default = None
2831
if is_optional:
2932
default = AST.Expression(AST.TypeHint.none())

generators/python/src/fern_python/generators/pydantic_model/model_utilities.py

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def can_tr_be_fern_model(tr: ir_types.TypeReference, types: Dict[ir_types.TypeId
1010
list_=lambda list_tr: can_tr_be_fern_model(list_tr, types),
1111
map_=lambda mt: can_tr_be_fern_model(mt.key_type, types) or can_tr_be_fern_model(mt.value_type, types),
1212
optional=lambda optional_tr: can_tr_be_fern_model(optional_tr, types),
13+
nullable=lambda nullable_tr: can_tr_be_fern_model(nullable_tr, types),
1314
set_=lambda set_tr: can_tr_be_fern_model(set_tr, types),
1415
literal=lambda _: False,
1516
),
@@ -31,6 +32,7 @@ def can_be_fern_model(type_: ir_types.Type, types: Dict[ir_types.TypeId, ir_type
3132
list_=lambda list_tr: can_tr_be_fern_model(list_tr, types),
3233
map_=lambda mt: can_tr_be_fern_model(mt.key_type, types) or can_tr_be_fern_model(mt.value_type, types),
3334
optional=lambda optional_tr: can_tr_be_fern_model(optional_tr, types),
35+
nullable=lambda nullable_tr: can_tr_be_fern_model(nullable_tr, types),
3436
set_=lambda set_tr: can_tr_be_fern_model(set_tr, types),
3537
literal=lambda _: False,
3638
),

generators/python/src/fern_python/generators/pydantic_model/type_declaration_handler/discriminated_union/simple_discriminated_union_generator.py

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ def _get_type_id(self, tr: ir_types.TypeReference) -> List[Union[ir_types.TypeId
250250
list_=lambda lt: self._get_type_id(lt),
251251
map_=lambda mt: self._get_type_id(mt.key_type) + self._get_type_id(mt.value_type),
252252
optional=lambda ot: self._get_type_id(ot),
253+
nullable=lambda nt: self._get_type_id(nt),
253254
set_=lambda st: self._get_type_id(st),
254255
literal=lambda _: [],
255256
)

generators/python/src/fern_python/generators/pydantic_model/type_declaration_handler/pydantic_models/pydantic_model_alias_generator.py

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def _get_builder_name(self, alias_of: ir_types.TypeReference) -> str:
8484
map_=lambda _: "from_map",
8585
set_=lambda _: "from_set",
8686
optional=self._get_builder_name,
87+
nullable=self._get_builder_name,
8788
literal=lambda _: "from_string",
8889
),
8990
named=lambda type_name: "from_" + type_name.name.snake_case.unsafe_name,
@@ -112,6 +113,7 @@ def _get_getter_name(self, alias_of: ir_types.TypeReference) -> str:
112113
map_=lambda _: "get_as_map",
113114
set_=lambda _: "get_as_set",
114115
optional=self._get_getter_name,
116+
nullable=self._get_getter_name,
115117
literal=lambda _: "get_as_string",
116118
),
117119
named=lambda type_name: "get_as_" + type_name.name.snake_case.unsafe_name,

generators/python/src/fern_python/generators/pydantic_model/typeddict.py

+3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ def add_field(
158158
if container_reference_unioned.type == "optional":
159159
type_reference = container_reference_unioned.optional
160160
is_optional = True
161+
if container_reference_unioned.type == "nullable":
162+
type_reference = container_reference_unioned.nullable
163+
is_optional = True
161164

162165
type_hint = self._get_type_hint_for_type_reference(type_reference, as_if_type_checking)
163166
if json_field_name != name:

0 commit comments

Comments
 (0)