10BC0 Add pipeline API by adriangb · Pull Request #9459 · pydantic/pydantic · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
e7eb43c
Add pipeline API
adriangb May 20, 2024
7d78407
port to python 3.10
adriangb May 20, 2024
6a1622d
port to python 3.10
adriangb May 20, 2024
947e920
fix syntax
adriangb May 20, 2024
b3fe1c4 8000
handle slots
adriangb May 20, 2024
a6d56cc
Remove match
adriangb May 21, 2024
42505df
Remove match
adriangb May 21, 2024
b2855d0
ignore warning
adriangb May 21, 2024
aafb856
fix import
adriangb May 21, 2024
0bd8b39
fix union
adriangb May 21, 2024
697833f
fix union
adriangb May 21, 2024
d767731
sort imports
adriangb May 21, 2024
8abb6e4
move
adriangb May 21, 2024
217b11d
move
adriangb May 21, 2024
89c46a1
add missing file
adriangb May 21, 2024
6e91a32
namespace
adriangb May 23, 2024
8e4d535
initial tests
sydney-runkle May 29, 2024
ada5853
add more operators
adriangb May 30, 2024
8742e9e
Add json schema tests, add section mapping existing validators
adriangb May 31, 2024
f55b6e1
move things around for expeirmental pattern
sydney-runkle May 31, 2024
7132bae
fix docs tests
sydney-runkle May 31, 2024
0444fc9
maybe fix 3.9 test
sydney-runkle May 31, 2024
1a8e505
use typing Pattern
sydney-runkle May 31, 2024
d979841
add PydanticExperimentalWarning
sydney-runkle May 31, 2024
fadf3bb
ignore warnings, for some reason pytestmark wasn't working
sydney-runkle May 31, 2024
1699f35
3.8 friendly removesuffix
sydney-runkle May 31, 2024
d0a9372
Apply docs suggestions from code review
sydney-runkle Jun 4, 2024
bed0752
add __all__
adriangb Jun 4, 2024
eb61549
rename class to pipeline
adriangb Jun 4, 2024
a18a4df
get rid of on_lambda_err
adriangb Jun 4, 2024
34663fe
pr feedback
adriangb Jun 4, 2024
dff9ad9
make transform use the field type instead of any
adriangb Jun 4, 2024
479ab3c
add import
adriangb Jun 4, 2024
7b49219
rename parse() -> validate_as()
adriangb Jun 4, 2024
51bcad6
rename internal classes
adriangb Jun 4, 2024
13b1721
make Pipeline _Pipeline
adriangb Jun 4, 2024
b8573b5
Remove namespaces
adriangb Jun 4, 2024
888c4ed
more test
adriangb Jun 4, 2024
141c8b6
use ellipsis
sydney-runkle Jun 4, 2024
9d4194b
updating imports from internal test
sydney-runkle Jun 4, 2024
128d4ea
maybe fixing zoneinfo tests, switching up validate_as annotation again
sydney-runkle Jun 4, 2024
1c7302d
docs and linting
sydney-runkle Jun 4, 2024
88dcb75
removing tzinfo stuff :(
sydney-runkle Jun 5, 2024
19a3ee6
a bit more explanation
sydney-runkle Jun 5, 2024
0652472
api docs update
sydney-runkle Jun 5, 2024
4ccf4e5
Additional Test Cases for Experimental Pipeline API (#9566)
dAIsySHEng1 Jun 5, 2024
bad0a1a
fix common predicates + add tests
sydney-runkle Jun 5, 2024
a9d1099
remove unneeded line
sydney-runkle Jun 5, 2024
14e9944
update to version policy docs
sydney-runkle Jun 5, 2024
42a2708
skip linting
sydney-runkle Jun 5, 2024
021604f
fix type hint for _Pipeline.then
adriangb Jun 5, 2024
38a2730
Apply suggestions from code review
sydney-runkle Jun 5, 2024
0c36b7c
Update pydantic/experimental/pipeline.py
sydney-runkle Jun 5, 2024
8d46b21
add public todo
sydney-runkle Jun 5, 2024
a46c2e3
move predicate up
sydney-runkle Jun 5, 2024
7386d69
new idea for overload
sydney-runkle Jun 5, 2024
dc07b50
test fixes
sydney-runkle Jun 5, 2024
cbb216b
update test cases with comments
sydney-runkle Jun 5, 2024
581cbe8
no freeze notes
sydney-runkle Jun 5, 2024
c3a008f
suggested frozen change
sydney-runkle Jun 5, 2024
26c5325
add test
adriangb Jun 5, 2024
166df3d
add more assertions
adriangb Jun 5, 2024
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
1 change: 1 addition & 0 deletions docs/api/experimental.md
8000
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: pydantic.experimental
76 changes: 76 additions & 0 deletions docs/concepts/experimental.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Experimental Features

In this section you will find documentation for new, experimental features in Pydantic. These features are subject to change or removal, and we are looking for feedback and suggestions before making them a permanent part of Pydantic.

<!-- TODO: (@sydney-runkle) add link to versioning policy for experimental features -->

## Pipeline API

Pydantic v2.8.0 introduced an experimental "pipeline" API that allows composing parsing, constraints and transformations in a more type-safe manner than existing APIs. This API is subject to change or removal, we are looking for feedback and suggestions before making it a permanent part of Pydantic.

```python
from __future__ import annotations

from datetime import datetime

from typing_extensions import Annotated

from pydantic import BaseModel
from pydantic.experimental.pipeline import parse, parse_defer


class User(BaseModel):
name: Annotated[str, parse(str).str.lower()] # (1)!
age: Annotated[int, parse(int).gt(0)] # (2)!
username: Annotated[str, parse(str).str.pattern(r'[a-z]+')] # (3)!
password: Annotated[
str,
parse(str)
.transform(str.lower)
.predicate(lambda x: x != 'password'), # (4)!
]
favorite_number: Annotated[ # (5)!
int,
(parse(int) | parse(str).str.strip().parse(int)).gt(0),
]
friends: Annotated[list[User], parse().len(0, 100)] # (6)!
family: Annotated[ # (7)!
list[User],
parse_defer(lambda: list[User]).transform(lambda x: x[1:]),
]
bio: Annotated[
datetime, parse(int).transform(lambda x: x / 1_000_000).parse() # (8)!
]
```

1. Lowercase a string.
2. Constrain an integer to be greater than zero.
3. Constrain a string to match a regex pattern.
4. You can also use the lower level transform, constrain and predicate methods.
5. Use the `|` or `&` operators to combine steps (like a logical OR or AND).
6. Calling `parse()` with no arguments implies `parse(<field type>)`. Use `parse(Any)` to accept any type.
7. For recursive types you can use `parse_defer` to reference the type itself before it's defined.
8. You can call `parse()` before or after other steps to do pre or post processing.

### Mapping from `BeforeValidator`, `AfterValidator` and `WrapValidator`

The `parse` method is a more type-safe way to define `BeforeValidator`, `AfterValidator` and `WrapValidator`:

```python
from typing_extensions import Annotated

from pydantic.experimental.pipeline import parse, transform

# BeforeValidator
Annotated[int, parse(str).str.strip().parse()] # (1)!
# AfterValidator
Annotated[int, transform(lambda x: x * 2)] # (2)!
# WrapValidator
Annotated[
int, parse(str).str.strip().parse().transform(lambda x: x * 2) # (3)!
]
```

1. Strip whitespace from a string before parsing it as an integer.
2. Multiply an integer by 2 after parsing it.
3. Strip whitespace from a string, parse it as an integer, then multiply it by 2.
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ nav:
- Settings Management: concepts/pydantic_settings.md
- Performance: concepts/performance.md
- Pydantic Plugins: concepts/plugins.md
- Experimental: concepts/experimental.md
- API Documentation:
- Pydantic:
- BaseModel: api/base_model.md
Expand All @@ -124,6 +125,7 @@ nav:
- Version Information: api/version.md
- Pydantic Plugins: api/plugin.md
- Annotated Handlers: api/annotated_handlers.md
- Experimental: api/experimental.md
- Pydantic Core:
- pydantic_core: api/pydantic_core.md
- pydantic_core.core_schema: api/pydantic_core_schema.md
Expand Down
9 changes: 8 additions & 1 deletion pydantic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@
from .type_adapter import TypeAdapter
from .types import *
from .validate_call_decorator import validate_call
from .warnings import PydanticDeprecatedSince20, PydanticDeprecatedSince26, PydanticDeprecationWarning
from .warnings import (
PydanticDeprecatedSince20,
PydanticDeprecatedSince26,
PydanticDeprecationWarning,
PydanticExperimentalWarning,
)

# this encourages pycharm to import `ValidationError` from here, not pydantic_core
ValidationError = pydantic_core.ValidationError
Expand Down Expand Up @@ -203,6 +208,7 @@
'PydanticDeprecatedSince20',
'PydanticDeprecatedSince26',
'PydanticDeprecationWarning',
'PydanticExperimentalWarning',
# annotated handlers
'GetCoreSchemaHandler',
'GetJsonSchemaHandler',
Expand Down Expand Up @@ -354,6 +360,7 @@
'PydanticDeprecatedSince20': (__spec__.parent, '.warnings'),
'PydanticDeprecatedSince26': (__spec__.parent, '.warnings'),
'PydanticDeprecationWarning': (__spec__.parent, '.warnings'),
'PydanticExperimentalWarning': (__spec__.parent, '.warnings'),
# annotated handlers
'GetCoreSchemaHandler': (__spec__.parent, '.annotated_handlers'),
'GetJsonSchemaHandler': (__spec__.parent, '.annotated_handlers'),
Expand Down
2 changes: 1 addition & 1 deletion pydantic/_internal/_generate_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ def _apply_annotations(
pydantic_js_annotation_functions: list[GetJsonSchemaFunction] = []

def inner_handler(obj: Any) -> CoreSchema:
from_property = self._generate_schema_from_property(obj, obj)
from_property = self._generate_schema_from_property(obj, source_type)
if from_property is None:
schema = self._generate_schema_inner(obj)
else:
Expand Down
3 changes: 0 additions & 3 deletions pydantic/_internal/_internal_dataclass.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import sys
from typing import Any, Dict

dataclass_kwargs: Dict[str, Any]

# `slots` is available on Python >= 3.10
if sys.version_info >= (3, 10):
Expand Down
10 changes: 10 additions & 0 deletions pydantic/experimental/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""The "experimental" module of pydantic contains potential new features that are subject to change."""

import warnings

from pydantic.warnings import PydanticExperimentalWarning

warnings.warn(
'This module is experimental, its contents are subject to change and deprecation.',
category=PydanticExperimentalWarning,
)
Loading
0