Skip to content

Commit

Permalink
Merge pull request #4048 from microsoft/feature/python-deprecation-su…
Browse files Browse the repository at this point in the history
…pport

Feature/python deprecation support
  • Loading branch information
samwelkanda authored Jan 25, 2024
2 parents 2137233 + b7fd989 commit 30ca221
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Added Japanese translations to vscode extension.
- Added support for deprecation annotations in Python. [#2798](https://github.com/microsoft/kiota/issues/2798)

### Changed

Expand Down
2 changes: 2 additions & 0 deletions src/Kiota.Builder/Refiners/PythonRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
new (static x => x is CodeClass @class && (@class.IsOfKind(CodeClassKind.Model) || x.Parent is CodeClass), "dataclasses", "dataclass, field"),
new (static x => x is CodeClass { OriginalComposedType: CodeIntersectionType intersectionType } && intersectionType.Types.Any(static y => !y.IsExternal) && intersectionType.DiscriminatorInformation.HasBasicDiscriminatorInformation,
$"{AbstractionsPackageName}.serialization", "ParseNodeHelper"),
new (static x => x is IDeprecableElement element && element.Deprecation is not null && element.Deprecation.IsDeprecated,
"warnings", "warn"),
};

private static void CorrectCommonNames(CodeElement currentElement)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit
_codeUsingWriter.WriteConditionalInternalImports(codeElement, writer, parentNamespace);
}
conventions.WriteLongDescription(parent.Documentation, writer);
conventions.WriteDeprecationWarning(parent, writer);
}
}
}
1 change: 1 addition & 0 deletions src/Kiota.Builder/Writers/Python/CodeEnumWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write
writer.WriteLine("from enum import Enum");
writer.WriteLine();
writer.WriteLine($"class {codeElement.Name}(str, Enum):");
conventions.WriteDeprecationWarning(codeElement, writer);
writer.IncreaseIndent();
if (!codeElement.Options.Any())
{
Expand Down
1 change: 1 addition & 0 deletions src/Kiota.Builder/Writers/Python/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,7 @@ private void WriteMethodDocumentation(CodeMethod code, LanguageWriter writer, st
.OrderBy(static x => x.Name, StringComparer.OrdinalIgnoreCase)
.Select(x => $"param {x.Name}: {PythonConventionService.RemoveInvalidDescriptionCharacters(x.Documentation.Description)}")
.Union(new[] { returnRemark }));
conventions.WriteDeprecationWarning(code, writer);
}
private static readonly PythonCodeParameterOrderComparer parameterOrderComparer = new();
private void WriteMethodPrototype(CodeMethod code, LanguageWriter writer, string returnType, bool isVoid)
Expand Down
21 changes: 20 additions & 1 deletion src/Kiota.Builder/Writers/Python/PythonConventionService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

using Kiota.Builder.CodeDOM;
Expand Down Expand Up @@ -53,7 +54,9 @@ public override string GetParameterSignature(CodeParameter parameter, CodeElemen
ArgumentNullException.ThrowIfNull(parameter);
ArgumentNullException.ThrowIfNull(targetElement);
var defaultValueSuffix = string.IsNullOrEmpty(parameter.DefaultValue) ? string.Empty : $" = {parameter.DefaultValue}";
return $"{parameter.Name}: {(parameter.Type.IsNullable ? "Optional[" : string.Empty)}{GetTypeString(parameter.Type, targetElement, true, writer)}{(parameter.Type.IsNullable ? "] = None" : string.Empty)}{defaultValueSuffix}";
var deprecationInfo = GetDeprecationInformation(parameter);
var deprecationSuffix = string.IsNullOrEmpty(deprecationInfo) ? string.Empty : $"# {deprecationInfo}";
return $"{parameter.Name}: {(parameter.Type.IsNullable ? "Optional[" : string.Empty)}{GetTypeString(parameter.Type, targetElement, true, writer)}{(parameter.Type.IsNullable ? "] = None" : string.Empty)}{defaultValueSuffix}{deprecationSuffix}";
}
private static string GetTypeAlias(CodeType targetType, CodeElement targetElement)
{
Expand Down Expand Up @@ -190,4 +193,20 @@ public void WriteInLineDescription(string description, LanguageWriter writer)
writer.WriteLine($"{InLineCommentPrefix}{RemoveInvalidDescriptionCharacters(description)}");
}
}

private static string GetDeprecationInformation(IDeprecableElement element)
{
if (element.Deprecation is null || !element.Deprecation.IsDeprecated) return string.Empty;

var versionComment = string.IsNullOrEmpty(element.Deprecation.Version) ? string.Empty : $" as of {element.Deprecation.Version}";
var dateComment = element.Deprecation.Date is null ? string.Empty : $" on {element.Deprecation.Date.Value.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)}";
var removalComment = element.Deprecation.RemovalDate is null ? string.Empty : $" and will be removed {element.Deprecation.RemovalDate.Value.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)}";
return $"{element.Deprecation.Description}{versionComment}{dateComment}{removalComment}";
}
internal void WriteDeprecationWarning(IDeprecableElement element, LanguageWriter writer)
{
var deprecationMessage = GetDeprecationInformation(element);
if (!string.IsNullOrEmpty(deprecationMessage))
writer.WriteLine($"warn(\"{deprecationMessage}\", DeprecationWarning)");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,19 @@ public void WritesInternalImportsNoTypeDef()
var result = tw.ToString();
Assert.DoesNotContain("from . import message", result);
}
[Fact]
public void WritesModelClassDeprecationInformation()
{
parentClass.Kind = CodeClassKind.Model;
parentClass.Deprecation = new("This class is deprecated", DateTimeOffset.Parse("2024-01-01T00:00:00Z"), DateTimeOffset.Parse("2024-01-01T00:00:00Z"), "v2.0");
codeElementWriter.WriteCodeElement(parentClass.StartBlock, writer);
var result = tw.ToString();
Assert.Contains("@dataclass", result);
Assert.Contains("class ParentClass()", result);
Assert.Contains("warn(", result);
Assert.Contains("This class is deprecated", result);
Assert.Contains("2024-01-01", result);
Assert.Contains("2024-01-01", result);
Assert.Contains("v2.0", result);
}
}
13 changes: 13 additions & 0 deletions tests/Kiota.Builder.Tests/Writers/Python/CodeMethodWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2175,4 +2175,17 @@ public void DoesntWriteReadOnlyPropertiesInSerializerBody()
Assert.DoesNotContain("ReadOnlyProperty", result);
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
public void WritesDeprecationInformation()
{
setup();
method.Deprecation = new("This method is deprecated", DateTimeOffset.Parse("2020-01-01T00:00:00Z"), DateTimeOffset.Parse("2021-01-01T00:00:00Z"), "v2.0");
writer.Write(method);
var result = tw.ToString();
Assert.Contains("This method is deprecated", result);
Assert.Contains("2020-01-01", result);
Assert.Contains("2021-01-01", result);
Assert.Contains("v2.0", result);
Assert.Contains("warn(", result);
}
}

0 comments on commit 30ca221

Please sign in to comment.