@@ -1412,6 +1412,79 @@ def as_value(self):
14121412 return self .dest
14131413
14141414
1415+ class MockShapeCastableFormat (ShapeCastable ):
1416+ def __init__ (self , dest ):
1417+ self .dest = dest
1418+
1419+ def as_shape (self ):
1420+ return self .dest
1421+
1422+ def __call__ (self , value ):
1423+ return value
1424+
1425+ def const (self , init ):
1426+ return Const (init , self .dest )
1427+
1428+ def from_bits (self , bits ):
1429+ return bits
1430+
1431+ def format (self , value , format_desc ):
1432+ return Format ("_{}_{}_" , Value .cast (value ), format_desc )
1433+
1434+
1435+ class MockValueCastableFormat (ValueCastable ):
1436+ def __init__ (self , dest ):
1437+ self .dest = dest
1438+
1439+ def shape (self ):
1440+ return MockShapeCastableFormat (Value .cast (self .dest ).shape ())
1441+
1442+ def as_value (self ):
1443+ return self .dest
1444+
1445+
1446+ class MockValueCastableNoFormat (ValueCastable ):
1447+ def __init__ (self , dest ):
1448+ self .dest = dest
1449+
1450+ def shape (self ):
1451+ return MockShapeCastable (Value .cast (self .dest ).shape ())
1452+
1453+ def as_value (self ):
1454+ return self .dest
1455+
1456+
1457+ class MockShapeCastableFormatWrong (ShapeCastable ):
1458+ def __init__ (self , dest ):
1459+ self .dest = dest
1460+
1461+ def as_shape (self ):
1462+ return self .dest
1463+
1464+ def __call__ (self , value ):
1465+ return value
1466+
1467+ def const (self , init ):
1468+ return Const (init , self .dest )
1469+
1470+ def from_bits (self , bits ):
1471+ return bits
1472+
1473+ def format (self , value , format_desc ):
1474+ return Value .cast (value )
1475+
1476+
1477+ class MockValueCastableFormatWrong (ValueCastable ):
1478+ def __init__ (self , dest ):
1479+ self .dest = dest
1480+
1481+ def shape (self ):
1482+ return MockShapeCastableFormatWrong (Value .cast (self .dest ).shape ())
1483+
1484+ def as_value (self ):
1485+ return self .dest
1486+
1487+
14151488class MockValueCastableChanges (ValueCastable ):
14161489 def __init__ (self , width = 0 ):
14171490 self .width = width
@@ -1567,6 +1640,21 @@ def test_construct(self):
15671640 fmt = Format ("sub: {}, c: {:4x}" , subfmt , c )
15681641 self .assertRepr (fmt , "(format 'sub: a: {:2x}, b: {:3x}, c: {:4x}' (sig a) (sig b) (sig c))" )
15691642
1643+ def test_construct_valuecastable (self ):
1644+ a = Signal ()
1645+ b = MockValueCastable (a )
1646+ fmt = Format ("{:x}" , b )
1647+ self .assertRepr (fmt , "(format '{:x}' (sig a))" )
1648+ c = MockValueCastableFormat (a )
1649+ fmt = Format ("{:meow}" , c )
1650+ self .assertRepr (fmt , "(format '_{}_meow_' (sig a))" )
1651+ d = MockValueCastableNoFormat (a )
1652+ fmt = Format ("{:x}" , d )
1653+ self .assertRepr (fmt , "(format '{:x}' (sig a))" )
1654+ e = MockValueCastableFormat (a )
1655+ fmt = Format ("{!v:x}" , e )
1656+ self .assertRepr (fmt , "(format '{:x}' (sig a))" )
1657+
15701658 def test_construct_wrong (self ):
15711659 a = Signal ()
15721660 b = Signal (signed (16 ))
@@ -1576,9 +1664,6 @@ def test_construct_wrong(self):
15761664 with self .assertRaisesRegex (ValueError ,
15771665 r"^cannot switch from automatic field numbering to manual field specification$" ):
15781666 Format ("{}, {1}" , a , b )
1579- with self .assertRaisesRegex (TypeError ,
1580- r"^'ValueCastable' formatting is not supported$" ):
1581- Format ("{}" , MockValueCastable (Const (0 )))
15821667 with self .assertRaisesRegex (ValueError ,
15831668 r"^Format specifiers \('s'\) cannot be used for 'Format' objects$" ):
15841669 Format ("{:s}" , Format ("" ))
@@ -1622,6 +1707,14 @@ def test_construct_wrong(self):
16221707 r"^Cannot specify '_' with format specifier 'c'$" ):
16231708 Format ("{a:_c}" , a = a )
16241709
1710+ def test_construct_valuecastable_wrong (self ):
1711+ a = Signal ()
1712+ b = MockValueCastableFormatWrong (a )
1713+ with self .assertRaisesRegex (TypeError ,
1714+ r"^`ShapeCastable.format` must return a 'Format' instance, "
1715+ r"not \(sig a\)$" ):
1716+ fmt = Format ("{:x}" , b )
1717+
16251718 def test_plus (self ):
16261719 a = Signal ()
16271720 b = Signal ()
0 commit comments