Skip to content

python.code_duplication

Maintainability Low

Detects duplicated code blocks that should be extracted into reusable functions or classes.

Code duplication causes:

  • Maintenance burden — Fixes must be applied multiple times
  • Inconsistent behavior — Copies drift apart over time
  • Increased bug risk — Bugs in duplicated code multiply
  • Harder refactoring — Changes require finding all copies
# ❌ Before (duplicated validation logic)
def create_user(data):
if not data.get('email'):
raise ValueError("Email required")
if '@' not in data['email']:
raise ValueError("Invalid email format")
# ... create user
def update_user(user_id, data):
if not data.get('email'):
raise ValueError("Email required")
if '@' not in data['email']:
raise ValueError("Invalid email format")
# ... update user
# ✅ After (extracted helper)
def validate_email(email: str) -> None:
if not email:
raise ValueError("Email required")
if '@' not in email:
raise ValueError("Invalid email format")
def create_user(data):
validate_email(data.get('email', ''))
# ... create user
def update_user(user_id, data):
validate_email(data.get('email', ''))
# ... update user
  • Identical or near-identical code blocks (3+ lines)
  • Similar function bodies with minor variations
  • Copy-pasted exception handling
  • Repeated validation logic

Unfault suggests extracting duplicated code into helper functions:

# Suggested extraction
def _common_setup():
"""Extracted from multiple locations."""
config = load_config()
client = create_client(config)
return client
# Strategy pattern for similar functions with differences
from abc import ABC, abstractmethod
class Processor(ABC):
def process(self, data):
self.validate(data)
result = self.transform(data)
self.save(result)
return result
@abstractmethod
def transform(self, data):
pass
class UserProcessor(Processor):
def transform(self, data):
return User(**data)
class OrderProcessor(Processor):
def transform(self, data):
return Order(**data)