commit 4d998c9d6b130ed4e2d54cb96b010fec749a9c59 Author: xtreak Date: Wed Jun 19 14:54:22 2019 +0000 Patch time.time_ns to support Python 3.8 diff --git a/CHANGELOG b/CHANGELOG index efac4d3..14d96be 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ Latest * Ignore Selenium * Move to pytest * Conditionally patch time.clock +* Patch time.time_ns added in Python 3.7 0.3.11 ------ @@ -57,4 +58,4 @@ Latest * Add `tick` argument to allow time to move forward * Performance improvements -* Fix timezone example in README \ No newline at end of file +* Fix timezone example in README diff --git a/freezegun/api.py b/freezegun/api.py index 5e7d7fa..bc61270 100644 --- a/freezegun/api.py +++ b/freezegun/api.py @@ -20,6 +20,7 @@ try: except ImportError: MayaDT = None +_TIME_NS_PRESENT = hasattr(time, 'time_ns') real_time = time.time real_localtime = time.localtime @@ -28,6 +29,11 @@ real_strftime = time.strftime real_date = datetime.date real_datetime = datetime.datetime real_date_objects = [real_time, real_localtime, real_gmtime, real_strftime, real_date, real_datetime] + +if _TIME_NS_PRESENT: + real_time_ns = time.time_ns + real_date_objects.append(real_time_ns) + _real_time_object_ids = set(id(obj) for obj in real_date_objects) # time.clock is deprecated and was removed in Python 3.8 @@ -175,6 +181,12 @@ def fake_time(): current_time = get_current_time() return calendar.timegm(current_time.timetuple()) + current_time.microsecond / 1000000.0 +if _TIME_NS_PRESENT: + def fake_time_ns(): + if _should_use_real_time(): + return real_time_ns() + return int(int(fake_time()) * 1e9) + def fake_localtime(t=None): if t is not None: @@ -331,7 +343,7 @@ class FakeDatetime(with_metaclass(FakeDatetimeMeta, real_datetime, FakeDate)): def date(self): return date_to_fakedate(self) - + @property def nanosecond(self): try: @@ -599,6 +611,10 @@ class _freeze_time(object): ('real_time', real_time, fake_time), ] + if _TIME_NS_PRESENT: + time.time_ns = fake_time_ns + to_patch.append(('real_time_ns', real_time_ns, fake_time_ns)) + if real_clock is not None: # time.clock is deprecated and was removed in Python 3.8 time.clock = fake_clock @@ -741,7 +757,7 @@ def freeze_time(time_to_freeze=None, tz_offset=0, ignore=None, tick=False, as_ar ignore.append('selenium') ignore.append('_pytest.terminal.') ignore.append('_pytest.runner.') - + return _freeze_time(time_to_freeze, tz_offset, ignore, tick, as_arg, auto_tick_seconds) diff --git a/tests/test_datetimes.py b/tests/test_datetimes.py index cfef4a1..688fdce 100644 --- a/tests/test_datetimes.py +++ b/tests/test_datetimes.py @@ -19,6 +19,7 @@ except ImportError: # time.clock was removed in Python 3.8 HAS_CLOCK = hasattr(time, 'clock') +HAS_TIME_NS = hasattr(time, 'time_ns') class temp_locale(object): """Temporarily change the locale.""" @@ -656,3 +657,18 @@ def test_should_use_real_time(): assert time.gmtime() != expected_frozen_gmt if HAS_CLOCK: assert time.clock() != expected_clock + + +@pytest.mark.skipif(not HAS_TIME_NS, + reason="time.time_ns is present only on 3.7 and above") +def test_time_ns(): + freezer = freeze_time("2012-01-14") + local_time = datetime.datetime(2012, 1, 14) + utc_time = local_time - datetime.timedelta(seconds=time.timezone) + expected_timestamp = time.mktime(utc_time.timetuple()) + + freezer.start() + assert time.time() == expected_timestamp + assert time.time_ns() == expected_timestamp * 1e9 + freezer.stop() + assert time.time() != expected_timestamp