Skip to content

Commit

Permalink
Merge pull request #135 from tonybaloney/optional
Browse files Browse the repository at this point in the history
Implement Optional[T] with a default of None as a nullable type of T.
  • Loading branch information
tonybaloney authored Aug 19, 2024
2 parents 04e5adc + 752fda7 commit acd6e72
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ CSnakes supports the following typed scenarios:
| `typing.Dict[K, V]` | `IReadOnlyDictionary<K, V>` |
| `typing.Mapping[K, V]` | `IReadOnlyDictionary<K, V>` |
| `typing.Tuple[T1, T2, ...]` | `(T1, T2, ...)` |
| `typing.Optional[T]` | `T?` |
| `None` (Return) | `void` |


Expand Down
1 change: 1 addition & 0 deletions src/CSnakes.Tests/GeneratedSignatureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class GeneratedSignatureTests(TestEnvironment testEnv) : IClassFixture<Te
[InlineData("def hello(a: int = 0xdeadbeef) -> None:\n ...\n", "void Hello(long a = 0xDEADBEEF)")]
[InlineData("def hello(a: int = 0b10101010) -> None:\n ...\n", "void Hello(long a = 0b10101010)")]
[InlineData("def hello(a: int = 2147483648) -> None:\n ...\n", "void Hello(long a = 2147483648L)")]
[InlineData("def hello(a: Optional[int] = None) -> None:\n ...\n", "void Hello(long? a = null)")]
public void TestGeneratedSignature(string code, string expected)
{

Expand Down
1 change: 1 addition & 0 deletions src/CSnakes/Reflection/TypeReflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public static TypeSyntax AsPredefinedType(PythonTypeSpec pythonType)
"Dict" => CreateDictionaryType(pythonType.Arguments[0], pythonType.Arguments[1]),
"Mapping" => CreateDictionaryType(pythonType.Arguments[0], pythonType.Arguments[1]),
"Sequence" => CreateListType(pythonType.Arguments[0]),
"Optional" => AsPredefinedType(pythonType.Arguments[0]),
// Todo more types... see https://docs.python.org/3/library/stdtypes.html#standard-generic-classes
_ => SyntaxFactory.ParseTypeName("PyObject"),// TODO : Should be nullable?
};
Expand Down
28 changes: 28 additions & 0 deletions src/Integration.Tests/DefaultsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,33 @@ public void TestDefault_FloatArg()
{
var testDefaults = Env.TestDefaults();
Assert.Equal(-1, testDefaults.TestDefaultFloatArg());
}

[Fact]
public void TestDefault_OptionalInt()
{
var testDefaults = Env.TestDefaults();
Assert.True(testDefaults.TestOptionalInt());
}

[Fact]
public void TestDefault_OptionalStr()
{
var testDefaults = Env.TestDefaults();
Assert.True(testDefaults.TestOptionalStr());
}

[Fact]
public void TestDefault_OptionalList()
{
var testDefaults = Env.TestDefaults();
Assert.True(testDefaults.TestOptionalList());
}

[Fact]
public void TestDefault_OptionalAny()
{
var testDefaults = Env.TestDefaults();
Assert.True(testDefaults.TestOptionalAny());
}
}
17 changes: 17 additions & 0 deletions src/Integration.Tests/python/test_defaults.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Any, Optional

def test_default_str_arg(a: str = "hello") -> str:
return a

Expand All @@ -9,3 +11,18 @@ def test_default_float_arg(a: float = -1) -> float:

def test_int_literals(a: int = 0x1337, b: int = 0b10101011) -> int:
return a

def test_optional_int(a: Optional[int] = None) -> bool:
return a is None


def test_optional_str(a: Optional[str] = None) -> bool:
return a is None


def test_optional_list(a: Optional[list[int]] = None) -> bool:
return a is None


def test_optional_any(a: Optional[Any] = None) -> bool:
return a is None

0 comments on commit acd6e72

Please sign in to comment.