[consider merging] Bugfix: Python did not support downcasting of PolygonWithProperties to Polygon on Shapes#polygon for example

This commit is contained in:
Matthias Koefferlein 2026-02-24 21:00:21 +01:00
parent de7ace9295
commit 3af5568663
2 changed files with 24 additions and 3 deletions

View File

@ -1214,8 +1214,9 @@ property_setter_impl (int mid, PyObject *self, PyObject *value)
// check arguments (count and type)
bool is_valid = (*m)->compatible_with_num_args (1);
bool loose = (pass != 0); // loose in the second pass
if (is_valid && ! test_arg (*(*m)->begin_arguments (), value, loose, loose)) {
bool loose = (pass > 0); // loose in the second and third pass
bool object_substitution = (pass > 1); // object substitution in the third pass
if (is_valid && ! test_arg (*(*m)->begin_arguments (), value, loose, object_substitution)) {
is_valid = false;
}
@ -1228,7 +1229,7 @@ property_setter_impl (int mid, PyObject *self, PyObject *value)
++pass;
} while (! meth && pass < 2);
} while (! meth && pass < 3);
}

View File

@ -61,6 +61,26 @@ class DBShapesTest(unittest.TestCase):
shapes = top.shapes(l1)
self.assertEqual(sys.getrefcount(shapes), 2)
# Tests the ability to take PolygonWithProperties instead of base class
# for setter
def test_3(self):
shapes = pya.Shapes()
shapes.insert(pya.Polygon(pya.Box(0, 0, 100, 200)))
self.assertEqual(";".join([ str(s) for s in shapes.each() ]), "polygon (0,0;0,200;100,200;100,0)")
pwp = pya.PolygonWithProperties(pya.Polygon(pya.Box(0, 0, 110, 210)))
s0 = [ s for s in shapes.each() ][0]
s0.polygon = pwp
self.assertEqual(";".join([ str(s) for s in shapes.each() ]), "polygon (0,0;0,210;110,210;110,0)")
# with object substitution
s0.polygon = ( pya.Box(0, 0, 120, 220) )
self.assertEqual(";".join([ str(s) for s in shapes.each() ]), "polygon (0,0;0,220;120,220;120,0)")
# with object substitution by constructor inference
s0.polygon = pya.Box(0, 0, 130, 230)
self.assertEqual(";".join([ str(s) for s in shapes.each() ]), "polygon (0,0;0,230;130,230;130,0)")
# run unit tests
if __name__ == '__main__':