Skip to content

Commit f6f4cbe

Browse files
committed
Merge branch 'main' into pyo3-main
2 parents 28fcc97 + ed43fb3 commit f6f4cbe

26 files changed

+1040
-766
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pydantic-core"
3-
version = "0.31.0"
3+
version = "0.33.0"
44
edition = "2021"
55
license = "MIT"
66
homepage = "https://github.com/pydantic/pydantic-core"

pydantic_core/core_schema.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ def dict_not_none(**kwargs: Any) -> Any:
2626
class CoreConfig(TypedDict, total=False):
2727
title: str
2828
strict: bool
29-
# higher priority configs take precedence of over lower, if priority matches the two configs are merged, default 0
30-
config_choose_priority: int
31-
# if configs are merged, which should take precedence, default 0, default means child takes precedence
32-
config_merge_priority: int
3329
# settings related to typed dicts, model fields, dataclass fields
3430
extra_fields_behavior: ExtraBehavior
3531
typed_dict_total: bool # default: True
@@ -1188,7 +1184,6 @@ class ListSchema(TypedDict, total=False):
11881184
min_length: int
11891185
max_length: int
11901186
strict: bool
1191-
allow_any_iter: bool
11921187
ref: str
11931188
metadata: Any
11941189
serialization: IncExSeqOrElseSerSchema
@@ -1200,7 +1195,6 @@ def list_schema(
12001195
min_length: int | None = None,
12011196
max_length: int | None = None,
12021197
strict: bool | None = None,
1203-
allow_any_iter: bool | None = None,
12041198
ref: str | None = None,
12051199
metadata: Any = None,
12061200
serialization: IncExSeqOrElseSerSchema | None = None,
@@ -1221,7 +1215,6 @@ def list_schema(
12211215
min_length: The value must be a list with at least this many items
12221216
max_length: The value must be a list with at most this many items
12231217
strict: The value must be a list with exactly this many items
1224-
allow_any_iter: Whether the value can be any iterable
12251218
ref: optional unique identifier of the schema, used to reference the schema in other places
12261219
metadata: Any other information you want to include with the schema, not used by pydantic-core
12271220
serialization: Custom serialization schema
@@ -1232,7 +1225,6 @@ def list_schema(
12321225
min_length=min_length,
12331226
max_length=max_length,
12341227
strict=strict,
1235-
allow_any_iter=allow_any_iter,
12361228
ref=ref,
12371229
metadata=metadata,
12381230
serialization=serialization,
@@ -1353,7 +1345,6 @@ class SetSchema(TypedDict, total=False):
13531345
items_schema: CoreSchema
13541346
min_length: int
13551347
max_length: int
1356-
generator_max_length: int
13571348
strict: bool
13581349
ref: str
13591350
metadata: Any
@@ -1365,7 +1356,6 @@ def set_schema(
13651356
*,
13661357
min_length: int | None = None,
13671358
max_length: int | None = None,
1368-
generator_max_length: int | None = None,
13691359
strict: bool | None = None,
13701360
ref: str | None = None,
13711361
metadata: Any = None,
@@ -1388,9 +1378,6 @@ def set_schema(
13881378
items_schema: The value must be a set with items that match this schema
13891379
min_length: The value must be a set with at least this many items
13901380
max_length: The value must be a set with at most this many items
1391-
generator_max_length: At most this many items will be read from a generator before failing validation
1392-
This is important because generators can be infinite, and even with a `max_length` on the set,
1393-
an infinite generator could run forever without producing more than `max_length` distinct items.
13941381
strict: The value must be a set with exactly this many items
13951382
ref: optional unique identifier of the schema, used to reference the schema in other places
13961383
metadata: Any other information you want to include with the schema, not used by pydantic-core
@@ -1401,7 +1388,6 @@ def set_schema(
14011388
items_schema=items_schema,
14021389
min_length=min_length,
14031390
max_length=max_length,
1404-
generator_max_length=generator_max_length,
14051391
strict=strict,
14061392
ref=ref,
14071393
metadata=metadata,
@@ -1414,7 +1400,6 @@ class FrozenSetSchema(TypedDict, total=False):
14141400
items_schema: CoreSchema
14151401
min_length: int
14161402
max_length: int
1417-
generator_max_length: int
14181403
strict: bool
14191404
ref: str
14201405
metadata: Any
@@ -1426,7 +1411,6 @@ def frozenset_schema(
14261411
*,
14271412
min_length: int | None = None,
14281413
max_length: int | None = None,
1429-
generator_max_length: int | None = None,
14301414
strict: bool | None = None,
14311415
ref: str | None = None,
14321416
metadata: Any = None,
@@ -1449,7 +1433,6 @@ def frozenset_schema(
14491433
items_schema: The value must be a frozenset with items that match this schema
14501434
min_length: The value must be a frozenset with at least this many items
14511435
max_length: The value must be a frozenset with at most this many items
1452-
generator_max_length: The value must generate a frozenset with at most this many items
14531436
strict: The value must be a frozenset with exactly this many items
14541437
ref: optional unique identifier of the schema, used to reference the schema in other places
14551438
metadata: Any other information you want to include with the schema, not used by pydantic-core
@@ -1460,7 +1443,6 @@ def frozenset_schema(
14601443
items_schema=items_schema,
14611444
min_length=min_length,
14621445
max_length=max_length,
1463-
generator_max_length=generator_max_length,
14641446
strict=strict,
14651447
ref=ref,
14661448
metadata=metadata,

src/build_tools.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::borrow::Cow;
2-
use std::cmp::Ordering;
32
use std::error::Error;
43
use std::fmt;
54

@@ -281,43 +280,3 @@ impl ExtraBehavior {
281280
Ok(res)
282281
}
283282
}
284-
285-
pub(crate) fn build_model_config<'a>(
286-
py: Python<'a>,
287-
schema: &'a PyDict,
288-
parent_config: Option<&'a PyDict>,
289-
) -> PyResult<Option<&'a PyDict>> {
290-
let child_config: Option<&PyDict> = schema.get_as(intern!(py, "config"))?;
291-
match (parent_config, child_config) {
292-
(Some(parent), None) => Ok(Some(parent)),
293-
(None, Some(child)) => Ok(Some(child)),
294-
(None, None) => Ok(None),
295-
(Some(parent), Some(child)) => {
296-
let key = intern!(py, "config_choose_priority");
297-
let parent_choose: i32 = parent.get_as(key)?.unwrap_or_default();
298-
let child_choose: i32 = child.get_as(key)?.unwrap_or_default();
299-
match parent_choose.cmp(&child_choose) {
300-
Ordering::Greater => Ok(Some(parent)),
301-
Ordering::Less => Ok(Some(child)),
302-
Ordering::Equal => {
303-
let key = intern!(py, "config_merge_priority");
304-
let parent_merge: i32 = parent.get_as(key)?.unwrap_or_default();
305-
let child_merge: i32 = child.get_as(key)?.unwrap_or_default();
306-
match parent_merge.cmp(&child_merge) {
307-
Ordering::Greater => {
308-
let new_child = child.copy()?;
309-
new_child.update(parent.as_mapping())?;
310-
Ok(Some(new_child))
311-
}
312-
// otherwise child is the winner
313-
_ => {
314-
let new_parent = parent.copy()?;
315-
new_parent.update(child.as_mapping())?;
316-
Ok(Some(new_parent))
317-
}
318-
}
319-
}
320-
}
321-
}
322-
}
323-
}

src/input/input_abstract.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{PyMultiHostUrl, PyUrl};
88

99
use super::datetime::{EitherDate, EitherDateTime, EitherTime, EitherTimedelta};
1010
use super::return_enums::{EitherBytes, EitherString};
11-
use super::{GenericArguments, GenericCollection, GenericIterator, GenericMapping, JsonInput};
11+
use super::{GenericArguments, GenericIterable, GenericIterator, GenericMapping, JsonInput};
1212

1313
#[derive(Debug, Clone, Copy)]
1414
pub enum InputType {
@@ -166,58 +166,60 @@ pub trait Input<'a>: fmt::Debug + ToPyObject {
166166
self.validate_dict(strict)
167167
}
168168

169-
fn validate_list(&'a self, strict: bool, allow_any_iter: bool) -> ValResult<GenericCollection<'a>> {
170-
if strict && !allow_any_iter {
169+
fn validate_list(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
170+
if strict {
171171
self.strict_list()
172172
} else {
173-
self.lax_list(allow_any_iter)
173+
self.lax_list()
174174
}
175175
}
176-
fn strict_list(&'a self) -> ValResult<GenericCollection<'a>>;
176+
fn strict_list(&'a self) -> ValResult<GenericIterable<'a>>;
177177
#[cfg_attr(has_no_coverage, no_coverage)]
178-
fn lax_list(&'a self, _allow_any_iter: bool) -> ValResult<GenericCollection<'a>> {
178+
fn lax_list(&'a self) -> ValResult<GenericIterable<'a>> {
179179
self.strict_list()
180180
}
181181

182-
fn validate_tuple(&'a self, strict: bool) -> ValResult<GenericCollection<'a>> {
182+
fn validate_tuple(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
183183
if strict {
184184
self.strict_tuple()
185185
} else {
186186
self.lax_tuple()
187187
}
188188
}
189-
fn strict_tuple(&'a self) -> ValResult<GenericCollection<'a>>;
189+
fn strict_tuple(&'a self) -> ValResult<GenericIterable<'a>>;
190190
#[cfg_attr(has_no_coverage, no_coverage)]
191-
fn lax_tuple(&'a self) -> ValResult<GenericCollection<'a>> {
191+
fn lax_tuple(&'a self) -> ValResult<GenericIterable<'a>> {
192192
self.strict_tuple()
193193
}
194194

195-
fn validate_set(&'a self, strict: bool) -> ValResult<GenericCollection<'a>> {
195+
fn validate_set(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
196196
if strict {
197197
self.strict_set()
198198
} else {
199199
self.lax_set()
200200
}
201201
}
202-
fn strict_set(&'a self) -> ValResult<GenericCollection<'a>>;
202+
fn strict_set(&'a self) -> ValResult<GenericIterable<'a>>;
203203
#[cfg_attr(has_no_coverage, no_coverage)]
204-
fn lax_set(&'a self) -> ValResult<GenericCollection<'a>> {
204+
fn lax_set(&'a self) -> ValResult<GenericIterable<'a>> {
205205
self.strict_set()
206206
}
207207

208-
fn validate_frozenset(&'a self, strict: bool) -> ValResult<GenericCollection<'a>> {
208+
fn validate_frozenset(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
209209
if strict {
210210
self.strict_frozenset()
211211
} else {
212212
self.lax_frozenset()
213213
}
214214
}
215-
fn strict_frozenset(&'a self) -> ValResult<GenericCollection<'a>>;
215+
fn strict_frozenset(&'a self) -> ValResult<GenericIterable<'a>>;
216216
#[cfg_attr(has_no_coverage, no_coverage)]
217-
fn lax_frozenset(&'a self) -> ValResult<GenericCollection<'a>> {
217+
fn lax_frozenset(&'a self) -> ValResult<GenericIterable<'a>> {
218218
self.strict_frozenset()
219219
}
220220

221+
fn extract_generic_iterable(&'a self) -> ValResult<GenericIterable<'a>>;
222+
221223
fn validate_iter(&self) -> ValResult<GenericIterator>;
222224

223225
fn validate_date(&self, strict: bool) -> ValResult<EitherDate> {

src/input/input_json.rs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::datetime::{
1010
use super::parse_json::JsonArray;
1111
use super::shared::{float_as_int, int_as_bool, map_json_err, str_as_bool, str_as_int};
1212
use super::{
13-
EitherBytes, EitherString, EitherTimedelta, GenericArguments, GenericCollection, GenericIterator, GenericMapping,
13+
EitherBytes, EitherString, EitherTimedelta, GenericArguments, GenericIterable, GenericIterator, GenericMapping,
1414
Input, JsonArgs, JsonInput,
1515
};
1616

@@ -187,53 +187,62 @@ impl<'a> Input<'a> for JsonInput {
187187
self.validate_dict(false)
188188
}
189189

190-
fn validate_list(&'a self, _strict: bool, _allow_any_iter: bool) -> ValResult<GenericCollection<'a>> {
190+
fn validate_list(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
191191
match self {
192-
JsonInput::Array(a) => Ok(a.into()),
192+
JsonInput::Array(a) => Ok(GenericIterable::JsonArray(a)),
193193
_ => Err(ValError::new(ErrorType::ListType, self)),
194194
}
195195
}
196196
#[cfg_attr(has_no_coverage, no_coverage)]
197-
fn strict_list(&'a self) -> ValResult<GenericCollection<'a>> {
198-
self.validate_list(false, false)
197+
fn strict_list(&'a self) -> ValResult<GenericIterable<'a>> {
198+
self.validate_list(false)
199199
}
200200

201-
fn validate_tuple(&'a self, _strict: bool) -> ValResult<GenericCollection<'a>> {
201+
fn validate_tuple(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
202202
// just as in set's case, List has to be allowed
203203
match self {
204-
JsonInput::Array(a) => Ok(a.into()),
204+
JsonInput::Array(a) => Ok(GenericIterable::JsonArray(a)),
205205
_ => Err(ValError::new(ErrorType::TupleType, self)),
206206
}
207207
}
208208
#[cfg_attr(has_no_coverage, no_coverage)]
209-
fn strict_tuple(&'a self) -> ValResult<GenericCollection<'a>> {
209+
fn strict_tuple(&'a self) -> ValResult<GenericIterable<'a>> {
210210
self.validate_tuple(false)
211211
}
212212

213-
fn validate_set(&'a self, _strict: bool) -> ValResult<GenericCollection<'a>> {
213+
fn validate_set(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
214214
// we allow a list here since otherwise it would be impossible to create a set from JSON
215215
match self {
216-
JsonInput::Array(a) => Ok(a.into()),
216+
JsonInput::Array(a) => Ok(GenericIterable::JsonArray(a)),
217217
_ => Err(ValError::new(ErrorType::SetType, self)),
218218
}
219219
}
220220
#[cfg_attr(has_no_coverage, no_coverage)]
221-
fn strict_set(&'a self) -> ValResult<GenericCollection<'a>> {
221+
fn strict_set(&'a self) -> ValResult<GenericIterable<'a>> {
222222
self.validate_set(false)
223223
}
224224

225-
fn validate_frozenset(&'a self, _strict: bool) -> ValResult<GenericCollection<'a>> {
225+
fn validate_frozenset(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
226226
// we allow a list here since otherwise it would be impossible to create a frozenset from JSON
227227
match self {
228-
JsonInput::Array(a) => Ok(a.into()),
228+
JsonInput::Array(a) => Ok(GenericIterable::JsonArray(a)),
229229
_ => Err(ValError::new(ErrorType::FrozenSetType, self)),
230230
}
231231
}
232232
#[cfg_attr(has_no_coverage, no_coverage)]
233-
fn strict_frozenset(&'a self) -> ValResult<GenericCollection<'a>> {
233+
fn strict_frozenset(&'a self) -> ValResult<GenericIterable<'a>> {
234234
self.validate_frozenset(false)
235235
}
236236

237+
fn extract_generic_iterable(&self) -> ValResult<GenericIterable> {
238+
match self {
239+
JsonInput::Array(a) => Ok(GenericIterable::JsonArray(a)),
240+
JsonInput::String(s) => Ok(GenericIterable::JsonString(s)),
241+
JsonInput::Object(object) => Ok(GenericIterable::JsonObject(object)),
242+
_ => Err(ValError::new(ErrorType::IterableType, self)),
243+
}
244+
}
245+
237246
fn validate_iter(&self) -> ValResult<GenericIterator> {
238247
match self {
239248
JsonInput::Array(a) => Ok(a.clone().into()),
@@ -405,41 +414,45 @@ impl<'a> Input<'a> for String {
405414
}
406415

407416
#[cfg_attr(has_no_coverage, no_coverage)]
408-
fn validate_list(&'a self, _strict: bool, _allow_any_iter: bool) -> ValResult<GenericCollection<'a>> {
417+
fn validate_list(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
409418
Err(ValError::new(ErrorType::ListType, self))
410419
}
411420
#[cfg_attr(has_no_coverage, no_coverage)]
412-
fn strict_list(&'a self) -> ValResult<GenericCollection<'a>> {
413-
self.validate_list(false, false)
421+
fn strict_list(&'a self) -> ValResult<GenericIterable<'a>> {
422+
self.validate_list(false)
414423
}
415424

416425
#[cfg_attr(has_no_coverage, no_coverage)]
417-
fn validate_tuple(&'a self, _strict: bool) -> ValResult<GenericCollection<'a>> {
426+
fn validate_tuple(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
418427
Err(ValError::new(ErrorType::TupleType, self))
419428
}
420429
#[cfg_attr(has_no_coverage, no_coverage)]
421-
fn strict_tuple(&'a self) -> ValResult<GenericCollection<'a>> {
430+
fn strict_tuple(&'a self) -> ValResult<GenericIterable<'a>> {
422431
self.validate_tuple(false)
423432
}
424433

425434
#[cfg_attr(has_no_coverage, no_coverage)]
426-
fn validate_set(&'a self, _strict: bool) -> ValResult<GenericCollection<'a>> {
435+
fn validate_set(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
427436
Err(ValError::new(ErrorType::SetType, self))
428437
}
429438
#[cfg_attr(has_no_coverage, no_coverage)]
430-
fn strict_set(&'a self) -> ValResult<GenericCollection<'a>> {
439+
fn strict_set(&'a self) -> ValResult<GenericIterable<'a>> {
431440
self.validate_set(false)
432441
}
433442

434443
#[cfg_attr(has_no_coverage, no_coverage)]
435-
fn validate_frozenset(&'a self, _strict: bool) -> ValResult<GenericCollection<'a>> {
444+
fn validate_frozenset(&'a self, _strict: bool) -> ValResult<GenericIterable<'a>> {
436445
Err(ValError::new(ErrorType::FrozenSetType, self))
437446
}
438447
#[cfg_attr(has_no_coverage, no_coverage)]
439-
fn strict_frozenset(&'a self) -> ValResult<GenericCollection<'a>> {
448+
fn strict_frozenset(&'a self) -> ValResult<GenericIterable<'a>> {
440449
self.validate_frozenset(false)
441450
}
442451

452+
fn extract_generic_iterable(&'a self) -> ValResult<GenericIterable<'a>> {
453+
Ok(GenericIterable::JsonString(self))
454+
}
455+
443456
fn validate_iter(&self) -> ValResult<GenericIterator> {
444457
Ok(string_to_vec(self).into())
445458
}

0 commit comments

Comments
 (0)