@@ -10,7 +10,7 @@ use ahash::AHashSet;
10
10
use pyo3:: IntoPyObjectExt ;
11
11
use url:: { ParseError , SyntaxViolation , Url } ;
12
12
13
- use crate :: build_tools:: { is_strict, py_schema_err} ;
13
+ use crate :: build_tools:: { is_strict, py_schema_err, schema_or_config } ;
14
14
use crate :: errors:: ToErrorValue ;
15
15
use crate :: errors:: { ErrorType , ErrorTypeDefaults , ValError , ValResult } ;
16
16
use crate :: input:: downcast_python_input;
@@ -34,7 +34,17 @@ pub struct UrlValidator {
34
34
default_port : Option < u16 > ,
35
35
default_path : Option < String > ,
36
36
name : String ,
37
- extra_trailing_slash : bool ,
37
+ add_trailing_slash : bool ,
38
+ }
39
+
40
+ fn get_add_trailing_slash ( schema : & Bound < ' _ , PyDict > , config : Option < & Bound < ' _ , PyDict > > ) -> PyResult < bool > {
41
+ schema_or_config (
42
+ schema,
43
+ config,
44
+ intern ! ( schema. py( ) , "add_trailing_slash" ) ,
45
+ intern ! ( schema. py( ) , "url_add_trailing_slash" ) ,
46
+ )
47
+ . map ( |v| v. unwrap_or ( true ) )
38
48
}
39
49
40
50
impl BuildValidator for UrlValidator {
@@ -56,9 +66,7 @@ impl BuildValidator for UrlValidator {
56
66
default_path : schema. get_as ( intern ! ( schema. py( ) , "default_path" ) ) ?,
57
67
allowed_schemes,
58
68
name,
59
- extra_trailing_slash : schema
60
- . get_as ( intern ! ( schema. py( ) , "extra_trailing_slash" ) ) ?
61
- . unwrap_or ( true ) ,
69
+ add_trailing_slash : get_add_trailing_slash ( schema, config) ?,
62
70
}
63
71
. into ( ) )
64
72
}
@@ -73,7 +81,7 @@ impl Validator for UrlValidator {
73
81
input : & ( impl Input < ' py > + ?Sized ) ,
74
82
state : & mut ValidationState < ' _ , ' py > ,
75
83
) -> ValResult < PyObject > {
76
- let mut either_url = self . get_url ( input, state. strict_or ( self . strict ) , self . extra_trailing_slash ) ?;
84
+ let mut either_url = self . get_url ( input, state. strict_or ( self . strict ) , self . add_trailing_slash ) ?;
77
85
78
86
if let Some ( ( ref allowed_schemes, ref expected_schemes_repr) ) = self . allowed_schemes {
79
87
if !allowed_schemes. contains ( either_url. url ( ) . scheme ( ) ) {
@@ -114,7 +122,7 @@ impl UrlValidator {
114
122
& self ,
115
123
input : & ( impl Input < ' py > + ?Sized ) ,
116
124
strict : bool ,
117
- extra_trailing_slash : bool ,
125
+ add_trailing_slash : bool ,
118
126
) -> ValResult < EitherUrl < ' py > > {
119
127
match input. validate_str ( strict, false ) {
120
128
Ok ( val_match) => {
@@ -124,7 +132,7 @@ impl UrlValidator {
124
132
125
133
self . check_length ( input, url_str) ?;
126
134
127
- parse_url ( url_str, input, strict, extra_trailing_slash ) . map ( EitherUrl :: Owned )
135
+ parse_url ( url_str, input, strict, add_trailing_slash ) . map ( EitherUrl :: Owned )
128
136
}
129
137
Err ( _) => {
130
138
// we don't need to worry about whether the url was parsed in strict mode before,
@@ -136,7 +144,7 @@ impl UrlValidator {
136
144
let url_str = multi_host_url. get ( ) . __str__ ( ) ;
137
145
self . check_length ( input, & url_str) ?;
138
146
139
- parse_url ( & url_str, input, strict, extra_trailing_slash ) . map ( EitherUrl :: Owned )
147
+ parse_url ( & url_str, input, strict, add_trailing_slash ) . map ( EitherUrl :: Owned )
140
148
} else {
141
149
Err ( ValError :: new ( ErrorTypeDefaults :: UrlType , input) )
142
150
}
@@ -208,7 +216,7 @@ pub struct MultiHostUrlValidator {
208
216
default_port : Option < u16 > ,
209
217
default_path : Option < String > ,
210
218
name : String ,
211
- extra_trailing_slash : bool ,
219
+ add_trailing_slash : bool ,
212
220
}
213
221
214
222
impl BuildValidator for MultiHostUrlValidator {
@@ -236,9 +244,7 @@ impl BuildValidator for MultiHostUrlValidator {
236
244
default_port : schema. get_as ( intern ! ( schema. py( ) , "default_port" ) ) ?,
237
245
default_path : schema. get_as ( intern ! ( schema. py( ) , "default_path" ) ) ?,
238
246
name,
239
- extra_trailing_slash : schema
240
- . get_as ( intern ! ( schema. py( ) , "extra_trailing_slash" ) ) ?
241
- . unwrap_or ( true ) ,
247
+ add_trailing_slash : get_add_trailing_slash ( schema, config) ?,
242
248
}
243
249
. into ( ) )
244
250
}
@@ -253,7 +259,7 @@ impl Validator for MultiHostUrlValidator {
253
259
input : & ( impl Input < ' py > + ?Sized ) ,
254
260
state : & mut ValidationState < ' _ , ' py > ,
255
261
) -> ValResult < PyObject > {
256
- let mut multi_url = self . get_url ( input, state. strict_or ( self . strict ) , self . extra_trailing_slash ) ?;
262
+ let mut multi_url = self . get_url ( input, state. strict_or ( self . strict ) , self . add_trailing_slash ) ?;
257
263
258
264
if let Some ( ( ref allowed_schemes, ref expected_schemes_repr) ) = self . allowed_schemes {
259
265
if !allowed_schemes. contains ( multi_url. url ( ) . scheme ( ) ) {
@@ -293,7 +299,7 @@ impl MultiHostUrlValidator {
293
299
& self ,
294
300
input : & ( impl Input < ' py > + ?Sized ) ,
295
301
strict : bool ,
296
- extra_trailing_slash : bool ,
302
+ add_trailing_slash : bool ,
297
303
) -> ValResult < EitherMultiHostUrl < ' py > > {
298
304
match input. validate_str ( strict, false ) {
299
305
Ok ( val_match) => {
@@ -303,7 +309,7 @@ impl MultiHostUrlValidator {
303
309
304
310
self . check_length ( input, || url_str. len ( ) ) ?;
305
311
306
- parse_multihost_url ( url_str, input, strict, extra_trailing_slash ) . map ( EitherMultiHostUrl :: Rust )
312
+ parse_multihost_url ( url_str, input, strict, add_trailing_slash ) . map ( EitherMultiHostUrl :: Rust )
307
313
}
308
314
Err ( _) => {
309
315
// we don't need to worry about whether the url was parsed in strict mode before,
@@ -384,7 +390,7 @@ fn parse_multihost_url<'py>(
384
390
url_str : & str ,
385
391
input : & ( impl Input < ' py > + ?Sized ) ,
386
392
strict : bool ,
387
- extra_trailing_slash : bool ,
393
+ add_trailing_slash : bool ,
388
394
) -> ValResult < PyMultiHostUrl > {
389
395
macro_rules! parsing_err {
390
396
( $parse_error: expr) => {
@@ -474,7 +480,7 @@ fn parse_multihost_url<'py>(
474
480
// with just one host, for consistent behaviour, we parse the URL the same as with multiple hosts
475
481
476
482
let reconstructed_url = format ! ( "{prefix}{}" , & url_str[ start..] ) ;
477
- let ref_url = parse_url ( & reconstructed_url, input, strict, extra_trailing_slash ) ?;
483
+ let ref_url = parse_url ( & reconstructed_url, input, strict, add_trailing_slash ) ?;
478
484
479
485
if hosts. is_empty ( ) {
480
486
// if there's no one host (e.g. no `,`), we allow it to be empty to allow for default hosts
@@ -488,7 +494,7 @@ fn parse_multihost_url<'py>(
488
494
. iter ( )
489
495
. map ( |host| {
490
496
let reconstructed_url = format ! ( "{prefix}{host}" ) ;
491
- parse_url ( & reconstructed_url, input, strict, extra_trailing_slash ) . map ( Into :: into)
497
+ parse_url ( & reconstructed_url, input, strict, add_trailing_slash ) . map ( Into :: into)
492
498
} )
493
499
. collect :: < ValResult < _ > > ( ) ?;
494
500
@@ -500,7 +506,7 @@ fn parse_multihost_url<'py>(
500
506
}
501
507
}
502
508
503
- fn parse_url ( url_str : & str , input : impl ToErrorValue , strict : bool , extra_trailing_slash : bool ) -> ValResult < PyUrl > {
509
+ fn parse_url ( url_str : & str , input : impl ToErrorValue , strict : bool , add_trailing_slash : bool ) -> ValResult < PyUrl > {
504
510
if url_str. is_empty ( ) {
505
511
return Err ( ValError :: new (
506
512
ErrorType :: UrlParsing {
@@ -510,7 +516,7 @@ fn parse_url(url_str: &str, input: impl ToErrorValue, strict: bool, extra_traili
510
516
input,
511
517
) ) ;
512
518
}
513
- let remove_trailing_slash = !extra_trailing_slash && !url_str. ends_with ( '/' ) ;
519
+ let remove_trailing_slash = !add_trailing_slash && !url_str. ends_with ( '/' ) ;
514
520
515
521
// if we're in strict mode, we consider a syntax violation as an error
516
522
if strict {
0 commit comments