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.
Files changed (2) hide show
  1. package/AGENTS.md +167 -0
  2. 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.5",
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.1",
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.1"
49
+ "ast-search-js": "1.0.3"
49
50
  }
50
51
  }