1
1
"""Module containing the implementation of the URIMixin class."""
2
+
3
+ import typing as t
2
4
import warnings
3
5
4
6
from . import exceptions as exc
5
7
from . import misc
6
8
from . import normalizers
9
+ from . import uri
7
10
from . import validators
11
+ from ._typing_compat import Self as _Self
12
+
13
+
14
+ class _AuthorityInfo (t .TypedDict ):
15
+ """A typed dict for the authority info triple: userinfo, host, and port."""
16
+
17
+ userinfo : t .Optional [str ]
18
+ host : t .Optional [str ]
19
+ port : t .Optional [str ]
8
20
9
21
10
22
class URIMixin :
11
23
"""Mixin with all shared methods for URIs and IRIs."""
12
24
13
- __hash__ = tuple .__hash__
25
+ if t .TYPE_CHECKING :
26
+ scheme : t .Optional [str ]
27
+ authority : t .Optional [str ]
28
+ path : t .Optional [str ]
29
+ query : t .Optional [str ]
30
+ fragment : t .Optional [str ]
31
+ encoding : str
14
32
15
- def authority_info (self ):
33
+ def authority_info (self ) -> _AuthorityInfo :
16
34
"""Return a dictionary with the ``userinfo``, ``host``, and ``port``.
17
35
18
36
If the authority is not valid, it will raise a
@@ -53,11 +71,11 @@ def authority_info(self):
53
71
54
72
return matches
55
73
56
- def _match_subauthority (self ):
74
+ def _match_subauthority (self ) -> t . Optional [ t . Match [ str ]] :
57
75
return misc .SUBAUTHORITY_MATCHER .match (self .authority )
58
76
59
77
@property
60
- def _validator (self ):
78
+ def _validator (self ) -> validators . Validator :
61
79
v = getattr (self , "_cached_validator" , None )
62
80
if v is not None :
63
81
return v
@@ -67,7 +85,7 @@ def _validator(self):
67
85
return self ._cached_validator
68
86
69
87
@property
70
- def host (self ):
88
+ def host (self ) -> t . Optional [ str ] :
71
89
"""If present, a string representing the host."""
72
90
try :
73
91
authority = self .authority_info ()
@@ -76,7 +94,7 @@ def host(self):
76
94
return authority ["host" ]
77
95
78
96
@property
79
- def port (self ):
97
+ def port (self ) -> t . Optional [ str ] :
80
98
"""If present, the port extracted from the authority."""
81
99
try :
82
100
authority = self .authority_info ()
@@ -85,15 +103,15 @@ def port(self):
85
103
return authority ["port" ]
86
104
87
105
@property
88
- def userinfo (self ):
106
+ def userinfo (self ) -> t . Optional [ str ] :
89
107
"""If present, the userinfo extracted from the authority."""
90
108
try :
91
109
authority = self .authority_info ()
92
110
except exc .InvalidAuthority :
93
111
return None
94
112
return authority ["userinfo" ]
95
113
96
- def is_absolute (self ):
114
+ def is_absolute (self ) -> bool :
97
115
"""Determine if this URI Reference is an absolute URI.
98
116
99
117
See http://tools.ietf.org/html/rfc3986#section-4.3 for explanation.
@@ -103,7 +121,7 @@ def is_absolute(self):
103
121
"""
104
122
return bool (misc .ABSOLUTE_URI_MATCHER .match (self .unsplit ()))
105
123
106
- def is_valid (self , ** kwargs ) :
124
+ def is_valid (self , ** kwargs : bool ) -> bool :
107
125
"""Determine if the URI is valid.
108
126
109
127
.. deprecated:: 1.1.0
@@ -137,7 +155,7 @@ def is_valid(self, **kwargs):
137
155
]
138
156
return all (v (r ) for v , r in validators )
139
157
140
- def authority_is_valid (self , require = False ):
158
+ def authority_is_valid (self , require : bool = False ) -> bool :
141
159
"""Determine if the authority component is valid.
142
160
143
161
.. deprecated:: 1.1.0
@@ -167,7 +185,7 @@ def authority_is_valid(self, require=False):
167
185
require = require ,
168
186
)
169
187
170
- def scheme_is_valid (self , require = False ):
188
+ def scheme_is_valid (self , require : bool = False ) -> bool :
171
189
"""Determine if the scheme component is valid.
172
190
173
191
.. deprecated:: 1.1.0
@@ -186,7 +204,7 @@ def scheme_is_valid(self, require=False):
186
204
)
187
205
return validators .scheme_is_valid (self .scheme , require )
188
206
189
- def path_is_valid (self , require = False ):
207
+ def path_is_valid (self , require : bool = False ) -> bool :
190
208
"""Determine if the path component is valid.
191
209
192
210
.. deprecated:: 1.1.0
@@ -205,7 +223,7 @@ def path_is_valid(self, require=False):
205
223
)
206
224
return validators .path_is_valid (self .path , require )
207
225
208
- def query_is_valid (self , require = False ):
226
+ def query_is_valid (self , require : bool = False ) -> bool :
209
227
"""Determine if the query component is valid.
210
228
211
229
.. deprecated:: 1.1.0
@@ -224,7 +242,7 @@ def query_is_valid(self, require=False):
224
242
)
225
243
return validators .query_is_valid (self .query , require )
226
244
227
- def fragment_is_valid (self , require = False ):
245
+ def fragment_is_valid (self , require : bool = False ) -> bool :
228
246
"""Determine if the fragment component is valid.
229
247
230
248
.. deprecated:: 1.1.0
@@ -243,7 +261,7 @@ def fragment_is_valid(self, require=False):
243
261
)
244
262
return validators .fragment_is_valid (self .fragment , require )
245
263
246
- def normalized_equality (self , other_ref ) :
264
+ def normalized_equality (self , other_ref : "uri.URIReference" ) -> bool :
247
265
"""Compare this URIReference to another URIReference.
248
266
249
267
:param URIReference other_ref: (required), The reference with which
@@ -253,7 +271,11 @@ def normalized_equality(self, other_ref):
253
271
"""
254
272
return tuple (self .normalize ()) == tuple (other_ref .normalize ())
255
273
256
- def resolve_with (self , base_uri , strict = False ):
274
+ def resolve_with ( # noqa: C901
275
+ self ,
276
+ base_uri : t .Union [str , "uri.URIReference" ],
277
+ strict : bool = False ,
278
+ ) -> _Self :
257
279
"""Use an absolute URI Reference to resolve this relative reference.
258
280
259
281
Assuming this is a relative reference that you would like to resolve,
@@ -272,6 +294,9 @@ def resolve_with(self, base_uri, strict=False):
272
294
if not isinstance (base_uri , URIMixin ):
273
295
base_uri = type (self ).from_string (base_uri )
274
296
297
+ if t .TYPE_CHECKING :
298
+ base_uri = t .cast (uri .URIReference , base_uri )
299
+
275
300
try :
276
301
self ._validator .validate (base_uri )
277
302
except exc .ValidationError :
@@ -325,14 +350,14 @@ def resolve_with(self, base_uri, strict=False):
325
350
)
326
351
return target
327
352
328
- def unsplit (self ):
353
+ def unsplit (self ) -> str :
329
354
"""Create a URI string from the components.
330
355
331
356
:returns: The URI Reference reconstituted as a string.
332
357
:rtype: str
333
358
"""
334
359
# See http://tools.ietf.org/html/rfc3986#section-5.3
335
- result_list = []
360
+ result_list : list [ str ] = []
336
361
if self .scheme :
337
362
result_list .extend ([self .scheme , ":" ])
338
363
if self .authority :
@@ -347,12 +372,12 @@ def unsplit(self):
347
372
348
373
def copy_with (
349
374
self ,
350
- scheme = misc .UseExisting ,
351
- authority = misc .UseExisting ,
352
- path = misc .UseExisting ,
353
- query = misc .UseExisting ,
354
- fragment = misc .UseExisting ,
355
- ):
375
+ scheme : t . Optional [ str ] = misc .UseExisting ,
376
+ authority : t . Optional [ str ] = misc .UseExisting ,
377
+ path : t . Optional [ str ] = misc .UseExisting ,
378
+ query : t . Optional [ str ] = misc .UseExisting ,
379
+ fragment : t . Optional [ str ] = misc .UseExisting ,
380
+ ) -> _Self :
356
381
"""Create a copy of this reference with the new components.
357
382
358
383
:param str scheme:
@@ -380,6 +405,6 @@ def copy_with(
380
405
for key , value in list (attributes .items ()):
381
406
if value is misc .UseExisting :
382
407
del attributes [key ]
383
- uri = self ._replace (** attributes )
408
+ uri : _Self = self ._replace (** attributes )
384
409
uri .encoding = self .encoding
385
410
return uri
0 commit comments