5
5
# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
6
6
7
7
8
+ import builtins
9
+ import typing
10
+ import typing_extensions
11
+
12
+
8
13
__all__ = (
9
14
'BitString' , 'Point' , 'Path' , 'Polygon' ,
10
15
'Box' , 'Line' , 'LineSegment' , 'Circle' ,
11
16
)
12
17
18
+ _BS = typing .TypeVar ('_BS' , bound = 'BitString' )
19
+ _P = typing .TypeVar ('_P' , bound = 'Point' )
20
+ _BitOrder = typing_extensions .Literal ['big' , 'little' ]
21
+
13
22
14
23
class BitString :
15
24
"""Immutable representation of PostgreSQL `bit` and `varbit` types."""
16
25
17
26
__slots__ = '_bytes' , '_bitlength'
18
27
19
- def __init__ (self , bitstring = None ):
28
+ def __init__ (self ,
29
+ bitstring : typing .Optional [builtins .bytes ] = None ) -> None :
20
30
if not bitstring :
21
31
self ._bytes = bytes ()
22
32
self ._bitlength = 0
@@ -28,7 +38,7 @@ def __init__(self, bitstring=None):
28
38
bit_pos = 0
29
39
30
40
for i , bit in enumerate (bitstring ):
31
- if bit == ' ' :
41
+ if bit == ' ' : # type: ignore
32
42
continue
33
43
bit = int (bit )
34
44
if bit != 0 and bit != 1 :
@@ -53,14 +63,15 @@ def __init__(self, bitstring=None):
53
63
self ._bitlength = bitlen
54
64
55
65
@classmethod
56
- def frombytes (cls , bytes_ = None , bitlength = None ):
57
- if bitlength is None and bytes_ is None :
58
- bytes_ = bytes ()
59
- bitlength = 0
60
-
61
- elif bitlength is None :
62
- bitlength = len (bytes_ ) * 8
63
-
66
+ def frombytes (cls : typing .Type [_BS ],
67
+ bytes_ : typing .Optional [builtins .bytes ] = None ,
68
+ bitlength : typing .Optional [int ] = None ) -> _BS :
69
+ if bitlength is None :
70
+ if bytes_ is None :
71
+ bytes_ = bytes ()
72
+ bitlength = 0
73
+ else :
74
+ bitlength = len (bytes_ ) * 8
64
75
else :
65
76
if bytes_ is None :
66
77
bytes_ = bytes (bitlength // 8 + 1 )
@@ -87,10 +98,10 @@ def frombytes(cls, bytes_=None, bitlength=None):
87
98
return result
88
99
89
100
@property
90
- def bytes (self ):
101
+ def bytes (self ) -> builtins . bytes :
91
102
return self ._bytes
92
103
93
- def as_string (self ):
104
+ def as_string (self ) -> str :
94
105
s = ''
95
106
96
107
for i in range (self ._bitlength ):
@@ -100,7 +111,8 @@ def as_string(self):
100
111
101
112
return s .strip ()
102
113
103
- def to_int (self , bitorder = 'big' , * , signed = False ):
114
+ def to_int (self , bitorder : _BitOrder = 'big' ,
115
+ * , signed : bool = False ) -> int :
104
116
"""Interpret the BitString as a Python int.
105
117
Acts similarly to int.from_bytes.
106
118
@@ -135,7 +147,8 @@ def to_int(self, bitorder='big', *, signed=False):
135
147
return x
136
148
137
149
@classmethod
138
- def from_int (cls , x , length , bitorder = 'big' , * , signed = False ):
150
+ def from_int (cls : typing .Type [_BS ], x : int , length : int ,
151
+ bitorder : _BitOrder = 'big' , * , signed : bool = False ) -> _BS :
139
152
"""Represent the Python int x as a BitString.
140
153
Acts similarly to int.to_bytes.
141
154
@@ -187,27 +200,27 @@ def from_int(cls, x, length, bitorder='big', *, signed=False):
187
200
bytes_ = x .to_bytes ((length + 7 ) // 8 , byteorder = 'big' )
188
201
return cls .frombytes (bytes_ , length )
189
202
190
- def __repr__ (self ):
203
+ def __repr__ (self ) -> str :
191
204
return '<BitString {}>' .format (self .as_string ())
192
205
193
206
__str__ = __repr__
194
207
195
- def __eq__ (self , other ) :
208
+ def __eq__ (self , other : object ) -> bool :
196
209
if not isinstance (other , BitString ):
197
210
return NotImplemented
198
211
199
212
return (self ._bytes == other ._bytes and
200
213
self ._bitlength == other ._bitlength )
201
214
202
- def __hash__ (self ):
215
+ def __hash__ (self ) -> int :
203
216
return hash ((self ._bytes , self ._bitlength ))
204
217
205
- def _getitem (self , i ) :
218
+ def _getitem (self , i : int ) -> int :
206
219
byte = self ._bytes [i // 8 ]
207
220
shift = 8 - i % 8 - 1
208
221
return (byte >> shift ) & 0x1
209
222
210
- def __getitem__ (self , i ) :
223
+ def __getitem__ (self , i : int ) -> int :
211
224
if isinstance (i , slice ):
212
225
raise NotImplementedError ('BitString does not support slices' )
213
226
@@ -216,100 +229,117 @@ def __getitem__(self, i):
216
229
217
230
return self ._getitem (i )
218
231
219
- def __len__ (self ):
232
+ def __len__ (self ) -> int :
220
233
return self ._bitlength
221
234
222
235
223
- class Point (tuple ):
236
+ class Point (typing . Tuple [ float , float ] ):
224
237
"""Immutable representation of PostgreSQL `point` type."""
225
238
226
239
__slots__ = ()
227
240
228
- def __new__ (cls , x , y ):
229
- return super ().__new__ (cls , (float (x ), float (y )))
230
-
231
- def __repr__ (self ):
241
+ def __new__ (cls ,
242
+ x : typing .Union [typing .SupportsFloat ,
243
+ 'builtins._SupportsIndex' ,
244
+ typing .Text ,
245
+ builtins .bytes ,
246
+ builtins .bytearray ],
247
+ y : typing .Union [typing .SupportsFloat ,
248
+ 'builtins._SupportsIndex' ,
249
+ typing .Text ,
250
+ builtins .bytes ,
251
+ builtins .bytearray ]) -> 'Point' :
252
+ return super ().__new__ (cls ,
253
+ typing .cast (typing .Any , (float (x ), float (y ))))
254
+
255
+ def __repr__ (self ) -> str :
232
256
return '{}.{}({})' .format (
233
257
type (self ).__module__ ,
234
258
type (self ).__name__ ,
235
259
tuple .__repr__ (self )
236
260
)
237
261
238
262
@property
239
- def x (self ):
263
+ def x (self ) -> float :
240
264
return self [0 ]
241
265
242
266
@property
243
- def y (self ):
267
+ def y (self ) -> float :
244
268
return self [1 ]
245
269
246
270
247
- class Box (tuple ):
271
+ class Box (typing . Tuple [ Point , Point ] ):
248
272
"""Immutable representation of PostgreSQL `box` type."""
249
273
250
274
__slots__ = ()
251
275
252
- def __new__ (cls , high , low ):
253
- return super ().__new__ (cls , (Point (* high ), Point (* low )))
276
+ def __new__ (cls , high : typing .Sequence [float ],
277
+ low : typing .Sequence [float ]) -> 'Box' :
278
+ return super ().__new__ (cls ,
279
+ typing .cast (typing .Any , (Point (* high ),
280
+ Point (* low ))))
254
281
255
- def __repr__ (self ):
282
+ def __repr__ (self ) -> str :
256
283
return '{}.{}({})' .format (
257
284
type (self ).__module__ ,
258
285
type (self ).__name__ ,
259
286
tuple .__repr__ (self )
260
287
)
261
288
262
289
@property
263
- def high (self ):
290
+ def high (self ) -> Point :
264
291
return self [0 ]
265
292
266
293
@property
267
- def low (self ):
294
+ def low (self ) -> Point :
268
295
return self [1 ]
269
296
270
297
271
- class Line (tuple ):
298
+ class Line (typing . Tuple [ float , float , float ] ):
272
299
"""Immutable representation of PostgreSQL `line` type."""
273
300
274
301
__slots__ = ()
275
302
276
- def __new__ (cls , A , B , C ) :
277
- return super ().__new__ (cls , ( A , B , C ))
303
+ def __new__ (cls , A : float , B : float , C : float ) -> 'Line' :
304
+ return super ().__new__ (cls , typing . cast ( typing . Any , ( A , B , C ) ))
278
305
279
306
@property
280
- def A (self ):
307
+ def A (self ) -> float :
281
308
return self [0 ]
282
309
283
310
@property
284
- def B (self ):
311
+ def B (self ) -> float :
285
312
return self [1 ]
286
313
287
314
@property
288
- def C (self ):
315
+ def C (self ) -> float :
289
316
return self [2 ]
290
317
291
318
292
- class LineSegment (tuple ):
319
+ class LineSegment (typing . Tuple [ Point , Point ] ):
293
320
"""Immutable representation of PostgreSQL `lseg` type."""
294
321
295
322
__slots__ = ()
296
323
297
- def __new__ (cls , p1 , p2 ):
298
- return super ().__new__ (cls , (Point (* p1 ), Point (* p2 )))
324
+ def __new__ (cls , p1 : typing .Sequence [float ],
325
+ p2 : typing .Sequence [float ]) -> 'LineSegment' :
326
+ return super ().__new__ (cls ,
327
+ typing .cast (typing .Any , (Point (* p1 ),
328
+ Point (* p2 ))))
299
329
300
- def __repr__ (self ):
330
+ def __repr__ (self ) -> str :
301
331
return '{}.{}({})' .format (
302
332
type (self ).__module__ ,
303
333
type (self ).__name__ ,
304
334
tuple .__repr__ (self )
305
335
)
306
336
307
337
@property
308
- def p1 (self ):
338
+ def p1 (self ) -> Point :
309
339
return self [0 ]
310
340
311
341
@property
312
- def p2 (self ):
342
+ def p2 (self ) -> Point :
313
343
return self [1 ]
314
344
315
345
@@ -318,34 +348,44 @@ class Path:
318
348
319
349
__slots__ = '_is_closed' , 'points'
320
350
321
- def __init__ (self , * points , is_closed = False ):
351
+ def __init__ (self , * points : typing .Sequence [float ],
352
+ is_closed : bool = False ) -> None :
322
353
self .points = tuple (Point (* p ) for p in points )
323
354
self ._is_closed = is_closed
324
355
325
356
@property
326
- def is_closed (self ):
357
+ def is_closed (self ) -> bool :
327
358
return self ._is_closed
328
359
329
- def __eq__ (self , other ) :
360
+ def __eq__ (self , other : object ) -> bool :
330
361
if not isinstance (other , Path ):
331
362
return NotImplemented
332
363
333
364
return (self .points == other .points and
334
365
self ._is_closed == other ._is_closed )
335
366
336
- def __hash__ (self ):
367
+ def __hash__ (self ) -> int :
337
368
return hash ((self .points , self .is_closed ))
338
369
339
- def __iter__ (self ):
370
+ def __iter__ (self ) -> typing . Iterator [ Point ] :
340
371
return iter (self .points )
341
372
342
- def __len__ (self ):
373
+ def __len__ (self ) -> int :
343
374
return len (self .points )
344
375
345
- def __getitem__ (self , i ):
376
+ @typing .overload
377
+ def __getitem__ (self , i : int ) -> Point :
378
+ ...
379
+
380
+ @typing .overload
381
+ def __getitem__ (self , i : slice ) -> typing .Tuple [Point , ...]:
382
+ ...
383
+
384
+ def __getitem__ (self , i : typing .Union [int , slice ]) \
385
+ -> typing .Union [Point , typing .Tuple [Point , ...]]:
346
386
return self .points [i ]
347
387
348
- def __contains__ (self , point ) :
388
+ def __contains__ (self , point : object ) -> bool :
349
389
return point in self .points
350
390
351
391
@@ -354,23 +394,23 @@ class Polygon(Path):
354
394
355
395
__slots__ = ()
356
396
357
- def __init__ (self , * points ) :
397
+ def __init__ (self , * points : typing . Sequence [ float ]) -> None :
358
398
# polygon is always closed
359
399
super ().__init__ (* points , is_closed = True )
360
400
361
401
362
- class Circle (tuple ):
402
+ class Circle (typing . Tuple [ Point , float ] ):
363
403
"""Immutable representation of PostgreSQL `circle` type."""
364
404
365
405
__slots__ = ()
366
406
367
- def __new__ (cls , center , radius ) :
368
- return super ().__new__ (cls , ( center , radius ))
407
+ def __new__ (cls , center : Point , radius : float ) -> 'Circle' :
408
+ return super ().__new__ (cls , typing . cast ( typing . Any , ( center , radius ) ))
369
409
370
410
@property
371
- def center (self ):
411
+ def center (self ) -> Point :
372
412
return self [0 ]
373
413
374
414
@property
375
- def radius (self ):
415
+ def radius (self ) -> float :
376
416
return self [1 ]
0 commit comments