Skip to content

Python

Python's zen principles come directly from PEP 20 — The Zen of Python. If you've ever typed import this in a Python REPL, you've seen them. MCP Zen of Languages turns these aphorisms into actionable code analysis — 12 principles enforced by 23 detectors.

Deepest analysis available

Python is the only language with full AST parsing, cyclomatic complexity measurement, maintainability index scoring, and dependency graph analysis. Other languages use regex-based detection.

Optional External Tool Augmentation

Consent-first external tooling

External tool execution is optional and disabled by default. Use --enable-external-tools (CLI) or enable_external_tools=true (MCP) to opt in. Missing tools should return recommendations; no automatic installs occur during analysis.

Tool Default invocation Output
ruff ruff check --stdin-filename stdin.py - Text / structured stderr

Temporary runner fallback

For temporary execution via package runners, use --allow-temporary-runners (CLI) or allow_temporary_runners=true (MCP).

Zen Principles

20 principles across 11 categories, drawn from PEP 20 - The Zen of Python.

Architecture · 1 principle Clarity · 1 principle Complexity · 1 principle Consistency · 1 principle Correctness · 2 principles Design · 2 principles Error Handling · 1 principle Idioms · 2 principles Organization · 2 principles Readability · 5 principles Structure · 2 principles

Rule ID Principle Category Severity Dogma
python-001 Beautiful is better than ugly Readability 4 ZEN-UNAMBIGUOUS-NAME
python-002 Explicit is better than implicit Clarity 7 ZEN-EXPLICIT-INTENT
python-003 Simple is better than complex Complexity 8 ZEN-PROPORTIONATE-COMPLEXITY, ZEN-RETURN-EARLY, ZEN-RIGHT-ABSTRACTION
python-004 Complex is better than complicated Architecture 7 ZEN-RIGHT-ABSTRACTION, ZEN-PROPORTIONATE-COMPLEXITY
python-005 Flat is better than nested Structure 8 ZEN-RETURN-EARLY
python-006 Sparse is better than dense Readability 5 ZEN-UNAMBIGUOUS-NAME, ZEN-VISIBLE-STATE
python-007 Readability counts Readability 9 ZEN-UNAMBIGUOUS-NAME
python-008 Special cases aren't special enough to break the rules Consistency 6 ZEN-EXPLICIT-INTENT, ZEN-FAIL-FAST
python-009 Errors should never pass silently Error Handling 9 ZEN-FAIL-FAST, ZEN-EXPLICIT-INTENT
python-010 In the face of ambiguity, refuse the temptation to guess Correctness 7 ZEN-EXPLICIT-INTENT
python-011 There should be one-- and preferably only one --obvious way to do it Idioms 6 ZEN-RIGHT-ABSTRACTION, ZEN-VISIBLE-STATE
python-012 Namespaces are one honking great idea Organization 7 ZEN-STRICT-FENCES, ZEN-UNAMBIGUOUS-NAME
python-013 Practicality beats purity Design 5 ZEN-RIGHT-ABSTRACTION, ZEN-PROPORTIONATE-COMPLEXITY
python-014 Unless explicitly silenced Correctness 8 ZEN-EXPLICIT-INTENT, ZEN-FAIL-FAST
python-015 Now is better than never Structure 4 ZEN-RETURN-EARLY, ZEN-RUTHLESS-DELETION
python-016 Although never is often better than right now Design 5 ZEN-RIGHT-ABSTRACTION, ZEN-FAIL-FAST, ZEN-RUTHLESS-DELETION
python-017 If the implementation is hard to explain, it's a bad idea Readability 6 ZEN-UNAMBIGUOUS-NAME
python-018 If the implementation is easy to explain, it may be a good idea Readability 3 ZEN-UNAMBIGUOUS-NAME, ZEN-PROPORTIONATE-COMPLEXITY
python-019 Although that way may not be obvious at first unless you're Dutch Idioms 5 ZEN-RIGHT-ABSTRACTION
python-020 Let's do more of those Organization 6 ZEN-STRICT-FENCES, ZEN-UNAMBIGUOUS-NAME
python-001 — Beautiful is better than ugly

Code should be aesthetically pleasing and well-formatted

Universal Dogmas: ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Inconsistent indentation
  • Poor naming conventions
  • Lack of whitespace around operators
  • Overly compact code

Thresholds:

Parameter Default
max_line_length 88
naming_convention snake_case
min_identifier_length 2
python-002 — Explicit is better than implicit

Code behavior should be obvious and unambiguous

Universal Dogmas: ZEN-EXPLICIT-INTENT Common Violations:

  • Using global variables without declaration
  • Implicit type conversions
  • Magic numbers without constants
  • Overuse of * imports
  • Hidden side effects in functions

Detectable Patterns:

  • from module import *
  • global keyword abuse
  • functions modifying arguments without clear indication
python-003 — Simple is better than complex

Favor straightforward solutions over complicated ones

Universal Dogmas: ZEN-PROPORTIONATE-COMPLEXITY, ZEN-RETURN-EARLY, ZEN-RIGHT-ABSTRACTION Common Violations:

  • High cyclomatic complexity (>10)
  • Overly nested comprehensions
  • Unnecessary abstraction layers
  • Complex one-liners

Thresholds:

Parameter Default
max_cyclomatic_complexity 10
python-004 — Complex is better than complicated

When complexity is necessary, keep it organized and understandable

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-PROPORTIONATE-COMPLEXITY Common Violations:

  • Tangled dependencies
  • Unclear module boundaries
  • Mixed concerns in single class
python-005 — Flat is better than nested

Avoid deep nesting of control structures

Universal Dogmas: ZEN-RETURN-EARLY Common Violations:

  • Nesting depth > 3 levels
  • Multiple nested loops
  • Deeply nested if-else chains

Thresholds:

Parameter Default
max_nesting_depth 3
python-006 — Sparse is better than dense

Code should have appropriate spacing and not be cramped

Universal Dogmas: ZEN-UNAMBIGUOUS-NAME, ZEN-VISIBLE-STATE Common Violations:

  • Multiple statements on one line
  • Overly compact expressions
  • Lack of blank lines between logical sections

Thresholds:

Parameter Default
max_statements_per_line 1
min_blank_lines_between_defs 1
python-007 — Readability counts

Code is read more often than written

Universal Dogmas: ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Functions longer than 50 lines
  • Classes longer than 300 lines
  • Unclear variable names (a, b, x)
  • Missing docstrings for public APIs

Thresholds:

Parameter Default
max_function_length 50
max_class_length 300
python-008 — Special cases aren't special enough to break the rules

Maintain consistency even for edge cases

Universal Dogmas: ZEN-EXPLICIT-INTENT, ZEN-FAIL-FAST Common Violations:

  • Inconsistent error handling patterns
  • Different naming conventions within same module
  • Special-case code paths without justification

Thresholds:

Parameter Default
max_naming_styles 1
python-009 — Errors should never pass silently

Always handle errors explicitly

Universal Dogmas: ZEN-FAIL-FAST, ZEN-EXPLICIT-INTENT Common Violations:

  • Bare except clauses
  • Catching Exception without handling
  • Ignoring return codes
  • Empty except blocks

Detectable Patterns:

  • except: pass
  • except Exception: pass
python-010 — In the face of ambiguity, refuse the temptation to guess

Be explicit rather than making assumptions

Universal Dogmas: ZEN-EXPLICIT-INTENT Common Violations:

  • Implicit type assumptions
  • Unclear function contracts
  • Missing input validation

Thresholds:

Parameter Default
require_type_hints True
python-011 — There should be one-- and preferably only one --obvious way to do it

Prefer pythonic idioms over alternatives

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-VISIBLE-STATE Common Violations:

  • Using range(len()) instead of enumerate
  • Manual iteration instead of list comprehensions
  • Not using context managers for resources
  • Multiple implementations of same logic

Detectable Patterns:

  • for i in range(len(list))
  • file without 'with' statement
python-012 — Namespaces are one honking great idea

Use namespaces to organize code clearly

Universal Dogmas: ZEN-STRICT-FENCES, ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Polluting global namespace
  • Too many items in all
  • Deep module nesting without purpose

Thresholds:

Parameter Default
max_top_level_symbols 25
max_exports 20
python-013 — Practicality beats purity

Prefer simple, practical solutions over excessive abstraction

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-PROPORTIONATE-COMPLEXITY Common Violations:

  • Over-engineered ABC/Protocol hierarchies
  • Premature abstraction with few implementations
python-014 — Unless explicitly silenced

Only suppress exceptions when suppression is intentional and documented

Universal Dogmas: ZEN-EXPLICIT-INTENT, ZEN-FAIL-FAST Common Violations:

  • Bare except clauses
  • Silent exception catching with pass
python-015 — Now is better than never

Address TODOs and stubs promptly

Universal Dogmas: ZEN-RETURN-EARLY, ZEN-RUTHLESS-DELETION Common Violations:

  • TODO/FIXME/HACK/XXX comments left unresolved
python-016 — Although never is often better than right now

Document why functionality is deferred rather than raising bare NotImplementedError

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-FAIL-FAST, ZEN-RUTHLESS-DELETION Common Violations:

  • Undocumented NotImplementedError stubs
python-017 — If the implementation is hard to explain, it's a bad idea

Complex code must be documented

Universal Dogmas: ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Functions without docstrings
python-018 — If the implementation is easy to explain, it may be a good idea

Even simple public functions benefit from docstrings

Universal Dogmas: ZEN-UNAMBIGUOUS-NAME, ZEN-PROPORTIONATE-COMPLEXITY Common Violations:

  • Public functions without docstrings
python-019 — Although that way may not be obvious at first unless you're Dutch

Use idiomatic Python constructs that may not be obvious to newcomers

Universal Dogmas: ZEN-RIGHT-ABSTRACTION Common Violations:

  • Using range(len()) instead of enumerate()
  • Comparing with == True/False instead of direct boolean checks
python-020 — Let's do more of those

Actively use namespaces to keep modules focused and maintainable

Universal Dogmas: ZEN-STRICT-FENCES, ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Polluting global namespace
  • Too many items in all
  • Monolithic modules instead of focused namespaces

Thresholds:

Parameter Default
max_top_level_symbols 25
max_exports 20

Detector Catalog

Architecture

Detector What It Catches Rule IDs
GodClassDetector Detect God classes — classes with too many methods or lines of code python-004
CircularDependencyDetector Detect circular import dependencies across modules python-004
DeepInheritanceDetector Detect class hierarchies that exceed a safe inheritance depth python-004

Clarity

Detector What It Catches Rule IDs
MagicMethodDetector Detect classes that overload too many dunder (magic) methods python-002
StarImportDetector Detect wildcard from X import * statements that pollute the module namespace python-002
MagicNumberDetector Detect excessive use of unexplained numeric literals (magic numbers) python-002

Complexity

Detector What It Catches Rule IDs
CyclomaticComplexityDetector Detect functions whose cyclomatic complexity exceeds the configured threshold python-003
ComplexOneLinersDetector Detect overly dense one-liner expressions that sacrifice readability python-003

Consistency

Detector What It Catches Rule IDs
ConsistencyDetector Detect mixed naming conventions within a single module python-008

Correctness

Detector What It Catches Rule IDs
ExplicitnessDetector Detect function parameters missing type annotations python-010
PythonExplicitSilenceDetector Detects bare except clauses and silently caught exceptions python-014

Design

Detector What It Catches Rule IDs
PythonPracticalityDetector Flags over-engineered abstractions like ABCs with likely few implementations python-013
PythonPrematureImplDetector Detects raise NotImplementedError stubs without documentation python-016

Error Handling

Detector What It Catches Rule IDs
BareExceptDetector Detect bare except: clauses and silently swallowed exceptions python-009

Idioms

Detector What It Catches Rule IDs
FeatureEnvyDetector Detect methods that access another object's data more than their own python-011
DuplicateImplementationDetector Detect identical or near-identical function implementations across files python-011
ContextManagerDetector Detect open() calls not wrapped in a with context manager python-011
PythonIdiomDetector Detects non-idiomatic Python patterns like range(len(...)) and == True python-019

Organization

Detector What It Catches Rule IDs
NamespaceUsageDetector Detect modules with too many top-level symbols or __all__ exports python-012, python-020

Readability

Detector What It Catches Rule IDs
NameStyleDetector Detect function and variable names that violate Python's snake_case convention python-001
LongFunctionDetector Detect functions whose line count exceeds the configured maximum python-007
ShortVariableNamesDetector Detect variables and loop targets with names shorter than the configured minimum python-007
ClassSizeDetector Detect classes whose line count exceeds the configured maximum python-007
LineLengthDetector Detect source lines that exceed a configured character limit python-001
SparseCodeDetector Detect lines packing multiple statements separated by semicolons python-006
DocstringDetector Detect top-level functions and classes missing a docstring python-007
PythonComplexUndocumentedDetector Detects functions missing docstrings python-017
PythonSimpleDocumentedDetector Detects public functions (not starting with _) missing docstrings python-018

Structure

Detector What It Catches Rule IDs
NestingDepthDetector Detect code blocks with excessive indentation depth and nested loops python-005
PythonTodoStubDetector Detects TODO, FIXME, HACK, and XXX comments left in source code python-015
Principle → Detector Wiring
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 40, "rankSpacing": 60}}}%%
graph TD
python_001["python-001<br/>Beautiful is better than ..."]
python_002["python-002<br/>Explicit is better than i..."]
python_003["python-003<br/>Simple is better than com..."]
python_004["python-004<br/>Complex is better than co..."]
python_005["python-005<br/>Flat is better than neste..."]
python_006["python-006<br/>Sparse is better than den..."]
python_007["python-007<br/>Readability counts"]
python_008["python-008<br/>Special cases aren&#x27;t spec..."]
python_009["python-009<br/>Errors should never pass ..."]
python_010["python-010<br/>In the face of ambiguity,..."]
python_011["python-011<br/>There should be one-- and..."]
python_012["python-012<br/>Namespaces are one honkin..."]
python_013["python-013<br/>Practicality beats purity"]
python_014["python-014<br/>Unless explicitly silence..."]
python_015["python-015<br/>Now is better than never"]
python_016["python-016<br/>Although never is often b..."]
python_017["python-017<br/>If the implementation is ..."]
python_018["python-018<br/>If the implementation is ..."]
python_019["python-019<br/>Although that way may not..."]
python_020["python-020<br/>Let&#x27;s do more of those"]
det_BareExceptDetector["Bare Except"]
python_009 --> det_BareExceptDetector
det_CircularDependencyDetector["Circular Dependency"]
python_004 --> det_CircularDependencyDetector
det_ClassSizeDetector["Class Size"]
python_007 --> det_ClassSizeDetector
det_ComplexOneLinersDetector["Complex One<br/>Liners"]
python_003 --> det_ComplexOneLinersDetector
det_ConsistencyDetector["Consistency"]
python_008 --> det_ConsistencyDetector
det_ContextManagerDetector["Context Manager"]
python_011 --> det_ContextManagerDetector
det_CyclomaticComplexityDetector["Cyclomatic Complexity"]
python_003 --> det_CyclomaticComplexityDetector
det_DeepInheritanceDetector["Deep Inheritance"]
python_004 --> det_DeepInheritanceDetector
det_DocstringDetector["Docstring"]
python_007 --> det_DocstringDetector
det_DuplicateImplementationDetector["Duplicate Implementation"]
python_011 --> det_DuplicateImplementationDetector
det_ExplicitnessDetector["Explicitness"]
python_010 --> det_ExplicitnessDetector
det_FeatureEnvyDetector["Feature Envy"]
python_011 --> det_FeatureEnvyDetector
det_GodClassDetector["God Class"]
python_004 --> det_GodClassDetector
det_LineLengthDetector["Line Length"]
python_001 --> det_LineLengthDetector
det_LongFunctionDetector["Long Function"]
python_007 --> det_LongFunctionDetector
det_MagicMethodDetector["Magic Method"]
python_002 --> det_MagicMethodDetector
det_MagicNumberDetector["Magic Number"]
python_002 --> det_MagicNumberDetector
det_NameStyleDetector["Name Style"]
det_NamespaceUsageDetector["Namespace Usage"]
python_012 --> det_NamespaceUsageDetector
python_020 --> det_NamespaceUsageDetector
det_NestingDepthDetector["Nesting Depth"]
python_005 --> det_NestingDepthDetector
det_PythonComplexUndocumentedDetector["Python Complex<br/>Undocumented"]
python_017 --> det_PythonComplexUndocumentedDetector
det_PythonExplicitSilenceDetector["Python Explicit<br/>Silence"]
python_014 --> det_PythonExplicitSilenceDetector
det_PythonIdiomDetector["Python Idiom"]
python_019 --> det_PythonIdiomDetector
det_PythonPracticalityDetector["Python Practicality"]
python_013 --> det_PythonPracticalityDetector
det_PythonPrematureImplDetector["Python Premature<br/>Impl"]
python_016 --> det_PythonPrematureImplDetector
det_PythonSimpleDocumentedDetector["Python Simple<br/>Documented"]
python_018 --> det_PythonSimpleDocumentedDetector
det_PythonTodoStubDetector["Python Todo<br/>Stub"]
python_015 --> det_PythonTodoStubDetector
det_ShortVariableNamesDetector["Short Variable<br/>Names"]
python_007 --> det_ShortVariableNamesDetector
det_SparseCodeDetector["Sparse Code"]
python_006 --> det_SparseCodeDetector
det_StarImportDetector["Star Import"]
python_002 --> det_StarImportDetector
Detector Class Hierarchy
%%{init: {"theme": "base"}}%%
classDiagram
    direction TB
    class ViolationDetector {
        <<abstract>>
        +detect(context, config)
    }
    class det_01["Bare Except"]
    ViolationDetector <|-- det_01
    class det_02["Circular Dependency"]
    ViolationDetector <|-- det_02
    class det_03["Class Size"]
    ViolationDetector <|-- det_03
    class det_04["Complex One Liners"]
    ViolationDetector <|-- det_04
    class det_05["Consistency"]
    ViolationDetector <|-- det_05
    class det_06["Context Manager"]
    ViolationDetector <|-- det_06
    class det_07["Cyclomatic Complexity"]
    ViolationDetector <|-- det_07
    class det_08["Deep Inheritance"]
    ViolationDetector <|-- det_08
    class det_09["Docstring"]
    ViolationDetector <|-- det_09
    class det_10["Duplicate Implementation"]
    ViolationDetector <|-- det_10
    class det_11["Explicitness"]
    ViolationDetector <|-- det_11
    class det_12["Feature Envy"]
    ViolationDetector <|-- det_12
    class det_13["God Class"]
    ViolationDetector <|-- det_13
    class det_14["Line Length"]
    ViolationDetector <|-- det_14
    class det_15["Long Function"]
    ViolationDetector <|-- det_15
    class det_16["Magic Method"]
    ViolationDetector <|-- det_16
    class det_17["Magic Number"]
    ViolationDetector <|-- det_17
    class det_18["Name Style"]
    ViolationDetector <|-- det_18
    class det_19["Namespace Usage"]
    ViolationDetector <|-- det_19
    class det_20["Nesting Depth"]
    ViolationDetector <|-- det_20
    class det_21["Python Complex Undocumented"]
    ViolationDetector <|-- det_21
    class det_22["Python Explicit Silence"]
    ViolationDetector <|-- det_22
    class det_23["Python Idiom"]
    ViolationDetector <|-- det_23
    class det_24["Python Practicality"]
    ViolationDetector <|-- det_24
    class det_25["Python Premature Impl"]
    ViolationDetector <|-- det_25
    class det_26["Python Simple Documented"]
    ViolationDetector <|-- det_26
    class det_27["Python Todo Stub"]
    ViolationDetector <|-- det_27
    class det_28["Short Variable Names"]
    ViolationDetector <|-- det_28
    class det_29["Sparse Code"]
    ViolationDetector <|-- det_29
    class det_30["Star Import"]
    ViolationDetector <|-- det_30
Analysis Pipeline
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 50, "rankSpacing": 70}}}%%
flowchart TD
Source(["Source Code"]) --> Parse["Parse & Tokenize"]
Parse --> Metrics["Compute Metrics"]
Metrics --> Pipeline{"30 Detectors"}
Pipeline --> Collect["Aggregate Violations"]
Collect --> Result(["AnalysisResult<br/>20 principles"])
Analysis States
%%{init: {"theme": "base"}}%%
stateDiagram-v2
    [*] --> Ready
    Ready --> Parsing : analyze(code)
    Parsing --> Computing : AST ready
    Computing --> Detecting : metrics ready
    Detecting --> Reporting : 30 detectors run
    Reporting --> [*] : AnalysisResult
    Parsing --> Reporting : parse error (best-effort)

Configuration

languages:
  python:
    enabled: true
    pipeline:
      - type: cyclomatic_complexity
        max_cyclomatic_complexity: 10
      - type: complex_one_liners
        max_for_clauses: 1
        max_line_length: 120
      - type: nesting_depth
        max_nesting_depth: 3
      - type: long_functions
        max_function_length: 50
      - type: short_variable_names
        min_identifier_length: 3
        allowed_loop_names: ['i', 'j', 'k', 'x', 'y']
      - type: god_classes
        max_methods: 10
        max_class_length: 300
      - type: magic_methods
        max_magic_methods: 3
      - type: deep_inheritance
        max_depth: 3
      - type: feature_envy
        min_occurrences: 3
      - type: class_size
        max_class_length: 300
      - type: magic_number
        max_magic_numbers: 0
      - type: line_length
        max_line_length: 88
      - type: sparse_code
        max_statements_per_line: 1
        min_blank_lines_between_defs: 1
      - type: consistency
        max_naming_styles: 1
      - type: explicitness
        require_type_hints: True
      - type: namespace_usage
        max_top_level_symbols: 25
        max_exports: 20
Start relaxed, tighten over time

For legacy codebases, start with max_cyclomatic_complexity: 15 and max_function_length: 80, then lower thresholds as you remediate.

See Also