Skip to content

Commit e432a2c

Browse files
committed
support for json cow
1 parent 3d2e53e commit e432a2c

File tree

11 files changed

+102
-79
lines changed

11 files changed

+102
-79
lines changed

‎Cargo.lock‎

Lines changed: 2 additions & 2 deletions
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
@@ -44,7 +44,7 @@ base64 = "0.21.7"
4444
num-bigint = "0.4.4"
4545
python3-dll-a = "0.2.7"
4646
uuid = "1.7.0"
47-
jiter = {version = "0.0.7", features = ["python"]}
47+
jiter = { version = "0.1.0", features = ["python"] }
4848

4949
[lib]
5050
name = "_pydantic_core"

‎src/errors/line_error.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl ValLineError {
151151
#[derive(Clone)]
152152
pub enum InputValue {
153153
Python(PyObject),
154-
Json(JsonValue),
154+
Json(JsonValue<'static>),
155155
}
156156

157157
impl ToPyObject for InputValue {

‎src/errors/location.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use pyo3::exceptions::PyTypeError;
22
use pyo3::sync::GILOnceCell;
3+
use std::borrow::Cow;
34
use std::fmt;
45

56
use pyo3::prelude::*;
@@ -52,6 +53,12 @@ impl From<&str> for LocItem {
5253
}
5354
}
5455

56+
impl From<Cow<'_, str>> for LocItem {
57+
fn from(s: Cow<'_, str>) -> Self {
58+
Self::S(s.into_owned())
59+
}
60+
}
61+
5562
impl From<i64> for LocItem {
5663
fn from(i: i64) -> Self {
5764
Self::I(i)

‎src/input/input_abstract.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub trait Input<'py>: fmt::Debug + ToPyObject {
180180

181181
fn validate_frozenset(&self, strict: bool) -> ValMatch<Self::Set<'_>>;
182182

183-
fn validate_iter(&self) -> ValResult<GenericIterator>;
183+
fn validate_iter(&self) -> ValResult<GenericIterator<'static>>;
184184

185185
fn validate_date(&self, strict: bool) -> ValMatch<EitherDate<'py>>;
186186

‎src/input/input_json.rs‎

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,26 @@ use super::{
2424
};
2525

2626
/// This is required but since JSON object keys are always strings, I don't think it can be called
27-
impl From<&JsonValue> for LocItem {
27+
impl From<&JsonValue<'_>> for LocItem {
2828
fn from(json_value: &JsonValue) -> Self {
2929
match json_value {
3030
JsonValue::Int(i) => (*i).into(),
31-
JsonValue::Str(s) => s.as_str().into(),
31+
JsonValue::Str(s) => s.clone().into(),
3232
v => format!("{v:?}").into(),
3333
}
3434
}
3535
}
3636

37-
impl From<JsonValue> for LocItem {
37+
impl From<JsonValue<'_>> for LocItem {
3838
fn from(json_value: JsonValue) -> Self {
3939
(&json_value).into()
4040
}
4141
}
4242

43-
impl<'py> Input<'py> for JsonValue {
43+
impl<'py, 'data> Input<'py> for JsonValue<'data> {
4444
fn as_error_value(&self) -> InputValue {
4545
// cloning JsonValue is cheap due to use of Arc
46-
InputValue::Json(self.clone())
46+
InputValue::Json(self.to_static())
4747
}
4848

4949
fn is_none(&self) -> bool {
@@ -63,19 +63,19 @@ impl<'py> Input<'py> for JsonValue {
6363
}
6464
}
6565

66-
type Arguments<'a> = JsonArgs<'a>
66+
type Arguments<'a> = JsonArgs<'a, 'data>
6767
where
6868
Self: 'a,;
6969

70-
fn validate_args(&self) -> ValResult<JsonArgs<'_>> {
70+
fn validate_args(&self) -> ValResult<JsonArgs<'_, 'data>> {
7171
match self {
7272
JsonValue::Object(object) => Ok(JsonArgs::new(None, Some(object))),
7373
JsonValue::Array(array) => Ok(JsonArgs::new(Some(array), None)),
7474
_ => Err(ValError::new(ErrorTypeDefaults::ArgumentsType, self)),
7575
}
7676
}
7777

78-
fn validate_dataclass_args<'a>(&'a self, class_name: &str) -> ValResult<JsonArgs<'a>> {
78+
fn validate_dataclass_args<'a>(&'a self, class_name: &str) -> ValResult<JsonArgs<'a, 'data>> {
7979
match self {
8080
JsonValue::Object(object) => Ok(JsonArgs::new(None, Some(object))),
8181
_ => {
@@ -98,7 +98,7 @@ impl<'py> Input<'py> for JsonValue {
9898
// TODO: in V3 we may want to make JSON str always win if in union, for consistency,
9999
// see https://github.com/pydantic/pydantic-core/pull/867#discussion_r1386582501
100100
match self {
101-
JsonValue::Str(s) => Ok(ValidationMatch::strict(s.as_str().into())),
101+
JsonValue::Str(s) => Ok(ValidationMatch::strict(s.as_ref().into())),
102102
JsonValue::Int(i) if !strict && coerce_numbers_to_str => Ok(ValidationMatch::lax(i.to_string().into())),
103103
JsonValue::BigInt(b) if !strict && coerce_numbers_to_str => Ok(ValidationMatch::lax(b.to_string().into())),
104104
JsonValue::Float(f) if !strict && coerce_numbers_to_str => Ok(ValidationMatch::lax(f.to_string().into())),
@@ -142,7 +142,7 @@ impl<'py> Input<'py> for JsonValue {
142142

143143
fn exact_str(&self) -> ValResult<EitherString<'_>> {
144144
match self {
145-
JsonValue::Str(s) => Ok(s.as_str().into()),
145+
JsonValue::Str(s) => Ok(s.as_ref().into()),
146146
_ => Err(ValError::new(ErrorTypeDefaults::StringType, self)),
147147
}
148148
}
@@ -168,7 +168,7 @@ impl<'py> Input<'py> for JsonValue {
168168
}
169169
}
170170

171-
type Dict<'a> = &'a JsonObject;
171+
type Dict<'a> = &'a JsonObject<'data> where Self: 'a;
172172

173173
fn validate_dict(&self, _strict: bool) -> ValResult<Self::Dict<'_>> {
174174
match self {
@@ -181,51 +181,51 @@ impl<'py> Input<'py> for JsonValue {
181181
self.validate_dict(false)
182182
}
183183

184-
type List<'a> = &'a JsonArray;
184+
type List<'a> = &'a JsonArray<'data> where Self: 'a;
185185

186-
fn validate_list(&self, _strict: bool) -> ValMatch<&JsonArray> {
186+
fn validate_list(&self, _strict: bool) -> ValMatch<&JsonArray<'data>> {
187187
match self {
188188
JsonValue::Array(a) => Ok(ValidationMatch::exact(a)),
189189
_ => Err(ValError::new(ErrorTypeDefaults::ListType, self)),
190190
}
191191
}
192192

193-
type Tuple<'a> = &'a JsonArray;
193+
type Tuple<'a> = &'a JsonArray<'data> where Self: 'a;
194194

195-
fn validate_tuple(&self, _strict: bool) -> ValMatch<&JsonArray> {
195+
fn validate_tuple(&self, _strict: bool) -> ValMatch<&JsonArray<'data>> {
196196
// just as in set's case, List has to be allowed
197197
match self {
198198
JsonValue::Array(a) => Ok(ValidationMatch::strict(a)),
199199
_ => Err(ValError::new(ErrorTypeDefaults::TupleType, self)),
200200
}
201201
}
202202

203-
type Set<'a> = &'a JsonArray;
203+
type Set<'a> = &'a JsonArray<'data> where Self: 'a;
204204

205-
fn validate_set(&self, _strict: bool) -> ValMatch<&JsonArray> {
205+
fn validate_set(&self, _strict: bool) -> ValMatch<&JsonArray<'data>> {
206206
// we allow a list here since otherwise it would be impossible to create a set from JSON
207207
match self {
208208
JsonValue::Array(a) => Ok(ValidationMatch::strict(a)),
209209
_ => Err(ValError::new(ErrorTypeDefaults::SetType, self)),
210210
}
211211
}
212212

213-
fn validate_frozenset(&self, _strict: bool) -> ValMatch<&JsonArray> {
213+
fn validate_frozenset(&self, _strict: bool) -> ValMatch<&JsonArray<'data>> {
214214
// we allow a list here since otherwise it would be impossible to create a frozenset from JSON
215215
match self {
216216
JsonValue::Array(a) => Ok(ValidationMatch::strict(a)),
217217
_ => Err(ValError::new(ErrorTypeDefaults::FrozenSetType, self)),
218218
}
219219
}
220220

221-
fn validate_iter(&self) -> ValResult<GenericIterator> {
221+
fn validate_iter(&self) -> ValResult<GenericIterator<'static>> {
222222
match self {
223-
JsonValue::Array(a) => Ok(a.clone().into()),
223+
JsonValue::Array(a) => Ok(GenericIterator::from(a.clone()).into_static()),
224224
JsonValue::Str(s) => Ok(string_to_vec(s).into()),
225225
JsonValue::Object(object) => {
226226
// return keys iterator to match python's behavior
227227
let keys: JsonArray = JsonArray::new(object.keys().map(|k| JsonValue::Str(k.clone())).collect());
228-
Ok(keys.into())
228+
Ok(GenericIterator::from(keys).into_static())
229229
}
230230
_ => Err(ValError::new(ErrorTypeDefaults::IterableType, self)),
231231
}
@@ -303,7 +303,7 @@ impl<'py> Input<'py> for str {
303303
fn as_error_value(&self) -> InputValue {
304304
// Justification for the clone: this is on the error pathway and we are generally ok
305305
// with errors having a performance penalty
306-
InputValue::Json(JsonValue::Str(self.to_owned()))
306+
InputValue::Json(JsonValue::Str(self.to_owned().into()))
307307
}
308308

309309
fn as_kwargs(&self, _py: Python<'py>) -> Option<Bound<'py, PyDict>> {
@@ -394,7 +394,7 @@ impl<'py> Input<'py> for str {
394394
Err(ValError::new(ErrorTypeDefaults::SetType, self))
395395
}
396396

397-
fn validate_iter(&self) -> ValResult<GenericIterator> {
397+
fn validate_iter(&self) -> ValResult<GenericIterator<'static>> {
398398
Ok(string_to_vec(self).into())
399399
}
400400

@@ -441,21 +441,21 @@ impl BorrowInput<'_> for String {
441441
}
442442
}
443443

444-
impl BorrowInput<'_> for JsonValue {
445-
type Input = JsonValue;
444+
impl<'data> BorrowInput<'_> for JsonValue<'data> {
445+
type Input = JsonValue<'data>;
446446
fn borrow_input(&self) -> &Self::Input {
447447
self
448448
}
449449
}
450450

451-
fn string_to_vec(s: &str) -> JsonArray {
452-
JsonArray::new(s.chars().map(|c| JsonValue::Str(c.to_string())).collect())
451+
fn string_to_vec(s: &str) -> JsonArray<'static> {
452+
JsonArray::new(s.chars().map(|c| JsonValue::Str(c.to_string().into())).collect())
453453
}
454454

455-
impl<'py> ValidatedDict<'py> for &'_ JsonObject {
455+
impl<'py, 'data> ValidatedDict<'py> for &'_ JsonObject<'data> {
456456
type Key<'a> = &'a str where Self: 'a;
457457

458-
type Item<'a> = &'a JsonValue where Self: 'a;
458+
type Item<'a> = &'a JsonValue<'data> where Self: 'a;
459459

460460
fn get_item<'k>(&self, key: &'k LookupKey) -> ValResult<Option<(&'k LookupPath, Self::Item<'_>)>> {
461461
key.json_get(self)
@@ -469,12 +469,12 @@ impl<'py> ValidatedDict<'py> for &'_ JsonObject {
469469
&'a self,
470470
consumer: impl ConsumeIterator<ValResult<(Self::Key<'a>, Self::Item<'a>)>, Output = R>,
471471
) -> ValResult<R> {
472-
Ok(consumer.consume_iterator(LazyIndexMap::iter(self).map(|(k, v)| Ok((k.as_str(), v)))))
472+
Ok(consumer.consume_iterator(LazyIndexMap::iter(self).map(|(k, v)| Ok((k.as_ref(), v)))))
473473
}
474474
}
475475

476-
impl<'a, 'py> ValidatedList<'py> for &'a JsonArray {
477-
type Item = &'a JsonValue;
476+
impl<'a, 'py, 'data> ValidatedList<'py> for &'a JsonArray<'data> {
477+
type Item = &'a JsonValue<'data>;
478478

479479
fn len(&self) -> Option<usize> {
480480
Some(SmallVec::len(self))
@@ -487,8 +487,8 @@ impl<'a, 'py> ValidatedList<'py> for &'a JsonArray {
487487
}
488488
}
489489

490-
impl<'a, 'py> ValidatedTuple<'py> for &'a JsonArray {
491-
type Item = &'a JsonValue;
490+
impl<'a, 'data> ValidatedTuple<'_> for &'a JsonArray<'data> {
491+
type Item = &'a JsonValue<'data>;
492492

493493
fn len(&self) -> Option<usize> {
494494
Some(SmallVec::len(self))
@@ -498,29 +498,29 @@ impl<'a, 'py> ValidatedTuple<'py> for &'a JsonArray {
498498
}
499499
}
500500

501-
impl<'a, 'py> ValidatedSet<'py> for &'a JsonArray {
502-
type Item = &'a JsonValue;
501+
impl<'a, 'data> ValidatedSet<'_> for &'a JsonArray<'data> {
502+
type Item = &'a JsonValue<'data>;
503503

504504
fn iterate<R>(self, consumer: impl ConsumeIterator<PyResult<Self::Item>, Output = R>) -> ValResult<R> {
505505
Ok(consumer.consume_iterator(self.iter().map(Ok)))
506506
}
507507
}
508508

509509
#[cfg_attr(debug_assertions, derive(Debug))]
510-
pub struct JsonArgs<'a> {
511-
args: Option<&'a [JsonValue]>,
512-
kwargs: Option<&'a JsonObject>,
510+
pub struct JsonArgs<'a, 'data> {
511+
args: Option<&'a [JsonValue<'data>]>,
512+
kwargs: Option<&'a JsonObject<'data>>,
513513
}
514514

515-
impl<'a> JsonArgs<'a> {
516-
fn new(args: Option<&'a [JsonValue]>, kwargs: Option<&'a JsonObject>) -> Self {
515+
impl<'a, 'data> JsonArgs<'a, 'data> {
516+
fn new(args: Option<&'a [JsonValue<'data>]>, kwargs: Option<&'a JsonObject<'data>>) -> Self {
517517
Self { args, kwargs }
518518
}
519519
}
520520

521-
impl<'a> Arguments<'_> for JsonArgs<'a> {
522-
type Args = [JsonValue];
523-
type Kwargs = JsonObject;
521+
impl<'a, 'data> Arguments<'_> for JsonArgs<'a, 'data> {
522+
type Args = [JsonValue<'data>];
523+
type Kwargs = JsonObject<'data>;
524524

525525
fn args(&self) -> Option<&Self::Args> {
526526
self.args
@@ -531,8 +531,8 @@ impl<'a> Arguments<'_> for JsonArgs<'a> {
531531
}
532532
}
533533

534-
impl PositionalArgs<'_> for [JsonValue] {
535-
type Item<'a> = &'a JsonValue;
534+
impl<'data> PositionalArgs<'_> for [JsonValue<'data>] {
535+
type Item<'a> = &'a JsonValue<'data> where Self: 'a;
536536

537537
fn len(&self) -> usize {
538538
<[JsonValue]>::len(self)
@@ -545,9 +545,9 @@ impl PositionalArgs<'_> for [JsonValue] {
545545
}
546546
}
547547

548-
impl KeywordArgs<'_> for JsonObject {
549-
type Key<'a> = &'a str;
550-
type Item<'a> = &'a JsonValue;
548+
impl<'data> KeywordArgs<'_> for JsonObject<'data> {
549+
type Key<'a> = &'a str where Self: 'a;
550+
type Item<'a> = &'a JsonValue<'data> where Self: 'a;
551551

552552
fn len(&self) -> usize {
553553
LazyIndexMap::len(self)
@@ -556,6 +556,6 @@ impl KeywordArgs<'_> for JsonObject {
556556
key.json_get(self)
557557
}
558558
fn iter(&self) -> impl Iterator<Item = ValResult<(Self::Key<'_>, Self::Item<'_>)>> {
559-
LazyIndexMap::iter(self).map(|(k, v)| Ok((k.as_str(), v)))
559+
LazyIndexMap::iter(self).map(|(k, v)| Ok((k.as_ref(), v)))
560560
}
561561
}

‎src/input/input_python.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ impl<'py> Input<'py> for Bound<'py, PyAny> {
475475
Err(ValError::new(ErrorTypeDefaults::FrozenSetType, self))
476476
}
477477

478-
fn validate_iter(&self) -> ValResult<GenericIterator> {
478+
fn validate_iter(&self) -> ValResult<GenericIterator<'static>> {
479479
if self.iter().is_ok() {
480480
Ok(self.into())
481481
} else {

‎src/input/input_string.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl<'py> Input<'py> for StringMapping<'py> {
171171
Err(ValError::new(ErrorTypeDefaults::FrozenSetType, self))
172172
}
173173

174-
fn validate_iter(&self) -> ValResult<GenericIterator> {
174+
fn validate_iter(&self) -> ValResult<GenericIterator<'static>> {
175175
Err(ValError::new(ErrorTypeDefaults::IterableType, self))
176176
}
177177

0 commit comments

Comments
 (0)