Snake Shift
A powerful Python refactoring tool that converts camelCase codebases to pythonic naming conventions while intelligently preserving external library calls.
Features
- Smart Environment Detection - Automatically distinguishes between internal and external modules
- Aggressive Refactoring - Converts entire codebases while preserving external library APIs
- File & Directory Renaming - Renames files and directories to match pythonic conventions
- Ignores non-code directories.
- Gitignore Integration - Respects .gitignore patterns and includes sensible defaults
- PascalCase Preservation - Keeps class names and type imports in PascalCase
- LibCST-Powered - Uses concrete syntax trees for accurate code transformation
- Dry Run Support - Preview changes before applying them
Quick Start
# Install the tool
pip install snake-shift
# Preview changes to a single file
snake-shift my_file.py --dry-run
# Refactor code and rename files in a directory
snake-shift src/ --rename-files
# Just refactor code without renaming files
snake-shift project/ --dry-run
Before & After
Before:
# myModule.py
import pandas as pd
from myPackage.dataUtils import processData
class myClass:
def myMethod(self, inputData):
df = pd.DataFrame(inputData)
processedData = processData(df.dropna())
return processedData
After:
# my_module.py
import pandas as pd
from my_package.data_utils import process_data
class MyClass:
def my_method(self, input_data):
df = pd.DataFrame(input_data) # External library preserved!
processed_data = process_data(df.dropna())
return processed_data
How It Works
1. Environment-Based Module Detection
Unlike other tools that use hardcoded library lists, snake-shift intelligently detects external modules by:
- Checking if modules are installed in your Python environment
- Identifying standard library modules
- Recognizing common external packages even when not installed
- Treating unknown modules as internal (local code)
2. Pythonic Convention Application
- Classes ?
PascalCase(MyClass) - Functions & Variables ?
snake_case(my_function, my_var) - PascalCase Imports ? Preserved (Dict, Path, MyClass)
- External Library Calls ? Untouched (pd.DataFrame, np.zeros)
3. File System Organization
With --rename-files:
myModule.py?my_module.pydataUtils/?data_utils/MyClass.py?MyClass.py(PascalCase preserved)
Installation
pip install snake-shift
Or install from source:
git clone https://github.com/simondoesstuff/snake_shift.git
pip install -e .
Usage
Command Line Interface
snake-shift [OPTIONS] PATH
Options:
--dry-run, -n- Show changes without writing to files--rename-files, -r- Also rename files and directories--stdout- Print refactored code to stdout (single files only)--verbose, -v- Show detailed output during processing--help- Show help message
Examples:
# Preview all changes to a project
snake-shift my_project/ --rename-files --dry-run
# Refactor a single file
snake-shift utils.py
# Refactor directory with file renaming
snake-shift src/ --rename-files --verbose
# Output refactored code to stdout
snake-shift my_script.py --stdout
Python API
from snake_shift import refactor_source, refactor_directory
# Refactor source code string
code = """
def myFunction(inputData):
return inputData.lower()
"""
refactored = refactor_source(code)
print(refactored)
# Output: def my_function(input_data):\n return input_data.lower()
# Refactor entire directory
from pathlib import Path
refactor_directory(
Path("my_project/"),
rename_files=True,
dry_run=False
)
What Gets Refactored
Internal Code (Your Code)
- Variable names:
myVar$\to$my_var - Function names:
myFunction$\to$my_function - Class names:
myClass$\to$MyClass - Module imports:
from myPackage.myModule$\to$from my_package.my_module - File names:
myModule.py$\to$my_module.py - Directory names:
myPackage/$\to$my_package/
External Code (Preserved)
- Library calls:
pd.DataFrame()stayspd.DataFrame() - Standard library:
os.path.join()staysos.path.join() - PascalCase imports:
from typing import DictstaysDict - External attributes:
model.fit()staysmodel.fit()
Contributing
Contributions are welcome!
Building
# run tests with,
uv run pytest
# or just set up the environment,
uv sync
# or if you don't have UV,
pip install -r requirements.txt
pytest # tests
License
MIT Licence
Acknowledgments
Metadata
Release files for snake-shift 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| snake_shift-1.0.2.tar.gz | 92.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| snake_shift-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 108.1 kB
Release files / snake_shift-1.0.2.tar.gz
| Download URL | snake_shift-1.0.2.tar.gz |
|---|---|
| Size | 92.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ae94880cea64181d54a32cedb14ae7910160a126c39062ad3a641b9ec2de81dd
|
|
BLAKE2b-256 checksum How to use checksums |
d0162be29a5671f626beb19c1a813d6e15341b1afb17750411ecb0ed9bcff349
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.23
|
Release files / snake_shift-1.0.2-py3-none-any.whl
| Download URL | snake_shift-1.0.2-py3-none-any.whl |
|---|---|
| Size | 15.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
77ad1dc51b12a4b7348bc969487c62f7a6aa088f1fbee1ddb561afdbaf19a08c
|
|
BLAKE2b-256 checksum How to use checksums |
45dd555f6a81493fa41daf4ea127b5b4d406bfbdac1d75d2f0b5314e03e882bd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.9.23
|