Split top-level Python functions into dedicated modules and rewire imports automatically.
Project description
ManaSplice
ManaSplice is a small CLI for pulling top-level Python functions into their own files without leaving the original module broken.
It creates a
modules/package next to the source file, moves the function there, and rewrites the source module to import it back in.
What it does
- Splits one top-level function with
splitfunc. - Splits every top-level function in a file, or every top-level function in each Python file in a directory, with
splitall. - Checks whether a split is safe, and shows the planned changes without writing files, with
check. - Copies the imports and top-level definitions the extracted function needs.
- Maintains
modules/__init__.pyso rewritten files can use a single merged import line.
Quick example
Starting point:
import math
def area(radius: float) -> float:
return math.pi * radius * radius
def greet(name: str) -> str:
return f"Hello, {name}!"
Run:
uv run manasplice splitfunc main.area
Result:
import math
from modules import area
def greet(name: str) -> str:
return f"Hello, {name}!"
"""Auto-generated by ManaSplice from main.py."""
import math
def area(radius: float) -> float:
return math.pi * radius * radius
Installation
For using in a project:
uv add manasplice
or
pip install manasplice
For local development in this repo:
uv sync
To run the CLI without installing it globally:
uv run manasplice --help
Commands
manasplice splitfunc <module>.<function>
manasplice splitall <path/to/file.py>
manasplice splitall --dir <directory>
manasplice check <module>.<function>
manasplice check <path/to/file.py>
manasplice check --dir <directory>
manasplice undo [count]
manasplice splitfunc <module>.<function> --preview
manasplice splitall <path/to/file.py> --preview
manasplice splitfunc <module>.<function> --validate
manasplice splitall <path/to/file.py> --public-only --exclude main,_*
manasplice splitall <path/to/file.py> --auto-group
manasplice splitfunc <module>.<function> --output-package generated
manasplice splitfunc <module>.<function> --force
Examples:
uv run manasplice splitfunc main.area
uv run manasplice splitfunc package.utils.normalize_name
uv run manasplice splitall main.py
uv run manasplice splitall --dir app
uv run manasplice check main.area
uv run manasplice check main.py --public-only --exclude main,_*
uv run manasplice splitall main.py --preview
uv run manasplice splitall main.py --public-only --exclude main,_*
uv run manasplice splitall main.py --auto-group
uv run manasplice splitfunc main.area --validate
uv run manasplice splitfunc main.area --output-package generated
uv run manasplice undo
Notes
- ManaSplice only moves top-level functions.
splitallis literal: it will split every top-level function it finds, including helper functions andmain()if present.- Use
checkfor a no-write safety report without diffs. - Use
--previewto inspect planned edits with a safety report and unified diffs before ManaSplice writes anything. - Use
--validateto make ManaSplice parse the generated Python source before it writes changes. - Use
--include,--exclude, and--public-onlyto makesplitallselective instead of splitting every top-level function. - Use
--auto-groupto keep top-level functions that reference each other in the same generated module. - Use
--output-packageif you want generated modules somewhere other thanmodules/. - ManaSplice refuses to overwrite an existing generated module unless you pass
--force. - ManaSplice refuses splits that depend on mutable top-level globals, because copying those globals into a new module changes runtime state.
- ManaSplice now refuses to split functions that participate in a local top-level dependency cycle, such as simple mutual recursion.
- Every non-preview split records rollback history in
.manasplice_history.json, andundoreplays the last recorded operation. - The generated
modules/package is part of the rewritten code, not just scratch output.
Development
Run tests with:
uv run python -m pytest tests --basetemp .pytest_tmp
uv run ruff check src tests
uv run mypy
CONTRIBUTION
Feel free to give feedback and/or suggest changes. This is just meant to be a helpful tool for larger projects made for fun.
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 manasplice-0.1.0.3a0.tar.gz.
File metadata
- Download URL: manasplice-0.1.0.3a0.tar.gz
- Upload date:
- Size: 100.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f864f7f92efcbe1030c69acf0f48177e553a0c6e0fe1091cdf1fa92e5a039770
|
|
| MD5 |
8fd44ac4946ddb717c4d1f467d407107
|
|
| BLAKE2b-256 |
9ea4f50461eca5966a881b64fed5af9779faf29295e198607854ee00afee8f10
|
File details
Details for the file manasplice-0.1.0.3a0-py3-none-any.whl.
File metadata
- Download URL: manasplice-0.1.0.3a0-py3-none-any.whl
- Upload date:
- Size: 22.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f50c684fecf1195446a76374fa5e3d8be05948e43907e59d12b790a1322cc2b
|
|
| MD5 |
2bb6bd687dfb0cf6cf6c0d0cb3e1f306
|
|
| BLAKE2b-256 |
2b5f3dd15fca98f32c886a4fca9f397e99ca030201269a18edf3ba8d8e3386f5
|