Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/starlette/convertors.py: 60%

50 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:12 +0000

1import math 

2import typing 

3import uuid 

4 

5T = typing.TypeVar("T") 

6 

7 

8class Convertor(typing.Generic[T]): 

9 regex: typing.ClassVar[str] = "" 

10 

11 def convert(self, value: str) -> T: 

12 raise NotImplementedError() # pragma: no cover 

13 

14 def to_string(self, value: T) -> str: 

15 raise NotImplementedError() # pragma: no cover 

16 

17 

18class StringConvertor(Convertor): 

19 regex = "[^/]+" 

20 

21 def convert(self, value: str) -> str: 

22 return value 

23 

24 def to_string(self, value: str) -> str: 

25 value = str(value) 

26 assert "/" not in value, "May not contain path separators" 

27 assert value, "Must not be empty" 

28 return value 

29 

30 

31class PathConvertor(Convertor): 

32 regex = ".*" 

33 

34 def convert(self, value: str) -> str: 

35 return str(value) 

36 

37 def to_string(self, value: str) -> str: 

38 return str(value) 

39 

40 

41class IntegerConvertor(Convertor): 

42 regex = "[0-9]+" 

43 

44 def convert(self, value: str) -> int: 

45 return int(value) 

46 

47 def to_string(self, value: int) -> str: 

48 value = int(value) 

49 assert value >= 0, "Negative integers are not supported" 

50 return str(value) 

51 

52 

53class FloatConvertor(Convertor): 

54 regex = r"[0-9]+(\.[0-9]+)?" 

55 

56 def convert(self, value: str) -> float: 

57 return float(value) 

58 

59 def to_string(self, value: float) -> str: 

60 value = float(value) 

61 assert value >= 0.0, "Negative floats are not supported" 

62 assert not math.isnan(value), "NaN values are not supported" 

63 assert not math.isinf(value), "Infinite values are not supported" 

64 return ("%0.20f" % value).rstrip("0").rstrip(".") 

65 

66 

67class UUIDConvertor(Convertor): 

68 regex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" 

69 

70 def convert(self, value: str) -> uuid.UUID: 

71 return uuid.UUID(value) 

72 

73 def to_string(self, value: uuid.UUID) -> str: 

74 return str(value) 

75 

76 

77CONVERTOR_TYPES = { 

78 "str": StringConvertor(), 

79 "path": PathConvertor(), 

80 "int": IntegerConvertor(), 

81 "float": FloatConvertor(), 

82 "uuid": UUIDConvertor(), 

83} 

84 

85 

86def register_url_convertor(key: str, convertor: Convertor) -> None: 

87 CONVERTOR_TYPES[key] = convertor