or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-add-trailing-comma

Automatically add trailing commas to calls and literals in Python code

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/add-trailing-comma@3.2.x

To install, run

npx @tessl/cli install tessl/pypi-add-trailing-comma@3.2.0

0

# add-trailing-comma

1

2

A Python tool and pre-commit hook that automatically adds trailing commas to function calls, literals (lists, tuples, dicts, sets), function definitions, import statements, class definitions, with statements, match statements, and PEP-695 type aliases. This improves code maintainability by ensuring consistent trailing comma usage, reducing git diff noise, preserving git blame information, and avoiding arbitrary indentation issues.

3

4

## Package Information

5

6

- **Package Name**: add-trailing-comma (for pip), add_trailing_comma (Python module)

7

- **Language**: Python

8

- **Installation**: `pip install add-trailing-comma`

9

- **Python Requirements**: >=3.9

10

- **Dependencies**: tokenize-rt>=3.0.1

11

12

## Core Imports

13

14

This package is primarily designed for command-line usage and does not export a public programmatic API. The `__init__.py` is empty, making direct imports unsuitable for typical programmatic use.

15

16

**Command-line usage** (recommended):

17

```bash

18

add-trailing-comma

19

```

20

21

**Python module invocation**:

22

```bash

23

python -m add_trailing_comma

24

```

25

26

**Internal API access** (for advanced use cases, accessing private modules):

27

```python

28

from add_trailing_comma._main import main, fix_file

29

```

30

31

## Basic Usage

32

33

### Command Line Usage

34

35

```bash

36

# Process single file

37

add-trailing-comma script.py

38

39

# Process multiple files

40

add-trailing-comma file1.py file2.py src/

41

42

# Read from stdin

43

cat script.py | add-trailing-comma -

44

45

# Exit with 0 even if files were changed (useful for CI)

46

add-trailing-comma --exit-zero-even-if-changed file.py

47

```

48

49

### Pre-commit Hook Usage

50

51

Add to your `.pre-commit-config.yaml`:

52

53

```yaml

54

- repo: https://github.com/asottile/add-trailing-comma

55

rev: v3.2.0

56

hooks:

57

- id: add-trailing-comma

58

```

59

60

### Programmatic Usage

61

62

**Note**: The following shows internal API usage accessing private modules. This is not recommended for production use as private APIs may change without notice.

63

64

```python

65

import argparse

66

from add_trailing_comma._main import fix_file, main

67

68

# Process a single file using internal API

69

args = argparse.Namespace(exit_zero_even_if_changed=False)

70

result = fix_file("script.py", args)

71

72

# Use main function with arguments

73

result = main(["script.py", "--exit-zero-even-if-changed"])

74

```

75

76

## Capabilities

77

78

### Command Line Interface

79

80

The main entry point for command-line usage with argument parsing and file processing.

81

82

```python { .api }

83

def main(argv: Sequence[str] | None = None) -> int:

84

"""

85

Main entry point for command line interface.

86

87

Parameters:

88

- argv: Command line arguments (defaults to sys.argv if None)

89

90

Returns:

91

int: Exit code (0 for success or no changes, 1 for errors or changes made)

92

93

Available command line options:

94

- filenames: List of files to process

95

- --exit-zero-even-if-changed: Exit with 0 even if files were modified

96

- --py35-plus, --py36-plus: Legacy flags (deprecated, no effect)

97

"""

98

```

99

100

### File Processing

101

102

Process individual files to add trailing commas with configurable options.

103

104

```python { .api }

105

def fix_file(filename: str, args: argparse.Namespace) -> int:

106

"""

107

Process a single file to add trailing commas.

108

109

Parameters:

110

- filename: Path to file to process, or '-' for stdin

111

- args: Namespace with configuration options (requires exit_zero_even_if_changed attribute)

112

113

Returns:

114

int: 1 if file was changed or error occurred, 0 if no changes or exit_zero_even_if_changed=True

115

116

Handles:

117

- Unicode decode errors (prints error message, returns 1)

118

- Syntax errors (returns content unchanged)

119

- File I/O operations for both files and stdin

120

"""

121

```

122

123

### Source Code Transformation

124

125

Core internal functionality for transforming Python source code to add trailing commas. This is a private function used internally by the tool.

126

127

```python { .api }

128

def _fix_src(contents_text: str) -> str:

129

"""

130

Internal function that applies AST transformations to add trailing commas.

131

132

Note: This is a private function (prefix '_') and should not be used in

133

production code as it may change without notice.

134

135

Parameters:

136

- contents_text: Python source code as string

137

138

Returns:

139

str: Transformed source code with trailing commas added

140

141

Raises:

142

SyntaxError: Returns original content if syntax errors are encountered

143

"""

144

```

145

146

## Transformations Supported

147

148

### Function Calls

149

150

Adds trailing commas to multi-line function calls:

151

152

```python

153

# Before

154

function_call(

155

argument,

156

5 ** 5,

157

kwarg=foo

158

)

159

160

# After

161

function_call(

162

argument,

163

5 ** 5,

164

kwarg=foo,

165

)

166

```

167

168

### Literals

169

170

Adds trailing commas to lists, tuples, dictionaries, and sets:

171

172

```python

173

# Lists

174

x = [

175

1, 2, 3, # trailing comma added

176

]

177

178

# Tuples

179

y = (

180

'a', 'b', 'c', # trailing comma added

181

)

182

183

# Dictionaries

184

config = {

185

'key1': 'value1',

186

'key2': 'value2', # trailing comma added

187

}

188

189

# Sets

190

items = {

191

'item1',

192

'item2', # trailing comma added

193

}

194

```

195

196

### Function Definitions

197

198

Adds trailing commas to function and method parameters:

199

200

```python

201

def func(

202

arg1,

203

arg2, # trailing comma added

204

):

205

pass

206

207

async def async_func(

208

arg1,

209

arg2, # trailing comma added

210

):

211

pass

212

```

213

214

### Import Statements

215

216

Adds trailing commas to from-import statements:

217

218

```python

219

from os import (

220

path,

221

makedirs, # trailing comma added

222

)

223

```

224

225

### Class Definitions

226

227

Adds trailing commas to class inheritance lists:

228

229

```python

230

class MyClass(

231

Base1,

232

Base2, # trailing comma added

233

):

234

pass

235

```

236

237

### With Statements

238

239

Adds trailing commas to with statement context managers:

240

241

```python

242

with (

243

open('f1', 'r') as f1,

244

open('f2', 'w') as f2, # trailing comma added

245

):

246

pass

247

```

248

249

### Match Statements (Python 3.10+)

250

251

Adds trailing commas to match patterns:

252

253

```python

254

match x:

255

case A(

256

1,

257

2, # trailing comma added

258

):

259

pass

260

case (

261

1,

262

2, # trailing comma added

263

):

264

pass

265

case [

266

1,

267

2, # trailing comma added

268

]:

269

pass

270

case {

271

'x': 1,

272

'y': 2, # trailing comma added

273

}:

274

pass

275

```

276

277

### PEP-695 Type Aliases (Python 3.12+)

278

279

Adds trailing commas to type parameter lists:

280

281

```python

282

def f[

283

T, # trailing comma added

284

](x: T) -> T:

285

return x

286

287

class A[

288

K, # trailing comma added

289

]:

290

def __init__(self, x: K) -> None:

291

self.x = x

292

293

type ListOrSet[

294

T, # trailing comma added

295

] = list[T] | set[T]

296

```

297

298

## Additional Features

299

300

### Parentheses Formatting

301

302

The tool also performs "unhugging" - formatting parentheses positioning:

303

304

```python

305

# Unhug trailing paren

306

x(

307

arg1,

308

arg2, # trailing comma and proper closing

309

)

310

311

# Unhug leading paren

312

function_name(

313

arg1,

314

arg2,

315

)

316

317

# Match closing brace indentation

318

x = [

319

1,

320

2,

321

3,

322

] # proper indentation

323

```

324

325

### Comma Removal

326

327

Removes unnecessary commas from single-line structures:

328

329

```python

330

# Before

331

[1, 2, 3,]

332

[1, 2, 3, ]

333

334

# After

335

[1, 2, 3]

336

[1, 2, 3]

337

```

338

339

## Command Line Arguments

340

341

The tool supports the following command line arguments:

342

343

- **filenames**: List of files to process (accepts multiple files and directories)

344

- **--exit-zero-even-if-changed**: Exit with code 0 even if files were modified

345

- **--py35-plus**: Legacy flag (deprecated, does nothing)

346

- **--py36-plus**: Legacy flag (deprecated, does nothing)

347

348

## Error Handling

349

350

The tool handles various error conditions gracefully:

351

352

- **Syntax Errors**: Files with syntax errors are returned unchanged

353

- **Unicode Errors**: Non-UTF-8 files are skipped with error message

354

- **File Access**: Handles stdin input with '-' filename

355

356

## Integration

357

358

### Pre-commit Hook

359

360

The tool is designed to work seamlessly with pre-commit hooks for automated code formatting in development workflows.

361

362

### CI/CD Integration

363

364

Use `--exit-zero-even-if-changed` flag in CI environments where you want the tool to run but not fail the build when changes are made.

365

366

## Dependencies and Types

367

368

The tool relies on the following dependencies and type definitions:

369

370

### External Dependencies

371

372

```python { .api }

373

# Required external dependency

374

from tokenize_rt import src_to_tokens, tokens_to_src, Token, Offset

375

376

# Standard library dependencies

377

from typing import Sequence, Iterable

378

from collections.abc import Sequence

379

from argparse import Namespace, ArgumentParser

380

import ast

381

import sys

382

```

383

384

### Core Type Signatures

385

386

```python { .api }

387

# Main API functions

388

def main(argv: Sequence[str] | None = None) -> int

389

def fix_file(filename: str, args: Namespace) -> int

390

391

# Internal transformation function

392

def _fix_src(contents_text: str) -> str

393

394

# Helper types from tokenize-rt

395

Token: # Represents a token with .src, .name, .offset attributes

396

Offset: # Represents position in source (line, column)

397

```