Python cleanup suite
ProprietaryRun every Python cleanup recipe in one pass, including the code quality fixes: literal simplification, boolean and comparison tidying, dead code removal, naming fixes, and more. Each recipe leaves code alone where its rewrite could change what the code does.
org. openrewrite. python. cleanup. PythonBestPracticesmod run . --recipe= org. openrewrite. python. cleanup. PythonBestPracticesInstall it once, then run it on every repository under the current directory. New to the Moderne CLI? Set it up.
Recipe list
It runs these recipes, in this order.
- Use
{}literal instead ofdict()constructor - Use
[]literal instead oflist()constructor - Use
()literal instead oftuple()constructor - Unwrap
tuple(),list()orset()around a collection literal - Drop unnecessary step
1argument fromrange() - Drop unnecessary
0start argument fromrange() - Compare to
Nonewith identity operators (is/is not) - Fold same-literal
==/!=comparisons to boolean constants - Collapse self-cancelling
^/-with duplicate operands to0 - Rewrite self-multiplication as
** 2 - Convert
else: iftoelif - Flip an empty
ifbody by negating the condition - Drop a
pass-onlyelifby negating its condition - Simplify a negated
eliftoelse - Drop
elseafter an early-exitifbranch - Use a conditional expression for a simple
if/elseassignment - Collapse boolean ternary to bare condition
- Eliminate boolean literal from
and/or - Replace
len()emptiness check with truthiness - Substitute constant collection condition with boolean
- Collapse
if/elsereturning boolean literals - Flatten negated logic via De Morgan's identities
- Replace self-referencing ternary with
or - Swap conditional expression branches to drop a negated condition
- Use augmented assignment
- Drop default slice boundaries
- Use negative index instead of
len()offset - Code quality
- Use chained comparison syntax
- Replace
.find()check within/not in - Consolidate repeated
==withorintoin - Merge
isinstance()calls - Prefer set literals in
inmembership tests - Remove redundant pass statements
- Strip trailing
continuefrom loop body - Drop
exists()check paired withis_dir()/is_file() - Delete no-op
assert Truestatements - Strip dead code after terminal statements
- Delete
ifblocks whose body is onlypass - Unwrap
str()fromprint()arguments - Remove redundant
Nonedefault fromdict.get() - Drop
fprefix from strings without placeholders - Strip
str()from f-string placeholders - Prefer
startswith/endswithover slice comparison - Use bracket access for
re.Matchgroups - Fold constants into f-string text
- Drop redundant
.keys()on dict iteration - Convert one-item
dict.update()to bracket assignment - Unwrap unnecessary
dict()from union operands - Deduplicate repeated keys in dict literals
- Deduplicate repeated elements in set literals
- Flatten
for/elsewhen the loop has nobreak - Use comprehension syntax instead of
list()/set()around generators - Pass iterable directly to
any()/all()instead of identity generator - Use generator expression instead of list comprehension in iterable-accepting calls
- Simplify identity comprehension to
list()/set()call - Swap
not all()/not any()by negating the comparison - Apply De Morgan's law to
any(not ...)/all(not ...) - Rewrite
any(v == literal ...)asliteral in collection - Simplify
sum(1 for x in items if cond)tosum(bool(cond) for x in items) - Unwrap one-element exception tuple in
except - Chain exceptions with
raise ... frominexceptblocks - Standardize
@classmethodfirst parameter tocls - Standardize instance method first parameter to
self - Convert
apply('name')to a direct method invocation - Replace the
and/oridiom with a conditional expression - Swap variables with tuple unpacking
- Use
datetime.now()instead ofdatetime.today() - Replace
getattr(x, 'attr')withx.attr - Replace
setattr()with constant attribute assignment - Replace
not x in ywithx not in y - Use
is notinstead ofnot ... is - Replace
logger.warn()withlogger.warning() - Remove unnecessary assignment before return
- Replace Yoda conditions with normal comparisons
- Remove useless
objectinheritance - Merge multiple
startswith()/endswith()calls into one - Replace
zip(d.keys(), d.values())withd.items() - Remove trailing
return Nonefrom functions - Replace
del x[:]withx.clear() - Merge nested
withstatements into one