Skip to content

Commit c04c79f

Browse files
committed
feat: bind snake case name properties along with original method .net to python
1 parent 07285dd commit c04c79f

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

src/embed_tests/ClassManagerTests.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ public class SnakeCaseNamesTesClass
4141

4242
public static string SettablePublicStaticStringField = "settable_public_static_string_field";
4343

44+
public string PublicStringProperty { get; set; } = "public_string_property";
45+
public static string PublicStaticStringProperty { get; set; } = "public_static_string_property";
46+
47+
4448
public int AddNumbersAndGetHalf(int a, int b)
4549
{
4650
return (a + b) / 2;
@@ -145,6 +149,77 @@ def SetSnakeCaseStaticProperty(value):
145149
}
146150
}
147151

152+
[TestCase("PublicStringProperty", "public_string_property")]
153+
[TestCase("PublicStaticStringProperty", "public_static_string_property")]
154+
public void BindsSnakeCaseClassProperties(string originalPropertyName, string snakeCasePropertyName)
155+
{
156+
using var obj = new SnakeCaseNamesTesClass().ToPython();
157+
var expectedValue = originalPropertyName switch
158+
{
159+
"PublicStringProperty" => "public_string_property",
160+
"PublicStaticStringProperty" => "public_static_string_property",
161+
_ => throw new ArgumentException("Invalid property name")
162+
};
163+
164+
var originalPropertyValue = obj.GetAttr(originalPropertyName).As<string>();
165+
var snakeCasePropertyValue = obj.GetAttr(snakeCasePropertyName).As<string>();
166+
167+
Assert.AreEqual(expectedValue, originalPropertyValue);
168+
Assert.AreEqual(expectedValue, snakeCasePropertyValue);
169+
}
170+
171+
[Test]
172+
public void CanSetPropertyUsingSnakeCaseName()
173+
{
174+
var obj = new SnakeCaseNamesTesClass();
175+
using var pyObj = obj.ToPython();
176+
177+
// Try with the original property name
178+
var newValue1 = "new value 1";
179+
using var pyNewValue1 = newValue1.ToPython();
180+
pyObj.SetAttr("PublicStringProperty", pyNewValue1);
181+
Assert.AreEqual(newValue1, obj.PublicStringProperty);
182+
183+
// Try with the snake case property name
184+
var newValue2 = "new value 2";
185+
using var pyNewValue2 = newValue2.ToPython();
186+
pyObj.SetAttr("public_string_property", pyNewValue2);
187+
Assert.AreEqual(newValue2, obj.PublicStringProperty);
188+
}
189+
190+
[Test]
191+
public void CanSetStaticPropertyUsingSnakeCaseName()
192+
{
193+
using (Py.GIL())
194+
{
195+
var module = PyModule.FromString("module", $@"
196+
from clr import AddReference
197+
AddReference(""Python.EmbeddingTest"")
198+
AddReference(""System"")
199+
200+
from Python.EmbeddingTest import *
201+
202+
def SetCamelCaseStaticProperty(value):
203+
ClassManagerTests.SnakeCaseNamesTesClass.PublicStaticStringProperty = value
204+
205+
def SetSnakeCaseStaticProperty(value):
206+
ClassManagerTests.SnakeCaseNamesTesClass.public_static_string_property = value
207+
");
208+
209+
// Try with the original property name
210+
var newValue1 = "new value 1";
211+
using var pyNewValue1 = newValue1.ToPython();
212+
module.InvokeMethod("SetCamelCaseStaticProperty", pyNewValue1);
213+
Assert.AreEqual(newValue1, SnakeCaseNamesTesClass.PublicStaticStringProperty);
214+
215+
// Try with the snake case property name
216+
var newValue2 = "new value 2";
217+
using var pyNewValue2 = newValue2.ToPython();
218+
module.InvokeMethod("SetSnakeCaseStaticProperty", pyNewValue2);
219+
Assert.AreEqual(newValue2, SnakeCaseNamesTesClass.PublicStaticStringProperty);
220+
}
221+
}
222+
148223
#endregion
149224
}
150225

src/runtime/ClassManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
504504

505505
ob = new PropertyObject(pi);
506506
ci.members[pi.Name] = ob.AllocObject();
507+
ci.members[pi.Name.ToSnakeCase()] = ob.AllocObject();
507508
continue;
508509

509510
case MemberTypes.Field:
@@ -514,6 +515,7 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
514515
}
515516
ob = new FieldObject(fi);
516517
ci.members[mi.Name] = ob.AllocObject();
518+
// TODO: Upper-case constants?
517519
ci.members[mi.Name.ToSnakeCase()] = ob.AllocObject();
518520
continue;
519521

0 commit comments

Comments
 (0)