Smart codebase refactor from camelCase to pythonic snake_case
Project description
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
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 snake_shift-1.0.1.tar.gz.
File metadata
- Download URL: snake_shift-1.0.1.tar.gz
- Upload date:
- Size: 92.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af2ce6c2ead65849f01255feda26273360e60fc962b8555b32359d63f23cc5aa
|
|
| MD5 |
2fd722d6af08605ada12c4a3ea1e3877
|
|
| BLAKE2b-256 |
57fb0190fecab0102d58dea31974b1efccbf048b15e671ece8bbc7bdc02e31b7
|
File details
Details for the file snake_shift-1.0.1-py3-none-any.whl.
File metadata
- Download URL: snake_shift-1.0.1-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06ad50e85db70807a96b7db7fc1bcf4eda8948abc232b447b5f5b404902714e7
|
|
| MD5 |
afabe5f02ebf211b461ad4e8b285e9c1
|
|
| BLAKE2b-256 |
b08ca9a7d2402ab5a0a4963d0285b5f13409ae4ec25827ee4714d630619d2e2f
|