Skip to content

Commit 8db3a6f

Browse files
authored
separate Input trait 'a and 'py lifetimes (#1227)
1 parent 9efbc16 commit 8db3a6f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+424
-441
lines changed

benches/main.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ fn dict_value_error(bench: &mut Bencher) {
277277
Python::with_gil(|py| {
278278
let validator = build_schema_validator(
279279
py,
280-
r#"{
280+
r"{
281281
'type': 'dict',
282282
'keys_schema': {'type': 'str'},
283283
'values_schema': {'type': 'int', 'lt': 0},
284-
}"#,
284+
}",
285285
);
286286

287287
let code = format!(
@@ -322,7 +322,7 @@ fn typed_dict_json(bench: &mut Bencher) {
322322
Python::with_gil(|py| {
323323
let validator = build_schema_validator(
324324
py,
325-
r#"{
325+
r"{
326326
'type': 'typed-dict',
327327
'extra_behavior': 'ignore',
328328
'fields': {
@@ -337,7 +337,7 @@ fn typed_dict_json(bench: &mut Bencher) {
337337
'i': {'type': 'typed-dict-field', 'schema': {'type': 'int'}},
338338
'j': {'type': 'typed-dict-field', 'schema': {'type': 'int'}},
339339
},
340-
}"#,
340+
}",
341341
);
342342

343343
let code = r#"{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9, "j": 0}"#.to_string();
@@ -351,7 +351,7 @@ fn typed_dict_python(bench: &mut Bencher) {
351351
Python::with_gil(|py| {
352352
let validator = build_schema_validator(
353353
py,
354-
r#"{
354+
r"{
355355
'type': 'typed-dict',
356356
'extra_behavior': 'ignore',
357357
'fields': {
@@ -366,7 +366,7 @@ fn typed_dict_python(bench: &mut Bencher) {
366366
'i': {'type': 'typed-dict-field', 'schema': {'type': 'int'}},
367367
'j': {'type': 'typed-dict-field', 'schema': {'type': 'int'}},
368368
},
369-
}"#,
369+
}",
370370
);
371371

372372
let code = r#"{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9, "j": 0}"#.to_string();
@@ -384,7 +384,7 @@ fn typed_dict_deep_error(bench: &mut Bencher) {
384384
Python::with_gil(|py| {
385385
let validator = build_schema_validator(
386386
py,
387-
r#"{
387+
r"{
388388
'type': 'typed-dict',
389389
'fields': {
390390
'field_a': {'type': 'typed-dict-field', 'schema': {'type': 'str'}},
@@ -405,7 +405,7 @@ fn typed_dict_deep_error(bench: &mut Bencher) {
405405
}
406406
},
407407
},
408-
}"#,
408+
}",
409409
);
410410

411411
let code = "{'field_a': '1', 'field_b': {'field_c': '2', 'field_d': {'field_e': '4', 'field_f': 'xx'}}}";
@@ -557,15 +557,15 @@ fn literal_enums_few_python(bench: &mut Bencher) {
557557
Python::with_gil(|py| {
558558
let globals = PyDict::new_bound(py);
559559
py.run_bound(
560-
r#"
560+
r"
561561
from enum import Enum
562562
563563
class Foo(Enum):
564564
v1 = object()
565565
v2 = object()
566566
v3 = object()
567567
v4 = object()
568-
"#,
568+
",
569569
Some(&globals),
570570
None,
571571
)
@@ -682,15 +682,15 @@ fn literal_mixed_few_python(bench: &mut Bencher) {
682682
Python::with_gil(|py| {
683683
let globals = PyDict::new_bound(py);
684684
py.run_bound(
685-
r#"
685+
r"
686686
from enum import Enum
687687
688688
class Foo(Enum):
689689
v1 = object()
690690
v2 = object()
691691
v3 = object()
692692
v4 = object()
693-
"#,
693+
",
694694
Some(&globals),
695695
None,
696696
)

src/input/input_abstract.rs

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl TryFrom<&str> for InputType {
4646
/// the convention is to either implement:
4747
/// * `strict_*` & `lax_*` if they have different behavior
4848
/// * or, `validate_*` and `strict_*` to just call `validate_*` if the behavior for strict and lax is the same
49-
pub trait Input<'a>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
49+
pub trait Input<'py>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
5050
fn as_error_value(&self) -> InputValue;
5151

5252
fn identity(&self) -> Option<usize> {
@@ -57,15 +57,15 @@ pub trait Input<'a>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
5757
false
5858
}
5959

60-
fn input_is_instance(&self, _class: &Bound<'_, PyType>) -> Option<&Bound<'a, PyAny>> {
60+
fn input_is_instance(&self, _class: &Bound<'py, PyType>) -> Option<&Bound<'py, PyAny>> {
6161
None
6262
}
6363

6464
fn is_python(&self) -> bool {
6565
false
6666
}
6767

68-
fn as_kwargs(&self, py: Python<'a>) -> Option<Bound<'a, PyDict>>;
68+
fn as_kwargs(&self, py: Python<'py>) -> Option<Bound<'py, PyDict>>;
6969

7070
fn input_is_subclass(&self, _class: &Bound<'_, PyType>) -> PyResult<bool> {
7171
Ok(false)
@@ -83,23 +83,19 @@ pub trait Input<'a>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
8383
false
8484
}
8585

86-
fn validate_args(&'a self) -> ValResult<GenericArguments<'a>>;
86+
fn validate_args(&self) -> ValResult<GenericArguments<'_>>;
8787

88-
fn validate_dataclass_args(&'a self, dataclass_name: &str) -> ValResult<GenericArguments<'a>>;
88+
fn validate_dataclass_args<'a>(&'a self, dataclass_name: &str) -> ValResult<GenericArguments<'a>>;
8989

90-
fn validate_str(
91-
&'a self,
92-
strict: bool,
93-
coerce_numbers_to_str: bool,
94-
) -> ValResult<ValidationMatch<EitherString<'a>>>;
90+
fn validate_str(&self, strict: bool, coerce_numbers_to_str: bool) -> ValResult<ValidationMatch<EitherString<'_>>>;
9591

96-
fn validate_bytes(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherBytes<'a>>>;
92+
fn validate_bytes<'a>(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherBytes<'a, 'py>>>;
9793

9894
fn validate_bool(&self, strict: bool) -> ValResult<ValidationMatch<bool>>;
9995

100-
fn validate_int(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherInt<'a>>>;
96+
fn validate_int(&self, strict: bool) -> ValResult<ValidationMatch<EitherInt<'_>>>;
10197

102-
fn exact_int(&'a self) -> ValResult<EitherInt<'a>> {
98+
fn exact_int(&self) -> ValResult<EitherInt<'_>> {
10399
self.validate_int(true).and_then(|val_match| {
104100
val_match
105101
.require_exact()
@@ -109,99 +105,99 @@ pub trait Input<'a>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
109105

110106
/// Extract a String from the input, only allowing exact
111107
/// matches for a String (no subclasses)
112-
fn exact_str(&'a self) -> ValResult<EitherString<'a>> {
108+
fn exact_str(&self) -> ValResult<EitherString<'_>> {
113109
self.validate_str(true, false).and_then(|val_match| {
114110
val_match
115111
.require_exact()
116112
.ok_or_else(|| ValError::new(ErrorTypeDefaults::StringType, self))
117113
})
118114
}
119115

120-
fn validate_float(&'a self, strict: bool) -> ValResult<ValidationMatch<EitherFloat<'a>>>;
116+
fn validate_float(&self, strict: bool) -> ValResult<ValidationMatch<EitherFloat<'_>>>;
121117

122-
fn validate_decimal(&'a self, strict: bool, py: Python<'a>) -> ValResult<Bound<'a, PyAny>> {
118+
fn validate_decimal(&self, strict: bool, py: Python<'py>) -> ValResult<Bound<'py, PyAny>> {
123119
if strict {
124120
self.strict_decimal(py)
125121
} else {
126122
self.lax_decimal(py)
127123
}
128124
}
129-
fn strict_decimal(&'a self, py: Python<'a>) -> ValResult<Bound<'a, PyAny>>;
125+
fn strict_decimal(&self, py: Python<'py>) -> ValResult<Bound<'py, PyAny>>;
130126
#[cfg_attr(has_coverage_attribute, coverage(off))]
131-
fn lax_decimal(&'a self, py: Python<'a>) -> ValResult<Bound<'a, PyAny>> {
127+
fn lax_decimal(&self, py: Python<'py>) -> ValResult<Bound<'py, PyAny>> {
132128
self.strict_decimal(py)
133129
}
134130

135-
fn validate_dict(&'a self, strict: bool) -> ValResult<GenericMapping<'a>> {
131+
fn validate_dict<'a>(&'a self, strict: bool) -> ValResult<GenericMapping<'a, 'py>> {
136132
if strict {
137133
self.strict_dict()
138134
} else {
139135
self.lax_dict()
140136
}
141137
}
142-
fn strict_dict(&'a self) -> ValResult<GenericMapping<'a>>;
138+
fn strict_dict<'a>(&'a self) -> ValResult<GenericMapping<'a, 'py>>;
143139
#[cfg_attr(has_coverage_attribute, coverage(off))]
144-
fn lax_dict(&'a self) -> ValResult<GenericMapping<'a>> {
140+
fn lax_dict<'a>(&'a self) -> ValResult<GenericMapping<'a, 'py>> {
145141
self.strict_dict()
146142
}
147143

148-
fn validate_model_fields(&'a self, strict: bool, _from_attributes: bool) -> ValResult<GenericMapping<'a>> {
144+
fn validate_model_fields<'a>(&'a self, strict: bool, _from_attributes: bool) -> ValResult<GenericMapping<'a, 'py>> {
149145
self.validate_dict(strict)
150146
}
151147

152-
fn validate_list(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
148+
fn validate_list<'a>(&'a self, strict: bool) -> ValResult<GenericIterable<'a, 'py>> {
153149
if strict {
154150
self.strict_list()
155151
} else {
156152
self.lax_list()
157153
}
158154
}
159-
fn strict_list(&'a self) -> ValResult<GenericIterable<'a>>;
155+
fn strict_list<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>>;
160156
#[cfg_attr(has_coverage_attribute, coverage(off))]
161-
fn lax_list(&'a self) -> ValResult<GenericIterable<'a>> {
157+
fn lax_list<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>> {
162158
self.strict_list()
163159
}
164160

165-
fn validate_tuple(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
161+
fn validate_tuple<'a>(&'a self, strict: bool) -> ValResult<GenericIterable<'a, 'py>> {
166162
if strict {
167163
self.strict_tuple()
168164
} else {
169165
self.lax_tuple()
170166
}
171167
}
172-
fn strict_tuple(&'a self) -> ValResult<GenericIterable<'a>>;
168+
fn strict_tuple<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>>;
173169
#[cfg_attr(has_coverage_attribute, coverage(off))]
174-
fn lax_tuple(&'a self) -> ValResult<GenericIterable<'a>> {
170+
fn lax_tuple<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>> {
175171
self.strict_tuple()
176172
}
177173

178-
fn validate_set(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
174+
fn validate_set<'a>(&'a self, strict: bool) -> ValResult<GenericIterable<'a, 'py>> {
179175
if strict {
180176
self.strict_set()
181177
} else {
182178
self.lax_set()
183179
}
184180
}
185-
fn strict_set(&'a self) -> ValResult<GenericIterable<'a>>;
181+
fn strict_set<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>>;
186182
#[cfg_attr(has_coverage_attribute, coverage(off))]
187-
fn lax_set(&'a self) -> ValResult<GenericIterable<'a>> {
183+
fn lax_set<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>> {
188184
self.strict_set()
189185
}
190186

191-
fn validate_frozenset(&'a self, strict: bool) -> ValResult<GenericIterable<'a>> {
187+
fn validate_frozenset<'a>(&'a self, strict: bool) -> ValResult<GenericIterable<'a, 'py>> {
192188
if strict {
193189
self.strict_frozenset()
194190
} else {
195191
self.lax_frozenset()
196192
}
197193
}
198-
fn strict_frozenset(&'a self) -> ValResult<GenericIterable<'a>>;
194+
fn strict_frozenset<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>>;
199195
#[cfg_attr(has_coverage_attribute, coverage(off))]
200-
fn lax_frozenset(&'a self) -> ValResult<GenericIterable<'a>> {
196+
fn lax_frozenset<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>> {
201197
self.strict_frozenset()
202198
}
203199

204-
fn extract_generic_iterable(&'a self) -> ValResult<GenericIterable<'a>>;
200+
fn extract_generic_iterable<'a>(&'a self) -> ValResult<GenericIterable<'a, 'py>>;
205201

206202
fn validate_iter(&self) -> ValResult<GenericIterator>;
207203

@@ -231,9 +227,7 @@ pub trait Input<'a>: fmt::Debug + ToPyObject + Into<LocItem> + Sized {
231227
/// this trait we abstract over whether the return value from the iterator is owned
232228
/// or borrowed; all we care about is that we can borrow it again with `borrow_input`
233229
/// for some lifetime 'a.
234-
pub trait BorrowInput {
235-
type Input<'a>: Input<'a>
236-
where
237-
Self: 'a;
238-
fn borrow_input(&self) -> &Self::Input<'_>;
230+
pub trait BorrowInput<'py> {
231+
type Input: Input<'py>;
232+
fn borrow_input(&self) -> &Self::Input;
239233
}

0 commit comments

Comments
 (0)