Semantic Python refactoring and symbol search CLI
Project description
pyseam
Find and safely refactor Python symbols from the command line. pyseam resolves
names through scopes and imports with jedi, so it
sees the same symbols your interpreter does: every real use, without the false
matches and misses that grep and sed produce.
It does two things, both first-class:
- Search. Find where a symbol is defined and every place it is used, and inspect what sits under any position.
- Refactor. Rename a symbol, module, or package and rewrite every reference
and import across the project, or inline a single-use variable. Changes are
dry-run by default: review the diff, then re-run with
--apply.
What you can do
| Command | What it does |
|---|---|
pyseam find NAME [--refs] |
Locate a symbol's definition; with --refs, list every reference across the project (for a module, its import sites). |
pyseam describe FILE:LINE:COL | NAME |
Report the kind, type, and full name of the symbol at a position or name. Use it to confirm the cursor before a rename. |
pyseam rename TARGET NEW_NAME [--apply] |
Rename a symbol (by name or FILE:LINE:COL) or a module/package (by path), updating every reference and import. |
pyseam inline FILE:LINE:COL | NAME [--apply] |
Replace a single-use variable with its value and delete the assignment. |
pyseam runs project-wide from anywhere in a git repository, and refuses rather than
corrupts: it will not write a result that fails to parse, collides with an
existing name, or shadows a builtin, and it warns you where jedi cannot guarantee
completeness. Exit codes are scriptable: 0 ok, 2 nothing to do, 1 error.
Install
CLI
Install the command with uv:
uv tool install pyseam # from PyPI
uv tool install git+https://github.com/artificiadrian/pyseam.git # from GitHub
uv tool install . # from a local clone
The distribution is pyseam; the installed command is pyseam. Confirm with
pyseam --version.
Claude Code plugin
This repository is also a Claude Code plugin marketplace. The plugin provides the
use-pyseam skill, which directs Claude to use pyseam for semantic Python
refactors rather than editing across files by hand.
Install pyseam as a tool (above) first, then:
/plugin marketplace add artificiadrian/pyseam
/plugin install pyseam@pyseam
/reload-plugins # skills are not loaded automatically
The skill is then available as /pyseam:use-pyseam. To test against a local
checkout, add the marketplace by path: /plugin marketplace add ./path/to/pyseam.
The plugin documents how to use pyseam; it does not bundle the binary, so the CLI
must be on PATH.
Examples
Find where a symbol lives, then every place it is used:
pyseam find load_config # definition, e.g. app/core.py:12:5
pyseam find load_config --refs # definition and all references
Confirm what is under a position, or address an ambiguous name precisely:
pyseam describe app/core.py:12:5 # kind, type, full name
Rename a symbol by name; pyseam resolves it to its definition and rewrites every reference:
pyseam rename load_config read_config # dry-run; prints the diff
pyseam rename load_config read_config --apply # applies it
Rename a module or package by path; imports are rewritten across the project:
pyseam rename app/core/money.py currency --apply # module: file and imports
pyseam rename app/core newpkg --apply # package: directory and imports
Inline a single-use variable back into its use site:
pyseam inline app/core.py:40:5 --apply
Learn more
pyseam docsprints the full guide from the installed binary (so it matches your version): commands, the position/name/path forms, interpreter resolution, exit codes, and caveats.pyseam <command> --helplists the complete flags for a command.
Limitations
pyseam rewrites references that jedi can resolve statically, which is the bulk of a
real codebase. It cannot see a symbol named inside a string (mock.patch
targets, getattr keys, string and forward-reference annotations, dotted paths in
configuration), and jedi has a tail it under-resolves (duck-typed attribute
access, method overrides in sibling classes, rare comprehension cases). rename --apply prints a reminder listing what to check; review the dry-run diff and run
your test suite, and grep for the old name (including non-.py files) to catch
string references.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyseam-0.1.0.tar.gz.
File metadata
- Download URL: pyseam-0.1.0.tar.gz
- Upload date:
- Size: 22.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68c53a3ca18ee1fe1e9b461fdba52e5eb4f67d2ae7ef6932823c2e91587cd322
|
|
| MD5 |
dd841517da840f8e35ab21b36054527c
|
|
| BLAKE2b-256 |
4755a91a6c3284f270697393c4535cd35b708b0eb184c85089c04ab6c8359bdf
|
Provenance
The following attestation bundles were made for pyseam-0.1.0.tar.gz:
Publisher:
publish.yml on artificiadrian/pyseam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyseam-0.1.0.tar.gz -
Subject digest:
68c53a3ca18ee1fe1e9b461fdba52e5eb4f67d2ae7ef6932823c2e91587cd322 - Sigstore transparency entry: 2082100726
- Sigstore integration time:
-
Permalink:
artificiadrian/pyseam@6ebb8e50c2b0c6e9cdf283fea043940190f0be04 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/artificiadrian
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6ebb8e50c2b0c6e9cdf283fea043940190f0be04 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyseam-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pyseam-0.1.0-py3-none-any.whl
- Upload date:
- Size: 29.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f17639e7d60a310f5187b4e4769f8e52c0def4eeaff9138fe6a6ab189b04a11
|
|
| MD5 |
2558900c2d48eaf61f47f7bed735a119
|
|
| BLAKE2b-256 |
b6ec162a3387bf6a248fc1f784ec816b2db4229fecf2464d011a097779e5a3ff
|
Provenance
The following attestation bundles were made for pyseam-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on artificiadrian/pyseam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyseam-0.1.0-py3-none-any.whl -
Subject digest:
2f17639e7d60a310f5187b4e4769f8e52c0def4eeaff9138fe6a6ab189b04a11 - Sigstore transparency entry: 2082100731
- Sigstore integration time:
-
Permalink:
artificiadrian/pyseam@6ebb8e50c2b0c6e9cdf283fea043940190f0be04 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/artificiadrian
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6ebb8e50c2b0c6e9cdf283fea043940190f0be04 -
Trigger Event:
push
-
Statement type: