@typespec/http-client-python 0.22.0 → 0.23.0
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.
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +1 -0
- package/dist/emitter/types.js.map +1 -1
- package/emitter/src/types.ts +1 -0
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/ci/regenerate.ts +5 -1
- package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
- package/generator/build/lib/pygen/codegen/models/property.py +1 -0
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +2 -0
- package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +12 -5
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +28 -0
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/models/property.py +1 -0
- package/generator/pygen/codegen/serializers/model_serializer.py +2 -0
- package/generator/pygen/codegen/templates/macros.jinja2 +12 -5
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +28 -0
- package/generator/test/azure/requirements.txt +1 -0
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_array_async.py +43 -0
- package/generator/test/generic_mock_api_tests/asynctests/test_specs_documentation_async.py +60 -0
- package/generator/test/generic_mock_api_tests/test_encode_array.py +38 -0
- package/generator/test/generic_mock_api_tests/test_specs_documentation.py +52 -0
- package/generator/test/unbranded/requirements.txt +1 -0
- package/generator/test/unittests/test_model_base_serialization.py +264 -0
- package/package.json +1 -1
|
@@ -4108,3 +4108,267 @@ def test_multi_layer_discriminator():
|
|
|
4108
4108
|
|
|
4109
4109
|
assert AnotherPet(name="Buddy", trained=True) == model_pet
|
|
4110
4110
|
assert AnotherDog(name="Rex", trained=True, breed="German Shepherd") == model_dog
|
|
4111
|
+
|
|
4112
|
+
|
|
4113
|
+
def test_array_encode_comma_delimited():
|
|
4114
|
+
"""Test commaDelimited format for array of strings"""
|
|
4115
|
+
|
|
4116
|
+
class CommaDelimitedModel(Model):
|
|
4117
|
+
colors: list[str] = rest_field(format="commaDelimited")
|
|
4118
|
+
|
|
4119
|
+
@overload
|
|
4120
|
+
def __init__(self, *, colors: list[str]): ...
|
|
4121
|
+
|
|
4122
|
+
@overload
|
|
4123
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4124
|
+
|
|
4125
|
+
def __init__(self, *args, **kwargs):
|
|
4126
|
+
super().__init__(*args, **kwargs)
|
|
4127
|
+
|
|
4128
|
+
# Test serialization: list[str] -> comma-delimited string
|
|
4129
|
+
model = CommaDelimitedModel(colors=["blue", "red", "green"])
|
|
4130
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4131
|
+
assert model["colors"] == "blue,red,green"
|
|
4132
|
+
|
|
4133
|
+
# Test deserialization: comma-delimited string -> list[str]
|
|
4134
|
+
model = CommaDelimitedModel({"colors": "blue,red,green"})
|
|
4135
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4136
|
+
assert model["colors"] == "blue,red,green"
|
|
4137
|
+
|
|
4138
|
+
# Test with empty list
|
|
4139
|
+
model = CommaDelimitedModel(colors=[])
|
|
4140
|
+
assert model.colors == []
|
|
4141
|
+
assert model["colors"] == ""
|
|
4142
|
+
|
|
4143
|
+
# Test with single item
|
|
4144
|
+
model = CommaDelimitedModel(colors=["blue"])
|
|
4145
|
+
assert model.colors == ["blue"]
|
|
4146
|
+
assert model["colors"] == "blue"
|
|
4147
|
+
|
|
4148
|
+
|
|
4149
|
+
def test_array_encode_pipe_delimited():
|
|
4150
|
+
"""Test pipeDelimited format for array of strings"""
|
|
4151
|
+
|
|
4152
|
+
class PipeDelimitedModel(Model):
|
|
4153
|
+
colors: list[str] = rest_field(format="pipeDelimited")
|
|
4154
|
+
|
|
4155
|
+
@overload
|
|
4156
|
+
def __init__(self, *, colors: list[str]): ...
|
|
4157
|
+
|
|
4158
|
+
@overload
|
|
4159
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4160
|
+
|
|
4161
|
+
def __init__(self, *args, **kwargs):
|
|
4162
|
+
super().__init__(*args, **kwargs)
|
|
4163
|
+
|
|
4164
|
+
# Test serialization: list[str] -> pipe-delimited string
|
|
4165
|
+
model = PipeDelimitedModel(colors=["blue", "red", "green"])
|
|
4166
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4167
|
+
assert model["colors"] == "blue|red|green"
|
|
4168
|
+
|
|
4169
|
+
# Test deserialization: pipe-delimited string -> list[str]
|
|
4170
|
+
model = PipeDelimitedModel({"colors": "blue|red|green"})
|
|
4171
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4172
|
+
assert model["colors"] == "blue|red|green"
|
|
4173
|
+
|
|
4174
|
+
# Test with empty list
|
|
4175
|
+
model = PipeDelimitedModel(colors=[])
|
|
4176
|
+
assert model.colors == []
|
|
4177
|
+
assert model["colors"] == ""
|
|
4178
|
+
|
|
4179
|
+
|
|
4180
|
+
def test_array_encode_space_delimited():
|
|
4181
|
+
"""Test spaceDelimited format for array of strings"""
|
|
4182
|
+
|
|
4183
|
+
class SpaceDelimitedModel(Model):
|
|
4184
|
+
colors: list[str] = rest_field(format="spaceDelimited")
|
|
4185
|
+
|
|
4186
|
+
@overload
|
|
4187
|
+
def __init__(self, *, colors: list[str]): ...
|
|
4188
|
+
|
|
4189
|
+
@overload
|
|
4190
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4191
|
+
|
|
4192
|
+
def __init__(self, *args, **kwargs):
|
|
4193
|
+
super().__init__(*args, **kwargs)
|
|
4194
|
+
|
|
4195
|
+
# Test serialization: list[str] -> space-delimited string
|
|
4196
|
+
model = SpaceDelimitedModel(colors=["blue", "red", "green"])
|
|
4197
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4198
|
+
assert model["colors"] == "blue red green"
|
|
4199
|
+
|
|
4200
|
+
# Test deserialization: space-delimited string -> list[str]
|
|
4201
|
+
model = SpaceDelimitedModel({"colors": "blue red green"})
|
|
4202
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4203
|
+
assert model["colors"] == "blue red green"
|
|
4204
|
+
|
|
4205
|
+
# Test with empty list
|
|
4206
|
+
model = SpaceDelimitedModel(colors=[])
|
|
4207
|
+
assert model.colors == []
|
|
4208
|
+
assert model["colors"] == ""
|
|
4209
|
+
|
|
4210
|
+
|
|
4211
|
+
def test_array_encode_newline_delimited():
|
|
4212
|
+
"""Test newlineDelimited format for array of strings"""
|
|
4213
|
+
|
|
4214
|
+
class NewlineDelimitedModel(Model):
|
|
4215
|
+
colors: list[str] = rest_field(format="newlineDelimited")
|
|
4216
|
+
|
|
4217
|
+
@overload
|
|
4218
|
+
def __init__(self, *, colors: list[str]): ...
|
|
4219
|
+
|
|
4220
|
+
@overload
|
|
4221
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4222
|
+
|
|
4223
|
+
def __init__(self, *args, **kwargs):
|
|
4224
|
+
super().__init__(*args, **kwargs)
|
|
4225
|
+
|
|
4226
|
+
# Test serialization: list[str] -> newline-delimited string
|
|
4227
|
+
model = NewlineDelimitedModel(colors=["blue", "red", "green"])
|
|
4228
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4229
|
+
assert model["colors"] == "blue\nred\ngreen"
|
|
4230
|
+
|
|
4231
|
+
# Test deserialization: newline-delimited string -> list[str]
|
|
4232
|
+
model = NewlineDelimitedModel({"colors": "blue\nred\ngreen"})
|
|
4233
|
+
assert model.colors == ["blue", "red", "green"]
|
|
4234
|
+
assert model["colors"] == "blue\nred\ngreen"
|
|
4235
|
+
|
|
4236
|
+
# Test with empty list
|
|
4237
|
+
model = NewlineDelimitedModel(colors=[])
|
|
4238
|
+
assert model.colors == []
|
|
4239
|
+
assert model["colors"] == ""
|
|
4240
|
+
|
|
4241
|
+
|
|
4242
|
+
def test_array_encode_optional():
|
|
4243
|
+
"""Test array encoding with optional fields"""
|
|
4244
|
+
|
|
4245
|
+
class OptionalEncodedModel(Model):
|
|
4246
|
+
colors: Optional[list[str]] = rest_field(default=None, format="commaDelimited")
|
|
4247
|
+
|
|
4248
|
+
@overload
|
|
4249
|
+
def __init__(self, *, colors: Optional[list[str]] = None): ...
|
|
4250
|
+
|
|
4251
|
+
@overload
|
|
4252
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4253
|
+
|
|
4254
|
+
def __init__(self, *args, **kwargs):
|
|
4255
|
+
super().__init__(*args, **kwargs)
|
|
4256
|
+
|
|
4257
|
+
# Test with None
|
|
4258
|
+
model = OptionalEncodedModel(colors=None)
|
|
4259
|
+
assert model.colors is None
|
|
4260
|
+
assert model["colors"] is None
|
|
4261
|
+
|
|
4262
|
+
# Test with value
|
|
4263
|
+
model = OptionalEncodedModel(colors=["blue", "red"])
|
|
4264
|
+
assert model.colors == ["blue", "red"]
|
|
4265
|
+
assert model["colors"] == "blue,red"
|
|
4266
|
+
|
|
4267
|
+
# Test deserialization with None
|
|
4268
|
+
model = OptionalEncodedModel({"colors": None})
|
|
4269
|
+
assert model.colors is None
|
|
4270
|
+
|
|
4271
|
+
|
|
4272
|
+
def test_array_encode_modification():
|
|
4273
|
+
"""Test modifying array-encoded fields"""
|
|
4274
|
+
|
|
4275
|
+
class ModifiableModel(Model):
|
|
4276
|
+
colors: list[str] = rest_field(format="commaDelimited")
|
|
4277
|
+
|
|
4278
|
+
@overload
|
|
4279
|
+
def __init__(self, *, colors: list[str]): ...
|
|
4280
|
+
|
|
4281
|
+
@overload
|
|
4282
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4283
|
+
|
|
4284
|
+
def __init__(self, *args, **kwargs):
|
|
4285
|
+
super().__init__(*args, **kwargs)
|
|
4286
|
+
|
|
4287
|
+
model = ModifiableModel(colors=["blue", "red"])
|
|
4288
|
+
assert model.colors == ["blue", "red"]
|
|
4289
|
+
assert model["colors"] == "blue,red"
|
|
4290
|
+
|
|
4291
|
+
# Modify through property
|
|
4292
|
+
model.colors = ["green", "yellow", "purple"]
|
|
4293
|
+
assert model.colors == ["green", "yellow", "purple"]
|
|
4294
|
+
assert model["colors"] == "green,yellow,purple"
|
|
4295
|
+
|
|
4296
|
+
# Modify through dict access
|
|
4297
|
+
model["colors"] = "orange,pink"
|
|
4298
|
+
assert model.colors == ["orange", "pink"]
|
|
4299
|
+
assert model["colors"] == "orange,pink"
|
|
4300
|
+
|
|
4301
|
+
|
|
4302
|
+
def test_array_encode_json_roundtrip():
|
|
4303
|
+
"""Test JSON serialization and deserialization with array encoding"""
|
|
4304
|
+
|
|
4305
|
+
class JsonModel(Model):
|
|
4306
|
+
pipe_colors: list[str] = rest_field(name="pipeColors", format="pipeDelimited")
|
|
4307
|
+
comma_colors: list[str] = rest_field(name="commaColors", format="commaDelimited")
|
|
4308
|
+
|
|
4309
|
+
@overload
|
|
4310
|
+
def __init__(
|
|
4311
|
+
self,
|
|
4312
|
+
*,
|
|
4313
|
+
pipe_colors: list[str],
|
|
4314
|
+
comma_colors: list[str],
|
|
4315
|
+
): ...
|
|
4316
|
+
|
|
4317
|
+
@overload
|
|
4318
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4319
|
+
|
|
4320
|
+
def __init__(self, *args, **kwargs):
|
|
4321
|
+
super().__init__(*args, **kwargs)
|
|
4322
|
+
|
|
4323
|
+
model = JsonModel(
|
|
4324
|
+
pipe_colors=["blue", "red", "green"],
|
|
4325
|
+
comma_colors=["small", "medium", "large"],
|
|
4326
|
+
)
|
|
4327
|
+
|
|
4328
|
+
# Serialize to JSON
|
|
4329
|
+
json_str = json.dumps(dict(model), cls=SdkJSONEncoder)
|
|
4330
|
+
assert json.loads(json_str) == {
|
|
4331
|
+
"pipeColors": "blue|red|green",
|
|
4332
|
+
"commaColors": "small,medium,large",
|
|
4333
|
+
}
|
|
4334
|
+
|
|
4335
|
+
# Deserialize from JSON
|
|
4336
|
+
deserialized = JsonModel(json.loads(json_str))
|
|
4337
|
+
assert deserialized.pipe_colors == ["blue", "red", "green"]
|
|
4338
|
+
assert deserialized.comma_colors == ["small", "medium", "large"]
|
|
4339
|
+
|
|
4340
|
+
|
|
4341
|
+
def test_array_encode_with_special_characters():
|
|
4342
|
+
"""Test array encoding with strings containing special characters"""
|
|
4343
|
+
|
|
4344
|
+
class SpecialCharsModel(Model):
|
|
4345
|
+
comma_values: list[str] = rest_field(name="commaValues", format="commaDelimited")
|
|
4346
|
+
pipe_values: list[str] = rest_field(name="pipeValues", format="pipeDelimited")
|
|
4347
|
+
|
|
4348
|
+
@overload
|
|
4349
|
+
def __init__(
|
|
4350
|
+
self,
|
|
4351
|
+
*,
|
|
4352
|
+
comma_values: list[str],
|
|
4353
|
+
pipe_values: list[str],
|
|
4354
|
+
): ...
|
|
4355
|
+
|
|
4356
|
+
@overload
|
|
4357
|
+
def __init__(self, mapping: Mapping[str, Any], /): ...
|
|
4358
|
+
|
|
4359
|
+
def __init__(self, *args, **kwargs):
|
|
4360
|
+
super().__init__(*args, **kwargs)
|
|
4361
|
+
|
|
4362
|
+
# Test with strings that might contain delimiters
|
|
4363
|
+
# Note: In real usage, the strings should not contain the delimiter character
|
|
4364
|
+
# This test documents current behavior
|
|
4365
|
+
model = SpecialCharsModel(
|
|
4366
|
+
comma_values=["value with spaces", "another-value", "value_3"],
|
|
4367
|
+
pipe_values=["path/to/file", "another-path", "final.path"],
|
|
4368
|
+
)
|
|
4369
|
+
|
|
4370
|
+
assert model.comma_values == ["value with spaces", "another-value", "value_3"]
|
|
4371
|
+
assert model["commaValues"] == "value with spaces,another-value,value_3"
|
|
4372
|
+
|
|
4373
|
+
assert model.pipe_values == ["path/to/file", "another-path", "final.path"]
|
|
4374
|
+
assert model["pipeValues"] == "path/to/file|another-path|final.path"
|