Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 28 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,45 @@ USE_MATURIN = $(shell [ "$$VIRTUAL_ENV" != "" ] && (which maturin))
.uv:
@uv -V || echo 'Please install uv: https://docs.astral.sh/uv/getting-started/installation/'

.PHONY: .pre-commit ## Check that pre-commit is installed
.pre-commit:
@pre-commit -V || echo 'Please install pre-commit: https://pre-commit.com/'

.PHONY: install
install: .uv .pre-commit
uv pip install -U wheel
.PHONY: install ## Install the package, dependencies, and pre-commit for local development
install: .uv
uv sync --frozen --group all
uv pip install -v -e .
pre-commit install
uv run pre-commit install --install-hooks

.PHONY: rebuild-lockfiles ## Rebuild lockfiles from scratch, updating all dependencies
rebuild-lockfiles: .uv
uv lock --upgrade

.PHONY: install-rust-coverage
.PHONY: install-rust-coverage ## Install Rust coverage tools
install-rust-coverage:
cargo install rustfilt coverage-prepare
rustup component add llvm-tools-preview

.PHONY: install-pgo
.PHONY: install-pgo ## Install Rust PGO tools
install-pgo:
rustup component add llvm-tools-preview

.PHONY: build-dev
.PHONY: build-dev ## Build the development version of the package
build-dev:
@rm -f python/pydantic_core/*.so
uv run maturin develop --uv

.PHONY: build-prod
.PHONY: build-prod ## Build the production version of the package
build-prod:
@rm -f python/pydantic_core/*.so
uv run maturin develop --uv --release

.PHONY: build-profiling
.PHONY: build-profiling ## Build the profiling version of the package
build-profiling:
@rm -f python/pydantic_core/*.so
uv run maturin develop --uv --profile profiling

.PHONY: build-coverage
.PHONY: build-coverage ## Build the coverage version of the package
build-coverage:
@rm -f python/pydantic_core/*.so
RUSTFLAGS='-C instrument-coverage' uv run maturin develop --uv --release

.PHONY: build-pgo
.PHONY: build-pgo ## Build the PGO version of the package
build-pgo:
@rm -f python/pydantic_core/*.so
$(eval PROFDATA := $(shell mktemp -d))
Expand All @@ -69,44 +64,44 @@ build-pgo:
@rm -rf $(PROFDATA)


.PHONY: build-wasm
.PHONY: build-wasm ## Build the WebAssembly version of the package
build-wasm:
@echo 'This requires python 3.12, maturin and emsdk to be installed'
uv run maturin build --release --target wasm32-unknown-emscripten --out dist -i 3.12
ls -lh dist

.PHONY: format
.PHONY: format ## Auto-format rust and python source files
format:
uv run ruff check --fix $(sources)
uv run ruff format $(sources)
cargo fmt

.PHONY: lint-python
.PHONY: lint-python ## Lint python source files
lint-python:
uv run ruff check $(sources)
uv run ruff format --check $(sources)
uv run griffe dump -f -d google -LWARNING -o/dev/null python/pydantic_core
$(mypy-stubtest)

.PHONY: lint-rust
.PHONY: lint-rust ## Lint rust source files
lint-rust:
cargo fmt --version
cargo fmt --all -- --check
cargo clippy --version
cargo clippy --tests -- -D warnings

.PHONY: lint
.PHONY: lint ## Lint rust and python source files
lint: lint-python lint-rust

.PHONY: pyright
.PHONY: pyright ## Perform type-checking with pyright
pyright:
uv run pyright

.PHONY: test
.PHONY: test ## Run all tests
test:
uv run pytest

.PHONY: testcov
.PHONY: testcov ## Run tests and generate a coverage report
testcov: build-coverage
@rm -rf htmlcov
@mkdir -p htmlcov
Expand All @@ -115,10 +110,10 @@ testcov: build-coverage
coverage html -d htmlcov/python
coverage-prepare html python/pydantic_core/*.so

.PHONY: all
.PHONY: all ## Run the standard set of checks performed in CI
all: format build-dev lint test

.PHONY: clean
.PHONY: clean ## Clear local caches and build artifacts
clean:
rm -rf `find . -name __pycache__`
rm -f `find . -type f -name '*.py[co]' `
Expand All @@ -133,3 +128,10 @@ clean:
rm -rf build
rm -rf perf.data*
rm -rf python/pydantic_core/*.so

.PHONY: help ## Display this message
help:
@grep -E \
'^.PHONY: .*?## .*$$' $(MAKEFILE_LIST) | \
sort | \
awk 'BEGIN {FS = ".PHONY: |## "}; {printf "\033[36m%-19s\033[0m %s\n", $$2, $$3}'
55 changes: 36 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,35 +69,52 @@ except ValidationError as e:

## Getting Started

You'll need rust stable [installed](https://rustup.rs/), or rust nightly if you want to generate accurate coverage.
### Prerequisites

With rust and python 3.9+ installed, compiling pydantic-core should be possible with roughly the following:
You'll need:
1. **[Rust](https://rustup.rs/)** - Rust stable (or nightly for coverage)
2. **[uv](https://docs.astral.sh/uv/getting-started/installation/)** - Fast Python package manager (will install Python 3.9+ automatically)
3. **[git](https://git-scm.com/)** - For version control
4. **[make](https://www.gnu.org/software/make/)** - For running development commands (or use `nmake` on Windows)

### Quick Start

```bash
# clone this repo or your fork
# Clone the repository (or from your fork)
git clone [email protected]:pydantic/pydantic-core.git
cd pydantic-core
# create a new virtual env
python3 -m venv env
source env/bin/activate
# install dependencies and install pydantic-core

# Install all dependencies using uv, setup pre-commit hooks, and build the development version
make install
```

That should be it, the example shown above should now run.
Verify your installation by running:

```bash
make
```

This runs a full development cycle: formatting, building, linting, and testing

### Development Commands

Run `make help` to see all available commands, or use these common ones:

```bash
make build-dev # to build the package during development
make build-prod # to perform an optimised build for benchmarking
make test # to run the tests
make testcov # to run the tests and generate a coverage report
make lint # to run the linter
make format # to format python and rust code
make all # to run to run build-dev + format + lint + test
```

You might find it useful to look at [`python/pydantic_core/_pydantic_core.pyi`](./python/pydantic_core/_pydantic_core.pyi) and
[`python/pydantic_core/core_schema.py`](./python/pydantic_core/core_schema.py) for more information on the python API,
beyond that, [`tests/`](./tests) provide a large number of examples of usage.
### Useful Resources

If you want to contribute to pydantic-core, you'll want to use some other make commands:
* `make build-dev` to build the package during development
* `make build-prod` to perform an optimised build for benchmarking
* `make test` to run the tests
* `make testcov` to run the tests and generate a coverage report
* `make lint` to run the linter
* `make format` to format python and rust code
* `make` to run `format build-dev lint test`
* [`python/pydantic_core/_pydantic_core.pyi`](./python/pydantic_core/_pydantic_core.pyi) - Python API types
* [`python/pydantic_core/core_schema.py`](./python/pydantic_core/core_schema.py) - Core schema definitions
* [`tests/`](./tests) - Comprehensive usage examples

## Profiling

Expand Down
27 changes: 16 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ authors = [
{ name = 'David Montague', email = '[email protected]' },
{ name = 'David Hewitt', email = '[email protected]' },
{ name = 'Sydney Runkle', email = '[email protected]' },
{ name = 'Victorien Plot', email='[email protected]' },
{ name = 'Victorien Plot', email = '[email protected]' },
]
classifiers = [
'Development Status :: 3 - Alpha',
Expand All @@ -36,9 +36,7 @@ classifiers = [
'Operating System :: MacOS',
'Typing :: Typed',
]
dependencies = [
'typing-extensions>=4.14.1',
]
dependencies = ['typing-extensions>=4.14.1']
dynamic = ['readme', 'version']

[project.urls]
Expand All @@ -52,26 +50,33 @@ testing = [
{ include-group = "dev" },
'coverage',
'dirty-equals',
'inline-snapshot',
'exceptiongroup; python_version < "3.11"',
'hypothesis',
'inline-snapshot',
# numpy doesn't offer prebuilt wheels for all versions and platforms we test in CI e.g. aarch64 musllinux
'numpy; python_version < "3.13" and implementation_name == "cpython" and platform_machine == "x86_64"',
# pandas doesn't offer prebuilt wheels for all versions and platforms we test in CI e.g. aarch64 musllinux
'pandas; python_version < "3.13" and implementation_name == "cpython" and platform_machine == "x86_64"',
'pytest',
# pytest-examples currently depends on aiohttp via black; we don't want to build it on platforms like aarch64 musllinux in CI
'pytest-examples; implementation_name == "cpython" and platform_machine == "x86_64"',
'pytest-speed',
'pytest-mock',
'pytest-pretty',
'pytest-run-parallel',
'pytest-speed',
'pytest-timeout',
'python-dateutil',
# numpy doesn't offer prebuilt wheels for all versions and platforms we test in CI e.g. aarch64 musllinux
'numpy; python_version < "3.13" and implementation_name == "cpython" and platform_machine == "x86_64"',
'exceptiongroup; python_version < "3.11"',
'tzdata',
'typing-inspection>=0.4.1',
'tzdata',
]
linting = [
{ include-group = "dev" },
'griffe',
'mypy',
'pre-commit',
'pyright',
'ruff',
]
linting = [{ include-group = "dev" }, 'griffe', 'pyright', 'ruff', 'mypy']
wasm = [{ include-group = "dev" }, 'ruff']
codspeed = [
# codspeed is only run on CI, with latest version of CPython
Expand Down
Loading
Loading