or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdpath-matching.mdpattern-system.mdutilities.md

path-matching.mddocs/

0

# Path Matching

1

2

Core pattern matching functionality for testing files against gitignore-style patterns. This module provides the main interfaces for pattern matching operations, supporting both simple boolean tests and detailed result analysis.

3

4

## Imports

5

6

```python

7

from pathspec import PathSpec, GitIgnoreSpec

8

from pathspec.util import CheckResult, TreeEntry

9

from typing import AnyStr, Callable, Collection, Iterable, Iterator, Optional, Tuple, Union

10

import os

11

```

12

13

## Capabilities

14

15

### PathSpec Class

16

17

The main class for pattern matching operations. Wraps a list of compiled Pattern instances and provides methods for matching files and directory trees.

18

19

```python { .api }

20

class PathSpec:

21

def __init__(self, patterns: Iterable[Pattern]) -> None:

22

"""

23

Initialize PathSpec with compiled patterns.

24

25

Parameters:

26

- patterns: Iterable of compiled Pattern instances

27

"""

28

29

def __len__(self) -> int:

30

"""Returns the number of compiled patterns."""

31

32

def __eq__(self, other: object) -> bool:

33

"""Tests equality by comparing patterns."""

34

35

def __add__(self, other: "PathSpec") -> PathSpec:

36

"""Combines patterns from two PathSpec instances."""

37

38

def __iadd__(self, other: "PathSpec") -> PathSpec:

39

"""Adds patterns from another PathSpec to this instance."""

40

41

@classmethod

42

def from_lines(

43

cls,

44

pattern_factory: Union[str, Callable[[AnyStr], Pattern]],

45

lines: Iterable[AnyStr]

46

) -> PathSpec:

47

"""

48

Create PathSpec from lines of text patterns.

49

50

Parameters:

51

- pattern_factory: Pattern factory name or callable

52

- lines: Iterable of pattern strings

53

54

Returns:

55

PathSpec instance with compiled patterns

56

"""

57

```

58

59

### File Matching Methods

60

61

Methods for testing individual files and collections of files against patterns.

62

63

```python { .api }

64

def match_file(

65

self,

66

file: Union[str, os.PathLike],

67

separators: Optional[Collection[str]] = None

68

) -> bool:

69

"""

70

Test if a single file matches any pattern.

71

72

Parameters:

73

- file: File path to test

74

- separators: Path separators to normalize (defaults to os.sep)

75

76

Returns:

77

True if file matches any include pattern and no exclude patterns

78

"""

79

80

def match_files(

81

self,

82

files: Iterable[Union[str, os.PathLike]],

83

separators: Optional[Collection[str]] = None,

84

*,

85

negate: Optional[bool] = None

86

) -> Iterator[Union[str, os.PathLike]]:

87

"""

88

Match multiple files against patterns.

89

90

Parameters:

91

- files: Iterable of file paths to test

92

- separators: Path separators to normalize

93

- negate: If True, return non-matching files instead

94

95

Yields:

96

File paths that match the patterns

97

"""

98

99

def check_file(

100

self,

101

file: Union[str, os.PathLike],

102

separators: Optional[Collection[str]] = None

103

) -> CheckResult[Union[str, os.PathLike]]:

104

"""

105

Check a single file with detailed result information.

106

107

Parameters:

108

- file: File path to test

109

- separators: Path separators to normalize

110

111

Returns:

112

CheckResult with file path, match status, and pattern index

113

"""

114

115

def check_files(

116

self,

117

files: Iterable[Union[str, os.PathLike]],

118

separators: Optional[Collection[str]] = None

119

) -> Iterator[CheckResult[Union[str, os.PathLike]]]:

120

"""

121

Check multiple files with detailed results.

122

123

Parameters:

124

- files: Iterable of file paths to test

125

- separators: Path separators to normalize

126

127

Yields:

128

CheckResult for each file

129

"""

130

```

131

132

### Directory Tree Methods

133

134

Methods for traversing directory trees and matching files within them.

135

136

```python { .api }

137

def match_tree_files(

138

self,

139

root: Union[str, os.PathLike],

140

on_error: Optional[Callable[[OSError], None]] = None,

141

follow_links: Optional[bool] = None,

142

*,

143

negate: Optional[bool] = None

144

) -> Iterator[str]:

145

"""

146

Walk directory tree and match files against patterns.

147

148

Parameters:

149

- root: Root directory path to traverse

150

- on_error: Optional error handler for OS errors during traversal

151

- follow_links: Whether to follow symbolic links (defaults to False)

152

- negate: If True, return non-matching files instead

153

154

Yields:

155

File paths that match the patterns

156

"""

157

158

def match_tree_entries(

159

self,

160

root: Union[str, os.PathLike],

161

on_error: Optional[Callable[[OSError], None]] = None,

162

follow_links: Optional[bool] = None,

163

*,

164

negate: Optional[bool] = None

165

) -> Iterator[TreeEntry]:

166

"""

167

Walk directory tree and match TreeEntry objects.

168

169

Parameters:

170

- root: Root directory path to traverse

171

- on_error: Optional error handler for OS errors

172

- follow_links: Whether to follow symbolic links

173

- negate: If True, return non-matching entries instead

174

175

Yields:

176

TreeEntry objects for matching file system entries

177

"""

178

179

def check_tree_files(

180

self,

181

root: Union[str, os.PathLike],

182

on_error: Optional[Callable[[OSError], None]] = None,

183

follow_links: Optional[bool] = None

184

) -> Iterator[CheckResult[str]]:

185

"""

186

Walk directory tree and check files with detailed results.

187

188

Parameters:

189

- root: Root directory path to traverse

190

- on_error: Optional error handler for OS errors

191

- follow_links: Whether to follow symbolic links

192

193

Yields:

194

CheckResult for each file in the tree

195

"""

196

197

def match_entries(

198

self,

199

entries: Iterable[TreeEntry],

200

separators: Optional[Collection[str]] = None,

201

*,

202

negate: Optional[bool] = None

203

) -> Iterator[TreeEntry]:

204

"""

205

Match TreeEntry objects against patterns.

206

207

Parameters:

208

- entries: Iterable of TreeEntry objects to test

209

- separators: Path separators to normalize

210

- negate: If True, return non-matching entries instead

211

212

Yields:

213

TreeEntry objects that match the patterns

214

"""

215

216

def match_tree(

217

self,

218

root: str,

219

on_error: Optional[Callable[[OSError], None]] = None,

220

follow_links: Optional[bool] = None,

221

*,

222

negate: Optional[bool] = None

223

) -> Iterator[str]:

224

"""

225

DEPRECATED: Alias for match_tree_files.

226

227

Walk directory tree and match files against patterns.

228

229

Parameters:

230

- root: Root directory path to traverse

231

- on_error: Optional error handler for OS errors

232

- follow_links: Whether to follow symbolic links

233

- negate: If True, return non-matching files instead

234

235

Yields:

236

File paths that match the patterns

237

"""

238

```

239

240

### GitIgnoreSpec Class

241

242

Specialized PathSpec implementation that closely replicates .gitignore behavior with Git-specific edge case handling.

243

244

```python { .api }

245

class GitIgnoreSpec(PathSpec):

246

def __eq__(self, other: object) -> bool:

247

"""

248

Test equality. Only compares equal to other GitIgnoreSpec instances.

249

"""

250

251

@classmethod

252

def from_lines(

253

cls,

254

lines: Iterable[AnyStr],

255

pattern_factory: Optional[Union[str, Callable[[AnyStr], Pattern]]] = None

256

) -> GitIgnoreSpec:

257

"""

258

Create GitIgnoreSpec from pattern lines. Supports reversed parameter order for compatibility.

259

260

Parameters:

261

- lines: Iterable of gitignore-style pattern strings (or pattern_factory if using reversed order)

262

- pattern_factory: Optional pattern factory (defaults to GitWildMatchPattern, or lines if using reversed order)

263

264

Returns:

265

GitIgnoreSpec instance with compiled patterns

266

267

Note: This method supports both parameter orders:

268

- from_lines(lines, pattern_factory) - standard order

269

- from_lines(pattern_factory, lines) - reversed order for PathSpec compatibility

270

"""

271

272

@staticmethod

273

def _match_file(

274

patterns: Iterable[Tuple[int, GitWildMatchPattern]],

275

file: str

276

) -> Tuple[Optional[bool], Optional[int]]:

277

"""

278

Internal method for gitignore-specific matching logic.

279

280

Parameters:

281

- patterns: Indexed patterns to test against

282

- file: File path to test

283

284

Returns:

285

Tuple of (match_result, pattern_index)

286

"""

287

```

288

289

## Usage Examples

290

291

### Basic File Matching

292

293

```python

294

import pathspec

295

296

# Create PathSpec from patterns

297

patterns = ["*.py", "!test_*.py", "src/"]

298

spec = pathspec.PathSpec.from_lines('gitwildmatch', patterns)

299

300

# Test individual files

301

print(spec.match_file("main.py")) # True

302

print(spec.match_file("test_main.py")) # False

303

print(spec.match_file("src/utils.py")) # True

304

305

# Get matching files from a list

306

files = ["main.py", "test_main.py", "src/utils.py", "README.md"]

307

matches = list(spec.match_files(files))

308

print(matches) # ["main.py", "src/utils.py"]

309

```

310

311

### Directory Tree Traversal

312

313

```python

314

import pathspec

315

316

# Create spec for Python project files

317

spec = pathspec.PathSpec.from_lines('gitwildmatch', [

318

"*.py",

319

"*.md",

320

"!__pycache__/",

321

"!*.pyc",

322

"!.git/"

323

])

324

325

# Get all matching files in project directory

326

project_files = list(spec.match_tree_files("/path/to/project"))

327

328

# Handle errors during traversal

329

def handle_error(error):

330

print(f"Warning: {error}")

331

332

safe_files = list(spec.match_tree_files(

333

"/path/to/project",

334

on_error=handle_error

335

))

336

```

337

338

### Detailed Match Information

339

340

```python

341

import pathspec

342

343

spec = pathspec.PathSpec.from_lines('gitwildmatch', [

344

"*.py", # Pattern 0

345

"!test_*.py" # Pattern 1

346

])

347

348

# Get detailed information about matches

349

result = spec.check_file("main.py")

350

print(f"File: {result.file}")

351

print(f"Included: {result.include}")

352

print(f"Matched by pattern: {result.index}")

353

354

# Check multiple files with details

355

files = ["main.py", "test_main.py", "utils.py"]

356

for result in spec.check_files(files):

357

status = "included" if result.include else "excluded"

358

print(f"{result.file}: {status} (pattern {result.index})")

359

```

360

361

### GitIgnore-Specific Behavior

362

363

```python

364

import pathspec

365

366

# GitIgnoreSpec handles gitignore edge cases

367

gitignore_content = """

368

# Comments are ignored

369

*.log

370

temp/

371

!important.log

372

373

# Negation patterns work correctly

374

build/

375

!build/assets/

376

"""

377

378

spec = pathspec.GitIgnoreSpec.from_lines(gitignore_content.splitlines())

379

380

# Use exactly like PathSpec

381

matches = list(spec.match_tree_files("/project"))

382

```

383

384

### Combining PathSpecs

385

386

```python

387

import pathspec

388

389

# Create separate specs for different pattern sets

390

code_spec = pathspec.PathSpec.from_lines('gitwildmatch', [

391

"*.py", "*.js", "*.ts"

392

])

393

394

doc_spec = pathspec.PathSpec.from_lines('gitwildmatch', [

395

"*.md", "*.rst", "*.txt"

396

])

397

398

# Combine them

399

combined_spec = code_spec + doc_spec

400

401

# Or add in place

402

code_spec += doc_spec

403

```