Python refactoring CLI tool powered by LibCST
Project description
pycastic
Python refactoring CLI tool powered by LibCST.
Installation
pip install pycastic
Usage
pycastic uses a unified command interface that automatically detects the operation based on source and target arguments:
pycastic SOURCE TARGET [OPTIONS]
The project root is auto-detected by looking for pyproject.toml or .git directory, or can be specified with --root.
Operations
Symbol Operations (source contains ::)
| Example | Description |
|---|---|
pycastic src/utils.py::old_func src/utils.py::new_func |
Rename symbol |
pycastic src/utils.py::helper dest.py |
Move symbol |
pycastic src/utils.py::helper dest.py::new_name |
Move + rename |
pycastic src/utils.py::a,b,c dest.py |
Move multiple symbols |
File Operations (source is a file path)
| Example | Description |
|---|---|
pycastic src/old.py src/new.py |
Rename file |
pycastic src/utils.py lib/utils.py |
Move file |
pycastic src/utils.py lib/ |
Move file to directory |
Target Formats
| Format | Example | Description |
|---|---|---|
file.py::Symbol |
utils.py::helper |
Symbol by name |
file.py::A,B,C |
utils.py::foo,bar |
Multiple symbols |
file.py:line:col |
utils.py:10:5 |
Symbol at position |
Options
| Option | Effect |
|---|---|
--dry-run / -n |
Preview changes without applying |
--root PATH / -r |
Specify project root (auto-detected by default) |
--include-deps |
Auto-include shared dependencies in the move |
--shared-file |
Extract shared deps to default file ({source}_common.py) |
--shared-file-path PATH |
Extract shared deps to specified file |
Move Behavior Rules
| Scenario | Behavior |
|---|---|
| Symbol uses external imports | Imports copied to destination |
| Symbol uses internal dep (unused elsewhere) | Dep moved automatically |
| Symbol uses internal dep (used elsewhere) | Error: use --include-deps or --shared-file |
| Other files import moved symbol | Imports updated to new location |
| Original file uses moved symbol | Import added from new location |
| Original file has unused imports after move | Unused imports removed |
Examples
Rename a symbol
# Rename by name
pycastic src/utils.py::old_function src/utils.py::new_function
# Rename by position (line:column)
pycastic src/module.py:10:5 src/module.py::new_name
Move symbols
# Move a function (auto-includes unused internal dependencies)
pycastic src/utils.py::process_data src/processors.py
# Move multiple related functions together
pycastic src/utils.py::parse,validate,transform src/parsers.py
# Preview what would happen
pycastic src/utils.py::my_func dest.py --dry-run
Handling shared dependencies
When moving a symbol that depends on another symbol in the same file, pycastic checks if that dependency is used by other remaining code:
# If shared dependency detected, you have two options:
# Option 1: Include shared deps in the move
pycastic src/utils.py::func_a dest.py --include-deps
# Option 2: Extract shared deps to a common file (default: utils_common.py)
pycastic src/utils.py::func_a dest.py --shared-file
# Option 3: Extract shared deps to a specific file
pycastic src/utils.py::func_a dest.py --shared-file-path src/common.py
Rename and move files
# Rename a file (updates all imports)
pycastic src/old_name.py src/new_name.py
# Move a file to a new directory (updates all imports)
pycastic src/utils.py lib/
How It Works
pycastic uses LibCST to parse and transform Python code while preserving formatting. When moving symbols:
- Dependency Analysis: Analyzes what imports and internal symbols the target depends on
- Smart Resolution: Determines which dependencies should move automatically vs. require user input
- Import Management: Updates imports in all affected files
- Cleanup: Removes unused imports from the original file
License
MIT
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 pycastic-0.0.3.tar.gz.
File metadata
- Download URL: pycastic-0.0.3.tar.gz
- Upload date:
- Size: 41.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5b29f867dff4369e46b000f72b86750e57e3cba02f53a716d8111a15d3fd0dc
|
|
| MD5 |
0f938f42cc44a3768e25c053fc6af36e
|
|
| BLAKE2b-256 |
6addbd8456bf47614642b42051675b2677a0578f97ac92f3c2adf089bda068d1
|
Provenance
The following attestation bundles were made for pycastic-0.0.3.tar.gz:
Publisher:
bump-and-release.yml on tssweeney/pycastic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycastic-0.0.3.tar.gz -
Subject digest:
d5b29f867dff4369e46b000f72b86750e57e3cba02f53a716d8111a15d3fd0dc - Sigstore transparency entry: 820397345
- Sigstore integration time:
-
Permalink:
tssweeney/pycastic@70b3bf61ee9c4db51b0651a660cbe1bf33456a8c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tssweeney
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
bump-and-release.yml@70b3bf61ee9c4db51b0651a660cbe1bf33456a8c -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pycastic-0.0.3-py3-none-any.whl.
File metadata
- Download URL: pycastic-0.0.3-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80a6261b4026d2304a68a5ec0ddd8d9919cf1b893a24c696a4f157a11d53c800
|
|
| MD5 |
cc0c10c48ee20a39e12aef242fa4c5cc
|
|
| BLAKE2b-256 |
ad09742cac2ac0e6e7a01df256de59d2e555f59e069874fb2e4a720df4b19c12
|
Provenance
The following attestation bundles were made for pycastic-0.0.3-py3-none-any.whl:
Publisher:
bump-and-release.yml on tssweeney/pycastic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycastic-0.0.3-py3-none-any.whl -
Subject digest:
80a6261b4026d2304a68a5ec0ddd8d9919cf1b893a24c696a4f157a11d53c800 - Sigstore transparency entry: 820397356
- Sigstore integration time:
-
Permalink:
tssweeney/pycastic@70b3bf61ee9c4db51b0651a660cbe1bf33456a8c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/tssweeney
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
bump-and-release.yml@70b3bf61ee9c4db51b0651a660cbe1bf33456a8c -
Trigger Event:
workflow_dispatch
-
Statement type: