Skip to main content

Flake8 Pydantic

Python versions PyPI version Ruff

A flake8 plugin to check Pydantic related code.

Class detection

flake8_pydantic parses the AST to emit linting errors. As such, it cannot accurately determine if a class is defined as a Pydantic model. However, it tries its best, using the following heuristics:

  • The class inherits from BaseModel or RootModel.
  • The class has a model_config attribute set.
  • The class has a field defined with the Field function.
  • The class has a field making use of Annotated.
  • The class makes use of Pydantic decorators, such as computed_field or model_validator.
  • The class overrides any of the Pydantic methods, such as model_dump.

Error codes

PYD001 - Positional argument for Field default argument

Raise an error if the default argument of the Field function is positional.

class Model(BaseModel):
    foo: int = Field(1)

Although allowed at runtime by Pydantic, it does not comply with the typing specification (PEP 681) and type checkers will not be able to synthesize a correct __init__ method.

Instead, consider using an explicit keyword argument:

class Model(BaseModel):
    foo: int = Field(default=1)

PYD002 - Non-annotated attribute inside Pydantic model

Raise an error if a non-annotated attribute is defined inside a Pydantic model class.

class Model(BaseModel):
    foo = 1  # Will error at runtime

PYD003 - Unecessary Field call to specify a default value

Raise an error if the Field function is used only to specify a default value.

class Model(BaseModel):
    foo: int = Field(default=1)

Instead, consider specifying the default value directly:

class Model(BaseModel):
    foo: int = 1

PYD004 - Default argument specified in annotated

Raise an error if the default argument of the Field function is used together with Annotated.

class Model(BaseModel):
    foo: Annotated[int, Field(default=1, description="desc")]

To make type checkers aware of the default value, consider specifying the default value directly:

class Model(BaseModel):
    foo: Annotated[int, Field(description="desc")] = 1

PYD005 - Field name overrides annotation

Raise an error if the field name clashes with the annotation.

from datetime import date

class Model(BaseModel):
    date: date | None = None

Because of how Python evaluates annotated assignments, unexpected issues can happen when using an annotation name that clashes with a field name. Pydantic will try its best to warn you about such issues, but can fail in complex scenarios (and the issue may even be silently ignored).

Instead, consider, using an alias or referencing your type under a different name:

from datetime import date

date_ = date

class Model(BaseModel):
    date_aliased: date | None = Field(default=None, alias="date")
    # or
    date: date_ | None = None

PYD010 - Usage of __pydantic_config__

Raise an error if a Pydantic configuration is set with __pydantic_config__.

class Model(TypedDict):
    __pydantic_config__ = {}  # Type checkers will emit an error

Although allowed at runtime by Python, type checkers will emit an error as it is not allowed to assign values when defining a TypedDict.

Instead, consider using the with_config decorator:

@with_config({"str_to_lower": True})
class Model(TypedDict):
    pass

And many more to come.

Roadmap

Once the rules of the plugin gets stable, the goal will be to implement them in Ruff, with autofixes when possible.

Metadata

Release files for flake8-pydantic 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flake8-pydantic 0.4.0
File Size Uploaded
flake8_pydantic-0.4.0.tar.gz 11.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flake8-pydantic 0.4.0
File Interpreter ABI Platform
flake8_pydantic-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.9 kB

Release files / flake8_pydantic-0.4.0.tar.gz

Download URL flake8_pydantic-0.4.0.tar.gz
Size 11.1 kB
Tags Source
SHA-256 checksum
How to use checksums
80acd63cf62fc2f6ffd242617ef18f3919f68c58a4f1fe57db5b39c7d783712f
BLAKE2b-256 checksum
How to use checksums
6569dac5ed766d6fe130a1ed19d4b55e8fc8a02e9c354d22d1040b0520c6ec41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.12.7

Release files / flake8_pydantic-0.4.0-py3-none-any.whl

Download URL flake8_pydantic-0.4.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46b554d246317ca2606e6e0b5dcaf535094b0449d4e473f7fcf918d15c3c4df8
BLAKE2b-256 checksum
How to use checksums
a8eeb7d71d03d93599f2939a2fa51eafa6d7905205a9c9852de4684f26a4cb7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.12.7

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page