A tool to refactor magic strings and other magic constants into named constants.
Project description
Constantipy 🪄
The Magic Removal Tool.
Constantipy is a CLI tool that automatically refactors "magic" literals (strings, numbers, bytes) in your Python codebase into named constants.
It scans your project, identifies repeated literals, names them intelligently (e.g., "SELECT *" → STR_SELECT_SQL), and refactors your code to import them from a central constants.py or define them locally.
Features
- Zero Runtime Dependencies: Runs on standard library only.
- Smart Naming Heuristics:
- Auto-detects SQL (
STR_SELECT_SQL), URLs (HTTPS_GOOGLE_COM_URL), and Regex patterns. - Splits CamelCase (
FieldState→STR_FIELD_STATE).
- Auto-detects SQL (
- Scope Detection:
- Global: Strings used in multiple files are moved to
constants.py. - Local: Strings used in only one file are defined at the top of that file (keeps your global constants file clean).
- Global: Strings used in multiple files are moved to
- Safety First:
- Ignores f-strings (
f"Hello {name}") to prevent breaking interpolation. - Ignores docstrings.
- Checks for variable name collisions before generating constants.
- Ignores structural numbers (0, 1, 2, -1) by default.
- Ignores f-strings (
- Granular Control:
- Ignore specific values (
--ignore-str desc,--ignore-num 404). - Ignore specific types (
--no-ints,--no-floats). - Ignore specific function calls (like
logging.debug).
- Ignore specific values (
Installation
pip install constantipy
⚡️ Quick Example
Before Constantipy:
# db_utils.py
import time
import logging
def fetch_users(retries=3):
# Magic String (SQL)
query = "SELECT * FROM users WHERE active = 1"
if retries > 0:
# Magic String inside logging (can be ignored via config)
logging.debug("Attempting connection...")
# Magic Number
time.sleep(60)
return "Success"
After running constantipy apply:
# db_utils.py
import time
import logging
from constants import STR_SELECT_SQL, STR_SUCCESS, INT_60
def fetch_users(retries=3):
# Magic String (SQL)
query = STR_SELECT_SQL
if retries > 0:
# Magic String inside logging (can be ignored via config)
logging.debug("Attempting connection...")
# Magic Number
time.sleep(INT_60)
return STR_SUCCESS
Usage
1. Direct Mode
Scan the codebase and preview or apply changes
Dry Run (Preview changes to stdout)
constantipy
Apply changes to files
constantipy --apply
2. Pipeline Mode
Generate a JSON report, review/edit it manually, and then apply the refactoring.
Generate Report
constantipy report > report.json
Edit report manually (optional)
Validate Report
constantipy validate < report.json
Apply refactoring from report
constantipy refactor --apply < report.json
Configuration
You can fine-tune the extraction process using command-line flags:
| Flag | Description | Default |
|---|---|---|
--apply |
Apply detected changes to files (direct mode only) | False |
--constants-file |
File name for storing global constants | constants.py |
--exclude |
Directories to exclude | None |
--extra-constants |
Additional Python files to scan for constants | None |
--ignore-call |
Ignore specific function calls during scanning | None |
--min-count |
Minimum occurrences for a constant to be considered | 2 |
--min-length |
Minimum length for string literals | 4 |
--naming {generic,derived} |
Strategy for naming generated constants | derived |
--no-local-scope |
Force all constants to be global (ignore local scope) | False |
--path |
Path to scan or refactor (default: current directory) | . |
Numeric & Type Controls
| Flag | Description |
|---|---|
--ignore-num X |
Explicitly ignore number X (e.g. --ignore-num 42) |
--ignore-str S |
Explicitly ignore string S (e.g. --ignore-str "foo") |
--include-num X |
Explicitly extract number X (overrides default ignore) |
--no-bytes |
Skip bytes scanning |
--no-floats |
Skip float scanning |
--no-ints |
Skip integer scanning |
--no-numbers |
Disable ALL magic number extraction |
Safety Warning ⚠️
Constantipy modifies your source code.
While it contains safety checks (AST parsing, collision detection), automated refactoring always carries risk.
- Always commit your changes to git before running with
--apply. - Run your test suite immediately after applying.
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 constantipy-0.1.1.tar.gz.
File metadata
- Download URL: constantipy-0.1.1.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
022420b6f0e49dda865b92d54e3b1f36ebe8219c4bc03206cc7676c2539ec3c8
|
|
| MD5 |
c17d405b593ffd2dddcd9d172b4284a7
|
|
| BLAKE2b-256 |
9d5f324faeb19d5ada97f03ff0ebc7ff640b4236de08f0a103bada0d06dfd0b6
|
File details
Details for the file constantipy-0.1.1-py3-none-any.whl.
File metadata
- Download URL: constantipy-0.1.1-py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
babcf4119aa9b3e9498a2612d5e3e18d601bd184c1c4247c24ebed999ba0a5ff
|
|
| MD5 |
57bd2506cf2c5a682a4c836eb0d32584
|
|
| BLAKE2b-256 |
d74113d8cf19cee4ba2d5a912afac5615c99717fb7f1cd5b77bf9a5792672789
|