freezegun-0.3.15/0000755000076500000240000000000013622627362014054 5ustar stevestaff00000000000000freezegun-0.3.15/PKG-INFO0000644000076500000240000002411413622627362015153 0ustar stevestaff00000000000000Metadata-Version: 1.2 Name: freezegun Version: 0.3.15 Summary: Let your Python tests travel through time Home-page: https://github.com/spulec/freezegun Author: Steve Pulec Author-email: spulec@gmail.com License: Apache 2.0 Description: FreezeGun: Let your Python tests travel through time ==================================================== .. image:: https://img.shields.io/pypi/v/freezegun.svg :target: https://pypi.python.org/pypi/freezegun/ .. image:: https://secure.travis-ci.org/spulec/freezegun.svg?branch=master :target: https://travis-ci.org/spulec/freezegun .. image:: https://coveralls.io/repos/spulec/freezegun/badge.svg?branch=master :target: https://coveralls.io/r/spulec/freezegun FreezeGun is a library that allows your Python tests to travel through time by mocking the datetime module. Usage ----- Once the decorator or context manager have been invoked, all calls to datetime.datetime.now(), datetime.datetime.utcnow(), datetime.date.today(), time.time(), time.localtime(), time.gmtime(), and time.strftime() will return the time that has been frozen. Decorator ~~~~~~~~~ .. code-block:: python from freezegun import freeze_time import datetime import unittest @freeze_time("2012-01-14") def test(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) # Or a unittest TestCase - freezes for every test, from the start of setUpClass to the end of tearDownClass @freeze_time("1955-11-12") class MyTests(unittest.TestCase): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(1955, 11, 12) # Or any other class - freezes around each callable (may not work in every case) @freeze_time("2012-01-14") class Tester(object): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) Context manager ~~~~~~~~~~~~~~~ .. code-block:: python from freezegun import freeze_time def test(): assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) with freeze_time("2012-01-14"): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) Raw use ~~~~~~~ .. code-block:: python from freezegun import freeze_time freezer = freeze_time("2012-01-14 12:00:01") freezer.start() assert datetime.datetime.now() == datetime.datetime(2012, 1, 14, 12, 0, 1) freezer.stop() Timezones ~~~~~~~~~ .. code-block:: python from freezegun import freeze_time @freeze_time("2012-01-14 03:21:34", tz_offset=-4) def test(): assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34) assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 21, 34) # datetime.date.today() uses local time assert datetime.date.today() == datetime.date(2012, 1, 13) @freeze_time("2012-01-14 03:21:34", tz_offset=-datetime.timedelta(hours=3, minutes=30)) def test_timedelta_offset(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 51, 34) Nice inputs ~~~~~~~~~~~ FreezeGun uses dateutil behind the scenes so you can have nice-looking datetimes. .. code-block:: python @freeze_time("Jan 14th, 2012") def test_nice_datetime(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) Function and generator objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun is able to handle function and generator objects. .. code-block:: python def test_lambda(): with freeze_time(lambda: datetime.datetime(2012, 1, 14)): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) def test_generator(): datetimes = (datetime.datetime(year, 1, 1) for year in range(2010, 2012)) with freeze_time(datetimes): assert datetime.datetime.now() == datetime.datetime(2010, 1, 1) with freeze_time(datetimes): assert datetime.datetime.now() == datetime.datetime(2011, 1, 1) # The next call to freeze_time(datetimes) would raise a StopIteration exception. ``tick`` argument ~~~~~~~~~~~~~~~~~ FreezeGun has an additional ``tick`` argument which will restart time at the given value, but then time will keep ticking. This is alternative to the default parameters which will keep time stopped. .. code-block:: python @freeze_time("Jan 14th, 2020", tick=True) def test_nice_datetime(): assert datetime.datetime.now() > datetime.datetime(2020, 1, 14) ``auto_tick_seconds`` argument ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun has an additional ``auto_tick_seconds`` argument which will autoincrement the value every time by the given amount from the start value. This is alternative to the default parameters which will keep time stopped. Note that given ``auto_tick_seconds`` the ``tick`` parameter will be ignored. .. code-block:: python @freeze_time("Jan 14th, 2020", auto_tick_seconds=15) def test_nice_datetime(): first_time = datetime.datetime.now() auto_incremented_time = datetime.datetime.now() assert first_time + datetime.timedelta(seconds=15) == auto_incremented_time Manual ticks ~~~~~~~~~~~~ FreezeGun allows for the time to be manually forwarded as well. .. code-block:: python def test_manual_increment(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.tick() initial_datetime += datetime.timedelta(seconds=1) assert frozen_datetime() == initial_datetime frozen_datetime.tick(delta=datetime.timedelta(seconds=10)) initial_datetime += datetime.timedelta(seconds=10) assert frozen_datetime() == initial_datetime Moving time to specify datetime ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun allows moving time to specific dates. .. code-block:: python def test_move_to(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) other_datetime = datetime.datetime(year=2, month=8, day=13, hour=14, minute=5, second=0) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.move_to(other_datetime) assert frozen_datetime() == other_datetime frozen_datetime.move_to(initial_datetime) assert frozen_datetime() == initial_datetime @freeze_time("2012-01-14", as_arg=True) def test(frozen_time): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) frozen_time.move_to("2014-02-12") assert datetime.datetime.now() == datetime.datetime(2014, 2, 12) Parameter for ``move_to`` can be any valid ``freeze_time`` date (string, date, datetime). Default arguments ~~~~~~~~~~~~~~~~~ Note that FreezeGun will not modify default arguments. The following code will print the current date. See `here `_ for why. .. code-block:: python from freezegun import freeze_time import datetime as dt def test(default=dt.date.today()): print(default) with freeze_time('2000-1-1'): test() Installation ------------ To install FreezeGun, simply: .. code-block:: bash $ pip install freezegun On Debian systems: .. code-block:: bash $ sudo apt-get install python-freezegun Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* freezegun-0.3.15/freezegun.egg-info/0000755000076500000240000000000013622627362017540 5ustar stevestaff00000000000000freezegun-0.3.15/freezegun.egg-info/PKG-INFO0000644000076500000240000002411413622627362020637 0ustar stevestaff00000000000000Metadata-Version: 1.2 Name: freezegun Version: 0.3.15 Summary: Let your Python tests travel through time Home-page: https://github.com/spulec/freezegun Author: Steve Pulec Author-email: spulec@gmail.com License: Apache 2.0 Description: FreezeGun: Let your Python tests travel through time ==================================================== .. image:: https://img.shields.io/pypi/v/freezegun.svg :target: https://pypi.python.org/pypi/freezegun/ .. image:: https://secure.travis-ci.org/spulec/freezegun.svg?branch=master :target: https://travis-ci.org/spulec/freezegun .. image:: https://coveralls.io/repos/spulec/freezegun/badge.svg?branch=master :target: https://coveralls.io/r/spulec/freezegun FreezeGun is a library that allows your Python tests to travel through time by mocking the datetime module. Usage ----- Once the decorator or context manager have been invoked, all calls to datetime.datetime.now(), datetime.datetime.utcnow(), datetime.date.today(), time.time(), time.localtime(), time.gmtime(), and time.strftime() will return the time that has been frozen. Decorator ~~~~~~~~~ .. code-block:: python from freezegun import freeze_time import datetime import unittest @freeze_time("2012-01-14") def test(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) # Or a unittest TestCase - freezes for every test, from the start of setUpClass to the end of tearDownClass @freeze_time("1955-11-12") class MyTests(unittest.TestCase): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(1955, 11, 12) # Or any other class - freezes around each callable (may not work in every case) @freeze_time("2012-01-14") class Tester(object): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) Context manager ~~~~~~~~~~~~~~~ .. code-block:: python from freezegun import freeze_time def test(): assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) with freeze_time("2012-01-14"): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) Raw use ~~~~~~~ .. code-block:: python from freezegun import freeze_time freezer = freeze_time("2012-01-14 12:00:01") freezer.start() assert datetime.datetime.now() == datetime.datetime(2012, 1, 14, 12, 0, 1) freezer.stop() Timezones ~~~~~~~~~ .. code-block:: python from freezegun import freeze_time @freeze_time("2012-01-14 03:21:34", tz_offset=-4) def test(): assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34) assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 21, 34) # datetime.date.today() uses local time assert datetime.date.today() == datetime.date(2012, 1, 13) @freeze_time("2012-01-14 03:21:34", tz_offset=-datetime.timedelta(hours=3, minutes=30)) def test_timedelta_offset(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 51, 34) Nice inputs ~~~~~~~~~~~ FreezeGun uses dateutil behind the scenes so you can have nice-looking datetimes. .. code-block:: python @freeze_time("Jan 14th, 2012") def test_nice_datetime(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) Function and generator objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun is able to handle function and generator objects. .. code-block:: python def test_lambda(): with freeze_time(lambda: datetime.datetime(2012, 1, 14)): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) def test_generator(): datetimes = (datetime.datetime(year, 1, 1) for year in range(2010, 2012)) with freeze_time(datetimes): assert datetime.datetime.now() == datetime.datetime(2010, 1, 1) with freeze_time(datetimes): assert datetime.datetime.now() == datetime.datetime(2011, 1, 1) # The next call to freeze_time(datetimes) would raise a StopIteration exception. ``tick`` argument ~~~~~~~~~~~~~~~~~ FreezeGun has an additional ``tick`` argument which will restart time at the given value, but then time will keep ticking. This is alternative to the default parameters which will keep time stopped. .. code-block:: python @freeze_time("Jan 14th, 2020", tick=True) def test_nice_datetime(): assert datetime.datetime.now() > datetime.datetime(2020, 1, 14) ``auto_tick_seconds`` argument ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun has an additional ``auto_tick_seconds`` argument which will autoincrement the value every time by the given amount from the start value. This is alternative to the default parameters which will keep time stopped. Note that given ``auto_tick_seconds`` the ``tick`` parameter will be ignored. .. code-block:: python @freeze_time("Jan 14th, 2020", auto_tick_seconds=15) def test_nice_datetime(): first_time = datetime.datetime.now() auto_incremented_time = datetime.datetime.now() assert first_time + datetime.timedelta(seconds=15) == auto_incremented_time Manual ticks ~~~~~~~~~~~~ FreezeGun allows for the time to be manually forwarded as well. .. code-block:: python def test_manual_increment(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.tick() initial_datetime += datetime.timedelta(seconds=1) assert frozen_datetime() == initial_datetime frozen_datetime.tick(delta=datetime.timedelta(seconds=10)) initial_datetime += datetime.timedelta(seconds=10) assert frozen_datetime() == initial_datetime Moving time to specify datetime ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun allows moving time to specific dates. .. code-block:: python def test_move_to(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) other_datetime = datetime.datetime(year=2, month=8, day=13, hour=14, minute=5, second=0) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.move_to(other_datetime) assert frozen_datetime() == other_datetime frozen_datetime.move_to(initial_datetime) assert frozen_datetime() == initial_datetime @freeze_time("2012-01-14", as_arg=True) def test(frozen_time): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) frozen_time.move_to("2014-02-12") assert datetime.datetime.now() == datetime.datetime(2014, 2, 12) Parameter for ``move_to`` can be any valid ``freeze_time`` date (string, date, datetime). Default arguments ~~~~~~~~~~~~~~~~~ Note that FreezeGun will not modify default arguments. The following code will print the current date. See `here `_ for why. .. code-block:: python from freezegun import freeze_time import datetime as dt def test(default=dt.date.today()): print(default) with freeze_time('2000-1-1'): test() Installation ------------ To install FreezeGun, simply: .. code-block:: bash $ pip install freezegun On Debian systems: .. code-block:: bash $ sudo apt-get install python-freezegun Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* freezegun-0.3.15/freezegun.egg-info/SOURCES.txt0000644000076500000240000000126213622627362021425 0ustar stevestaff00000000000000AUTHORS.rst CHANGELOG LICENSE MANIFEST.in README.rst pyproject.toml setup.cfg setup.py freezegun/__init__.py freezegun/_async.py freezegun/_async_coroutine.py freezegun/api.py freezegun.egg-info/PKG-INFO freezegun.egg-info/SOURCES.txt freezegun.egg-info/dependency_links.txt freezegun.egg-info/requires.txt freezegun.egg-info/top_level.txt tests/__init__.py tests/another_module.py tests/fake_module.py tests/test_asyncio.py tests/test_class_import.py tests/test_datetimes.py tests/test_errors.py tests/test_import_alias.py tests/test_operations.py tests/test_pickle.py tests/test_sqlite3.py tests/test_ticking.py tests/test_utils.py tests/test_uuid.py tests/test_warnings.py tests/utils.pyfreezegun-0.3.15/freezegun.egg-info/requires.txt0000644000076500000240000000003713622627362022140 0ustar stevestaff00000000000000six python-dateutil!=2.0,>=1.0 freezegun-0.3.15/freezegun.egg-info/top_level.txt0000644000076500000240000000001213622627362022263 0ustar stevestaff00000000000000freezegun freezegun-0.3.15/freezegun.egg-info/dependency_links.txt0000644000076500000240000000000113622627362023606 0ustar stevestaff00000000000000 freezegun-0.3.15/LICENSE0000644000076500000240000002512213247360706015062 0ustar stevestaff00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2012 Steve Pulec Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.freezegun-0.3.15/CHANGELOG0000644000076500000240000000200213622627300015250 0ustar stevestaff00000000000000Freezegun Changelog =================== Latest ------ 0.3.15 ------ * Fix locale timestamp bug. CC #328 0.3.14 ------ * Fix calendar.timegm behavior 0.3.13 ------ * Fix for Py3.8 * Reset time.time_ns on stop 0.3.12 ------ * Refactor classes to functions * Ignore Selenium * Move to pytest * Conditionally patch time.clock * Patch time.time_ns added in Python 3.7 0.3.11 ------ * Performance improvements * Fix nesting time.time * Add nanosecond property 0.3.10 ------ * Performance improvements * Coroutine support 0.3.9 ----- * If no time to be frozen, use current time * Fix uuid1 issues * Add support for python 3.6 0.3.8 ----- * Bugfix for old-style classes * Ignore warnings when patching * Add `move_to` method to change time 0.3.7 ----- * Fix CPython detection 0.3.6 ----- * Catch TypeError when fetching attribute values * Speed improvements * Add manual tick increment 0.3.5 ----- * Add `tick` argument to allow time to move forward * Performance improvements * Fix timezone example in README freezegun-0.3.15/pyproject.toml0000644000076500000240000000013213510772770016764 0ustar stevestaff00000000000000[build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" freezegun-0.3.15/tests/0000755000076500000240000000000013622627362015216 5ustar stevestaff00000000000000freezegun-0.3.15/tests/test_utils.py0000644000076500000240000000204213607223747017767 0ustar stevestaff00000000000000from unittest import SkipTest try: from unittest import mock except (ImportError, AttributeError): import mock from freezegun import api from tests import utils try: reload except NameError: try: from importlib import reload except ImportError: from imp import reload @mock.patch('platform.python_implementation', lambda: 'CPython') def test_should_not_skip_cpython(): reload(api) reload(utils) function_mock = mock.MagicMock(__name__='function') try: utils.cpython_only(function_mock)() except SkipTest: raise AssertionError("Test was skipped in CPython") assert function_mock.called @mock.patch('platform.python_implementation', lambda: 'not-CPython') def test_should_skip_non_cpython(): reload(api) reload(utils) function_mock = mock.MagicMock(__name__='function', skipped=False) try: utils.cpython_only(function_mock)() except SkipTest: function_mock.skipped = True assert not function_mock.called assert function_mock.skipped freezegun-0.3.15/tests/test_class_import.py0000644000076500000240000001365213612161712021324 0ustar stevestaff00000000000000import time import sys from .fake_module import ( fake_date_function, fake_datetime_function, fake_gmtime_function, fake_localtime_function, fake_strftime_function, fake_time_function, ) from . import fake_module from freezegun import freeze_time from freezegun.api import ( FakeDatetime, FakeDate, fake_time, fake_localtime, fake_gmtime, fake_strftime, ) import datetime @freeze_time("2012-01-14") def test_import_datetime_works(): assert fake_datetime_function().day == 14 @freeze_time("2012-01-14") def test_import_date_works(): assert fake_date_function().day == 14 @freeze_time("2012-01-14") def test_import_time(): local_time = datetime.datetime(2012, 1, 14) utc_time = local_time - datetime.timedelta(seconds=time.timezone) expected_timestamp = time.mktime(utc_time.timetuple()) assert fake_time_function() == expected_timestamp def test_start_and_stop_works(): freezer = freeze_time("2012-01-14") result = fake_datetime_function() assert result.__class__ == datetime.datetime assert result.__class__ != FakeDatetime freezer.start() assert fake_datetime_function().day == 14 assert isinstance(fake_datetime_function(), datetime.datetime) assert isinstance(fake_datetime_function(), FakeDatetime) freezer.stop() result = fake_datetime_function() assert result.__class__ == datetime.datetime assert result.__class__ != FakeDatetime def test_isinstance_works(): date = datetime.date.today() now = datetime.datetime.now() freezer = freeze_time('2011-01-01') freezer.start() assert isinstance(date, datetime.date) assert not isinstance(date, datetime.datetime) assert isinstance(now, datetime.datetime) assert isinstance(now, datetime.date) freezer.stop() def test_issubclass_works(): real_date = datetime.date real_datetime = datetime.datetime freezer = freeze_time('2011-01-01') freezer.start() assert issubclass(real_date, datetime.date) assert issubclass(real_datetime, datetime.datetime) freezer.stop() def test_fake_uses_real_when_ignored(): real_time_before = time.time() with freeze_time('2012-01-14', ignore=['tests.fake_module']): real_time = fake_time_function() real_time_after = time.time() assert real_time_before <= real_time <= real_time_after def test_can_ignore_email_module(): from email.utils import formatdate with freeze_time('2012-01-14'): faked_date_str = formatdate() before_date_str = formatdate() with freeze_time('2012-01-14', ignore=['email']): date_str = formatdate() after_date_str = formatdate() assert date_str != faked_date_str assert before_date_str <= date_str <= after_date_str @freeze_time('2011-01-01') def test_avoid_replacing_equal_to_anything(): assert fake_module.equal_to_anything.description == 'This is the equal_to_anything object' @freeze_time("2012-01-14 12:00:00") def test_import_localtime(): struct = fake_localtime_function() assert struct.tm_year == 2012 assert struct.tm_mon == 1 assert struct.tm_mday >= 13 # eg. GMT+14 assert struct.tm_mday <= 15 # eg. GMT-14 @freeze_time("2012-01-14 12:00:00") def test_fake_gmtime_function(): struct = fake_gmtime_function() assert struct.tm_year == 2012 assert struct.tm_mon == 1 assert struct.tm_mday == 14 @freeze_time("2012-01-14") def test_fake_strftime_function(): assert fake_strftime_function() == '2012' def test_import_after_start(): with freeze_time('2012-01-14'): assert 'tests.another_module' not in sys.modules.keys() from tests import another_module # Reals assert another_module.get_datetime() is datetime.datetime assert another_module.get_datetime() is FakeDatetime assert another_module.get_date() is datetime.date assert another_module.get_date() is FakeDate assert another_module.get_time() is time.time assert another_module.get_time() is fake_time assert another_module.get_localtime() is time.localtime assert another_module.get_localtime() is fake_localtime assert another_module.get_gmtime() is time.gmtime assert another_module.get_gmtime() is fake_gmtime assert another_module.get_strftime() is time.strftime assert another_module.get_strftime() is fake_strftime # Fakes assert another_module.get_fake_datetime() is FakeDatetime assert another_module.get_fake_date() is FakeDate assert another_module.get_fake_time() is fake_time assert another_module.get_fake_localtime() is fake_localtime assert another_module.get_fake_gmtime() is fake_gmtime assert another_module.get_fake_strftime() is fake_strftime # Reals assert another_module.get_datetime() is datetime.datetime assert not another_module.get_datetime() is FakeDatetime assert another_module.get_date() is datetime.date assert not another_module.get_date() is FakeDate assert another_module.get_time() is time.time assert not another_module.get_time() is fake_time assert another_module.get_localtime() is time.localtime assert not another_module.get_localtime() is fake_localtime assert another_module.get_gmtime() is time.gmtime assert not another_module.get_gmtime() is fake_gmtime assert another_module.get_strftime() is time.strftime assert not another_module.get_strftime() is fake_strftime # Fakes assert another_module.get_fake_datetime() is FakeDatetime assert another_module.get_fake_date() is FakeDate assert another_module.get_fake_time() is fake_time assert another_module.get_fake_localtime() is fake_localtime assert another_module.get_fake_gmtime() is fake_gmtime assert another_module.get_fake_strftime() is fake_strftime def test_none_as_initial(): with freeze_time() as ft: ft.move_to('2012-01-14') assert fake_strftime_function() == '2012' freezegun-0.3.15/tests/test_warnings.py0000644000076500000240000000540613247360706020463 0ustar stevestaff00000000000000import contextlib import datetime import sys import types import warnings from freezegun import freeze_time class ModuleWithWarning(object): """ A module that triggers warnings on attribute access. This does not happen with regular modules, there has to be a bit of lazy module magic going on in order for this to happen. Examples of modules that uses this pattern in real projects can be found at: py.code - the compiler package import causes a warning to be emitted: https://github.com/pytest-dev/py/blob/67987e26aadddbbe7d1ec76c16ea9be346ae9811/py/__init__.py https://github.com/pytest-dev/py/blob/67987e26aadddbbe7d1ec76c16ea9be346ae9811/py/_code/_assertionold.py#L3 celery.task - the sets module is listed in __all__ in celery.task and freeze_time accesses it: https://github.com/celery/celery/blob/46c92025cdec07a4a30ad44901cf66cb27346638/celery/task/__init__.py https://github.com/celery/celery/blob/46c92025cdec07a4a30ad44901cf66cb27346638/celery/task/sets.py """ __name__ = 'module_with_warning' __dict__ = {} warning_triggered = False counter = 0 @property def attribute_that_emits_a_warning(self): # Use unique warning messages to avoid messages being only reported once self.__class__.counter += 1 warnings.warn('this is test warning #{counter}'.format(counter=self.__class__.counter)) self.warning_triggered = True @contextlib.contextmanager def assert_module_with_emitted_warning(): """Install a module that triggers warnings into sys.modules and ensure the warning was triggered in the with-block. """ module = sys.modules['module_with_warning'] = ModuleWithWarning() try: yield finally: del sys.modules['module_with_warning'] assert module.warning_triggered @contextlib.contextmanager def assert_no_warnings(): """A context manager that makes sure no warnings was emitted.""" with warnings.catch_warnings(record=True) as caught_warnings: warnings.filterwarnings('always') yield assert not caught_warnings def test_ignore_warnings_in_start(): """Make sure that modules being introspected in start() does not emit warnings.""" with assert_module_with_emitted_warning(): freezer = freeze_time(datetime.datetime(2016, 10, 27, 9, 56)) try: with assert_no_warnings(): freezer.start() finally: freezer.stop() def test_ignore_warnings_in_stop(): """Make sure that modules that was loaded after start() does not trigger warnings in stop()""" freezer = freeze_time(datetime.datetime(2016, 10, 27, 9, 56)) freezer.start() with assert_module_with_emitted_warning(): with assert_no_warnings(): freezer.stop() freezegun-0.3.15/tests/test_pickle.py0000644000076500000240000000371313247360706020101 0ustar stevestaff00000000000000import datetime import pickle from freezegun import freeze_time def assert_pickled_datetimes_equal_original(): min_datetime = datetime.datetime.min max_datetime = datetime.datetime.max min_date = datetime.date.min max_date = datetime.date.max now = datetime.datetime.now() today = datetime.date.today() utc_now = datetime.datetime.utcnow() assert pickle.loads(pickle.dumps(min_datetime)) == min_datetime assert pickle.loads(pickle.dumps(max_datetime)) == max_datetime assert pickle.loads(pickle.dumps(min_date)) == min_date assert pickle.loads(pickle.dumps(max_date)) == max_date assert pickle.loads(pickle.dumps(now)) == now assert pickle.loads(pickle.dumps(today)) == today assert pickle.loads(pickle.dumps(utc_now)) == utc_now def test_pickle(): freezer = freeze_time("2012-01-14") freezer.start() assert_pickled_datetimes_equal_original() freezer.stop() assert_pickled_datetimes_equal_original() def test_pickle_real_datetime(): real_datetime = datetime.datetime(1970, 2, 1) pickle.loads(pickle.dumps(real_datetime)) == real_datetime freezer = freeze_time("1970-01-01") freezer.start() fake_datetime = datetime.datetime.now() assert pickle.loads(pickle.dumps(fake_datetime)) == fake_datetime pickle.loads(pickle.dumps(real_datetime)) freezer.stop() assert pickle.loads(pickle.dumps(fake_datetime)) == fake_datetime assert pickle.loads(pickle.dumps(real_datetime)) == real_datetime def test_pickle_real_date(): real_date = datetime.date(1970, 2, 1) assert pickle.loads(pickle.dumps(real_date)) == real_date freezer = freeze_time("1970-01-01") freezer.start() fake_date = datetime.datetime.now() assert pickle.loads(pickle.dumps(fake_date)) == fake_date pickle.loads(pickle.dumps(real_date)) freezer.stop() assert pickle.loads(pickle.dumps(fake_date)) == fake_date assert pickle.loads(pickle.dumps(real_date)) == real_date freezegun-0.3.15/tests/test_errors.py0000644000076500000240000000310213473633537020144 0ustar stevestaff00000000000000import contextlib import datetime import sys import pytest from freezegun import freeze_time class ModuleWithError(object): """ A module that triggers an error on __dir__ access. This could happen with modules that overrides its __dir__ method and performing non standard operations. One such example is IPython which adds shim modules when certain packages are imported. (Eg. `import IPython.html`) This leads to errors upon activating freezegun if the modules being shimmed are not installed. See: https://github.com/ipython/ipython/blob/5.8.0/IPython/utils/shimmodule.py#L75 """ __name__ = 'module_with_error' __dict__ = {} def __init__(self, error_type): self.error_triggered = False self.error_type = error_type def __dir__(self): try: raise self.error_type() finally: self.error_triggered = True @contextlib.contextmanager def assert_module_with_raised_error(error_type): """Install a module into sys.modules that raises an error upon invoking __dir__.""" module = sys.modules['module_with_error'] = ModuleWithError(error_type) try: yield finally: del sys.modules['module_with_error'] assert module.error_triggered @pytest.mark.parametrize('error_type', [ImportError, TypeError]) def test_ignore_errors_in_start(error_type): with assert_module_with_raised_error(error_type): freezer = freeze_time(datetime.datetime(2019, 1, 11, 9, 34)) try: freezer.start() finally: freezer.stop() freezegun-0.3.15/tests/test_ticking.py0000644000076500000240000000467413607223747020274 0ustar stevestaff00000000000000import datetime import time try: from unittest import mock except (ImportError, AttributeError): import mock import pytest from freezegun import freeze_time from tests import utils @utils.cpython_only def test_ticking_datetime(): with freeze_time("Jan 14th, 2012", tick=True): time.sleep(0.001) # Deal with potential clock resolution problems assert datetime.datetime.now() > datetime.datetime(2012, 1, 14) @pytest.mark.skipif(not hasattr(time, "clock"), reason="time.clock was removed in Python 3.8") @utils.cpython_only def test_ticking_time_clock(): with freeze_time('2012-01-14 03:21:34', tick=True): first = time.clock() time.sleep(0.001) # Deal with potential clock resolution problems with freeze_time('2012-01-14 03:21:35', tick=True): second = time.clock() time.sleep(0.001) # Deal with potential clock resolution problems with freeze_time('2012-01-14 03:21:36', tick=True): third = time.clock() time.sleep(0.001) # Rewind time backwards with freeze_time('2012-01-14 03:20:00', tick=True): fourth = time.clock() time.sleep(0.001) fifth = time.clock() assert first > 0 assert second > first assert second > 1 assert third > second assert third > 2 assert third > fourth assert second > fourth assert first > fourth assert fifth > fourth @utils.cpython_only def test_ticking_date(): with freeze_time("Jan 14th, 2012, 23:59:59.9999999", tick=True): time.sleep(0.001) # Deal with potential clock resolution problems assert datetime.date.today() == datetime.date(2012, 1, 15) @utils.cpython_only def test_ticking_time(): with freeze_time("Jan 14th, 2012, 23:59:59", tick=True): time.sleep(0.001) # Deal with potential clock resolution problems assert time.time() > 1326585599.0 @mock.patch('freezegun.api._is_cpython', False) def test_pypy_compat(): try: freeze_time("Jan 14th, 2012, 23:59:59", tick=True) except SystemError: pass else: raise AssertionError("tick=True should error on non-CPython") @mock.patch('freezegun.api._is_cpython', True) def test_non_pypy_compat(): try: freeze_time("Jan 14th, 2012, 23:59:59", tick=True) except Exception: raise AssertionError("tick=True should not error on CPython") freezegun-0.3.15/tests/test_operations.py0000644000076500000240000000602213473633537021017 0ustar stevestaff00000000000000import datetime from freezegun import freeze_time from dateutil.relativedelta import relativedelta from datetime import timedelta, tzinfo from tests import utils @freeze_time("2012-01-14") def test_addition(): now = datetime.datetime.now() later = now + datetime.timedelta(days=1) other_later = now + relativedelta(days=1) assert utils.is_fake_datetime(later) assert utils.is_fake_datetime(other_later) today = datetime.date.today() tomorrow = today + datetime.timedelta(days=1) other_tomorrow = today + relativedelta(days=1) assert utils.is_fake_date(tomorrow) assert utils.is_fake_date(other_tomorrow) @freeze_time("2012-01-14") def test_subtraction(): now = datetime.datetime.now() before = now - datetime.timedelta(days=1) other_before = now - relativedelta(days=1) how_long = now - before assert utils.is_fake_datetime(before) assert utils.is_fake_datetime(other_before) assert isinstance(how_long, datetime.timedelta) today = datetime.date.today() yesterday = today - datetime.timedelta(days=1) other_yesterday = today - relativedelta(days=1) how_long = today - yesterday assert utils.is_fake_date(yesterday) assert utils.is_fake_date(other_yesterday) assert isinstance(how_long, datetime.timedelta) @freeze_time("2012-01-14") def test_datetime_timezone_none(): now = datetime.datetime.now(tz=None) assert now == datetime.datetime(2012, 1, 14) class GMT5(tzinfo): def utcoffset(self, dt): return timedelta(hours=5) def tzname(self, dt): return "GMT +5" def dst(self, dt): return timedelta(0) @freeze_time("2012-01-14 2:00:00") def test_datetime_timezone_real(): now = datetime.datetime.now(tz=GMT5()) assert now == datetime.datetime(2012, 1, 14, 7, tzinfo=GMT5()) assert now.utcoffset() == timedelta(0, 60 * 60 * 5) @freeze_time("2012-01-14 2:00:00", tz_offset=-4) def test_datetime_timezone_real_with_offset(): now = datetime.datetime.now(tz=GMT5()) assert now == datetime.datetime(2012, 1, 14, 3, tzinfo=GMT5()) assert now.utcoffset() == timedelta(0, 60 * 60 * 5) @freeze_time("2012-01-14 00:00:00") def test_astimezone(): now = datetime.datetime.now(tz=GMT5()) converted = now.astimezone(GMT5()) assert utils.is_fake_datetime(converted) @freeze_time("2012-01-14 00:00:00") def test_astimezone_tz_none(): now = datetime.datetime.now(tz=GMT5()) converted = now.astimezone() assert utils.is_fake_datetime(converted) @freeze_time("2012-01-14 00:00:00") def test_replace(): now = datetime.datetime.now() modified_time = now.replace(year=2013) assert utils.is_fake_datetime(modified_time) today = datetime.date.today() modified_date = today.replace(year=2013) assert utils.is_fake_date(modified_date) @freeze_time("Jan 14th, 2020", auto_tick_seconds=15) def test_auto_tick(): first_time = datetime.datetime.now() auto_incremented_time = datetime.datetime.now() assert first_time + datetime.timedelta(seconds=15) == auto_incremented_time freezegun-0.3.15/tests/__init__.py0000644000076500000240000000000013247360706017314 0ustar stevestaff00000000000000freezegun-0.3.15/tests/test_asyncio.py0000644000076500000240000000161713473633537020306 0ustar stevestaff00000000000000import datetime from textwrap import dedent from unittest import SkipTest from freezegun import freeze_time try: import asyncio except ImportError: asyncio = False def test_time_freeze_coroutine(): if not asyncio: raise SkipTest('asyncio required') @asyncio.coroutine @freeze_time('1970-01-01') def frozen_coroutine(): assert datetime.date.today() == datetime.date(1970, 1, 1) asyncio.get_event_loop().run_until_complete(frozen_coroutine()) def test_time_freeze_async_def(): try: exec('async def foo(): pass') except SyntaxError: raise SkipTest('async def not supported') else: exec(dedent(''' @freeze_time('1970-01-01') async def frozen_coroutine(): assert datetime.date.today() == datetime.date(1970, 1, 1) asyncio.get_event_loop().run_until_complete(frozen_coroutine()) ''')) freezegun-0.3.15/tests/utils.py0000644000076500000240000000067113473633537016741 0ustar stevestaff00000000000000from functools import wraps from unittest import SkipTest from freezegun.api import FakeDate, FakeDatetime, _is_cpython def is_fake_date(obj): return obj.__class__ is FakeDate def is_fake_datetime(obj): return obj.__class__ is FakeDatetime def cpython_only(func): @wraps(func) def wrapper(*args): if not _is_cpython: raise SkipTest("Requires CPython") return func(*args) return wrapper freezegun-0.3.15/tests/another_module.py0000644000076500000240000000137513612161712020572 0ustar stevestaff00000000000000from datetime import date, datetime from time import time, localtime, gmtime, strftime from freezegun.api import ( FakeDatetime, FakeDate, fake_time, fake_localtime, fake_gmtime, fake_strftime, ) # Reals def get_datetime(): return datetime def get_date(): return date def get_time(): return time def get_localtime(): return localtime def get_gmtime(): return gmtime def get_strftime(): return strftime # Fakes def get_fake_datetime(): return FakeDatetime def get_fake_date(): return FakeDate def get_fake_time(): return fake_time def get_fake_localtime(): return fake_localtime def get_fake_gmtime(): return fake_gmtime def get_fake_strftime(): return fake_strftime freezegun-0.3.15/tests/test_import_alias.py0000644000076500000240000000125013247360706021307 0ustar stevestaff00000000000000from freezegun import freeze_time from datetime import datetime as datetime_aliased from time import time as time_aliased @freeze_time("1980-01-01") def test_datetime_alias(): assert datetime_aliased.now() == datetime_aliased(1980, 1, 1) @freeze_time("1970-01-01") def test_time_alias(): assert time_aliased() == 0.0 @freeze_time('2013-04-09') class TestCallOtherFuncInTestClassDecoratorWithAlias(object): def test_calls_other_method(self): assert datetime_aliased(2013, 4, 9) == datetime_aliased.today() self.some_other_func() assert datetime_aliased(2013, 4, 9) == datetime_aliased.today() def some_other_func(self): pass freezegun-0.3.15/tests/test_uuid.py0000644000076500000240000000267113473633537017610 0ustar stevestaff00000000000000from __future__ import print_function, absolute_import, unicode_literals import datetime import uuid from freezegun import freeze_time def time_from_uuid(value): """ Converts an UUID(1) to it's datetime value """ uvalue = value if isinstance(value, uuid.UUID) else uuid.UUID(value) assert uvalue.version == 1 return (datetime.datetime(1582, 10, 15) + datetime.timedelta(microseconds=uvalue.time // 10)) def test_uuid1_future(): """ Test that we can go back in time after setting a future date. Normally UUID1 would disallow this, since it keeps track of the _last_timestamp, but we override that now. """ future_target = datetime.datetime(2056, 2, 6, 14, 3, 21) with freeze_time(future_target): assert time_from_uuid(uuid.uuid1()) == future_target past_target = datetime.datetime(1978, 7, 6, 23, 6, 31) with freeze_time(past_target): assert time_from_uuid(uuid.uuid1()) == past_target def test_uuid1_past(): """ Test that we can go forward in time after setting some time in the past. This is simply the opposite of test_uuid1_future() """ past_target = datetime.datetime(1978, 7, 6, 23, 6, 31) with freeze_time(past_target): assert time_from_uuid(uuid.uuid1()) == past_target future_target = datetime.datetime(2056, 2, 6, 14, 3, 21) with freeze_time(future_target): assert time_from_uuid(uuid.uuid1()) == future_target freezegun-0.3.15/tests/fake_module.py0000644000076500000240000000122313247360706020040 0ustar stevestaff00000000000000from datetime import datetime from datetime import date from time import time, localtime, gmtime, strftime def fake_datetime_function(): return datetime.now() def fake_date_function(): return date.today() def fake_time_function(): return time() def fake_localtime_function(): return localtime() def fake_gmtime_function(): return gmtime() def fake_strftime_function(): return strftime("%Y") class EqualToAnything(object): description = 'This is the equal_to_anything object' def __eq__(self, other): return True def __neq__(self, other): return False equal_to_anything = EqualToAnything() freezegun-0.3.15/tests/test_datetimes.py0000644000076500000240000006102013622627215020602 0ustar stevestaff00000000000000import time import calendar import datetime import unittest import locale import sys from unittest import SkipTest from dateutil.tz import UTC import pytest from tests import utils from freezegun import freeze_time from freezegun.api import FakeDatetime, FakeDate try: import maya except ImportError: maya = None # 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.""" def __init__(self, *targets): self.targets = targets def __enter__(self): self.old = locale.setlocale(locale.LC_ALL) for target in self.targets: try: locale.setlocale(locale.LC_ALL, target) return except locale.Error: pass msg = 'could not set locale to any of: %s' % ', '.join(self.targets) raise SkipTest(msg) def __exit__(self, *args): locale.setlocale(locale.LC_ALL, self.old) # Small sample of locales where '%x' expands to a dd/mm/yyyy string, # which can cause trouble when parsed with dateutil. _dd_mm_yyyy_locales = ['da_DK.UTF-8', 'de_DE.UTF-8', 'fr_FR.UTF-8'] def test_simple_api(): # time to freeze is always provided in UTC freezer = freeze_time("2012-01-14") # expected timestamp must be a timestamp, corresponding to 2012-01-14 UTC 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 datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14) assert datetime.date.today() == datetime.date(2012, 1, 14) assert datetime.datetime.now().today() == datetime.datetime(2012, 1, 14) freezer.stop() assert time.time() != expected_timestamp assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) assert datetime.datetime.utcnow() != datetime.datetime(2012, 1, 14) freezer = freeze_time("2012-01-10 13:52:01") freezer.start() assert datetime.datetime.now() == datetime.datetime(2012, 1, 10, 13, 52, 1) freezer.stop() def test_tz_offset(): freezer = freeze_time("2012-01-14 03:21:34", tz_offset=-4) # expected timestamp must be a timestamp, # corresponding to 2012-01-14 03:21:34 UTC # and it doesn't depend on tz_offset local_time = datetime.datetime(2012, 1, 14, 3, 21, 34) utc_time = local_time - datetime.timedelta(seconds=time.timezone) expected_timestamp = time.mktime(utc_time.timetuple()) freezer.start() assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 21, 34) assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34) assert time.time() == expected_timestamp freezer.stop() def test_timedelta_tz_offset(): freezer = freeze_time("2012-01-14 03:21:34", tz_offset=-datetime.timedelta(hours=3, minutes=30)) freezer.start() assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 51, 34) assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34) freezer.stop() def test_tz_offset_with_today(): freezer = freeze_time("2012-01-14", tz_offset=-4) freezer.start() assert datetime.date.today() == datetime.date(2012, 1, 13) freezer.stop() assert datetime.date.today() != datetime.date(2012, 1, 13) def test_zero_tz_offset_with_time(): # we expect the system to behave like a system with UTC timezone # at the beginning of the Epoch freezer = freeze_time('1970-01-01') freezer.start() assert datetime.date.today() == datetime.date(1970, 1, 1) assert datetime.datetime.now() == datetime.datetime(1970, 1, 1) assert datetime.datetime.utcnow() == datetime.datetime(1970, 1, 1) assert time.time() == 0.0 freezer.stop() def test_tz_offset_with_time(): # we expect the system to behave like a system with UTC-4 timezone # at the beginning of the Epoch (wall clock should be 4 hrs late) freezer = freeze_time('1970-01-01', tz_offset=-4) freezer.start() assert datetime.date.today() == datetime.date(1969, 12, 31) assert datetime.datetime.now() == datetime.datetime(1969, 12, 31, 20) assert datetime.datetime.utcnow() == datetime.datetime(1970, 1, 1) assert time.time() == 0.0 freezer.stop() def test_time_with_microseconds(): freezer = freeze_time(datetime.datetime(1970, 1, 1, 0, 0, 1, 123456)) freezer.start() assert time.time() == 1.123456 freezer.stop() def test_time_with_dst(): freezer = freeze_time(datetime.datetime(1970, 6, 1, 0, 0, 1, 123456)) freezer.start() assert time.time() == 13046401.123456 freezer.stop() def test_manual_increment(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.tick() initial_datetime += datetime.timedelta(seconds=1) assert frozen_datetime() == initial_datetime frozen_datetime.tick(delta=datetime.timedelta(seconds=10)) initial_datetime += datetime.timedelta(seconds=10) assert frozen_datetime() == initial_datetime def test_manual_increment_seconds(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.tick() initial_datetime += datetime.timedelta(seconds=1) assert frozen_datetime() == initial_datetime frozen_datetime.tick(10) initial_datetime += datetime.timedelta(seconds=10) assert frozen_datetime() == initial_datetime def test_move_to(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) other_datetime = datetime.datetime(year=2, month=8, day=13, hour=14, minute=5, second=0) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.move_to(other_datetime) assert frozen_datetime() == other_datetime frozen_datetime.move_to(initial_datetime) assert frozen_datetime() == initial_datetime def test_bad_time_argument(): try: freeze_time("2012-13-14", tz_offset=-4) except ValueError: pass else: assert False, "Bad values should raise a ValueError" def test_time_gmtime(): with freeze_time('2012-01-14 03:21:34'): time_struct = time.gmtime() assert time_struct.tm_year == 2012 assert time_struct.tm_mon == 1 assert time_struct.tm_mday == 14 assert time_struct.tm_hour == 3 assert time_struct.tm_min == 21 assert time_struct.tm_sec == 34 assert time_struct.tm_wday == 5 assert time_struct.tm_yday == 14 assert time_struct.tm_isdst == -1 @pytest.mark.skipif(not HAS_CLOCK, reason="time.clock was removed in Python 3.8") def test_time_clock(): with freeze_time('2012-01-14 03:21:34'): assert time.clock() == 0 with freeze_time('2012-01-14 03:21:35'): assert time.clock() == 1 with freeze_time('2012-01-14 03:21:36'): assert time.clock() == 2 class modify_timezone(object): def __init__(self, new_timezone): self.new_timezone = new_timezone self.original_timezone = time.timezone def __enter__(self): time.timezone = self.new_timezone def __exit__(self, *args): time.timezone = self.original_timezone def test_time_localtime(): with modify_timezone(-3600): # Set this for UTC-1 with freeze_time('2012-01-14 03:21:34'): time_struct = time.localtime() assert time_struct.tm_year == 2012 assert time_struct.tm_mon == 1 assert time_struct.tm_mday == 14 assert time_struct.tm_hour == 4 # offset of 1 hour due to time zone assert time_struct.tm_min == 21 assert time_struct.tm_sec == 34 assert time_struct.tm_wday == 5 assert time_struct.tm_yday == 14 assert time_struct.tm_isdst == -1 assert time.localtime().tm_year != 2012 def test_strftime(): with modify_timezone(0): with freeze_time('1970-01-01'): assert time.strftime("%Y") == "1970" def test_real_strftime_fall_through(): with freeze_time(ignore=['_pytest']): time.strftime('%Y') time.strftime('%Y', (2001, 1, 1, 1, 1, 1, 1, 1, 1)) == '2001' def test_date_object(): frozen_date = datetime.date(year=2012, month=11, day=10) date_freezer = freeze_time(frozen_date) regular_freezer = freeze_time('2012-11-10') assert date_freezer.time_to_freeze == regular_freezer.time_to_freeze def test_old_date_object(): frozen_date = datetime.date(year=1, month=1, day=1) with freeze_time(frozen_date): assert datetime.date.today() == frozen_date def test_date_with_locale(): with temp_locale(*_dd_mm_yyyy_locales): frozen_date = datetime.date(year=2012, month=1, day=2) date_freezer = freeze_time(frozen_date) assert date_freezer.time_to_freeze.date() == frozen_date def test_invalid_type(): try: freeze_time(int(4)) except TypeError: pass else: assert False, "Bad types should raise a TypeError" def test_datetime_object(): frozen_datetime = datetime.datetime(year=2012, month=11, day=10, hour=4, minute=15, second=30) datetime_freezer = freeze_time(frozen_datetime) regular_freezer = freeze_time('2012-11-10 04:15:30') assert datetime_freezer.time_to_freeze == regular_freezer.time_to_freeze def test_function_object(): frozen_datetime = datetime.datetime(year=2012, month=11, day=10, hour=4, minute=15, second=30) def function(): return frozen_datetime with freeze_time(function): assert frozen_datetime == datetime.datetime.now() def test_lambda_object(): frozen_datetime = datetime.datetime(year=2012, month=11, day=10, hour=4, minute=15, second=30) with freeze_time(lambda: frozen_datetime): assert frozen_datetime == datetime.datetime.now() def test_generator_object(): frozen_datetimes = (datetime.datetime(year=y, month=1, day=1) for y in range(2010, 2012)) with freeze_time(frozen_datetimes): assert datetime.datetime(2010, 1, 1) == datetime.datetime.now() with freeze_time(frozen_datetimes): assert datetime.datetime(2011, 1, 1) == datetime.datetime.now() with pytest.raises(StopIteration): freeze_time(frozen_datetimes) def test_maya_datetimes(): if not maya: raise SkipTest("maya is optional since it's not supported for " "enough python versions") with freeze_time(maya.when("October 2nd, 1997")): assert datetime.datetime.now() == datetime.datetime( year=1997, month=10, day=2 ) def test_old_datetime_object(): frozen_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(frozen_datetime): assert datetime.datetime.now() == frozen_datetime def test_datetime_with_locale(): with temp_locale(*_dd_mm_yyyy_locales): frozen_datetime = datetime.datetime(year=2012, month=1, day=2) date_freezer = freeze_time(frozen_datetime) assert date_freezer.time_to_freeze == frozen_datetime @freeze_time("2012-01-14") def test_decorator(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) def test_decorator_wrapped_attribute(): def to_decorate(): pass wrapped = freeze_time("2014-01-14")(to_decorate) assert wrapped.__wrapped__ is to_decorate class Callable(object): def __call__(self, *args, **kws): return (args, kws) @freeze_time("2012-01-14") class Tester(object): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) def test_still_the_same(self): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) def test_class_name_preserved_by_decorator(self): assert self.__class__.__name__ == "Tester" class NotATestClass(object): def perform_operation(self): return datetime.date.today() @freeze_time('2001-01-01') def test_class_decorator_ignores_nested_class(self): not_a_test = self.NotATestClass() assert not_a_test.perform_operation() == datetime.date(2001, 1, 1) a_mock = Callable() def test_class_decorator_skips_callable_object_py2(self): if sys.version_info[0] != 2: raise SkipTest("test target is Python2") assert self.a_mock.__class__ == Callable def test_class_decorator_wraps_callable_object_py3(self): if sys.version_info[0] == 2: raise SkipTest("test target is Python3+") assert self.a_mock.__wrapped__.__class__ == Callable @staticmethod def helper(): return datetime.date.today() def test_class_decorator_respects_staticmethod(self): assert self.helper() == datetime.date(2012, 1, 14) @freeze_time("Jan 14th, 2012") def test_nice_datetime(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) @freeze_time("2012-01-14") def test_datetime_date_method(): now = datetime.datetime.now() assert now.date() == FakeDate(2012, 1, 14) def test_context_manager(): with freeze_time("2012-01-14"): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) def test_nested_context_manager(): with freeze_time("2012-01-14"): with freeze_time("2012-12-25"): _assert_datetime_date_and_time_are_all_equal(datetime.datetime(2012, 12, 25)) _assert_datetime_date_and_time_are_all_equal(datetime.datetime(2012, 1, 14)) assert datetime.datetime.now() > datetime.datetime(2013, 1, 1) def _assert_datetime_date_and_time_are_all_equal(expected_datetime): assert datetime.datetime.now() == expected_datetime assert datetime.date.today() == expected_datetime.date() assert datetime.datetime.fromtimestamp(time.time()) == expected_datetime def test_nested_context_manager_with_tz_offsets(): with freeze_time("2012-01-14 23:00:00", tz_offset=2): with freeze_time("2012-12-25 19:00:00", tz_offset=6): assert datetime.datetime.now() == datetime.datetime(2012, 12, 26, 1) assert datetime.date.today() == datetime.date(2012, 12, 26) # no assertion for time.time() since it's not affected by tz_offset assert datetime.datetime.now() == datetime.datetime(2012, 1, 15, 1) assert datetime.date.today() == datetime.date(2012, 1, 15) assert datetime.datetime.now() > datetime.datetime(2013, 1, 1) @freeze_time("Jan 14th, 2012") def test_isinstance_with_active(): now = datetime.datetime.now() assert utils.is_fake_datetime(now) assert utils.is_fake_date(now.date()) today = datetime.date.today() assert utils.is_fake_date(today) def test_isinstance_without_active(): now = datetime.datetime.now() assert isinstance(now, datetime.datetime) assert isinstance(now, datetime.date) assert isinstance(now.date(), datetime.date) today = datetime.date.today() assert isinstance(today, datetime.date) @freeze_time('2013-04-09') class TestUnitTestClassDecorator(unittest.TestCase): @classmethod def setUpClass(cls): assert datetime.date(2013, 4, 9) == datetime.date.today() def setUp(self): self.assertEqual(datetime.date(2013, 4, 9), datetime.date.today()) def tearDown(self): self.assertEqual(datetime.date(2013, 4, 9), datetime.date.today()) @classmethod def tearDownClass(cls): assert datetime.date(2013, 4, 9) == datetime.date.today() def test_class_decorator_works_on_unittest(self): self.assertEqual(datetime.date(2013, 4, 9), datetime.date.today()) def test_class_name_preserved_by_decorator(self): self.assertEqual(self.__class__.__name__, "TestUnitTestClassDecorator") @freeze_time('2013-04-09') class TestUnitTestClassDecoratorWithNoSetUpOrTearDown(unittest.TestCase): def test_class_decorator_works_on_unittest(self): self.assertEqual(datetime.date(2013, 4, 9), datetime.date.today()) class TestUnitTestClassDecoratorSubclass(TestUnitTestClassDecorator): @classmethod def setUpClass(cls): # the super() call can fail if the class decoration was done wrong super(TestUnitTestClassDecoratorSubclass, cls).setUpClass() @classmethod def tearDownClass(cls): # the super() call can fail if the class decoration was done wrong super(TestUnitTestClassDecoratorSubclass, cls).tearDownClass() def test_class_name_preserved_by_decorator(self): self.assertEqual(self.__class__.__name__, "TestUnitTestClassDecoratorSubclass") class BaseInheritanceFreezableTests(unittest.TestCase): @classmethod def setUpClass(cls): pass @classmethod def tearDownClass(cls): pass class UnfrozenInheritedTests(BaseInheritanceFreezableTests): def test_time_is_not_frozen(self): # In this class, time should not be frozen - and the below decorated # class shouldn't affect that self.assertNotEqual(datetime.date(2013, 4, 9), datetime.date.today()) @freeze_time('2013-04-09') class FrozenInheritedTests(BaseInheritanceFreezableTests): def test_time_is_frozen(self): # In this class, time should be frozen self.assertEqual(datetime.date(2013, 4, 9), datetime.date.today()) class TestOldStyleClasses: def test_direct_method(self): # Make sure old style classes (not inheriting from object) is supported @freeze_time('2013-04-09') class OldStyleClass: def method(self): return datetime.date.today() assert OldStyleClass().method() == datetime.date(2013, 4, 9) def test_inherited_method(self): class OldStyleBaseClass: def inherited_method(self): return datetime.date.today() @freeze_time('2013-04-09') class OldStyleClass(OldStyleBaseClass): pass assert OldStyleClass().inherited_method() == datetime.date(2013, 4, 9) def test_min_and_max(): freezer = freeze_time("2012-01-14") real_datetime = datetime.datetime real_date = datetime.date freezer.start() assert datetime.datetime.min.__class__ == FakeDatetime assert datetime.datetime.max.__class__ == FakeDatetime assert datetime.date.min.__class__ == FakeDate assert datetime.date.max.__class__ == FakeDate assert datetime.datetime.min.__class__ != real_datetime assert datetime.datetime.max.__class__ != real_datetime assert datetime.date.min.__class__ != real_date assert datetime.date.max.__class__ != real_date freezer.stop() assert datetime.datetime.min.__class__ == datetime.datetime assert datetime.datetime.max.__class__ == datetime.datetime assert datetime.date.min.__class__ == datetime.date assert datetime.date.max.__class__ == datetime.date assert datetime.datetime.min.__class__ != FakeDatetime assert datetime.datetime.max.__class__ != FakeDatetime assert datetime.date.min.__class__ != FakeDate assert datetime.date.max.__class__ != FakeDate @freeze_time("2014-07-30T01:00:00Z") def test_freeze_with_timezone_aware_datetime_in_utc(): """ utcnow() should always return a timezone naive datetime """ utc_now = datetime.datetime.utcnow() assert utc_now.tzinfo is None @freeze_time("1970-01-01T00:00:00-04:00") def test_freeze_with_timezone_aware_datetime_in_non_utc(): """ we expect the system to behave like a system with UTC-4 timezone at the beginning of the Epoch (wall clock should be 4 hrs late) """ utc_now = datetime.datetime.utcnow() assert utc_now.tzinfo is None assert utc_now == datetime.datetime(1970, 1, 1, 4) @freeze_time('2015-01-01') def test_time_with_nested(): from time import time first = 1420070400.0 second = 1420070760.0 assert time() == first with freeze_time('2015-01-01T00:06:00'): assert time() == second def test_should_use_real_time(): frozen = datetime.datetime(2015, 3, 5) expected_frozen = 1425513600.0 # TODO: local time seems to leak the local timezone, so this test fails in CI # expected_frozen_local = (2015, 3, 5, 1, 0, 0, 3, 64, -1) expected_frozen_gmt = (2015, 3, 5, 0, 0, 0, 3, 64, -1) expected_clock = 0 from freezegun import api api.call_stack_inspection_limit = 100 # just to increase coverage timestamp_to_convert = 1579602312 time_tuple = time.gmtime(timestamp_to_convert) with freeze_time(frozen): assert time.time() == expected_frozen # assert time.localtime() == expected_frozen_local assert time.gmtime() == expected_frozen_gmt if HAS_CLOCK: assert time.clock() == expected_clock if HAS_TIME_NS: assert time.time_ns() == expected_frozen * 1e9 assert calendar.timegm(time.gmtime()) == expected_frozen assert calendar.timegm(time_tuple) == timestamp_to_convert with freeze_time(frozen, ignore=['_pytest', 'nose']): assert time.time() != expected_frozen # assert time.localtime() != expected_frozen_local assert time.gmtime() != expected_frozen_gmt if HAS_CLOCK: assert time.clock() != expected_clock if HAS_TIME_NS: assert time.time_ns() != expected_frozen * 1e9 assert calendar.timegm(time.gmtime()) != expected_frozen assert calendar.timegm(time_tuple) == timestamp_to_convert @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 assert time.time_ns() != expected_timestamp * 1e9 def test_compare_datetime_and_time_with_timezone(monkeypatch): """ Compare the result of datetime.datetime.now() and time.time() in a non-UTC timezone. These should be consistent. """ try: with monkeypatch.context() as m, freeze_time("1970-01-01 00:00:00"): m.setenv("TZ", "Europe/Berlin") time.tzset() now = datetime.datetime.now() assert now == datetime.datetime.fromtimestamp(time.time()) assert now == datetime.datetime.utcfromtimestamp(time.time()) assert now == datetime.datetime.utcnow() assert now.timestamp() == time.time() finally: time.tzset() # set the timezone back to what is was before def test_timestamp_with_tzoffset(): with freeze_time("2000-01-01", tz_offset=6): utcnow = datetime.datetime(2000, 1, 1, 0) nowtz = datetime.datetime(2000, 1, 1, 0, tzinfo=UTC) now = datetime.datetime(2000, 1, 1, 6) assert now == datetime.datetime.now() assert now == datetime.datetime.fromtimestamp(time.time()) assert now.timestamp() == time.time() assert nowtz.timestamp() == time.time() assert utcnow == datetime.datetime.utcfromtimestamp(time.time()) assert utcnow == datetime.datetime.utcnow() @pytest.mark.skip("timezone handling is currently incorrect") def test_datetime_in_timezone(monkeypatch): """ It is assumed that the argument passed to freeze_time is in UTC, unless explicitly indicated otherwise. Therefore datetime.now() should return the frozen time with an offset. """ try: with monkeypatch.context() as m, freeze_time("1970-01-01 00:00:00"): m.setenv("TZ", "Europe/Berlin") time.tzset() assert datetime.datetime.now() == datetime.datetime(1970, 1, 1, 1, 0, 0) finally: time.tzset() # set the timezone back to what is was before freezegun-0.3.15/tests/test_sqlite3.py0000644000076500000240000000056713247360706020222 0ustar stevestaff00000000000000import datetime from freezegun import freeze_time import sqlite3 @freeze_time("2013-01-01") def test_fake_datetime_select(): db = sqlite3.connect("/tmp/foo") db.execute("""select ?""", (datetime.datetime.now(),)) @freeze_time("2013-01-01") def test_fake_date_select(): db = sqlite3.connect("/tmp/foo") db.execute("""select ?""", (datetime.date.today(),)) freezegun-0.3.15/MANIFEST.in0000644000076500000240000000021513510772770015610 0ustar stevestaff00000000000000include README.rst LICENSE AUTHORS.rst CHANGELOG pyproject.toml recursive-include tests * global-exclude __pycache__ global-exclude *.py[co] freezegun-0.3.15/freezegun/0000755000076500000240000000000013622627362016046 5ustar stevestaff00000000000000freezegun-0.3.15/freezegun/__init__.py0000644000076500000240000000045613622627315020162 0ustar stevestaff00000000000000# -*- coding: utf-8 -*- """ freezegun ~~~~~~~~ :copyright: (c) 2012 by Steve Pulec. """ from .api import freeze_time __title__ = 'freezegun' __version__ = '0.3.15' __author__ = 'Steve Pulec' __license__ = 'Apache License 2.0' __copyright__ = 'Copyright 2012 Steve Pulec' __all__ = ["freeze_time"] freezegun-0.3.15/freezegun/api.py0000644000076500000240000006246513622627215017203 0ustar stevestaff00000000000000import dateutil import datetime import functools import sys import time import uuid import calendar import unittest import platform import warnings import types import numbers import inspect from dateutil import parser from dateutil.tz import tzlocal try: from maya import MayaDT except ImportError: MayaDT = None _TIME_NS_PRESENT = hasattr(time, 'time_ns') _EPOCH = datetime.datetime(1970, 1, 1) _EPOCHTZ = datetime.datetime(1970, 1, 1, tzinfo=dateutil.tz.UTC) real_time = time.time real_localtime = time.localtime real_gmtime = time.gmtime 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 = {id(obj) for obj in real_date_objects} # time.clock is deprecated and was removed in Python 3.8 real_clock = getattr(time, 'clock', None) freeze_factories = [] tz_offsets = [] ignore_lists = [] tick_flags = [] # Python3 doesn't have basestring, but it does have str. try: # noinspection PyUnresolvedReferences _string_type = basestring except NameError: _string_type = str try: # noinspection PyUnresolvedReferences real_uuid_generate_time = uuid._uuid_generate_time uuid_generate_time_attr = '_uuid_generate_time' except AttributeError: # noinspection PyUnresolvedReferences uuid._load_system_functions() # noinspection PyUnresolvedReferences real_uuid_generate_time = uuid._generate_time_safe uuid_generate_time_attr = '_generate_time_safe' except ImportError: real_uuid_generate_time = None uuid_generate_time_attr = None try: # noinspection PyUnresolvedReferences real_uuid_create = uuid._UuidCreate except (AttributeError, ImportError): real_uuid_create = None try: import copy_reg as copyreg except ImportError: import copyreg try: iscoroutinefunction = inspect.iscoroutinefunction if sys.version_info < (3, 5): from freezegun._async_coroutine import wrap_coroutine else: from freezegun._async import wrap_coroutine except AttributeError: iscoroutinefunction = lambda x: False def wrap_coroutine(*args): raise NotImplementedError() # keep a cache of module attributes otherwise freezegun will need to analyze too many modules all the time _GLOBAL_MODULES_CACHE = {} def _get_module_attributes(module): result = [] try: module_attributes = dir(module) except (ImportError, TypeError): return result for attribute_name in module_attributes: try: attribute_value = getattr(module, attribute_name) except (ImportError, AttributeError, TypeError): # For certain libraries, this can result in ImportError(_winreg) or AttributeError (celery) continue else: result.append((attribute_name, attribute_value)) return result def _setup_module_cache(module): date_attrs = [] all_module_attributes = _get_module_attributes(module) for attribute_name, attribute_value in all_module_attributes: if id(attribute_value) in _real_time_object_ids: date_attrs.append((attribute_name, attribute_value)) _GLOBAL_MODULES_CACHE[module.__name__] = (_get_module_attributes_hash(module), date_attrs) def _get_module_attributes_hash(module): try: module_dir = dir(module) except (ImportError, TypeError): module_dir = [] return '{}-{}'.format(id(module), hash(frozenset(module_dir))) def _get_cached_module_attributes(module): module_hash, cached_attrs = _GLOBAL_MODULES_CACHE.get(module.__name__, ('0', [])) if _get_module_attributes_hash(module) == module_hash: return cached_attrs # cache miss: update the cache and return the refreshed value _setup_module_cache(module) # return the newly cached value module_hash, cached_attrs = _GLOBAL_MODULES_CACHE[module.__name__] return cached_attrs # Stolen from six def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" return meta("NewBase", bases, {}) _is_cpython = ( hasattr(platform, 'python_implementation') and platform.python_implementation().lower() == "cpython" ) call_stack_inspection_limit = 5 def _should_use_real_time(): if not call_stack_inspection_limit: return False if not ignore_lists[-1]: return False frame = inspect.currentframe().f_back.f_back for _ in range(call_stack_inspection_limit): module_name = frame.f_globals.get('__name__') if module_name and module_name.startswith(ignore_lists[-1]): return True frame = frame.f_back if frame is None: break return False def get_current_time(): return freeze_factories[-1]() def fake_time(): if _should_use_real_time(): return real_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: return real_localtime(t) if _should_use_real_time(): return real_localtime() shifted_time = get_current_time() - datetime.timedelta(seconds=time.timezone) return shifted_time.timetuple() def fake_gmtime(t=None): if t is not None: return real_gmtime(t) if _should_use_real_time(): return real_gmtime() return get_current_time().timetuple() def fake_strftime(format, time_to_format=None): if time_to_format is None: if not _should_use_real_time(): time_to_format = fake_localtime() if time_to_format is None: return real_strftime(format) else: return real_strftime(format, time_to_format) if real_clock is not None: def fake_clock(): if _should_use_real_time(): return real_clock() if len(freeze_factories) == 1: return 0.0 if not tick_flags[-1] else real_clock() first_frozen_time = freeze_factories[0]() last_frozen_time = get_current_time() timedelta = (last_frozen_time - first_frozen_time) total_seconds = timedelta.total_seconds() if tick_flags[-1]: total_seconds += real_clock() return total_seconds class FakeDateMeta(type): @classmethod def __instancecheck__(self, obj): return isinstance(obj, real_date) @classmethod def __subclasscheck__(cls, subclass): return issubclass(subclass, real_date) def datetime_to_fakedatetime(datetime): return FakeDatetime(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second, datetime.microsecond, datetime.tzinfo) def date_to_fakedate(date): return FakeDate(date.year, date.month, date.day) class FakeDate(with_metaclass(FakeDateMeta, real_date)): def __new__(cls, *args, **kwargs): return real_date.__new__(cls, *args, **kwargs) def __add__(self, other): result = real_date.__add__(self, other) if result is NotImplemented: return result return date_to_fakedate(result) def __sub__(self, other): result = real_date.__sub__(self, other) if result is NotImplemented: return result if isinstance(result, real_date): return date_to_fakedate(result) else: return result @classmethod def today(cls): result = cls._date_to_freeze() + cls._tz_offset() return date_to_fakedate(result) @staticmethod def _date_to_freeze(): return get_current_time() @classmethod def _tz_offset(cls): return tz_offsets[-1] FakeDate.min = date_to_fakedate(real_date.min) FakeDate.max = date_to_fakedate(real_date.max) class FakeDatetimeMeta(FakeDateMeta): @classmethod def __instancecheck__(self, obj): return isinstance(obj, real_datetime) @classmethod def __subclasscheck__(cls, subclass): return issubclass(subclass, real_datetime) class FakeDatetime(with_metaclass(FakeDatetimeMeta, real_datetime, FakeDate)): def __new__(cls, *args, **kwargs): return real_datetime.__new__(cls, *args, **kwargs) def __add__(self, other): result = real_datetime.__add__(self, other) if result is NotImplemented: return result return datetime_to_fakedatetime(result) def __sub__(self, other): result = real_datetime.__sub__(self, other) if result is NotImplemented: return result if isinstance(result, real_datetime): return datetime_to_fakedatetime(result) else: return result def astimezone(self, tz=None): if tz is None: tz = tzlocal() return datetime_to_fakedatetime(real_datetime.astimezone(self, tz)) @classmethod def fromtimestamp(cls, t, tz=None): if tz is None: return real_datetime.fromtimestamp( t, tz=dateutil.tz.tzoffset("freezegun", cls._tz_offset()) ).replace(tzinfo=None) return datetime_to_fakedatetime(real_datetime.fromtimestamp(t, tz)) def timestamp(self): if self.tzinfo is None: return (self - _EPOCH - self._tz_offset()).total_seconds() return (self - _EPOCHTZ).total_seconds() @classmethod def now(cls, tz=None): now = cls._time_to_freeze() or real_datetime.now() if tz: result = tz.fromutc(now.replace(tzinfo=tz)) + cls._tz_offset() else: result = now + cls._tz_offset() return datetime_to_fakedatetime(result) def date(self): return date_to_fakedate(self) @property def nanosecond(self): try: # noinspection PyUnresolvedReferences return real_datetime.nanosecond except AttributeError: return 0 @classmethod def today(cls): return cls.now(tz=None) @classmethod def utcnow(cls): result = cls._time_to_freeze() or real_datetime.utcnow() return datetime_to_fakedatetime(result) @staticmethod def _time_to_freeze(): if freeze_factories: return get_current_time() @classmethod def _tz_offset(cls): return tz_offsets[-1] FakeDatetime.min = datetime_to_fakedatetime(real_datetime.min) FakeDatetime.max = datetime_to_fakedatetime(real_datetime.max) def convert_to_timezone_naive(time_to_freeze): """ Converts a potentially timezone-aware datetime to be a naive UTC datetime """ if time_to_freeze.tzinfo: time_to_freeze -= time_to_freeze.utcoffset() time_to_freeze = time_to_freeze.replace(tzinfo=None) return time_to_freeze def pickle_fake_date(datetime_): # A pickle function for FakeDate return FakeDate, ( datetime_.year, datetime_.month, datetime_.day, ) def pickle_fake_datetime(datetime_): # A pickle function for FakeDatetime return FakeDatetime, ( datetime_.year, datetime_.month, datetime_.day, datetime_.hour, datetime_.minute, datetime_.second, datetime_.microsecond, datetime_.tzinfo, ) def _parse_time_to_freeze(time_to_freeze_str): """Parses all the possible inputs for freeze_time :returns: a naive ``datetime.datetime`` object """ if time_to_freeze_str is None: time_to_freeze_str = datetime.datetime.utcnow() if isinstance(time_to_freeze_str, datetime.datetime): time_to_freeze = time_to_freeze_str elif isinstance(time_to_freeze_str, datetime.date): time_to_freeze = datetime.datetime.combine(time_to_freeze_str, datetime.time()) elif isinstance(time_to_freeze_str, datetime.timedelta): time_to_freeze = datetime.datetime.utcnow() + time_to_freeze_str else: time_to_freeze = parser.parse(time_to_freeze_str) return convert_to_timezone_naive(time_to_freeze) def _parse_tz_offset(tz_offset): if isinstance(tz_offset, datetime.timedelta): return tz_offset else: return datetime.timedelta(hours=tz_offset) class TickingDateTimeFactory(object): def __init__(self, time_to_freeze, start): self.time_to_freeze = time_to_freeze self.start = start def __call__(self): return self.time_to_freeze + (real_datetime.now() - self.start) class FrozenDateTimeFactory(object): def __init__(self, time_to_freeze): self.time_to_freeze = time_to_freeze def __call__(self): return self.time_to_freeze def tick(self, delta=datetime.timedelta(seconds=1)): if isinstance(delta, numbers.Real): # noinspection PyTypeChecker self.time_to_freeze += datetime.timedelta(seconds=delta) else: self.time_to_freeze += delta def move_to(self, target_datetime): """Moves frozen date to the given ``target_datetime``""" target_datetime = _parse_time_to_freeze(target_datetime) delta = target_datetime - self.time_to_freeze self.tick(delta=delta) class StepTickTimeFactory(object): def __init__(self, time_to_freeze, step_width): self.time_to_freeze = time_to_freeze self.step_width = step_width def __call__(self): return_time = self.time_to_freeze self.tick() return return_time def tick(self, delta=None): if not delta: delta = datetime.timedelta(seconds=self.step_width) self.time_to_freeze += delta def update_step_width(self, step_width): self.step_width = step_width def move_to(self, target_datetime): """Moves frozen date to the given ``target_datetime``""" target_datetime = _parse_time_to_freeze(target_datetime) delta = target_datetime - self.time_to_freeze self.tick(delta=delta) class _freeze_time(object): def __init__(self, time_to_freeze_str, tz_offset, ignore, tick, as_arg, auto_tick_seconds): self.time_to_freeze = _parse_time_to_freeze(time_to_freeze_str) self.tz_offset = _parse_tz_offset(tz_offset) self.ignore = tuple(ignore) self.tick = tick self.auto_tick_seconds = auto_tick_seconds self.undo_changes = [] self.modules_at_start = set() self.as_arg = as_arg def __call__(self, func): if inspect.isclass(func): return self.decorate_class(func) elif iscoroutinefunction(func): return self.decorate_coroutine(func) return self.decorate_callable(func) def decorate_class(self, klass): if issubclass(klass, unittest.TestCase): # If it's a TestCase, we assume you want to freeze the time for the # tests, from setUpClass to tearDownClass # Use getattr as in Python 2.6 they are optional orig_setUpClass = getattr(klass, 'setUpClass', None) orig_tearDownClass = getattr(klass, 'tearDownClass', None) # noinspection PyDecorator @classmethod def setUpClass(cls): self.start() if orig_setUpClass is not None: orig_setUpClass() # noinspection PyDecorator @classmethod def tearDownClass(cls): if orig_tearDownClass is not None: orig_tearDownClass() self.stop() klass.setUpClass = setUpClass klass.tearDownClass = tearDownClass return klass else: seen = set() klasses = klass.mro() if hasattr(klass, 'mro') else [klass] + list(klass.__bases__) for base_klass in klasses: for (attr, attr_value) in base_klass.__dict__.items(): if attr.startswith('_') or attr in seen: continue seen.add(attr) if not callable(attr_value) or inspect.isclass(attr_value): continue try: setattr(klass, attr, self(attr_value)) except (AttributeError, TypeError): # Sometimes we can't set this for built-in types and custom callables continue return klass def __enter__(self): return self.start() def __exit__(self, *args): self.stop() def start(self): if self.auto_tick_seconds: freeze_factory = StepTickTimeFactory(self.time_to_freeze, self.auto_tick_seconds) elif self.tick: freeze_factory = TickingDateTimeFactory(self.time_to_freeze, real_datetime.now()) else: freeze_factory = FrozenDateTimeFactory(self.time_to_freeze) is_already_started = len(freeze_factories) > 0 freeze_factories.append(freeze_factory) tz_offsets.append(self.tz_offset) ignore_lists.append(self.ignore) tick_flags.append(self.tick) if is_already_started: return freeze_factory # Change the modules datetime.datetime = FakeDatetime datetime.date = FakeDate time.time = fake_time time.localtime = fake_localtime time.gmtime = fake_gmtime time.strftime = fake_strftime if uuid_generate_time_attr: setattr(uuid, uuid_generate_time_attr, None) uuid._UuidCreate = None uuid._last_timestamp = None copyreg.dispatch_table[real_datetime] = pickle_fake_datetime copyreg.dispatch_table[real_date] = pickle_fake_date # Change any place where the module had already been imported to_patch = [ ('real_date', real_date, FakeDate), ('real_datetime', real_datetime, FakeDatetime), ('real_gmtime', real_gmtime, fake_gmtime), ('real_localtime', real_localtime, fake_localtime), ('real_strftime', real_strftime, fake_strftime), ('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 to_patch.append(('real_clock', real_clock, fake_clock)) self.fake_names = tuple(fake.__name__ for real_name, real, fake in to_patch) self.reals = {id(fake): real for real_name, real, fake in to_patch} fakes = {id(real): fake for real_name, real, fake in to_patch} add_change = self.undo_changes.append # Save the current loaded modules self.modules_at_start = set(sys.modules.keys()) with warnings.catch_warnings(): warnings.filterwarnings('ignore') for mod_name, module in list(sys.modules.items()): if mod_name is None or module is None or mod_name == __name__: continue elif mod_name.startswith(self.ignore) or mod_name.endswith('.six.moves'): continue elif (not hasattr(module, "__name__") or module.__name__ in ('datetime', 'time')): continue module_attrs = _get_cached_module_attributes(module) for attribute_name, attribute_value in module_attrs: fake = fakes.get(id(attribute_value)) if fake: setattr(module, attribute_name, fake) add_change((module, attribute_name, attribute_value)) return freeze_factory def stop(self): freeze_factories.pop() ignore_lists.pop() tick_flags.pop() tz_offsets.pop() if not freeze_factories: datetime.datetime = real_datetime datetime.date = real_date copyreg.dispatch_table.pop(real_datetime) copyreg.dispatch_table.pop(real_date) for module, module_attribute, original_value in self.undo_changes: setattr(module, module_attribute, original_value) self.undo_changes = [] # Restore modules loaded after start() modules_to_restore = set(sys.modules.keys()) - self.modules_at_start self.modules_at_start = set() with warnings.catch_warnings(): warnings.simplefilter('ignore') for mod_name in modules_to_restore: module = sys.modules.get(mod_name, None) if mod_name is None or module is None: continue elif mod_name.startswith(self.ignore) or mod_name.endswith('.six.moves'): continue elif (not hasattr(module, "__name__") or module.__name__ in ('datetime', 'time')): continue for module_attribute in dir(module): if module_attribute in self.fake_names: continue try: attribute_value = getattr(module, module_attribute) except (ImportError, AttributeError, TypeError): # For certain libraries, this can result in ImportError(_winreg) or AttributeError (celery) continue real = self.reals.get(id(attribute_value)) if real: setattr(module, module_attribute, real) time.time = real_time time.gmtime = real_gmtime time.localtime = real_localtime time.strftime = real_strftime time.clock = real_clock if _TIME_NS_PRESENT: time.time_ns = real_time_ns if uuid_generate_time_attr: setattr(uuid, uuid_generate_time_attr, real_uuid_generate_time) uuid._UuidCreate = real_uuid_create uuid._last_timestamp = None def decorate_coroutine(self, coroutine): return wrap_coroutine(self, coroutine) def decorate_callable(self, func): def wrapper(*args, **kwargs): with self as time_factory: if self.as_arg: result = func(time_factory, *args, **kwargs) else: result = func(*args, **kwargs) return result functools.update_wrapper(wrapper, func) # update_wrapper already sets __wrapped__ in Python 3.2+, this is only # needed for Python 2.x support wrapper.__wrapped__ = func return wrapper def freeze_time(time_to_freeze=None, tz_offset=0, ignore=None, tick=False, as_arg=False, auto_tick_seconds=0): acceptable_times = (type(None), _string_type, datetime.date, datetime.timedelta, types.FunctionType, types.GeneratorType) if MayaDT is not None: acceptable_times += MayaDT, if not isinstance(time_to_freeze, acceptable_times): raise TypeError(('freeze_time() expected None, a string, date instance, datetime ' 'instance, MayaDT, timedelta instance, function or a generator, but got ' 'type {}.').format(type(time_to_freeze))) if tick and not _is_cpython: raise SystemError('Calling freeze_time with tick=True is only compatible with CPython') if isinstance(time_to_freeze, types.FunctionType): return freeze_time(time_to_freeze(), tz_offset, ignore, tick, auto_tick_seconds) if isinstance(time_to_freeze, types.GeneratorType): return freeze_time(next(time_to_freeze), tz_offset, ignore, tick, auto_tick_seconds) if MayaDT is not None and isinstance(time_to_freeze, MayaDT): return freeze_time(time_to_freeze.datetime(), tz_offset, ignore, tick, as_arg) if ignore is None: ignore = [] ignore = ignore[:] ignore.append('nose.plugins') ignore.append('six.moves') ignore.append('django.utils.six.moves') ignore.append('google.gax') ignore.append('threading') ignore.append('Queue') 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) # Setup adapters for sqlite try: # noinspection PyUnresolvedReferences import sqlite3 except ImportError: # Some systems have trouble with this pass else: # These are copied from Python sqlite3.dbapi2 def adapt_date(val): return val.isoformat() def adapt_datetime(val): return val.isoformat(" ") sqlite3.register_adapter(FakeDate, adapt_date) sqlite3.register_adapter(FakeDatetime, adapt_datetime) # Setup converters for pymysql try: import pymysql.converters except ImportError: pass else: pymysql.converters.encoders[FakeDate] = pymysql.converters.encoders[real_date] pymysql.converters.conversions[FakeDate] = pymysql.converters.encoders[real_date] pymysql.converters.encoders[FakeDatetime] = pymysql.converters.encoders[real_datetime] pymysql.converters.conversions[FakeDatetime] = pymysql.converters.encoders[real_datetime] freezegun-0.3.15/freezegun/_async_coroutine.py0000644000076500000240000000064513607223747021772 0ustar stevestaff00000000000000import functools import asyncio def wrap_coroutine(api, coroutine): @functools.wraps(coroutine) @asyncio.coroutine def wrapper(*args, **kwargs): with api as time_factory: if api.as_arg: result = yield from coroutine(time_factory, *args, **kwargs) else: result = yield from coroutine(*args, **kwargs) return result return wrapper freezegun-0.3.15/freezegun/_async.py0000644000076500000240000000061213607223747017675 0ustar stevestaff00000000000000import functools import asyncio def wrap_coroutine(api, coroutine): @functools.wraps(coroutine) async def wrapper(*args, **kwargs): with api as time_factory: if api.as_arg: result = await coroutine(time_factory, *args, **kwargs) else: result = await coroutine(*args, **kwargs) return result return wrapper freezegun-0.3.15/setup.py0000644000076500000240000000254713622627310015567 0ustar stevestaff00000000000000#!/usr/bin/env python import sys from setuptools import setup requires = ['six'] tests_require = [ 'mock;python_version<"3.4"', 'nose' ] if sys.version_info.major == 2: requires += ['python-dateutil>=1.0, != 2.0'] else: # Py3k requires += ['python-dateutil>=2.0'] with open('README.rst') as f: readme = f.read() setup( name='freezegun', version='0.3.15', description='Let your Python tests travel through time', long_description=readme, author='Steve Pulec', author_email='spulec@gmail.com', url='https://github.com/spulec/freezegun', packages=['freezegun'], install_requires=requires, tests_require=tests_require, include_package_data=True, license='Apache 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', classifiers=[ 'License :: OSI Approved :: Apache Software License', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', ], ) freezegun-0.3.15/AUTHORS.rst0000644000076500000240000000126713360776010015733 0ustar stevestaff00000000000000Patches and Suggestions ``````````````````````` - `Dan Miller `_ - `Matthew Schinckel `_ - `JJ Geewax `_ - `Roman Imankulov `_ - `Martin Geisler `_ - `Richard Eames `_ - `Tye Wang `_ - `Andreas Pelme `_ - `Jesse London `_ - `Zach Smith `_ - `Adam Johnson `_ - `Alex Ehlke `_ - `James Lu `_ - `Dan Elkis `_ freezegun-0.3.15/setup.cfg0000644000076500000240000000023613622627362015676 0ustar stevestaff00000000000000[nosetests] verbosity = 1 detailed-errors = 1 with-coverage = 1 cover-package = freezegun [bdist_wheel] universal = 1 [egg_info] tag_build = tag_date = 0 freezegun-0.3.15/README.rst0000644000076500000240000001660313510772770015551 0ustar stevestaff00000000000000FreezeGun: Let your Python tests travel through time ==================================================== .. image:: https://img.shields.io/pypi/v/freezegun.svg :target: https://pypi.python.org/pypi/freezegun/ .. image:: https://secure.travis-ci.org/spulec/freezegun.svg?branch=master :target: https://travis-ci.org/spulec/freezegun .. image:: https://coveralls.io/repos/spulec/freezegun/badge.svg?branch=master :target: https://coveralls.io/r/spulec/freezegun FreezeGun is a library that allows your Python tests to travel through time by mocking the datetime module. Usage ----- Once the decorator or context manager have been invoked, all calls to datetime.datetime.now(), datetime.datetime.utcnow(), datetime.date.today(), time.time(), time.localtime(), time.gmtime(), and time.strftime() will return the time that has been frozen. Decorator ~~~~~~~~~ .. code-block:: python from freezegun import freeze_time import datetime import unittest @freeze_time("2012-01-14") def test(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) # Or a unittest TestCase - freezes for every test, from the start of setUpClass to the end of tearDownClass @freeze_time("1955-11-12") class MyTests(unittest.TestCase): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(1955, 11, 12) # Or any other class - freezes around each callable (may not work in every case) @freeze_time("2012-01-14") class Tester(object): def test_the_class(self): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) Context manager ~~~~~~~~~~~~~~~ .. code-block:: python from freezegun import freeze_time def test(): assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) with freeze_time("2012-01-14"): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) Raw use ~~~~~~~ .. code-block:: python from freezegun import freeze_time freezer = freeze_time("2012-01-14 12:00:01") freezer.start() assert datetime.datetime.now() == datetime.datetime(2012, 1, 14, 12, 0, 1) freezer.stop() Timezones ~~~~~~~~~ .. code-block:: python from freezegun import freeze_time @freeze_time("2012-01-14 03:21:34", tz_offset=-4) def test(): assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34) assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 21, 34) # datetime.date.today() uses local time assert datetime.date.today() == datetime.date(2012, 1, 13) @freeze_time("2012-01-14 03:21:34", tz_offset=-datetime.timedelta(hours=3, minutes=30)) def test_timedelta_offset(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 51, 34) Nice inputs ~~~~~~~~~~~ FreezeGun uses dateutil behind the scenes so you can have nice-looking datetimes. .. code-block:: python @freeze_time("Jan 14th, 2012") def test_nice_datetime(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) Function and generator objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun is able to handle function and generator objects. .. code-block:: python def test_lambda(): with freeze_time(lambda: datetime.datetime(2012, 1, 14)): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) def test_generator(): datetimes = (datetime.datetime(year, 1, 1) for year in range(2010, 2012)) with freeze_time(datetimes): assert datetime.datetime.now() == datetime.datetime(2010, 1, 1) with freeze_time(datetimes): assert datetime.datetime.now() == datetime.datetime(2011, 1, 1) # The next call to freeze_time(datetimes) would raise a StopIteration exception. ``tick`` argument ~~~~~~~~~~~~~~~~~ FreezeGun has an additional ``tick`` argument which will restart time at the given value, but then time will keep ticking. This is alternative to the default parameters which will keep time stopped. .. code-block:: python @freeze_time("Jan 14th, 2020", tick=True) def test_nice_datetime(): assert datetime.datetime.now() > datetime.datetime(2020, 1, 14) ``auto_tick_seconds`` argument ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun has an additional ``auto_tick_seconds`` argument which will autoincrement the value every time by the given amount from the start value. This is alternative to the default parameters which will keep time stopped. Note that given ``auto_tick_seconds`` the ``tick`` parameter will be ignored. .. code-block:: python @freeze_time("Jan 14th, 2020", auto_tick_seconds=15) def test_nice_datetime(): first_time = datetime.datetime.now() auto_incremented_time = datetime.datetime.now() assert first_time + datetime.timedelta(seconds=15) == auto_incremented_time Manual ticks ~~~~~~~~~~~~ FreezeGun allows for the time to be manually forwarded as well. .. code-block:: python def test_manual_increment(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.tick() initial_datetime += datetime.timedelta(seconds=1) assert frozen_datetime() == initial_datetime frozen_datetime.tick(delta=datetime.timedelta(seconds=10)) initial_datetime += datetime.timedelta(seconds=10) assert frozen_datetime() == initial_datetime Moving time to specify datetime ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FreezeGun allows moving time to specific dates. .. code-block:: python def test_move_to(): initial_datetime = datetime.datetime(year=1, month=7, day=12, hour=15, minute=6, second=3) other_datetime = datetime.datetime(year=2, month=8, day=13, hour=14, minute=5, second=0) with freeze_time(initial_datetime) as frozen_datetime: assert frozen_datetime() == initial_datetime frozen_datetime.move_to(other_datetime) assert frozen_datetime() == other_datetime frozen_datetime.move_to(initial_datetime) assert frozen_datetime() == initial_datetime @freeze_time("2012-01-14", as_arg=True) def test(frozen_time): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) frozen_time.move_to("2014-02-12") assert datetime.datetime.now() == datetime.datetime(2014, 2, 12) Parameter for ``move_to`` can be any valid ``freeze_time`` date (string, date, datetime). Default arguments ~~~~~~~~~~~~~~~~~ Note that FreezeGun will not modify default arguments. The following code will print the current date. See `here `_ for why. .. code-block:: python from freezegun import freeze_time import datetime as dt def test(default=dt.date.today()): print(default) with freeze_time('2000-1-1'): test() Installation ------------ To install FreezeGun, simply: .. code-block:: bash $ pip install freezegun On Debian systems: .. code-block:: bash $ sudo apt-get install python-freezegun