Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pendulum/parser.py: 33%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

48 statements  

1from __future__ import annotations 

2 

3import datetime 

4import os 

5import typing as t 

6 

7import pendulum 

8 

9from pendulum.duration import Duration 

10from pendulum.parsing import _Interval 

11from pendulum.parsing import parse as base_parse 

12from pendulum.tz.timezone import UTC 

13 

14 

15if t.TYPE_CHECKING: 

16 from pendulum.date import Date 

17 from pendulum.datetime import DateTime 

18 from pendulum.interval import Interval 

19 from pendulum.time import Time 

20 

21with_extensions = os.getenv("PENDULUM_EXTENSIONS", "1") == "1" 

22 

23try: 

24 if not with_extensions: 

25 raise ImportError() 

26 

27 from pendulum._pendulum import Duration as RustDuration 

28except ImportError: 

29 RustDuration = None # type: ignore[assignment,misc] 

30 

31 

32def parse(text: str, **options: t.Any) -> Date | Time | DateTime | Duration: 

33 # Use the mock now value if it exists 

34 options["now"] = options.get("now") 

35 

36 return _parse(text, **options) 

37 

38 

39def _parse( 

40 text: str, **options: t.Any 

41) -> Date | DateTime | Time | Duration | Interval[DateTime]: 

42 """ 

43 Parses a string with the given options. 

44 

45 :param text: The string to parse. 

46 """ 

47 # Handling special cases 

48 if text == "now": 

49 return pendulum.now() 

50 

51 parsed = base_parse(text, **options) 

52 

53 if isinstance(parsed, datetime.datetime): 

54 return pendulum.datetime( 

55 parsed.year, 

56 parsed.month, 

57 parsed.day, 

58 parsed.hour, 

59 parsed.minute, 

60 parsed.second, 

61 parsed.microsecond, 

62 tz=parsed.tzinfo or options.get("tz", UTC), 

63 ) 

64 

65 if isinstance(parsed, datetime.date): 

66 return pendulum.date(parsed.year, parsed.month, parsed.day) 

67 

68 if isinstance(parsed, datetime.time): 

69 return pendulum.time( 

70 parsed.hour, parsed.minute, parsed.second, parsed.microsecond 

71 ) 

72 

73 if isinstance(parsed, _Interval): 

74 if parsed.duration is not None: 

75 duration = parsed.duration 

76 

77 if parsed.start is not None: 

78 dt = pendulum.instance(parsed.start, tz=options.get("tz", UTC)) 

79 

80 return pendulum.interval( 

81 dt, 

82 dt.add( 

83 years=duration.years, 

84 months=duration.months, 

85 weeks=duration.weeks, 

86 days=duration.remaining_days, 

87 hours=duration.hours, 

88 minutes=duration.minutes, 

89 seconds=duration.remaining_seconds, 

90 microseconds=duration.microseconds, 

91 ), 

92 ) 

93 

94 dt = pendulum.instance( 

95 t.cast("datetime.datetime", parsed.end), tz=options.get("tz", UTC) 

96 ) 

97 

98 return pendulum.interval( 

99 dt.subtract( 

100 years=duration.years, 

101 months=duration.months, 

102 weeks=duration.weeks, 

103 days=duration.remaining_days, 

104 hours=duration.hours, 

105 minutes=duration.minutes, 

106 seconds=duration.remaining_seconds, 

107 microseconds=duration.microseconds, 

108 ), 

109 dt, 

110 ) 

111 

112 return pendulum.interval( 

113 pendulum.instance( 

114 t.cast("datetime.datetime", parsed.start), tz=options.get("tz", UTC) 

115 ), 

116 pendulum.instance( 

117 t.cast("datetime.datetime", parsed.end), tz=options.get("tz", UTC) 

118 ), 

119 ) 

120 

121 if isinstance(parsed, Duration): 

122 return parsed 

123 

124 if RustDuration is not None and isinstance(parsed, RustDuration): 

125 return pendulum.duration( 

126 years=parsed.years, 

127 months=parsed.months, 

128 weeks=parsed.weeks, 

129 days=parsed.days, 

130 hours=parsed.hours, 

131 minutes=parsed.minutes, 

132 seconds=parsed.seconds, 

133 microseconds=parsed.microseconds, 

134 ) 

135 

136 raise NotImplementedError