How to improve Python code quality
Most Python quality problems aren't exotic — they're a small, repeatable set of patterns that look harmless when you write them and cause a confusing bug months later. Here are the ones worth fixing first, with real before/after code for each.
Bare except: blocks
A bare except: catches everything — including KeyboardInterrupt and SystemExit, which almost never should be silently swallowed. It also hides the actual error, making the real bug harder to find later.
Before
try:
result = risky_call()
except:
result = None
After
try:
result = risky_call()
except (ValueError, KeyError) as exc:
log.warning("risky_call failed: %s", exc)
result = None
Mutable default arguments
Default argument values are evaluated once, when the function is defined — not once per call. A mutable default like [] or {} is silently shared and mutated across every call that doesn't pass its own value, producing state that leaks between unrelated calls.
Before — the list is shared across calls
def add_item(item, items=[]):
items.append(item)
return items
After — a fresh list every call
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
Mutable class attributes
The same sharing problem, one level up: a mutable value assigned at the class level is one single object shared by every instance, not a fresh copy per instance.
Before — every instance shares one list
class Cart:
items = []
After — initialized per instance
class Cart:
def __init__(self):
self.items = []
Wildcard imports
from module import * pollutes the current namespace with everything the module exports, and hides exactly where any given name came from — both for readers and for tools trying to statically trace where a symbol is defined.
Before
from utils import *
After
from utils import normalize, slugify
How REPO-SIGHT checks for these
All four patterns above are REPO-SIGHT's actual Python rules — py-bare-except, py-mutable-default-arg, py-mutable-class-attribute, and py-wildcard-import, alongside long-function, deep-nesting, and TODO-without-ticket checks. Run it on a Python repository to see which of these actually show up in your own code.