or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

comments.mdconfiguration.mdcore-printing.mddocument-system.mdextras.mdindex.mdregistration.md

registration.mddocs/

0

# Pretty Printer Registration

1

2

System for registering custom pretty printers for user-defined types and creating formatted function call representations. This enables extending prettyprinter to handle custom classes and data structures with specialized formatting logic.

3

4

## Capabilities

5

6

### Type Registration

7

8

Register custom pretty printers for specific types or predicate-based matching, enabling specialized formatting for user-defined classes and data structures.

9

10

```python { .api }

11

def register_pretty(type=None, predicate=None):

12

"""

13

Decorator that registers a function as the pretty printer for a type.

14

15

Parameters:

16

- type: Type to register for, or string 'module.ClassName' for deferred registration

17

- predicate: Function taking one argument returning bool for predicate-based matching

18

19

Notes:

20

- Exactly one of 'type' or 'predicate' must be provided

21

- Decorated function must accept (value, ctx) parameters

22

- Returns the original function unchanged

23

24

Usage:

25

@register_pretty(MyClass)

26

def pretty_my_class(value, ctx):

27

return pretty_call(ctx, MyClass, value.attr1, value.attr2)

28

"""

29

```

30

31

### Registration Status

32

33

Check whether a type has a registered pretty printer, useful for conditional formatting logic and debugging registration issues.

34

35

```python { .api }

36

def is_registered(type, *, check_superclasses=False, check_deferred=True,

37

register_deferred=True) -> bool:

38

"""

39

Check if a type has a registered pretty printer.

40

41

Parameters:

42

- type: Type to check for registration

43

- check_superclasses (bool): Check superclass types (default: False)

44

- check_deferred (bool): Check deferred registrations (default: True)

45

- register_deferred (bool): Register deferred printers when found (default: True)

46

47

Returns:

48

- bool: True if type has registered pretty printer

49

50

Raises:

51

- ValueError: If register_deferred=True when check_deferred=False

52

"""

53

```

54

55

### Function Call Formatting (Python 3.6+)

56

57

Create formatted function call representations with automatic argument handling and keyword argument preservation.

58

59

```python { .api }

60

def pretty_call(ctx, fn, *args, **kwargs):

61

"""

62

Create a Doc representing a function call with arguments.

63

64

Parameters:

65

- ctx (PrettyContext): Current pretty printing context

66

- fn: Callable to represent in the call

67

- args: Positional arguments for the call

68

- kwargs: Keyword arguments for the call

69

70

Returns:

71

- Doc: Document representing the formatted function call

72

73

Notes:

74

- Requires Python 3.6+ for keyword argument order preservation

75

- Automatically handles syntax highlighting and layout

76

- For Python 3.5 compatibility, use pretty_call_alt instead

77

"""

78

```

79

80

### Function Call Formatting (All Python Versions)

81

82

Create formatted function call representations with explicit argument specification, compatible with all Python versions.

83

84

```python { .api }

85

def pretty_call_alt(ctx, fn, args=(), kwargs=()):

86

"""

87

Create a Doc representing a function call with explicit arguments.

88

89

Parameters:

90

- ctx (PrettyContext): Current pretty printing context

91

- fn: Callable to represent in the call

92

- args (tuple): Tuple of positional arguments

93

- kwargs: OrderedDict, dict, or iterable of (key, value) pairs for keyword arguments

94

95

Returns:

96

- Doc: Document representing the formatted function call

97

98

Notes:

99

- Works on all Python versions including 3.5

100

- For consistent results on Python 3.5, use OrderedDict or list of tuples for kwargs

101

"""

102

```

103

104

## Usage Examples

105

106

### Basic Type Registration

107

108

```python

109

from prettyprinter import register_pretty, pretty_call

110

from collections import namedtuple

111

112

# Custom class example

113

class Person:

114

def __init__(self, name, age, email):

115

self.name = name

116

self.age = age

117

self.email = email

118

119

@register_pretty(Person)

120

def pretty_person(person, ctx):

121

return pretty_call(ctx, Person, person.name, person.age, person.email)

122

123

# Now Person instances are pretty printed as constructor calls

124

person = Person("Alice", 30, "alice@example.com")

125

pprint(person)

126

# Output: Person('Alice', 30, 'alice@example.com')

127

```

128

129

### Advanced Registration with Custom Logic

130

131

```python

132

from prettyprinter import register_pretty, pretty_call, comment

133

import datetime

134

135

class Task:

136

def __init__(self, title, priority=1, due_date=None, completed=False):

137

self.title = title

138

self.priority = priority

139

self.due_date = due_date

140

self.completed = completed

141

142

@register_pretty(Task)

143

def pretty_task(task, ctx):

144

# Show different representation based on completion status

145

if task.completed:

146

return comment(

147

pretty_call(ctx, Task, task.title,

148

priority=task.priority,

149

due_date=task.due_date,

150

completed=task.completed),

151

'COMPLETED'

152

)

153

else:

154

return pretty_call(ctx, Task, task.title,

155

priority=task.priority,

156

due_date=task.due_date)

157

158

# Usage

159

task1 = Task("Write documentation", priority=2,

160

due_date=datetime.date(2024, 1, 15))

161

task2 = Task("Review code", completed=True)

162

163

pprint([task1, task2])

164

```

165

166

### Predicate-Based Registration

167

168

```python

169

from prettyprinter import register_pretty

170

from collections.abc import Mapping

171

172

# Register pretty printer for all custom mapping types

173

@register_pretty(predicate=lambda obj: isinstance(obj, Mapping) and

174

type(obj).__name__.endswith('Dict'))

175

def pretty_custom_dicts(mapping, ctx):

176

return pretty_call(ctx, type(mapping), dict(mapping))

177

178

# This will handle CustomDict, OrderedDict, etc.

179

class CustomDict(dict):

180

pass

181

182

custom = CustomDict([('a', 1), ('b', 2)])

183

pprint(custom) # CustomDict({'a': 1, 'b': 2})

184

```

185

186

### Deferred Registration

187

188

```python

189

from prettyprinter import register_pretty

190

191

# Register for a type that might not be imported yet

192

@register_pretty('numpy.ndarray')

193

def pretty_numpy_array(arr, ctx):

194

# This registration is deferred until numpy.ndarray is actually encountered

195

return pretty_call(ctx, type(arr), arr.tolist())

196

197

# The registration becomes active when numpy arrays are first encountered

198

import numpy as np

199

arr = np.array([1, 2, 3, 4, 5])

200

pprint(arr) # Triggers registration and uses custom formatter

201

```

202

203

### Complex Object Hierarchies

204

205

```python

206

from prettyprinter import register_pretty, pretty_call

207

208

class Database:

209

def __init__(self, name, tables=None):

210

self.name = name

211

self.tables = tables or []

212

213

class Table:

214

def __init__(self, name, columns=None, rows=0):

215

self.name = name

216

self.columns = columns or []

217

self.rows = rows

218

219

@register_pretty(Database)

220

def pretty_database(db, ctx):

221

return pretty_call(ctx, Database, db.name, tables=db.tables)

222

223

@register_pretty(Table)

224

def pretty_table(table, ctx):

225

return pretty_call(ctx, Table, table.name,

226

columns=table.columns, rows=table.rows)

227

228

# Nested objects are automatically handled

229

db = Database("myapp", [

230

Table("users", ["id", "name", "email"], 1000),

231

Table("posts", ["id", "title", "content"], 5000)

232

])

233

234

pprint(db)

235

# Output shows nested structure with custom formatting for both types

236

```

237

238

### Checking Registration Status

239

240

```python

241

from prettyprinter import is_registered, register_pretty

242

243

class MyClass:

244

pass

245

246

# Check if registered

247

print(is_registered(MyClass)) # False

248

249

@register_pretty(MyClass)

250

def pretty_my_class(obj, ctx):

251

return "MyClass()"

252

253

# Now it's registered

254

print(is_registered(MyClass)) # True

255

256

# Check superclasses too

257

class MySubClass(MyClass):

258

pass

259

260

print(is_registered(MySubClass)) # False

261

print(is_registered(MySubClass, check_superclasses=True)) # True

262

```

263

264

### Using pretty_call_alt for Python 3.5 Compatibility

265

266

```python

267

from prettyprinter import register_pretty, pretty_call_alt

268

from collections import OrderedDict

269

270

@register_pretty(Person)

271

def pretty_person_alt(person, ctx):

272

# Use explicit args and kwargs for Python 3.5 compatibility

273

return pretty_call_alt(

274

ctx,

275

Person,

276

args=(person.name,),

277

kwargs=OrderedDict([

278

('age', person.age),

279

('email', person.email)

280

])

281

)

282

```