@@ -136,15 +136,19 @@ def __hash__(self):
136136
137137
138138class CustomPrintable :
139+ def __init__ (self , name = "my pprint" , value = 42 ):
140+ self .name = name
141+ self .value = value
142+
139143 def __str__ (self ):
140144 return "my str"
141145
142146 def __repr__ (self ):
143147 return "my str"
144148
145- def __pprint__ (self , context , maxlevels , level ):
146- # The custom pretty repr, not-readable bool, no recursion detected.
147- return "my pprint " , False , False
149+ def __pprint__ (self ):
150+ yield self . name
151+ yield ( "value " , self . value )
148152
149153
150154class QueryTestCase (unittest .TestCase ):
@@ -1490,7 +1494,72 @@ def test_custom_pprinter(self):
14901494 pp = pprint .PrettyPrinter (stream = stream )
14911495 custom_obj = CustomPrintable ()
14921496 pp .pprint (custom_obj )
1493- self .assertEqual (stream .getvalue (), "my pprint\n " )
1497+ self .assertEqual (stream .getvalue (), "CustomPrintable('my pprint', value=42)\n " )
1498+
1499+ def test_pprint_protocol_positional (self ):
1500+ # Test __pprint__ with positional arguments only
1501+ class Point :
1502+ def __init__ (self , x , y ):
1503+ self .x = x
1504+ self .y = y
1505+ def __pprint__ (self ):
1506+ yield self .x
1507+ yield self .y
1508+ self .assertEqual (pprint .pformat (Point (1 , 2 )), "Point(1, 2)" )
1509+
1510+ def test_pprint_protocol_keyword (self ):
1511+ # Test __pprint__ with keyword arguments
1512+ class Config :
1513+ def __init__ (self , host , port ):
1514+ self .host = host
1515+ self .port = port
1516+ def __pprint__ (self ):
1517+ yield ("host" , self .host )
1518+ yield ("port" , self .port )
1519+ self .assertEqual (pprint .pformat (Config ("localhost" , 8080 )),
1520+ "Config(host='localhost', port=8080)" )
1521+
1522+ def test_pprint_protocol_default (self ):
1523+ # Test __pprint__ with default values (3-tuple form)
1524+ class Bird :
1525+ def __init__ (self , name , fly = True , extinct = False ):
1526+ self .name = name
1527+ self .fly = fly
1528+ self .extinct = extinct
1529+ def __pprint__ (self ):
1530+ yield self .name
1531+ yield ("fly" , self .fly , True ) # hide if True
1532+ yield ("extinct" , self .extinct , False ) # hide if False
1533+
1534+ # Defaults should be hidden
1535+ self .assertEqual (pprint .pformat (Bird ("sparrow" )),
1536+ "Bird('sparrow')" )
1537+ # Non-defaults should be shown
1538+ self .assertEqual (pprint .pformat (Bird ("dodo" , fly = False , extinct = True )),
1539+ "Bird('dodo', fly=False, extinct=True)" )
1540+
1541+ def test_pprint_protocol_nested (self ):
1542+ # Test __pprint__ with nested objects
1543+ class Container :
1544+ def __init__ (self , items ):
1545+ self .items = items
1546+ def __pprint__ (self ):
1547+ yield ("items" , self .items )
1548+ c = Container ([1 , 2 , 3 ])
1549+ self .assertEqual (pprint .pformat (c ), "Container(items=[1, 2, 3])" )
1550+ # Nested in a list
1551+ self .assertEqual (pprint .pformat ([c ]), "[Container(items=[1, 2, 3])]" )
1552+
1553+ def test_pprint_protocol_isreadable (self ):
1554+ # Test that isreadable works correctly with __pprint__
1555+ class Readable :
1556+ def __pprint__ (self ):
1557+ yield 42
1558+ class Unreadable :
1559+ def __pprint__ (self ):
1560+ yield open # built-in function, not readable
1561+ self .assertTrue (pprint .isreadable (Readable ()))
1562+ self .assertFalse (pprint .isreadable (Unreadable ()))
14941563
14951564
14961565class DottedPrettyPrinter (pprint .PrettyPrinter ):
0 commit comments