1
1
from enum import IntEnum
2
+ from typing import Final , Iterable , List , Optional , TypedDict , Union
2
3
3
4
from ada_url ._ada_wrapper import ffi , lib
4
5
@@ -56,6 +57,21 @@ class HostType(IntEnum):
56
57
IPV6 = 2
57
58
58
59
60
+ class ParseAttributes (TypedDict , total = False ):
61
+ href : str
62
+ username : str
63
+ password : str
64
+ protocol : str
65
+ port : str
66
+ hostname : str
67
+ host : str
68
+ pathname : str
69
+ search : str
70
+ hash : str
71
+ origin : str
72
+ host_type : HostType
73
+
74
+
59
75
def _get_obj (constructor , destructor , * args ):
60
76
obj = constructor (* args )
61
77
@@ -95,6 +111,7 @@ class URL:
95
111
* ``port``
96
112
* ``pathname``
97
113
* ``search``
114
+ * ``hash``
98
115
99
116
You can additionally read the ``origin`` and ``host_type`` attributes.
100
117
``host_type`` is a :class:`HostType` enum.
@@ -114,7 +131,20 @@ class URL:
114
131
115
132
"""
116
133
117
- def __init__ (self , url , base = None ):
134
+ href : str
135
+ username : str
136
+ password : str
137
+ protocol : str
138
+ port : str
139
+ hostname : str
140
+ host : str
141
+ pathname : str
142
+ search : str
143
+ hash : str
144
+ origin : Final [str ]
145
+ host_type : Final [HostType ]
146
+
147
+ def __init__ (self , url : str , base : Optional [str ] = None ):
118
148
url_bytes = url .encode ('utf-8' )
119
149
120
150
if base is None :
@@ -150,7 +180,7 @@ def __deepcopy__(self, memo):
150
180
151
181
return ret
152
182
153
- def __delattr__ (self , attr ):
183
+ def __delattr__ (self , attr : str ):
154
184
if attr in CLEAR_ATTRIBUTES :
155
185
clear_func = getattr (lib , f'ada_clear_{ attr } ' )
156
186
clear_func (self .urlobj )
@@ -160,10 +190,10 @@ def __delattr__(self, attr):
160
190
else :
161
191
raise AttributeError (f'cannot remove { attr } ' )
162
192
163
- def __dir__ (self ):
193
+ def __dir__ (self ) -> List [ str ] :
164
194
return super ().__dir__ () + list (PARSE_ATTRIBUTES )
165
195
166
- def __getattr__ (self , attr ) :
196
+ def __getattr__ (self , attr : str ) -> Union [ str , HostType ] :
167
197
if attr in GET_ATTRIBUTES :
168
198
get_func = getattr (lib , f'ada_get_{ attr } ' )
169
199
data = get_func (self .urlobj )
@@ -179,7 +209,7 @@ def __getattr__(self, attr):
179
209
180
210
raise AttributeError (f'no attribute named { attr } ' )
181
211
182
- def __setattr__ (self , attr , value ) :
212
+ def __setattr__ (self , attr : str , value : str ) -> None :
183
213
if attr in SET_ATTRIBUTES :
184
214
try :
185
215
value_bytes = value .encode ()
@@ -202,7 +232,7 @@ def __repr__(self):
202
232
return f'<URL "{ self .href } ">'
203
233
204
234
@staticmethod
205
- def can_parse (url , base = None ):
235
+ def can_parse (url : str , base : Optional [ str ] = None ) -> bool :
206
236
try :
207
237
url_bytes = url .encode ('utf-8' )
208
238
except Exception :
@@ -221,7 +251,7 @@ def can_parse(url, base=None):
221
251
)
222
252
223
253
224
- def check_url (s ) :
254
+ def check_url (s : str ) -> bool :
225
255
"""
226
256
Returns ``True`` if *s* represents a valid URL, and ``False`` otherwise.
227
257
@@ -243,7 +273,7 @@ def check_url(s):
243
273
return lib .ada_is_valid (urlobj )
244
274
245
275
246
- def join_url (base_url , s ) :
276
+ def join_url (base_url : str , s : str ) -> str :
247
277
"""
248
278
Return the URL that results from joining *base_url* to *s*.
249
279
Raises ``ValueError`` if no valid URL can be constructed.
@@ -276,7 +306,7 @@ def join_url(base_url, s):
276
306
return _get_str (lib .ada_get_href (urlobj ))
277
307
278
308
279
- def normalize_url (s ) :
309
+ def normalize_url (s : str ) -> str :
280
310
"""
281
311
Returns a "normalized" URL with all ``'..'`` and ``'/'`` characters resolved.
282
312
@@ -290,7 +320,7 @@ def normalize_url(s):
290
320
return parse_url (s , attributes = ('href' ,))['href' ]
291
321
292
322
293
- def parse_url (s , attributes = PARSE_ATTRIBUTES ):
323
+ def parse_url (s : str , attributes : Iterable [ str ] = PARSE_ATTRIBUTES ) -> ParseAttributes :
294
324
"""
295
325
Returns a dictionary with the parsed components of the URL represented by *s*.
296
326
@@ -354,7 +384,7 @@ def parse_url(s, attributes=PARSE_ATTRIBUTES):
354
384
return ret
355
385
356
386
357
- def replace_url (s , ** kwargs ) :
387
+ def replace_url (s : str , ** kwargs : str ) -> str :
358
388
"""
359
389
Start with the URL represented by *s*, replace the attributes given in the *kwargs*
360
390
mapping, and return a normalized URL with the result.
@@ -433,15 +463,15 @@ class idna:
433
463
"""
434
464
435
465
@staticmethod
436
- def decode (s ) :
466
+ def decode (s : Union [ str , bytes ]) -> str :
437
467
if isinstance (s , str ):
438
468
s = s .encode ('ascii' )
439
469
440
470
data = _get_obj (lib .ada_idna_to_unicode , lib .ada_free_owned_string , s , len (s ))
441
471
return _get_str (data )
442
472
443
473
@staticmethod
444
- def encode (s ) :
474
+ def encode (s : Union [ str , bytes ]) -> str :
445
475
if isinstance (s , str ):
446
476
s = s .encode ('utf-8' )
447
477
0 commit comments