Skip to content

Commit

Permalink
Merge pull request #5041 from microsoft/bugfix/missing-properties-python
Browse files Browse the repository at this point in the history
fix: missing properties in python when no additional properties
  • Loading branch information
andrueastman authored Aug 1, 2024
2 parents 50aa810 + a4f05cd commit b8e5dc5
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Fixed a bug where properties would be missing in Python models if they didn't have additional properties. [#5037](https://github.com/microsoft/kiota/issues/5037)
- Fixed a bug in dotnet where CS1587 warnings are generated in generated enums with descriptions [#4957](https://github.com/microsoft/kiota/issues/4957)
- Fixed a bug where the copilot teams toolkit integration would serialize empty declarative copilots. [#4974](https://github.com/microsoft/kiota/issues/4974)
- Fixed a bug for the docker image where the volume path would not match the expected configuration for the description.
Expand Down
4 changes: 4 additions & 0 deletions src/Kiota.Builder/Refiners/PythonRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ private static void CorrectPropertyType(CodeProperty currentProperty)
if (!string.IsNullOrEmpty(currentProperty.DefaultValue))
currentProperty.DefaultValue = "{}";
}
else if (currentProperty.Kind is CodePropertyKind.Custom && currentProperty.Type.IsNullable && string.IsNullOrEmpty(currentProperty.DefaultValue))
{
currentProperty.DefaultValue = "None";
}
currentProperty.Type.Name = currentProperty.Type.Name.ToFirstCharacterUpperCase();
CorrectCoreTypes(currentProperty.Parent as CodeClass, DateTypesReplacements, currentProperty.Type);
}
Expand Down
31 changes: 16 additions & 15 deletions src/Kiota.Builder/Writers/Python/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override void WriteCodeElement(CodeMethod codeElement, LanguageWriter wri
if (codeElement.Parent is not CodeClass parentClass) throw new InvalidOperationException("the parent of a method should be a class");

var returnType = conventions.GetTypeString(codeElement.ReturnType, codeElement, true, writer);
var isVoid = "None".Equals(returnType, StringComparison.OrdinalIgnoreCase);
var isVoid = NoneKeyword.Equals(returnType, StringComparison.OrdinalIgnoreCase);
if (parentClass.IsOfKind(CodeClassKind.Model) && (codeElement.IsOfKind(CodeMethodKind.Setter) || codeElement.IsOfKind(CodeMethodKind.Getter) || codeElement.IsOfKind(CodeMethodKind.Constructor)))
{
writer.IncreaseIndent();
Expand Down Expand Up @@ -215,7 +215,7 @@ private void WriteFactoryMethodBody(CodeMethod codeElement, CodeClass parentClas
writer.WriteLine($"{DiscriminatorMappingVarName} = {parseNodeParameter.Name}.get_child_node(\"{parentClass.DiscriminatorInformation.DiscriminatorPropertyName}\").get_str_value()");
writer.DecreaseIndent();
writer.StartBlock($"except AttributeError:");
writer.WriteLine($"{DiscriminatorMappingVarName} = None");
writer.WriteLine($"{DiscriminatorMappingVarName} = {NoneKeyword}");
writer.DecreaseIndent();
}
if (parentClass.DiscriminatorInformation.ShouldWriteDiscriminatorForInheritedType)
Expand Down Expand Up @@ -351,7 +351,7 @@ private void WriteConstructorBody(CodeClass parentClass, CodeMethod currentMetho
writer.WriteLine($"super().__init__({requestAdapterParameter.Name}, {urlTemplateProperty.DefaultValue ?? ""}, {pathParametersParameter.Name})");
}
else
writer.WriteLine($"super().__init__({requestAdapterParameter.Name}, {urlTemplateProperty.DefaultValue ?? ""}, None)");
writer.WriteLine($"super().__init__({requestAdapterParameter.Name}, {urlTemplateProperty.DefaultValue ?? ""}, {NoneKeyword})");
}
else
writer.WriteLine("super().__init__()");
Expand All @@ -376,7 +376,7 @@ private void WriteConstructorBody(CodeClass parentClass, CodeMethod currentMetho
private void WriteDirectAccessProperties(CodeClass parentClass, LanguageWriter writer)
{
foreach (var propWithDefault in parentClass.GetPropertiesOfKind(DirectAccessProperties)
.Where(static x => !string.IsNullOrEmpty(x.DefaultValue))
.Where(static x => !string.IsNullOrEmpty(x.DefaultValue) && !NoneKeyword.Equals(x.DefaultValue, StringComparison.Ordinal))
.OrderByDescending(static x => x.Kind)
.ThenBy(static x => x.Name))
{
Expand All @@ -403,7 +403,7 @@ private void WriteDirectAccessProperties(CodeClass parentClass, LanguageWriter w
private void WriteSetterAccessProperties(CodeClass parentClass, LanguageWriter writer)
{
foreach (var propWithDefault in parentClass.GetPropertiesOfKind(SetterAccessProperties)
.Where(static x => !string.IsNullOrEmpty(x.DefaultValue))
.Where(static x => !string.IsNullOrEmpty(x.DefaultValue) && !NoneKeyword.Equals(x.DefaultValue, StringComparison.Ordinal))
// do not apply the default value if the type is composed as the default value may not necessarily which type to use
.Where(static x => x.Type is not CodeType propType || propType.TypeDefinition is not CodeClass propertyClass || propertyClass.OriginalComposedType is null)
.OrderByDescending(static x => x.Kind)
Expand All @@ -426,19 +426,20 @@ private void WriteSetterAccessProperties(CodeClass parentClass, LanguageWriter w
writer.WriteLine($"self.{setterString}");
}
}
private const string NoneKeyword = "None";
private void WriteSetterAccessPropertiesWithoutDefaults(CodeClass parentClass, LanguageWriter writer)
{
foreach (var propWithoutDefault in parentClass.GetPropertiesOfKind(SetterAccessProperties)
.Where(static x => string.IsNullOrEmpty(x.DefaultValue))
.Where(static x => string.IsNullOrEmpty(x.DefaultValue) || NoneKeyword.Equals(x.DefaultValue, StringComparison.Ordinal))
.OrderByDescending(static x => x.Kind)
.ThenBy(static x => x.Name))
{
var returnType = conventions.GetTypeString(propWithoutDefault.Type, propWithoutDefault, true, writer);
conventions.WriteInLineDescription(propWithoutDefault, writer);
if (parentClass.IsOfKind(CodeClassKind.Model))
writer.WriteLine($"{propWithoutDefault.Name}: {(propWithoutDefault.Type.IsNullable ? "Optional[" : string.Empty)}{returnType}{(propWithoutDefault.Type.IsNullable ? "]" : string.Empty)} = None");
writer.WriteLine($"{propWithoutDefault.Name}: {(propWithoutDefault.Type.IsNullable ? "Optional[" : string.Empty)}{returnType}{(propWithoutDefault.Type.IsNullable ? "]" : string.Empty)} = {NoneKeyword}");
else
writer.WriteLine($"self.{conventions.GetAccessModifier(propWithoutDefault.Access)}{propWithoutDefault.NamePrefix}{propWithoutDefault.Name}: {(propWithoutDefault.Type.IsNullable ? "Optional[" : string.Empty)}{returnType}{(propWithoutDefault.Type.IsNullable ? "]" : string.Empty)} = None");
writer.WriteLine($"self.{conventions.GetAccessModifier(propWithoutDefault.Access)}{propWithoutDefault.NamePrefix}{propWithoutDefault.Name}: {(propWithoutDefault.Type.IsNullable ? "Optional[" : string.Empty)}{returnType}{(propWithoutDefault.Type.IsNullable ? "]" : string.Empty)} = {NoneKeyword}");
}
}
private static void WriteSetterBody(CodeMethod codeElement, LanguageWriter writer, CodeClass parentClass)
Expand Down Expand Up @@ -539,7 +540,7 @@ private void WriteDeserializerBodyForIntersectionModel(CodeClass parentClass, La
private void WriteDeserializerBodyForInheritedModel(bool inherits, CodeMethod codeElement, CodeClass parentClass, LanguageWriter writer)
{
_codeUsingWriter.WriteInternalImports(parentClass, writer);
writer.StartBlock("fields: Dict[str, Callable[[Any], None]] = {");
writer.StartBlock($"fields: Dict[str, Callable[[Any], {NoneKeyword}]] = {{");
foreach (var otherProp in parentClass
.GetPropertiesOfKind(CodePropertyKind.Custom)
.Where(static x => !x.ExistsInBaseType)
Expand Down Expand Up @@ -579,7 +580,7 @@ private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requ
var returnTypeWithoutCollectionSymbol = GetReturnTypeWithoutCollectionSymbol(codeElement, returnType);
var genericTypeForSendMethod = GetSendRequestMethodName(isVoid, isStream, codeElement.ReturnType.IsCollection, returnTypeWithoutCollectionSymbol);
var newFactoryParameter = GetTypeFactory(isVoid, isStream, returnTypeWithoutCollectionSymbol);
var errorMappingVarName = "None";
var errorMappingVarName = NoneKeyword;
if (codeElement.ErrorMappings.Any())
{
_codeUsingWriter.WriteInternalErrorMappingImports(parentClass, writer);
Expand Down Expand Up @@ -660,7 +661,7 @@ private void WriteSerializerBodyForUnionModel(CodeClass parentClass, LanguageWri
.ThenBy(static x => x.Name))
{
writer.StartBlock($"{(includeElse ? "el" : string.Empty)}if self.{otherProp.Name}:");
writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type)}(None, self.{otherProp.Name})");
writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type)}({NoneKeyword}, self.{otherProp.Name})");
writer.DecreaseIndent();
if (!includeElse)
includeElse = true;
Expand All @@ -677,7 +678,7 @@ private void WriteSerializerBodyForIntersectionModel(CodeClass parentClass, Lang
.ThenBy(static x => x.Name))
{
writer.StartBlock($"{(includeElse ? "el" : string.Empty)}if self.{otherProp.Name}:");
writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type)}(None, self.{otherProp.Name})");
writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type)}({NoneKeyword}, self.{otherProp.Name})");
writer.DecreaseIndent();
if (!includeElse)
includeElse = true;
Expand All @@ -695,7 +696,7 @@ private void WriteSerializerBodyForIntersectionModel(CodeClass parentClass, Lang
.Select(static x => x.Name)
.OrderBy(static x => x, StringComparer.OrdinalIgnoreCase)
.Aggregate(static (x, y) => $"self.{x}, self.{y}");
writer.WriteLine($"writer.{GetSerializationMethodName(complexProperties[0].Type)}(None, {propertiesNames})");
writer.WriteLine($"writer.{GetSerializationMethodName(complexProperties[0].Type)}({NoneKeyword}, {propertiesNames})");
if (includeElse)
{
writer.DecreaseIndent();
Expand All @@ -706,7 +707,7 @@ private void WriteMethodDocumentation(CodeMethod code, LanguageWriter writer, st
{
var nullablePrefix = code.ReturnType.IsNullable && !isVoid ? "Optional[" : string.Empty;
var nullableSuffix = code.ReturnType.IsNullable && !isVoid ? "]" : string.Empty;
var returnRemark = isVoid ? "Returns: None" : $"Returns: {nullablePrefix}{returnType}{nullableSuffix}";
var returnRemark = isVoid ? $"Returns: {NoneKeyword}" : $"Returns: {nullablePrefix}{returnType}{nullableSuffix}";
conventions.WriteLongDescription(code,
writer,
code.Parameters
Expand Down Expand Up @@ -744,7 +745,7 @@ private void WriteMethodPrototype(CodeMethod code, LanguageWriter writer, string
_ => string.Empty
};
var nullReturnTypeSuffix = !isVoid && !isConstructor;
var returnTypeSuffix = nullReturnTypeSuffix ? $"{nullablePrefix}{returnType}{nullableSuffix}" : "None";
var returnTypeSuffix = nullReturnTypeSuffix ? $"{nullablePrefix}{returnType}{nullableSuffix}" : NoneKeyword;
if (!string.IsNullOrEmpty(propertyDecorator))
writer.WriteLine($"{propertyDecorator}");
writer.WriteLine($"{asyncPrefix}def {accessModifier}{methodName}({instanceReference}{parameters}) -> {returnTypeSuffix}:");
Expand Down

0 comments on commit b8e5dc5

Please sign in to comment.