@@ -126,13 +126,18 @@ def end_callback(instance):
126
126
127
127
128
128
class fake_time :
129
- def __init__ (self , datetime_spec , only_main_thread = True , tz_offset = None ):
129
+ def __init__ (self , datetime_spec = None , only_main_thread = True , tz_offset = None , timestamp_file = None ):
130
130
self .only_main_thread = only_main_thread
131
131
self .timezone_str = 'UTC'
132
132
if tz_offset is not None :
133
133
self .timezone_str = 'Etc/GMT{0:+}' .format (- tz_offset )
134
134
135
+ if not datetime_spec and not timestamp_file :
136
+ raise ValueError ("Either 'datetime_spec' or 'timestamp_file' must be passed." )
137
+
135
138
self .time_to_freeze = datetime_spec
139
+ self .timestamp_file = timestamp_file
140
+
136
141
if isinstance (datetime_spec , basestring ):
137
142
self .time_to_freeze = utc .localize (dateutil .parser .parse (datetime_spec )) \
138
143
.astimezone (timezone (self .timezone_str ))
@@ -164,21 +169,31 @@ def _should_patch_uuid(self):
164
169
def _format_datetime (self , _datetime ):
165
170
return _datetime .strftime (_FAKETIME_FMT )
166
171
172
+ def _update_time (self , time ):
173
+ if not self .timestamp_file :
174
+ os .environ ['FAKETIME' ] = self ._format_datetime (time )
175
+ else :
176
+ if time :
177
+ with open (self .timestamp_file , "w" ) as fd :
178
+ fd .write (self ._format_datetime (time ))
179
+ os .environ ['FAKETIME_TIMESTAMP_FILE' ] = self .timestamp_file
180
+
167
181
def tick (self , delta = datetime .timedelta (seconds = 1 )):
168
182
self .time_to_freeze += delta
169
- os . environ [ 'FAKETIME' ] = self ._format_datetime (self .time_to_freeze )
183
+ self ._update_time (self .time_to_freeze )
170
184
171
185
def __enter__ (self ):
172
186
if self ._should_fake ():
173
187
begin_callback (self )
174
188
self ._prev_spec = os .environ .get ('FAKETIME' )
175
189
self ._prev_tz = os .environ .get ('TZ' )
176
190
self ._prev_fmt = os .environ .get ('FAKETIME_FMT' )
191
+ self ._prev_timestamp_file = os .environ .get ('FAKETIME_TIMESTAMP_FILE' )
177
192
178
193
os .environ ['TZ' ] = self .timezone_str
179
194
180
195
time .tzset ()
181
- os . environ [ 'FAKETIME' ] = self ._format_datetime (self .time_to_freeze )
196
+ self ._update_time (self .time_to_freeze )
182
197
os .environ ['FAKETIME_FMT' ] = _FAKETIME_FMT
183
198
184
199
func_name = self ._should_patch_uuid ()
@@ -200,10 +215,17 @@ def __exit__(self, *exc):
200
215
del os .environ ['TZ' ]
201
216
time .tzset ()
202
217
203
- if self ._prev_spec is not None :
204
- os .environ ['FAKETIME' ] = self ._prev_spec
218
+ if self .timestamp_file :
219
+ if self ._prev_timestamp_file is not None :
220
+ os .environ ['FAKETIME_TIMESTAMP_FILE' ] = self ._prev_timestamp_file
221
+ elif 'FAKETIME_TIMESTAMP_FILE' in os .environ :
222
+ del os .environ ['FAKETIME_TIMESTAMP_FILE' ]
223
+
205
224
else :
206
- del os .environ ['FAKETIME' ]
225
+ if self ._prev_spec is not None :
226
+ os .environ ['FAKETIME' ] = self ._prev_spec
227
+ else :
228
+ del os .environ ['FAKETIME' ]
207
229
208
230
if self ._prev_fmt is not None :
209
231
os .environ ['FAKETIME_FMT' ] = self ._prev_spec
0 commit comments