@@ -1420,6 +1420,16 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
14201420 }
14211421 return true ;
14221422 }
1423+
1424+ public override bool TrySetMember ( SetMemberBinder binder , object value )
1425+ {
1426+ if ( value is PyObject pyValue && PyString . IsStringType ( pyValue ) )
1427+ {
1428+ throw new InvalidOperationException ( "Cannot set string value" ) ;
1429+ }
1430+
1431+ return base . TrySetMember ( binder , value ) ;
1432+ }
14231433 }
14241434
14251435 [ Test ]
@@ -1430,7 +1440,6 @@ public void TestHasAttrShouldNotThrowIfAttributeIsNotPresentForDynamicClassObjec
14301440 dynamic module = PyModule . FromString ( "TestHasAttrShouldNotThrowIfAttributeIsNotPresentForDynamicClassObjects" , @"
14311441from clr import AddReference
14321442AddReference(""Python.EmbeddingTest"")
1433- AddReference(""System"")
14341443
14351444from Python.EmbeddingTest import TestPropertyAccess
14361445
@@ -1466,6 +1475,40 @@ def has_attribute(obj, attribute):
14661475 Assert . IsFalse ( hasAttributeResult ) ;
14671476 }
14681477
1478+ [ Test ]
1479+ public void TestSetAttrShouldThrowPythonExceptionOnFailure ( )
1480+ {
1481+ using var _ = Py . GIL ( ) ;
1482+
1483+ dynamic module = PyModule . FromString ( "TestHasAttrShouldNotThrowIfAttributeIsNotPresentForDynamicClassObjects" , @"
1484+ from clr import AddReference
1485+ AddReference(""Python.EmbeddingTest"")
1486+
1487+ from Python.EmbeddingTest import TestPropertyAccess
1488+
1489+ class TestDynamicClass(TestPropertyAccess.ThrowingDynamicFixture):
1490+ pass
1491+
1492+ def set_attribute(obj):
1493+ obj.int_attribute = 11
1494+
1495+ def set_string_attribute(obj):
1496+ obj.string_attribute = 'string'
1497+ " ) ;
1498+
1499+ dynamic fixture = module . GetAttr ( "TestDynamicClass" ) ( ) ;
1500+
1501+ dynamic setAttribute = module . GetAttr ( "set_attribute" ) ;
1502+ Assert . DoesNotThrow ( ( ) => setAttribute ( fixture ) ) ;
1503+
1504+ dynamic setStringAttribute = module . GetAttr ( "set_string_attribute" ) ;
1505+ var exception = Assert . Throws < PythonException > ( ( ) => setStringAttribute ( fixture ) ) ;
1506+ Assert . AreEqual ( "Cannot set string value" , exception . Message ) ;
1507+
1508+ using var expectedExceptionType = new PyType ( Exceptions . AttributeError ) ;
1509+ Assert . AreEqual ( expectedExceptionType , exception . Type ) ;
1510+ }
1511+
14691512 public interface IModel
14701513 {
14711514 void InvokeModel ( ) ;
0 commit comments