Skip to content

Pydantic

Zen Principles

8 principles across 2 categories, drawn from Pydantic v2 documentation.

Correctness · 1 principle Idioms · 7 principles

Rule ID Principle Category Severity Dogma
pydantic-001 Use model_dump and model_dump_json instead of v1 serialization APIs Idioms 8 ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT
pydantic-002 Use model_validate instead of parse_obj or parse_raw Idioms 8 ZEN-RIGHT-ABSTRACTION
pydantic-003 Mutable defaults should use Field(default_factory=...) Correctness 9 ZEN-VISIBLE-STATE, ZEN-EXPLICIT-INTENT
pydantic-004 Prefer model_config over nested Config classes Idioms 7 ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT
pydantic-005 Use field_validator instead of validator Idioms 7 ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT
pydantic-006 Avoid fields; use model_fields in v2 Idioms 7 ZEN-RIGHT-ABSTRACTION, ZEN-UNAMBIGUOUS-NAME
pydantic-007 Prefer X None over Optional[X] in modern Python code Idioms 4
pydantic-008 Use from_attributes instead of orm_mode Idioms 7 ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT
pydantic-001 — Use model_dump and model_dump_json instead of v1 serialization APIs

Pydantic v2 renamed serialization APIs to make model boundaries more explicit.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT Common Violations:

  • Use model_dump and model_dump_json instead of v1 serialization APIs

Detectable Patterns:

  • re:\.(?:dict|json)\(

Recommended Fix

Use model_dump() or model_dump_json() on Pydantic models.

pydantic-002 — Use model_validate instead of parse_obj or parse_raw

v2 validation APIs center around model_validate and model_validate_json.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION Common Violations:

  • Use model_validate instead of parse_obj or parse_raw

Detectable Patterns:

  • re:\b(?:parse_obj|parse_raw|from_orm)\(

Recommended Fix

Use model_validate(), model_validate_json(), or from_attributes-compatible validation.

pydantic-003 — Mutable defaults should use Field(default_factory=...)

Plain list, dict, and set defaults are shared between instances and create state leaks.

Universal Dogmas: ZEN-VISIBLE-STATE, ZEN-EXPLICIT-INTENT Common Violations:

  • Mutable defaults should use Field(default_factory=...)

Detectable Patterns:

  • re::\s*(?:list|dict|set)\b[^=\n]*=\s*(?:\[\]|\{\}|set\(\))

Recommended Fix

Use Field(default_factory=list), dict, or set instead of a mutable literal default.

pydantic-004 — Prefer model_config over nested Config classes

Pydantic v2 consolidated model configuration into the model_config attribute.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT Common Violations:

  • Prefer model_config over nested Config classes

Detectable Patterns:

  • re:^\s*class\s+Config\s*:

Recommended Fix

Replace the nested Config class with model_config = ConfigDict(...).

pydantic-005 — Use field_validator instead of validator

v2 split validation hooks into explicit decorator families such as field_validator and model_validator.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT Common Violations:

  • Use field_validator instead of validator

Detectable Patterns:

  • re:@validator\b

Recommended Fix

Use @field_validator or @model_validator in Pydantic v2 code.

pydantic-006 — Avoid fields; use model_fields in v2

The v2 model introspection surface renamed fields to model_fields.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-UNAMBIGUOUS-NAME Common Violations:

  • Avoid fields; use model_fields in v2

Detectable Patterns:

  • re:\.__fields__\b

Recommended Fix

Use model_fields for field metadata lookups.

pydantic-007 — Prefer X | None over Optional[X] in modern Python code

Modern union syntax is the project standard for Python 3.12+ and keeps annotations consistent.

Universal Dogmas: ZEN-EXPLICIT-INTENT Common Violations:

  • Prefer X | None over Optional[X] in modern Python code

Detectable Patterns:

  • re:\bOptional\[

Recommended Fix

Use X | None instead of Optional[X].

pydantic-008 — Use from_attributes instead of orm_mode

Pydantic v2 renamed ORM compatibility settings to from_attributes.

Universal Dogmas: ZEN-RIGHT-ABSTRACTION, ZEN-EXPLICIT-INTENT Common Violations:

  • Use from_attributes instead of orm_mode

Detectable Patterns:

  • re:orm_mode\s*=\s*True

Recommended Fix

Configure from_attributes=True via model_config.

Detector Catalog

Correctness

Detector What It Catches Rule IDs
PydanticDefaultFactoryDetector Concrete detector binding for PydanticDefaultFactoryDetector pydantic-003

Idioms

Detector What It Catches Rule IDs
PydanticModelDumpDetector Concrete detector binding for PydanticModelDumpDetector pydantic-001
PydanticModelValidateDetector Concrete detector binding for PydanticModelValidateDetector pydantic-002
PydanticModelConfigDetector Concrete detector binding for PydanticModelConfigDetector pydantic-004
PydanticFieldValidatorDetector Concrete detector binding for PydanticFieldValidatorDetector pydantic-005
PydanticModelFieldsDetector Concrete detector binding for PydanticModelFieldsDetector pydantic-006
PydanticModernTypingDetector Concrete detector binding for PydanticModernTypingDetector pydantic-007
PydanticFromAttributesDetector Concrete detector binding for PydanticFromAttributesDetector pydantic-008
Principle → Detector Wiring
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 40, "rankSpacing": 60}}}%%
graph TD
pydantic_001["pydantic-001<br/>Use model_dump and model_..."]
pydantic_002["pydantic-002<br/>Use model_validate instea..."]
pydantic_003["pydantic-003<br/>Mutable defaults should u..."]
pydantic_004["pydantic-004<br/>Prefer model_config over ..."]
pydantic_005["pydantic-005<br/>Use field_validator inste..."]
pydantic_006["pydantic-006<br/>Avoid __fields__; use mod..."]
pydantic_007["pydantic-007<br/>Prefer X | None over Opti..."]
pydantic_008["pydantic-008<br/>Use from_attributes inste..."]
det_PydanticDefaultFactoryDetector["Pydantic Default<br/>Factory"]
pydantic_003 --> det_PydanticDefaultFactoryDetector
det_PydanticFieldValidatorDetector["Pydantic Field<br/>Validator"]
pydantic_005 --> det_PydanticFieldValidatorDetector
det_PydanticFromAttributesDetector["Pydantic From<br/>Attributes"]
pydantic_008 --> det_PydanticFromAttributesDetector
det_PydanticModelConfigDetector["Pydantic Model<br/>Config"]
pydantic_004 --> det_PydanticModelConfigDetector
det_PydanticModelDumpDetector["Pydantic Model<br/>Dump"]
pydantic_001 --> det_PydanticModelDumpDetector
det_PydanticModelFieldsDetector["Pydantic Model<br/>Fields"]
pydantic_006 --> det_PydanticModelFieldsDetector
det_PydanticModelValidateDetector["Pydantic Model<br/>Validate"]
pydantic_002 --> det_PydanticModelValidateDetector
det_PydanticModernTypingDetector["Pydantic Modern<br/>Typing"]
pydantic_007 --> det_PydanticModernTypingDetector
Detector Class Hierarchy
%%{init: {"theme": "base"}}%%
classDiagram
    direction TB
    class ViolationDetector {
        <<abstract>>
        +detect(context, config)
    }
    class det_01["Pydantic Default Factory"]
    ViolationDetector <|-- det_01
    class det_02["Pydantic Field Validator"]
    ViolationDetector <|-- det_02
    class det_03["Pydantic From Attributes"]
    ViolationDetector <|-- det_03
    class det_04["Pydantic Model Config"]
    ViolationDetector <|-- det_04
    class det_05["Pydantic Model Dump"]
    ViolationDetector <|-- det_05
    class det_06["Pydantic Model Fields"]
    ViolationDetector <|-- det_06
    class det_07["Pydantic Model Validate"]
    ViolationDetector <|-- det_07
    class det_08["Pydantic Modern Typing"]
    ViolationDetector <|-- det_08
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{"8 Detectors"}
Pipeline --> Collect["Aggregate Violations"]
Collect --> Result(["AnalysisResult<br/>8 principles"])
Analysis States
%%{init: {"theme": "base"}}%%
stateDiagram-v2
    [*] --> Ready
    Ready --> Parsing : analyze(code)
    Parsing --> Computing : AST ready
    Computing --> Detecting : metrics ready
    Detecting --> Reporting : 8 detectors run
    Reporting --> [*] : AnalysisResult
    Parsing --> Reporting : parse error (best-effort)

Configuration

languages:
  pydantic:
    enabled: true
    pipeline:

See Also