or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mddocstring-processing.mddocumentation-rendering.mdindex.mdmain-config.mdplugin-interfaces.mdpython-loading.mdutility-functions.md

utility-functions.mddocs/

0

# Utility Functions

1

2

Helper functions and classes for common operations including docspec manipulation, template processing, file watching, and page management.

3

4

## Capabilities

5

6

### Docspec Utilities

7

8

Functions for working with docspec objects and API analysis.

9

10

```python { .api }

11

def get_members_of_type(objs: Union[docspec.ApiObject, List[docspec.ApiObject]], type_: Type[T]) -> List[T]:

12

"""

13

Get all members of specified type from API objects.

14

15

Args:

16

objs: Single API object or list of API objects to search

17

type_: Type to filter for (e.g., docspec.Function, docspec.Class)

18

19

Returns:

20

List of objects matching the specified type

21

"""

22

23

def format_function_signature(func: docspec.Function, exclude_self: bool = False) -> str:

24

"""

25

Format function signature with arguments and return type.

26

27

Args:

28

func: Function object to format

29

exclude_self: Whether to exclude 'self' parameter from signature

30

31

Returns:

32

Formatted signature string like "(arg1, arg2) -> ReturnType"

33

"""

34

35

def is_function(obj: docspec.ApiObject) -> TypeGuard[docspec.Function]:

36

"""

37

Type guard to check if object is a function.

38

39

Args:

40

obj: API object to check

41

42

Returns:

43

True if object is a docspec.Function

44

"""

45

46

def is_method(obj: docspec.ApiObject) -> TypeGuard[docspec.Function]:

47

"""

48

Type guard to check if object is a method (function inside a class).

49

50

Args:

51

obj: API object to check

52

53

Returns:

54

True if object is a method

55

"""

56

57

def is_property(obj: docspec.ApiObject) -> TypeGuard[docspec.Function]:

58

"""

59

Type guard to check if object is a property (function with @property decorator).

60

61

Args:

62

obj: API object to check

63

64

Returns:

65

True if object is a property

66

"""

67

68

def is_attr(obj: docspec.ApiObject) -> TypeGuard[docspec.Variable]:

69

"""

70

Type guard to check if object is a class attribute.

71

72

Args:

73

obj: API object to check

74

75

Returns:

76

True if object is a class attribute

77

"""

78

79

def get_object_description(obj: docspec.ApiObject) -> str:

80

"""

81

Get descriptive text for an API object.

82

83

Args:

84

obj: API object to describe

85

86

Returns:

87

Description like "module", "class", "function", "method", etc.

88

"""

89

```

90

91

### ApiSuite Wrapper

92

93

Wrapper class for working with collections of API objects.

94

95

```python { .api }

96

class ApiSuite:

97

"""

98

Wrapper for API object collections with utility methods.

99

100

Provides convenient access to docspec objects with type filtering,

101

relationship analysis, and other collection operations.

102

"""

103

104

def get_members_of_type(self, type_: Type[T]) -> List[T]:

105

"""

106

Get all members of specified type from the suite.

107

108

Args:

109

type_: Type to filter for

110

111

Returns:

112

List of objects matching the specified type

113

"""

114

```

115

116

### Template Processing

117

118

YAML template loading with variable substitution.

119

120

```python { .api }

121

def load(filename: str, context: Dict[str, Any]) -> Any:

122

"""

123

Load YAML template file with variable substitution.

124

125

Args:

126

filename: Path to YAML template file

127

context: Dictionary of variables for substitution

128

129

Returns:

130

Parsed YAML data with variables substituted

131

"""

132

133

class Attributor:

134

"""

135

Attribute accessor for template variables.

136

137

Provides dot-notation access to dictionary data for use in templates.

138

"""

139

140

def __init__(self, data: Dict[str, Any]):

141

"""

142

Initialize with data dictionary.

143

144

Args:

145

data: Dictionary to provide attribute access for

146

"""

147

148

def __getattr__(self, name: str) -> Any:

149

"""

150

Get attribute value from underlying data.

151

152

Args:

153

name: Attribute name to access

154

155

Returns:

156

Value from data dictionary

157

158

Raises:

159

AttributeError: If attribute not found

160

"""

161

```

162

163

### File Watching

164

165

File system monitoring for development workflows.

166

167

```python { .api }

168

def watch_paths(paths: List[str]) -> Tuple[Observer, Event]:

169

"""

170

Set up file system watching for specified paths.

171

172

Args:

173

paths: List of file/directory paths to watch for changes

174

175

Returns:

176

Tuple of (Observer, Event) where Event is set when changes occur

177

"""

178

```

179

180

### Page Management

181

182

Utilities for managing documentation pages and collections.

183

184

```python { .api }

185

def collect_pages(directory: str, pattern: str = "*.md") -> List[str]:

186

"""

187

Collect documentation pages from directory.

188

189

Args:

190

directory: Directory to search for pages

191

pattern: File pattern to match (default: "*.md")

192

193

Returns:

194

List of page file paths

195

"""

196

```

197

198

### Markdown Utilities

199

200

Text processing utilities for Markdown generation.

201

202

```python { .api }

203

def escape_except_blockquotes(text: str) -> str:

204

"""

205

Escape Markdown special characters except in blockquotes.

206

207

Args:

208

text: Text to escape

209

210

Returns:

211

Text with Markdown characters escaped appropriately

212

"""

213

```

214

215

### Helper Functions

216

217

Additional utility functions for common operations.

218

219

```python { .api }

220

def dotted_name(obj: docspec.ApiObject) -> str:

221

"""

222

Get fully qualified dotted name for an API object.

223

224

Args:

225

obj: API object to get name for

226

227

Returns:

228

Dotted name like "module.Class.method"

229

"""

230

```

231

232

## Usage Examples

233

234

### Docspec Object Analysis

235

236

```python

237

from pydoc_markdown.util.docspec import get_members_of_type, is_method, format_function_signature

238

import docspec

239

240

# Get all functions from modules

241

modules = config.load_modules()

242

all_functions = get_members_of_type(modules, docspec.Function)

243

244

# Filter for methods only

245

methods = [f for f in all_functions if is_method(f)]

246

247

# Format signatures

248

for method in methods:

249

signature = format_function_signature(method, exclude_self=True)

250

print(f"{method.name}{signature}")

251

```

252

253

### API Object Type Checking

254

255

```python

256

from pydoc_markdown.util.docspec import is_function, is_method, is_property, is_attr

257

258

for obj in module.members:

259

if is_function(obj):

260

if is_method(obj):

261

print(f"Method: {obj.name}")

262

elif is_property(obj):

263

print(f"Property: {obj.name}")

264

else:

265

print(f"Function: {obj.name}")

266

elif is_attr(obj):

267

print(f"Attribute: {obj.name}")

268

```

269

270

### Template Processing

271

272

```python

273

from pydoc_markdown.util.ytemplate import load, Attributor

274

import os

275

276

# Load template with environment variables

277

context = {"env": Attributor(os.environ)}

278

config_data = load("pydoc-markdown.yml.template", context)

279

280

# Template file might contain:

281

# loaders:

282

# - type: python

283

# modules: ["{{ env.PACKAGE_NAME }}"]

284

```

285

286

### File Watching for Development

287

288

```python

289

from pydoc_markdown.util.watchdog import watch_paths

290

import time

291

292

# Watch source files for changes

293

source_files = ["src/mypackage/", "docs/"]

294

observer, event = watch_paths(source_files)

295

296

try:

297

while True:

298

if event.wait(timeout=1.0):

299

print("Files changed, regenerating docs...")

300

# Regenerate documentation

301

event.clear()

302

else:

303

time.sleep(0.1)

304

finally:

305

observer.stop()

306

```

307

308

### Page Collection

309

310

```python

311

from pydoc_markdown.util.pages import collect_pages

312

313

# Collect all markdown files in docs directory

314

doc_pages = collect_pages("docs/", "*.md")

315

316

# Collect specific patterns

317

api_pages = collect_pages("docs/api/", "*.md")

318

examples = collect_pages("examples/", "*.py")

319

```

320

321

### Markdown Text Processing

322

323

```python

324

from pydoc_markdown.util.misc import escape_except_blockquotes

325

326

# Safely escape markdown while preserving blockquotes

327

text = """

328

This text has *special* characters that need escaping.

329

330

> But this blockquote should remain unchanged

331

> with its *formatting* intact.

332

"""

333

334

escaped = escape_except_blockquotes(text)

335

```

336

337

### Object Path and Naming

338

339

```python

340

from pydoc_markdown.contrib.renderers.markdown import dotted_name

341

342

# Get full dotted names for API objects

343

for obj in module.members:

344

full_name = dotted_name(obj)

345

print(f"Full name: {full_name}")

346

# Output: "mypackage.MyClass.my_method"

347

```

348

349

## Integration Examples

350

351

### Custom Processor Using Utilities

352

353

```python

354

from pydoc_markdown.interfaces import Processor

355

from pydoc_markdown.util.docspec import get_members_of_type, is_method

356

import docspec

357

358

class MethodDocumentationProcessor(Processor):

359

def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:

360

# Get all methods across all modules

361

methods = get_members_of_type(modules, docspec.Function)

362

methods = [m for m in methods if is_method(m)]

363

364

# Add standard documentation for undocumented methods

365

for method in methods:

366

if not method.docstring:

367

signature = format_function_signature(method, exclude_self=True)

368

method.docstring = f"Method {method.name}{signature}"

369

```

370

371

### Custom Renderer Using Utilities

372

373

```python

374

from pydoc_markdown.interfaces import Renderer

375

from pydoc_markdown.util.docspec import get_object_description, dotted_name

376

from pydoc_markdown.util.misc import escape_except_blockquotes

377

378

class CustomTableRenderer(Renderer):

379

def render(self, modules: List[docspec.Module]) -> None:

380

with open("api-table.md", "w") as f:

381

f.write("# API Reference Table\n\n")

382

f.write("| Name | Type | Description |\n")

383

f.write("|------|------|-------------|\n")

384

385

for module in modules:

386

for obj in module.members:

387

name = dotted_name(obj)

388

obj_type = get_object_description(obj)

389

desc = obj.docstring or "No description"

390

desc = escape_except_blockquotes(desc.split('\n')[0]) # First line only

391

392

f.write(f"| {name} | {obj_type} | {desc} |\n")

393

```

394

395

### Development Workflow Integration

396

397

```python

398

from pydoc_markdown.util.watchdog import watch_paths

399

from pydoc_markdown.util.pages import collect_pages

400

from pydoc_markdown import PydocMarkdown

401

402

class DocumentationWatcher:

403

def __init__(self, config_file: str):

404

self.config_file = config_file

405

self.config = PydocMarkdown()

406

self.config.load_config(config_file)

407

408

def start_watching(self):

409

# Collect all relevant files to watch

410

source_files = []

411

412

# Add Python source files

413

for loader in self.config.loaders:

414

if hasattr(loader, 'search_path'):

415

source_files.extend(loader.search_path)

416

417

# Add documentation files

418

doc_files = collect_pages("docs/", "*.md")

419

source_files.extend(doc_files)

420

421

# Add config file

422

source_files.append(self.config_file)

423

424

# Start watching

425

observer, event = watch_paths(source_files)

426

427

try:

428

while True:

429

if event.wait(timeout=2.0):

430

print("Changes detected, regenerating documentation...")

431

self.regenerate_docs()

432

event.clear()

433

finally:

434

observer.stop()

435

436

def regenerate_docs(self):

437

modules = self.config.load_modules()

438

self.config.process(modules)

439

self.config.render(modules)

440

```