Skip to content

Commit

Permalink
Merge pull request #6 from tonybaloney/none_default
Browse files Browse the repository at this point in the history
Support None and boolean default values, treat None True and False as special tokens
  • Loading branch information
tonybaloney authored Jul 8, 2024
2 parents b15bece + ce51f62 commit 6ccdd9b
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 10 deletions.
5 changes: 2 additions & 3 deletions ExamplePythonDependency/ExamplePythonDependency.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
</PropertyGroup>

<ItemGroup>
<None Remove="HelloWorldOld.cs.txt" />
<None Remove="quick_demo.py" />
<None Remove="type_demos.py" />
</ItemGroup>
Expand All @@ -23,9 +22,9 @@
<AdditionalFiles Include="type_demos.py">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</AdditionalFiles>
<!--<AdditionalFiles Include="mistral_demo.py">
<AdditionalFiles Include="mistral_demo.py">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</AdditionalFiles>-->
</AdditionalFiles>
<AdditionalFiles Include="kmeans_example.py">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</AdditionalFiles>
Expand Down
2 changes: 1 addition & 1 deletion ExamplePythonDependency/mistral_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from mistral_common.protocol.instruct.request import ChatCompletionRequest


def invoke_mistral_inference(messages: list[str], lang: str = "en-US", temperature=0.0) -> str:
def invoke_mistral_inference(messages: list[str], lang: str = "en-US", temperature: float=0.0) -> str:
tokenizer = MistralTokenizer.from_file(f"{mistral_models_path}/tokenizer.model.v3")
model = Transformer.from_folder(mistral_models_path)

Expand Down
1 change: 1 addition & 0 deletions PythonSourceGenerator.Tests/SignatureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public BasicSmokeTest(TestEnvironment testEnv)
[InlineData("def hello_world(name: str, age: int) -> str:\n ...\n", "string HelloWorld(string name, long age)")]
[InlineData("def hello_world(numbers: list[float]) -> list[int]:\n ...\n", "IEnumerable<long> HelloWorld(IEnumerable<double> numbers)")]
[InlineData("def hello_world(a: bool, b: str, c: list[tuple[int, float]]) -> bool: \n ...\n", "bool HelloWorld(bool a, string b, IEnumerable<Tuple<long, double>> c)")]
[InlineData("def hello_world(a: bool = True, b: str = None) -> bool: \n ...\n", "bool HelloWorld(bool a = true, string b = null)")]
public void TestGeneratedSignature(string code, string expected)
{

Expand Down
62 changes: 60 additions & 2 deletions PythonSourceGenerator.Tests/TokenizerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void Tokenize()
PythonSignatureTokens.PythonSignatureToken.Identifier,
PythonSignatureTokens.PythonSignatureToken.CloseParenthesis,
PythonSignatureTokens.PythonSignatureToken.Arrow,
PythonSignatureTokens.PythonSignatureToken.Identifier,
PythonSignatureTokens.PythonSignatureToken.None,
PythonSignatureTokens.PythonSignatureToken.Colon,
], tokens.Select(t => t.Kind));
}
Expand All @@ -39,6 +39,9 @@ public void Tokenize()
[InlineData("abc123", PythonSignatureTokens.PythonSignatureToken.Identifier)]
[InlineData("'hello'", PythonSignatureTokens.PythonSignatureToken.SingleQuotedString)]
[InlineData("\"hello\"", PythonSignatureTokens.PythonSignatureToken.DoubleQuotedString)]
[InlineData("True", PythonSignatureTokens.PythonSignatureToken.True)]
[InlineData("False", PythonSignatureTokens.PythonSignatureToken.False)]
[InlineData("None", PythonSignatureTokens.PythonSignatureToken.None)]
public void AssertTokenKinds(string code, PythonSignatureTokens.PythonSignatureToken expectedToken)
{
var tokens = PythonSignatureTokenizer.Instance.Tokenize(code);
Expand All @@ -65,7 +68,7 @@ public void TokenizeWithDefaultValue()
PythonSignatureTokens.PythonSignatureToken.SingleQuotedString,
PythonSignatureTokens.PythonSignatureToken.CloseParenthesis,
PythonSignatureTokens.PythonSignatureToken.Arrow,
PythonSignatureTokens.PythonSignatureToken.Identifier,
PythonSignatureTokens.PythonSignatureToken.None,
PythonSignatureTokens.PythonSignatureToken.Colon,
], tokens.Select(t => t.Kind));
}
Expand Down Expand Up @@ -149,6 +152,61 @@ public void ParseFunctionParameterDefaultDoubleQuotedString()
Assert.False(result.Value.HasTypeAnnotation());
}

[Fact]
public void ParseFunctionParameterDefaultDouble()
{
var tokens = PythonSignatureTokenizer.Instance.Tokenize($"a: float = -1.1");
var result = PythonSignatureParser.PythonParameterTokenizer.TryParse(tokens);
Assert.True(result.HasValue);
Assert.Equal("a", result.Value.Name);
Assert.Equal("-1.1", result.Value.DefaultValue?.ToString());
Assert.True(result.Value.HasTypeAnnotation());
}

[Fact]
public void ParseFunctionParameterDefaultInt()
{
var tokens = PythonSignatureTokenizer.Instance.Tokenize($"a: int = 1234");
var result = PythonSignatureParser.PythonParameterTokenizer.TryParse(tokens);
Assert.True(result.HasValue);
Assert.Equal("a", result.Value.Name);
Assert.Equal("1234", result.Value.DefaultValue?.ToString());
Assert.True(result.Value.HasTypeAnnotation());
}

[Fact]
public void ParseFunctionParameterDefaultBoolTrue()
{
var tokens = PythonSignatureTokenizer.Instance.Tokenize($"a: bool = True");
var result = PythonSignatureParser.PythonParameterTokenizer.TryParse(tokens);
Assert.True(result.HasValue);
Assert.Equal("a", result.Value.Name);
Assert.Equal("True", result.Value.DefaultValue?.ToString());
Assert.True(result.Value.HasTypeAnnotation());
}

[Fact]
public void ParseFunctionParameterDefaultBoolFalse()
{
var tokens = PythonSignatureTokenizer.Instance.Tokenize($"a: bool = False");
var result = PythonSignatureParser.PythonParameterTokenizer.TryParse(tokens);
Assert.True(result.HasValue);
Assert.Equal("a", result.Value.Name);
Assert.Equal("False", result.Value.DefaultValue?.ToString());
Assert.True(result.Value.HasTypeAnnotation());
}

[Fact]
public void ParseFunctionParameterDefaultNone()
{
var tokens = PythonSignatureTokenizer.Instance.Tokenize($"a: bool = None");
var result = PythonSignatureParser.PythonParameterTokenizer.TryParse(tokens);
Assert.True(result.HasValue);
Assert.Equal("a", result.Value.Name);
Assert.Equal("None", result.Value.DefaultValue?.ToString());
Assert.True(result.Value.HasTypeAnnotation());
}

[Fact]
public void ParseFunctionParameterListSingleGeneric()
{
Expand Down
17 changes: 14 additions & 3 deletions PythonSourceGenerator/Parser/PythonSignatureParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ from exp in Character.EqualToIgnoreCase('e')
}

public static TokenListParser<PythonSignatureTokens.PythonSignatureToken, PythonTypeSpec> PythonTypeDefinitionTokenizer { get; } =
(from name in Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.Identifier)
from openBracket in Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.OpenBracket)
(from name in Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.Identifier).Or(Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.None))
from openBracket in Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.OpenBracket)
.Then(_ => PythonTypeDefinitionTokenizer.ManyDelimitedBy(
Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.Comma),
end: Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.CloseBracket)
Expand Down Expand Up @@ -123,13 +123,24 @@ from openBracket in Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.Ope
.Select(d => new PythonConstant { IsInteger = true, IntegerValue = d })
.Named("Integer Constant");

public static TokenListParser<PythonSignatureTokens.PythonSignatureToken, PythonConstant> BoolConstantTokenizer { get; } =
Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.True).Or(Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.False))
.Select(d => new PythonConstant { IsBool = true, BoolValue = d.Kind == PythonSignatureTokens.PythonSignatureToken.True })
.Named("Bool Constant");

public static TokenListParser<PythonSignatureTokens.PythonSignatureToken, PythonConstant> NoneConstantTokenizer { get; } =
Token.EqualTo(PythonSignatureTokens.PythonSignatureToken.None)
.Select(d => new PythonConstant { IsNone = true })
.Named("None Constant");

// Any constant value
public static TokenListParser<PythonSignatureTokens.PythonSignatureToken, PythonConstant> ConstantValueTokenizer { get; } =
DecimalConstantTokenizer.AsNullable()
.Or(IntegerConstantTokenizer.AsNullable())
.Or(BoolConstantTokenizer.AsNullable())
.Or(NoneConstantTokenizer.AsNullable())
.Or(DoubleQuotedStringConstantTokenizer.AsNullable())
.Or(SingleQuotedStringConstantTokenizer.AsNullable())
// TODO: Add None token
.Named("Constant");

public static TokenListParser<PythonSignatureTokens.PythonSignatureToken, PythonFunctionParameter> PythonParameterTokenizer { get; } =
Expand Down
4 changes: 3 additions & 1 deletion PythonSourceGenerator/Parser/PythonSignatureTokenizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ public static class PythonSignatureTokenizer
.Match(Span.EqualTo("def"), PythonSignatureTokens.PythonSignatureToken.Def, requireDelimiters: true)
.Match(Span.EqualTo("async"), PythonSignatureTokens.PythonSignatureToken.Async, requireDelimiters: true)
.Match(Span.EqualTo("..."), PythonSignatureTokens.PythonSignatureToken.Ellipsis)
.Match(Span.EqualTo("None"), PythonSignatureTokens.PythonSignatureToken.None, requireDelimiters: true)
.Match(Span.EqualTo("True"), PythonSignatureTokens.PythonSignatureToken.True, requireDelimiters: true)
.Match(Span.EqualTo("False"), PythonSignatureTokens.PythonSignatureToken.False, requireDelimiters: true)
.Match(Identifier.CStyle, PythonSignatureTokens.PythonSignatureToken.Identifier, requireDelimiters: true) // TODO: Does this require delimiters?
.Match(PythonSignatureParser.IntegerConstantToken, PythonSignatureTokens.PythonSignatureToken.Integer, requireDelimiters: true)
.Match(PythonSignatureParser.DecimalConstantToken, PythonSignatureTokens.PythonSignatureToken.Decimal, requireDelimiters: true)
.Match(PythonSignatureParser.DoubleQuotedStringConstantToken, PythonSignatureTokens.PythonSignatureToken.DoubleQuotedString)
.Match(PythonSignatureParser.SingleQuotedStringConstantToken, PythonSignatureTokens.PythonSignatureToken.SingleQuotedString)
// TODO: Treat None as a special token
.Build();
}
3 changes: 3 additions & 0 deletions PythonSourceGenerator/Parser/PythonSignatureTokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public enum PythonSignatureToken
Decimal,
DoubleQuotedString,
SingleQuotedString,
True,
False,
None,

[Token(Example = "...")]
Ellipsis
Expand Down
7 changes: 7 additions & 0 deletions PythonSourceGenerator/Parser/Types/PythonConstant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class PythonConstant
public bool IsFloat { get; set; }
public double FloatValue { get; set; }

public bool IsBool { get; set; }
public bool BoolValue { get; set; }

public override string ToString()
{
if (IsInteger)
Expand All @@ -31,6 +34,10 @@ public override string ToString()
{
return "None";
}
if (IsBool)
{
return BoolValue.ToString();
}
return "unknown";
}
}
4 changes: 4 additions & 0 deletions PythonSourceGenerator/Reflection/ArgumentReflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public static ParameterSyntax ArgumentSyntax(PythonFunctionParameter parameter)
literalExpressionSyntax = SyntaxFactory.LiteralExpression(
SyntaxKind.NumericLiteralExpression,
SyntaxFactory.Literal(parameter.DefaultValue.FloatValue));
else if (parameter.DefaultValue.IsBool && parameter.DefaultValue.BoolValue == true)
literalExpressionSyntax = SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression);
else if (parameter.DefaultValue.IsBool && parameter.DefaultValue.BoolValue == false)
literalExpressionSyntax = SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression);
else if (parameter.DefaultValue.IsNone)
literalExpressionSyntax = SyntaxFactory.LiteralExpression(
SyntaxKind.NullLiteralExpression);
Expand Down

0 comments on commit 6ccdd9b

Please sign in to comment.