or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-line.mdcore-formatting.mdfile-operations.mdindex.mdstyle-configuration.md

file-operations.mddocs/

0

# File Operations

1

2

YAPF's file operations module provides utilities for reading Python files with proper encoding detection, writing formatted code, managing configuration files, and handling exclude patterns for batch operations.

3

4

## Capabilities

5

6

### File Reading

7

8

Read Python files with automatic encoding detection and line ending preservation.

9

10

```python { .api }

11

def ReadFile(filename, logger=None):

12

"""

13

Read the contents of a file with encoding detection.

14

15

Args:

16

filename (str): Path to the file to read

17

logger: Optional function for logging errors

18

19

Returns:

20

tuple: (source, line_ending, encoding)

21

- source (str): File contents with normalized line endings

22

- line_ending (str): Original line ending style

23

- encoding (str): Detected file encoding

24

25

Raises:

26

IOError: If file cannot be read

27

UnicodeDecodeError: If file cannot be decoded

28

"""

29

30

def FileEncoding(filename):

31

"""

32

Detect the encoding of a Python file.

33

34

Args:

35

filename (str): Path to the file

36

37

Returns:

38

str: Detected encoding (e.g., 'utf-8', 'latin-1')

39

"""

40

41

def LineEnding(lines):

42

"""

43

Determine the line ending style of file lines.

44

45

Args:

46

lines (list): List of lines from file

47

48

Returns:

49

str: Line ending style ('\\n', '\\r\\n', '\\r')

50

"""

51

```

52

53

### File Writing

54

55

Write formatted code back to files with proper encoding and line ending handling.

56

57

```python { .api }

58

def WriteReformattedCode(filename, reformatted_code, encoding='', in_place=False):

59

"""

60

Write reformatted code to file or stdout.

61

62

Args:

63

filename (str): File path or '<stdout>' for stdout

64

reformatted_code (str): The formatted code to write

65

encoding (str): File encoding to use (default: '')

66

in_place (bool): Whether to write to the original file

67

"""

68

```

69

70

### File Discovery

71

72

Find Python files for formatting operations with support for exclusion patterns.

73

74

```python { .api }

75

def GetCommandLineFiles(command_line_file_list, recursive, exclude):

76

"""

77

Get list of Python files from command line arguments.

78

79

Args:

80

command_line_file_list (list): List of file and directory paths

81

recursive (bool): Whether to search directories recursively

82

exclude (list): Patterns for files to exclude

83

84

Returns:

85

list: List of Python file paths to process

86

"""

87

88

def IsPythonFile(filename):

89

"""

90

Check if a file is a Python file.

91

92

Args:

93

filename (str): Path to file to check

94

95

Returns:

96

bool: True if file is a Python file

97

"""

98

99

def IsIgnored(path, exclude):

100

"""

101

Check if a path matches any exclude pattern.

102

103

Args:

104

path (str): Path to check

105

exclude (list): List of exclude patterns

106

107

Returns:

108

bool: True if path should be ignored

109

"""

110

```

111

112

### Configuration Discovery

113

114

Find and load YAPF configuration files from project directories.

115

116

```python { .api }

117

def GetDefaultStyleForDir(directory):

118

"""

119

Get the default style configuration for a directory.

120

121

Searches up the directory tree for:

122

- .style.yapf files

123

- pyproject.toml with [tool.yapf] section

124

- setup.cfg with [yapf] section

125

126

Args:

127

directory (str): Directory to search from

128

129

Returns:

130

str: Path to configuration file or style name

131

"""

132

133

def GetExcludePatternsForDir(directory):

134

"""

135

Get exclude patterns from .yapfignore files.

136

137

Args:

138

directory (str): Directory to search from

139

140

Returns:

141

list: List of glob patterns to exclude

142

"""

143

```

144

145

## Usage Examples

146

147

### Reading Files with Encoding Detection

148

149

```python

150

from yapf.yapflib.yapf_api import ReadFile

151

import logging

152

153

# Read file with automatic encoding detection

154

try:

155

source, line_ending, encoding = ReadFile('my_script.py')

156

print(f"File encoding: {encoding}")

157

print(f"Line ending: {repr(line_ending)}")

158

print(f"File length: {len(source)} characters")

159

except (IOError, UnicodeDecodeError) as e:

160

print(f"Error reading file: {e}")

161

162

# Read with error logging

163

def log_error(message):

164

logging.error(f"File read error: {message}")

165

166

source, line_ending, encoding = ReadFile(

167

'my_script.py',

168

logger=log_error

169

)

170

```

171

172

### Writing Formatted Code

173

174

```python

175

from yapf.yapflib import file_resources

176

177

# Write to stdout

178

file_resources.WriteReformattedCode(

179

'<stdout>',

180

formatted_code,

181

encoding='utf-8'

182

)

183

184

# Write to specific file

185

file_resources.WriteReformattedCode(

186

'output.py',

187

formatted_code,

188

encoding='utf-8',

189

in_place=True

190

)

191

```

192

193

### File Discovery for Batch Operations

194

195

```python

196

from yapf.yapflib import file_resources

197

198

# Get all Python files in current directory

199

files = file_resources.GetCommandLineFiles(

200

['.'],

201

recursive=False,

202

exclude_patterns=[]

203

)

204

205

# Get files recursively, excluding test files

206

files = file_resources.GetCommandLineFiles(

207

['src/', 'lib/'],

208

recursive=True,

209

exclude_patterns=['*test*.py', '*_test.py']

210

)

211

212

print(f"Found {len(files)} Python files")

213

for file in files:

214

print(f" {file}")

215

```

216

217

### Configuration File Discovery

218

219

```python

220

from yapf.yapflib import file_resources

221

import os

222

223

# Find default style for current project

224

current_dir = os.getcwd()

225

style_config = file_resources.GetDefaultStyleForDir(current_dir)

226

print(f"Default style: {style_config}")

227

228

# Get exclude patterns from .yapfignore

229

exclude_patterns = file_resources.GetExcludePatternsForDir(current_dir)

230

print(f"Exclude patterns: {exclude_patterns}")

231

232

# Search from specific directory

233

project_root = '/path/to/my/project'

234

style_config = file_resources.GetDefaultStyleForDir(project_root)

235

```

236

237

### Complete File Processing Pipeline

238

239

```python

240

import os

241

from yapf.yapflib import file_resources

242

from yapf.yapflib.yapf_api import FormatFile

243

244

def format_project(directory, style='pep8', exclude_patterns=None):

245

"""

246

Format all Python files in a project directory.

247

248

Args:

249

directory (str): Root directory to process

250

style (str): Style configuration to use

251

exclude_patterns (list): Patterns for files to exclude

252

"""

253

if exclude_patterns is None:

254

exclude_patterns = []

255

256

# Discover configuration

257

local_style = file_resources.GetDefaultStyleForDir(directory)

258

if local_style:

259

style = local_style

260

print(f"Using local style: {style}")

261

262

# Get exclude patterns from .yapfignore

263

ignore_patterns = file_resources.GetExcludePatternsForDir(directory)

264

exclude_patterns.extend(ignore_patterns)

265

266

# Find all Python files

267

files = file_resources.GetCommandLineFiles(

268

[directory],

269

recursive=True,

270

exclude_patterns=exclude_patterns

271

)

272

273

print(f"Found {len(files)} Python files to format")

274

275

# Format each file

276

modified_count = 0

277

for filepath in files:

278

try:

279

_, _, changed = FormatFile(

280

filepath,

281

style_config=style,

282

in_place=True

283

)

284

if changed:

285

modified_count += 1

286

print(f" Formatted: {filepath}")

287

except Exception as e:

288

print(f" Error formatting {filepath}: {e}")

289

290

print(f"Modified {modified_count} files")

291

292

# Usage

293

format_project('/path/to/my/project', style='google')

294

```

295

296

### Encoding and Line Ending Handling

297

298

```python

299

from yapf.yapflib import file_resources

300

from yapf.yapflib.yapf_api import ReadFile, FormatCode

301

302

def safe_format_file(filepath):

303

"""

304

Safely format a file preserving encoding and line endings.

305

306

Args:

307

filepath (str): Path to file to format

308

309

Returns:

310

bool: True if file was modified

311

"""

312

try:

313

# Read with encoding detection

314

source, line_ending, encoding = ReadFile(filepath)

315

print(f"File: {filepath}")

316

print(f" Encoding: {encoding}")

317

print(f" Line ending: {repr(line_ending)}")

318

319

# Format the code

320

formatted, changed = FormatCode(source, filename=filepath)

321

322

if changed:

323

# Restore original line endings

324

if line_ending != '\n':

325

formatted = formatted.replace('\n', line_ending)

326

327

# Write back with original encoding

328

file_resources.WriteReformattedCode(

329

filepath,

330

formatted,

331

encoding=encoding,

332

in_place=True

333

)

334

print(f" Formatted and saved")

335

return True

336

else:

337

print(f" No changes needed")

338

return False

339

340

except Exception as e:

341

print(f" Error: {e}")

342

return False

343

344

# Process multiple files

345

files = ['script1.py', 'script2.py', 'module.py']

346

for filepath in files:

347

safe_format_file(filepath)

348

```

349

350

### Working with .yapfignore Files

351

352

Create a `.yapfignore` file in your project root:

353

354

```

355

# .yapfignore - patterns for files to exclude from formatting

356

357

# Generated files

358

*_pb2.py

359

*_pb2_grpc.py

360

361

# Third-party code

362

vendor/

363

external/

364

365

# Test fixtures

366

*/test_data/*

367

test_fixtures/

368

369

# Specific files

370

legacy_code.py

371

```

372

373

Then use it in your code:

374

375

```python

376

from yapf.yapflib import file_resources

377

378

# Exclude patterns are automatically loaded

379

exclude_patterns = file_resources.GetExcludePatternsForDir('.')

380

print("Exclude patterns:", exclude_patterns)

381

382

# Use in file discovery

383

files = file_resources.GetCommandLineFiles(

384

['.'],

385

recursive=True,

386

exclude_patterns=exclude_patterns

387

)

388

```

389

390

## Error Handling

391

392

File operations can raise various exceptions that should be handled appropriately:

393

394

```python

395

from yapf.yapflib.yapf_api import ReadFile

396

from yapf.yapflib import file_resources

397

398

def robust_file_processing(filepath):

399

"""Process a file with comprehensive error handling."""

400

try:

401

source, line_ending, encoding = ReadFile(filepath)

402

return source, line_ending, encoding

403

404

except IOError as e:

405

print(f"Cannot read file {filepath}: {e}")

406

return None, None, None

407

408

except UnicodeDecodeError as e:

409

print(f"Cannot decode file {filepath}: {e}")

410

print("File may not be a valid Python file or uses unsupported encoding")

411

return None, None, None

412

413

except Exception as e:

414

print(f"Unexpected error reading {filepath}: {e}")

415

return None, None, None

416

```

417

418

## Constants

419

420

```python { .api }

421

# Line ending constants

422

CR = '\r'

423

LF = '\n'

424

CRLF = '\r\n'

425

```