ast-search-python 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +167 -0
- package/package.json +5 -4
package/AGENTS.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# ast-search-python — Agent Reference
|
|
2
|
+
|
|
3
|
+
Use this plugin to extend [ast-search](../../AGENTS.md) with Python file support. Load it with `--plugin ast-search-python` to search `.py` and `.pyw` files using tree-sitter S-expression queries.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Invocation
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
ast-search <query> --plugin ast-search-python [--dir <path>] [--format text|json|files] [--lang python]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| Flag | Alias | Default | Description |
|
|
14
|
+
|------|-------|---------|-------------|
|
|
15
|
+
| `--plugin` | `-p` | — | Must be `ast-search-python` to activate Python support |
|
|
16
|
+
| `--dir` | `-d` | `cwd` | Root directory to search |
|
|
17
|
+
| `--format` | `-f` | `text` | Output format: `text`, `json`, or `files` |
|
|
18
|
+
| `--lang` | `-l` | all | Pass `python` to restrict to Python files only |
|
|
19
|
+
|
|
20
|
+
**Exit codes:** `0` = matches found · `1` = no matches · `2` = error (invalid selector, etc.)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Query Syntax
|
|
25
|
+
|
|
26
|
+
Python queries use [tree-sitter](https://tree-sitter.github.io/tree-sitter/) S-expression syntax. Every query must include at least one `@capture_name` to return results — shorthands include `@_` automatically.
|
|
27
|
+
|
|
28
|
+
### Shorthands
|
|
29
|
+
|
|
30
|
+
| Shorthand | Expands to |
|
|
31
|
+
|-------------|-------------------------------------|
|
|
32
|
+
| `fn` | `(function_definition) @_` |
|
|
33
|
+
| `call` | `(call) @_` |
|
|
34
|
+
| `class` | `(class_definition) @_` |
|
|
35
|
+
| `assign` | `(assignment) @_` |
|
|
36
|
+
| `return` | `(return_statement) @_` |
|
|
37
|
+
| `await` | `(await) @_` |
|
|
38
|
+
| `yield` | `(yield) @_` |
|
|
39
|
+
| `import` | `(import_statement) @_` |
|
|
40
|
+
| `from` | `(import_from_statement) @_` |
|
|
41
|
+
| `if` | `(if_statement) @_` |
|
|
42
|
+
| `for` | `(for_statement) @_` |
|
|
43
|
+
| `while` | `(while_statement) @_` |
|
|
44
|
+
| `raise` | `(raise_statement) @_` |
|
|
45
|
+
| `with` | `(with_statement) @_` |
|
|
46
|
+
| `lambda` | `(lambda) @_` |
|
|
47
|
+
| `decorator` | `(decorator) @_` |
|
|
48
|
+
| `augassign` | `(augmented_assignment) @_` |
|
|
49
|
+
| `comp` | `(list_comprehension) @_` |
|
|
50
|
+
| `dictcomp` | `(dictionary_comprehension) @_` |
|
|
51
|
+
| `setcomp` | `(set_comprehension) @_` |
|
|
52
|
+
| `genexp` | `(generator_expression) @_` |
|
|
53
|
+
| `assert` | `(assert_statement) @_` |
|
|
54
|
+
| `delete` | `(delete_statement) @_` |
|
|
55
|
+
| `global` | `(global_statement) @_` |
|
|
56
|
+
| `nonlocal` | `(nonlocal_statement) @_` |
|
|
57
|
+
| `decorated` | `(decorated_definition) @_` |
|
|
58
|
+
|
|
59
|
+
### Raw S-expression patterns
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
(node_type) @name # match by type
|
|
63
|
+
(node_type field: (child_type) @c) @n # field access
|
|
64
|
+
(node_type) @n (#eq? @n "value") # predicate: text equality
|
|
65
|
+
(node_type) @n (#match? @n "regex") # predicate: regex match
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Output Formats
|
|
71
|
+
|
|
72
|
+
Output formats (`text`, `json`, `files`) work identically to the core tool. See [ast-search AGENTS](../../AGENTS.md#output-formats) for details.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Python Refactoring Patterns
|
|
77
|
+
|
|
78
|
+
### Find all function definitions
|
|
79
|
+
```bash
|
|
80
|
+
ast-search 'fn' --plugin ast-search-python
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Find all class definitions
|
|
84
|
+
```bash
|
|
85
|
+
ast-search 'class' --plugin ast-search-python
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Find all imports (including `from X import Y`)
|
|
89
|
+
```bash
|
|
90
|
+
ast-search 'import' --plugin ast-search-python
|
|
91
|
+
ast-search 'from' --plugin ast-search-python
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Find calls to a specific function by name
|
|
95
|
+
```bash
|
|
96
|
+
ast-search '(call function: (identifier) @n (#eq? @n "my_func")) @c' --plugin ast-search-python
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Find all decorators
|
|
100
|
+
```bash
|
|
101
|
+
ast-search 'decorator' --plugin ast-search-python
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Find all `raise` statements
|
|
105
|
+
```bash
|
|
106
|
+
ast-search 'raise' --plugin ast-search-python
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Find all list comprehensions
|
|
110
|
+
```bash
|
|
111
|
+
ast-search 'comp' --plugin ast-search-python
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Find all async functions
|
|
115
|
+
```bash
|
|
116
|
+
ast-search '(function_definition "async" _) @fn' --plugin ast-search-python
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Restrict to Python files only in a mixed-language repo
|
|
120
|
+
```bash
|
|
121
|
+
ast-search 'fn' --lang python --plugin ast-search-python
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Composing with Shell Tools
|
|
127
|
+
|
|
128
|
+
Get all Python files containing `await` and process them:
|
|
129
|
+
```bash
|
|
130
|
+
ast-search 'await' --plugin ast-search-python --format files | xargs -I {} black {}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Count matches per file:
|
|
134
|
+
```bash
|
|
135
|
+
ast-search 'call' --plugin ast-search-python --format json | jq 'group_by(.file) | map({file: .[0].file, count: length})'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Programmatic API
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { defaultRegistry } from 'ast-search/plugin';
|
|
144
|
+
const { register } = await import('ast-search-python');
|
|
145
|
+
register(defaultRegistry);
|
|
146
|
+
|
|
147
|
+
import { searchRepo } from 'ast-search';
|
|
148
|
+
const matches = await searchRepo('fn', './src');
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Supported File Types
|
|
154
|
+
|
|
155
|
+
`.py` `.pyw`
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Gotchas
|
|
160
|
+
|
|
161
|
+
- **Raw S-expressions without `@capture_name` return no results.** The shorthands include `@_` automatically; raw queries require you to add your own capture. A bare `(function_definition)` returns nothing; write `(function_definition) @fn` or just use the `fn` shorthand.
|
|
162
|
+
- **`async def` functions are typed as `function_definition`** in tree-sitter-python 0.21+. There is no separate `async_function_definition` node. The `fn` shorthand matches both. To match only async, use a predicate query.
|
|
163
|
+
- **Shorthands are not expanded inside quoted strings.** `'(call function: (identifier) @n (#eq? @n "fn"))'` keeps `"fn"` literal.
|
|
164
|
+
- **Unparseable files are silently skipped.** Syntax errors in source files do not abort the search.
|
|
165
|
+
- **`node_modules` is always excluded**, as are files/directories whose names start with `.`.
|
|
166
|
+
- **Verify the AST structure before writing a query.** Python attribute chains like `self.client.send()` nest deeply — `self` is not the direct `object:` of the outer call; `self.client` is. If a predicate query returns no results, first remove the predicate and confirm the base pattern matches what you expect.
|
|
167
|
+
- **`captures()` returns every named capture, not just the outermost.** A query like `(function_definition name: (identifier) @n) @fn` produces two matches per function: one for `@fn` (the whole definition) and one for `@n` (the name identifier). Filter by `source` or capture name if you only want one.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ast-search-python",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Python language plugin for ast-search",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"build/*.js",
|
|
27
27
|
"build/*.d.ts",
|
|
28
|
-
"README.md"
|
|
28
|
+
"README.md",
|
|
29
|
+
"AGENTS.md"
|
|
29
30
|
],
|
|
30
31
|
"publishConfig": {
|
|
31
32
|
"access": "public",
|
|
@@ -39,12 +40,12 @@
|
|
|
39
40
|
"@jest/globals": "^29.7.0",
|
|
40
41
|
"@types/jest": "^29.5.12",
|
|
41
42
|
"@types/node": "^20.12.7",
|
|
42
|
-
"ast-search-js": "1.0.
|
|
43
|
+
"ast-search-js": "1.0.3",
|
|
43
44
|
"jest": "^29.7.0",
|
|
44
45
|
"ts-jest": "^29.1.2",
|
|
45
46
|
"typescript": "^5.4.5"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
|
-
"ast-search-js": "1.0.
|
|
49
|
+
"ast-search-js": "1.0.3"
|
|
49
50
|
}
|
|
50
51
|
}
|