bump-pydantic
bump-pydantic is a command-line tool designed to automatically convert Pydantic V1 codebases to Pydantic V2 syntax. It helps users migrate their models, validators, and settings from the old API to the new one, facilitating a smoother transition. The current version is 0.8.0, and it has a regular release cadence, with several minor versions released frequently to add new features and fix issues.
Common errors
-
cst.ParserSyntaxError: Syntax error while parsing the provided code.
cause The `bump-pydantic` tool relies on `libcst` to parse your Python code. This error occurs if `libcst` cannot parse a file due to invalid Python syntax, an unsupported syntax feature (e.g., very new Python versions or complex annotations), or a bug in `libcst` itself.fixFirst, ensure your Python code is syntactically correct and can be run by the interpreter. If the code is valid, try updating `bump-pydantic` (which often brings updated `libcst` versions). If the issue persists, isolate the problematic code snippet and simplify it if possible, or report the issue to the `libcst` or `bump-pydantic` maintainers. -
No files were modified by bump-pydantic.
cause This message (improved in 0.8.0) indicates that the tool ran but found no Pydantic V1 constructs to convert in the specified paths, or that your files were already in Pydantic V2 format, or that files were excluded by `--ignore` patterns.fixDouble-check that you are running `bump-pydantic` on the correct directory or files that contain Pydantic V1 code. Verify that the files are not excluded by any `.bump-pydantic-ignore` or command-line ignore patterns. If you expect changes, manually review your code to confirm it indeed uses Pydantic V1 syntax. -
bump-pydantic: command not found
cause The `bump-pydantic` executable is not in your system's PATH, typically because the package was not installed or installed into an environment not currently active.fixEnsure you have installed the package correctly using `pip install bump-pydantic`. If using a virtual environment, activate it before running the command. If installed, you might need to specify the full path to the executable or ensure your PATH environment variable is set correctly.
Warnings
- gotcha By default, `bump-pydantic` modifies files in place without a backup. Always commit your changes to version control (e.g., Git) before running the tool, or use the `--diff` argument to review changes before applying them.
- gotcha The tool uses `libcst` for Abstract Syntax Tree (AST) transformation. While powerful, it may encounter `ParserSyntaxError` if your code contains advanced or non-standard Python syntax not fully supported by `libcst` (e.g., very new Python features or malformed code).
- gotcha While `bump-pydantic` automates many conversions, Pydantic V2 introduces fundamental changes that cannot always be perfectly translated automatically (e.g., `model_validator`, `field_validator` semantics, or behavior of `Optional` fields with `Field` defaults). Always manually review the generated code for correctness and Pydantic V2 best practices.
- gotcha In version 0.7.0, the `example` argument in `Field` was converted to `examples` (a list), aligning with OpenAPI specification changes in Pydantic V2. Previous versions might not handle this, or only handle `example` as a single value.
Install
-
pip install bump-pydantic
Quickstart
import os
# Create a dummy Pydantic V1 file for demonstration
with open('my_model_v1.py', 'w') as f:
f.write(
"""from typing import Optional
from pydantic import BaseModel, Field, EmailStr
class User(BaseModel):
name: str = Field(..., min_length=1)
email: EmailStr
age: Optional[int] = Field(None, example=30)
"""
)
# Run bump-pydantic on the created file
# In a real scenario, you would run this command in your terminal
# and typically on a directory, e.g., `bump-pydantic .`
# For this quickstart, we'll demonstrate using a single file.
print("Running bump-pydantic on my_model_v1.py...")
os.system("bump-pydantic my_model_v1.py")
# Optionally, print the modified content
with open('my_model_v1.py', 'r') as f:
print("\n--- Modified my_model_v1.py ---")
print(f.read())
# Clean up the dummy file
os.remove('my_model_v1.py')