@@ -18,10 +18,10 @@ def __init__(self, datetime_class: type[DateTime] = DateTime) -> None:
18
18
self ._datetime_class : type [DateTime ] = datetime_class
19
19
20
20
def freeze (self ) -> Self :
21
- raise NotImplementedError ()
21
+ raise self . _not_implemented ()
22
22
23
23
def travel_back (self ) -> Self :
24
- raise NotImplementedError ()
24
+ raise self . _not_implemented ()
25
25
26
26
def travel (
27
27
self ,
@@ -34,10 +34,10 @@ def travel(
34
34
seconds : int = 0 ,
35
35
microseconds : int = 0 ,
36
36
) -> Self :
37
- raise NotImplementedError ()
37
+ raise self . _not_implemented ()
38
38
39
39
def travel_to (self , dt : DateTime , * , freeze : bool = False ) -> Self :
40
- raise NotImplementedError ()
40
+ raise self . _not_implemented ()
41
41
42
42
def __enter__ (self ) -> Self :
43
43
return self
@@ -50,103 +50,123 @@ def __exit__(
50
50
) -> None :
51
51
...
52
52
53
+ def _not_implemented (self ) -> NotImplementedError :
54
+ return NotImplementedError ()
55
+
53
56
54
57
if not PYPY :
55
- import time_machine
58
+ try :
59
+ import time_machine
60
+ except ImportError :
61
+ time_machine = None # type: ignore[assignment]
56
62
57
- class Traveller (BaseTraveller ):
58
- def __init__ (self , datetime_class : type [DateTime ] = DateTime ) -> None :
59
- super ().__init__ (datetime_class )
63
+ if time_machine is not None :
60
64
61
- self . _started : bool = False
62
- self . _traveller : time_machine . travel | None = None
63
- self . _coordinates : time_machine . Coordinates | None = None
65
+ class Traveller ( BaseTraveller ):
66
+ def __init__ ( self , datetime_class : type [ DateTime ] = DateTime ) -> None :
67
+ super (). __init__ ( datetime_class )
64
68
65
- def freeze (self ) -> Self :
66
- if self ._started :
67
- cast (time_machine .Coordinates , self ._coordinates ).move_to (
68
- self ._datetime_class .now (), tick = False
69
- )
70
- else :
71
- self ._start (freeze = True )
69
+ self ._started : bool = False
70
+ self ._traveller : time_machine .travel | None = None
71
+ self ._coordinates : time_machine .Coordinates | None = None
72
72
73
- return self
73
+ def freeze (self ) -> Self :
74
+ if self ._started :
75
+ cast (time_machine .Coordinates , self ._coordinates ).move_to (
76
+ self ._datetime_class .now (), tick = False
77
+ )
78
+ else :
79
+ self ._start (freeze = True )
74
80
75
- def travel_back (self ) -> Self :
76
- if not self ._started :
77
81
return self
78
82
79
- cast (time_machine .travel , self ._traveller ).stop ()
80
- self ._coordinates = None
81
- self ._traveller = None
82
- self ._started = False
83
-
84
- return self
85
-
86
- def travel (
87
- self ,
88
- years : int = 0 ,
89
- months : int = 0 ,
90
- weeks : int = 0 ,
91
- days : int = 0 ,
92
- hours : int = 0 ,
93
- minutes : int = 0 ,
94
- seconds : int = 0 ,
95
- microseconds : int = 0 ,
96
- * ,
97
- freeze : bool = False ,
98
- ) -> Self :
99
- self ._start (freeze = freeze )
100
-
101
- cast (time_machine .Coordinates , self ._coordinates ).move_to (
102
- self ._datetime_class .now ().add (
103
- years = years ,
104
- months = months ,
105
- weeks = weeks ,
106
- days = days ,
107
- hours = hours ,
108
- minutes = minutes ,
109
- seconds = seconds ,
110
- microseconds = microseconds ,
83
+ def travel_back (self ) -> Self :
84
+ if not self ._started :
85
+ return self
86
+
87
+ cast (time_machine .travel , self ._traveller ).stop ()
88
+ self ._coordinates = None
89
+ self ._traveller = None
90
+ self ._started = False
91
+
92
+ return self
93
+
94
+ def travel (
95
+ self ,
96
+ years : int = 0 ,
97
+ months : int = 0 ,
98
+ weeks : int = 0 ,
99
+ days : int = 0 ,
100
+ hours : int = 0 ,
101
+ minutes : int = 0 ,
102
+ seconds : int = 0 ,
103
+ microseconds : int = 0 ,
104
+ * ,
105
+ freeze : bool = False ,
106
+ ) -> Self :
107
+ self ._start (freeze = freeze )
108
+
109
+ cast (time_machine .Coordinates , self ._coordinates ).move_to (
110
+ self ._datetime_class .now ().add (
111
+ years = years ,
112
+ months = months ,
113
+ weeks = weeks ,
114
+ days = days ,
115
+ hours = hours ,
116
+ minutes = minutes ,
117
+ seconds = seconds ,
118
+ microseconds = microseconds ,
119
+ )
111
120
)
112
- )
113
121
114
- return self
122
+ return self
115
123
116
- def travel_to (self , dt : DateTime , * , freeze : bool = False ) -> Self :
117
- self ._start (freeze = freeze )
124
+ def travel_to (self , dt : DateTime , * , freeze : bool = False ) -> Self :
125
+ self ._start (freeze = freeze )
118
126
119
- cast (time_machine .Coordinates , self ._coordinates ).move_to (dt )
127
+ cast (time_machine .Coordinates , self ._coordinates ).move_to (dt )
120
128
121
- return self
129
+ return self
122
130
123
- def _start (self , freeze : bool = False ) -> None :
124
- if self ._started :
125
- return
131
+ def _start (self , freeze : bool = False ) -> None :
132
+ if self ._started :
133
+ return
126
134
127
- if not self ._traveller :
128
- self ._traveller = time_machine .travel (
129
- self ._datetime_class .now (), tick = not freeze
130
- )
135
+ if not self ._traveller :
136
+ self ._traveller = time_machine .travel (
137
+ self ._datetime_class .now (), tick = not freeze
138
+ )
131
139
132
- self ._coordinates = self ._traveller .start ()
140
+ self ._coordinates = self ._traveller .start ()
133
141
134
- self ._started = True
142
+ self ._started = True
135
143
136
- def __enter__ (self ) -> Self :
137
- self ._start ()
144
+ def __enter__ (self ) -> Self :
145
+ self ._start ()
138
146
139
- return self
147
+ return self
140
148
141
- def __exit__ (
142
- self ,
143
- exc_type : type [BaseException ] | None ,
144
- exc_val : BaseException | None ,
145
- exc_tb : TracebackType ,
146
- ) -> None :
147
- self .travel_back ()
149
+ def __exit__ (
150
+ self ,
151
+ exc_type : type [BaseException ] | None ,
152
+ exc_val : BaseException | None ,
153
+ exc_tb : TracebackType ,
154
+ ) -> None :
155
+ self .travel_back ()
156
+
157
+ else :
158
+
159
+ class Traveller (BaseTraveller ): # type: ignore[no-redef]
160
+ def _not_implemented (self ) -> NotImplementedError :
161
+ return NotImplementedError (
162
+ "Time travelling is an optional feature. "
163
+ 'You can add it by installing Pendulum with the "test" extra.'
164
+ )
148
165
149
166
else :
150
167
151
168
class Traveller (BaseTraveller ): # type: ignore[no-redef]
152
- ...
169
+ def _not_implemented (self ) -> NotImplementedError :
170
+ return NotImplementedError (
171
+ "Time travelling is not supported on the PyPy Python implementation."
172
+ )
0 commit comments