Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/http-client-python"
---

Keep original client name for backcompat reasons when the name is only padded for tsp generations
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,14 @@ def _get_relative_generation_dir(self, root_dir: Path, namespace: str) -> Path:
def has_operation_named_list(self) -> bool:
return any(o.name.lower() == "list" for c in self.clients for og in c.operation_groups for o in og.operations)

@property
def has_padded_model_property(self) -> bool:
for model_type in self.model_types:
for prop in model_type.properties:
if prop.original_tsp_name:
return True
return False

@property
def external_types(self) -> list[ExternalType]:
"""All of the external types"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def __init__(
self.flattened_names: list[str] = yaml_data.get("flattenedNames", [])
self.is_multipart_file_input: bool = yaml_data.get("isMultipartFileInput", False)
self.flatten = self.yaml_data.get("flatten", False) and not getattr(self.type, "flattened_property", False)
self.original_tsp_name: Optional[str] = self.yaml_data.get("originalTspName")

def pylint_disable(self) -> str:
retval: str = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ def declare_property(self, prop: Property) -> str:
if prop.xml_metadata:
args.append(f"xml={prop.xml_metadata}")

if prop.original_tsp_name:
args.append(f'original_tsp_name="{prop.original_tsp_name}"')

field = "rest_discriminator" if prop.is_discriminator else "rest_field"
type_ignore = (
" # type: ignore"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,12 @@ class Model(_MyMutableMapping):
if not rf._rest_name_input:
rf._rest_name_input = attr
cls._attr_to_rest_field: dict[str, _RestField] = dict(attr_to_rest_field.items())
{% if code_model.has_padded_model_property %}
cls._backcompat_attr_to_rest_field: dict[str, _RestField] = {
Model._get_backcompat_attribute_name(cls._attr_to_rest_field, attr): rf for attr, rf in cls
._attr_to_rest_field.items()
}
{% endif %}
cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}")

return super().__new__(cls)
Expand All @@ -671,6 +677,18 @@ class Model(_MyMutableMapping):
if hasattr(base, "__mapping__"):
base.__mapping__[discriminator or cls.__name__] = cls # type: ignore

{% if code_model.has_padded_model_property %}
@classmethod
def _get_backcompat_attribute_name(cls, attr_to_rest_field: dict[str, "_RestField"], attr_name: str) -> str:
rest_field_obj = attr_to_rest_field.get(attr_name) # pylint: disable=protected-access
if rest_field_obj is None:
return attr_name
original_tsp_name = getattr(rest_field_obj, "_original_tsp_name", None) # pylint: disable=protected-access
if original_tsp_name:
return original_tsp_name
return attr_name
{% endif %}

@classmethod
def _get_discriminator(cls, exist_discriminators) -> typing.Optional["_RestField"]:
for v in cls.__dict__.values():
Expand Down Expand Up @@ -997,6 +1015,9 @@ def _failsafe_deserialize_xml(
return None


{% if code_model.has_padded_model_property %}
# pylint: disable=too-many-instance-attributes
{% endif %}
class _RestField:
def __init__(
self,
Expand All @@ -1009,6 +1030,9 @@ class _RestField:
format: typing.Optional[str] = None,
is_multipart_file_input: bool = False,
xml: typing.Optional[dict[str, typing.Any]] = None,
{% if code_model.has_padded_model_property %}
original_tsp_name: typing.Optional[str] = None,
{% endif %}
):
self._type = type
self._rest_name_input = name
Expand All @@ -1020,6 +1044,9 @@ class _RestField:
self._format = format
self._is_multipart_file_input = is_multipart_file_input
self._xml = xml if xml is not None else {}
{% if code_model.has_padded_model_property %}
self._original_tsp_name = original_tsp_name
{% endif %}

@property
def _class_type(self) -> typing.Any:
Expand Down Expand Up @@ -1071,6 +1098,9 @@ def rest_field(
format: typing.Optional[str] = None,
is_multipart_file_input: bool = False,
xml: typing.Optional[dict[str, typing.Any]] = None,
{% if code_model.has_padded_model_property %}
original_tsp_name: typing.Optional[str] = None,
{% endif %}
) -> typing.Any:
return _RestField(
name=name,
Expand All @@ -1080,6 +1110,9 @@ def rest_field(
format=format,
is_multipart_file_input=is_multipart_file_input,
xml=xml,
{% if code_model.has_padded_model_property %}
original_tsp_name=original_tsp_name,
{% endif %}
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def add_body_param_type(
body_parameter["type"]["types"].insert(1, any_obj_list_or_dict)
code_model["types"].append(body_parameter["type"])

def pad_reserved_words(self, name: str, pad_type: PadType):
def pad_reserved_words(self, name: str, pad_type: PadType, yaml_type: dict[str, Any]) -> str:
# we want to pad hidden variables as well
if not name:
# we'll pass in empty operation groups sometime etc.
Expand All @@ -250,26 +250,32 @@ def pad_reserved_words(self, name: str, pad_type: PadType):
name_prefix = "_" if name[0] == "_" else ""
name = name[1:] if name[0] == "_" else name
if name.lower() in reserved_words[pad_type]:
if self.is_tsp and name.lower() in TSP_RESERVED_WORDS.get(pad_type, []):
# to maintain backcompat for cases where we pad in tsp but not in autorest,
# if we have a tsp reserved word, we also want to keep track of the original name for backcompat
yaml_type["originalTspName"] = name_prefix + name
return name_prefix + name + pad_type
return name_prefix + name

def update_types(self, yaml_data: list[dict[str, Any]]) -> None:
for type in yaml_data:
for property in type.get("properties", []):
property["description"] = update_description(property.get("description", ""))
property["clientName"] = self.pad_reserved_words(property["clientName"].lower(), PadType.PROPERTY)
property["clientName"] = self.pad_reserved_words(
property["clientName"].lower(), PadType.PROPERTY, property
)
add_redefined_builtin_info(property["clientName"], property)
if type.get("name"):
pad_type = PadType.MODEL if type["type"] == "model" else PadType.ENUM_CLASS
name = self.pad_reserved_words(type["name"], pad_type)
name = self.pad_reserved_words(type["name"], pad_type, type)
type["name"] = name[0].upper() + name[1:]
type["description"] = update_description(type.get("description", ""), type["name"])
type["snakeCaseName"] = to_snake_case(type["name"])
if type.get("values"):
# we're enums
values_to_add = []
for value in type["values"]:
padded_name = self.pad_reserved_words(value["name"].lower(), PadType.ENUM_VALUE).upper()
padded_name = self.pad_reserved_words(value["name"].lower(), PadType.ENUM_VALUE, value).upper()
if self.version_tolerant:
if padded_name[0] in "0123456789":
padded_name = "ENUM_" + padded_name
Expand Down Expand Up @@ -364,12 +370,14 @@ def get_operation_updater(self, yaml_data: dict[str, Any]) -> Callable[[dict[str
def update_parameter(self, yaml_data: dict[str, Any]) -> None:
yaml_data["description"] = update_description(yaml_data.get("description", ""))
if not (yaml_data["location"] == "header" and yaml_data["clientName"] in ("content_type", "accept")):
yaml_data["clientName"] = self.pad_reserved_words(yaml_data["clientName"].lower(), PadType.PARAMETER)
yaml_data["clientName"] = self.pad_reserved_words(
yaml_data["clientName"].lower(), PadType.PARAMETER, yaml_data
)
if yaml_data.get("propertyToParameterName"):
# need to create a new one with padded keys and values
yaml_data["propertyToParameterName"] = {
self.pad_reserved_words(prop, PadType.PROPERTY): self.pad_reserved_words(
param_name, PadType.PARAMETER
self.pad_reserved_words(prop, PadType.PROPERTY, yaml_data): self.pad_reserved_words(
param_name, PadType.PARAMETER, yaml_data
).lower()
for prop, param_name in yaml_data["propertyToParameterName"].items()
}
Expand All @@ -390,15 +398,17 @@ def update_operation(
*,
is_overload: bool = False,
) -> None:
yaml_data["groupName"] = self.pad_reserved_words(yaml_data["groupName"], PadType.OPERATION_GROUP)
yaml_data["groupName"] = self.pad_reserved_words(yaml_data["groupName"], PadType.OPERATION_GROUP, yaml_data)
yaml_data["groupName"] = to_snake_case(yaml_data["groupName"])
yaml_data["name"] = yaml_data["name"].lower()
if yaml_data.get("isLroInitialOperation") is True:
yaml_data["name"] = (
"_" + self.pad_reserved_words(extract_original_name(yaml_data["name"]), PadType.METHOD) + "_initial"
"_"
+ self.pad_reserved_words(extract_original_name(yaml_data["name"]), PadType.METHOD, yaml_data)
+ "_initial"
)
else:
yaml_data["name"] = self.pad_reserved_words(yaml_data["name"], PadType.METHOD)
yaml_data["name"] = self.pad_reserved_words(yaml_data["name"], PadType.METHOD, yaml_data)
yaml_data["description"] = update_description(yaml_data["description"], yaml_data["name"])
yaml_data["summary"] = update_description(yaml_data.get("summary", ""))
body_parameter = yaml_data.get("bodyParameter")
Expand Down Expand Up @@ -485,7 +495,7 @@ def update_paging_operation(
item_type = item_type or yaml_data["itemType"]["elementType"]
if yaml_data.get("nextOperation"):
yaml_data["nextOperation"]["groupName"] = self.pad_reserved_words(
yaml_data["nextOperation"]["groupName"], PadType.OPERATION_GROUP
yaml_data["nextOperation"]["groupName"], PadType.OPERATION_GROUP, yaml_data["nextOperation"]
)
yaml_data["nextOperation"]["groupName"] = to_snake_case(yaml_data["nextOperation"]["groupName"])
for response in yaml_data["nextOperation"].get("responses", []):
Expand All @@ -503,10 +513,11 @@ def update_operation_groups(self, code_model: dict[str, Any], client: dict[str,
operation_group["identifyName"] = self.pad_reserved_words(
operation_group.get("name", operation_group["propertyName"]),
PadType.OPERATION_GROUP,
operation_group,
)
operation_group["identifyName"] = to_snake_case(operation_group["identifyName"])
operation_group["propertyName"] = self.pad_reserved_words(
operation_group["propertyName"], PadType.OPERATION_GROUP
operation_group["propertyName"], PadType.OPERATION_GROUP, operation_group
)
operation_group["propertyName"] = to_snake_case(operation_group["propertyName"])
operation_group["className"] = update_operation_group_class_name(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


def pad_reserved_words(name: str, pad_type: PadType) -> str:
return PreProcessPlugin(output_folder="").pad_reserved_words(name, pad_type)
return PreProcessPlugin(output_folder="").pad_reserved_words(name, pad_type, {})


def test_escaped_reserved_words():
Expand Down
Loading