@@ -1412,6 +1412,79 @@ def as_value(self):
1412
1412
return self.dest
1413
1413
1414
1414
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
+
1415
1488
class MockValueCastableChanges(ValueCastable):
1416
1489
def __init__(self, width=0):
1417
1490
self.width = width
@@ -1567,6 +1640,21 @@ def test_construct(self):
1567
1640
fmt = Format("sub: {}, c: {:4x}", subfmt, c)
1568
1641
self.assertRepr(fmt, "(format 'sub: a: {:2x}, b: {:3x}, c: {:4x}' (sig a) (sig b) (sig c))")
1569
1642
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
+
1570
1658
def test_construct_wrong(self):
1571
1659
a = Signal()
1572
1660
b = Signal(signed(16))
@@ -1576,9 +1664,6 @@ def test_construct_wrong(self):
1576
1664
with self.assertRaisesRegex(ValueError,
1577
1665
r"^cannot switch from automatic field numbering to manual field specification$"):
1578
1666
Format("{}, {1}", a, b)
1579
- with self.assertRaisesRegex(TypeError,
1580
- r"^'ValueCastable' formatting is not supported$"):
1581
- Format("{}", MockValueCastable(Const(0)))
1582
1667
with self.assertRaisesRegex(ValueError,
1583
1668
r"^Format specifiers \('s'\) cannot be used for 'Format' objects$"):
1584
1669
Format("{:s}", Format(""))
@@ -1622,6 +1707,14 @@ def test_construct_wrong(self):
1622
1707
r"^Cannot specify '_' with format specifier 'c'$"):
1623
1708
Format("{a:_c}", a=a)
1624
1709
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
+
1625
1718
def test_plus(self):
1626
1719
a = Signal()
1627
1720
b = Signal()
0 commit comments