From 456b1a8b385d2ef14d7a52cf790497b4424338c4 Mon Sep 17 00:00:00 2001 From: Lukasz Balcerzak Date: Wed, 7 Oct 2020 09:32:22 +0200 Subject: [PATCH 1/2] Allow to configure default ignore list --- AUTHORS.rst | 1 + README.rst | 45 +++++++++++++++++++++++++++++++++++++++++ freezegun/__init__.py | 3 ++- freezegun/api.py | 26 ++++++++++++------------ freezegun/config.py | 26 ++++++++++++++++++++++++ tests/test_configure.py | 29 ++++++++++++++++++++++++++ tox.ini | 2 +- 7 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 freezegun/config.py create mode 100644 tests/test_configure.py diff --git a/AUTHORS.rst b/AUTHORS.rst index 41bdaabd..af301bae 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -17,3 +17,4 @@ Patches and Suggestions - `Dan Elkis `_ - `Bastien Vallet `_ - `Julian Mehnle `_ +- `Lukasz Balcerzak `_ diff --git a/README.rst b/README.rst index a33a8b2a..c7bd7ee3 100644 --- a/README.rst +++ b/README.rst @@ -264,3 +264,48 @@ On Debian systems: .. code-block:: bash $ sudo apt-get install python-freezegun + + +Ignore packages +--------------- + +Sometimes it's desired to ignore FreezeGun behaviour for particular packages (i.e. libraries). +It's possible to ignore them for a single invocation: + + +.. code-block:: python + + from freezegun import freeze_time + + with freeze_time('2020-10-06', ignore=['threading']): + # ... + + +By default FreezeGun ignores following packages: + +.. code-block:: python + + [ + 'nose.plugins', + 'six.moves', + 'django.utils.six.moves', + 'google.gax', + 'threading', + 'Queue', + 'selenium', + '_pytest.terminal.', + '_pytest.runner.', + 'gi', + ] + + +It's possible to set your own default ignore list: + +.. code-block:: python + + import freezegun + + freezegun.configure(default_ignore=['threading', 'tensorflow']) + + +Please note this will override default ignore list. diff --git a/freezegun/__init__.py b/freezegun/__init__.py index 7c7beec9..d3511b88 100644 --- a/freezegun/__init__.py +++ b/freezegun/__init__.py @@ -7,6 +7,7 @@ """ from .api import freeze_time +from .config import configure __title__ = 'freezegun' __version__ = '1.0.0' @@ -15,4 +16,4 @@ __copyright__ = 'Copyright 2012 Steve Pulec' -__all__ = ["freeze_time"] +__all__ = ["freeze_time", "configure"] diff --git a/freezegun/api.py b/freezegun/api.py index 1c69d8e5..58aa825e 100644 --- a/freezegun/api.py +++ b/freezegun/api.py @@ -1,3 +1,4 @@ +from . import config import dateutil import datetime import functools @@ -809,19 +810,18 @@ def freeze_time(time_to_freeze=None, tz_offset=0, ignore=None, tick=False, as_ar if ignore is None: ignore = [] ignore = ignore[:] - ignore.extend(['nose.plugins', - 'six.moves', - 'django.utils.six.moves', - 'google.gax', - 'threading', - 'Queue', - 'selenium', - '_pytest.terminal.', - '_pytest.runner.', - 'gi', - ]) - - return _freeze_time(time_to_freeze, tz_offset, ignore, tick, as_arg, as_kwarg, auto_tick_seconds) + if config.settings.default_ignore: + ignore.extend(config.settings.default_ignore) + + return _freeze_time( + time_to_freeze_str=time_to_freeze, + tz_offset=tz_offset, + ignore=ignore, + tick=tick, + as_arg=as_arg, + as_kwarg=as_kwarg, + auto_tick_seconds=auto_tick_seconds, + ) # Setup adapters for sqlite diff --git a/freezegun/config.py b/freezegun/config.py new file mode 100644 index 00000000..33b62279 --- /dev/null +++ b/freezegun/config.py @@ -0,0 +1,26 @@ + + +DEFAULT_IGNORE = [ + 'nose.plugins', + 'six.moves', + 'django.utils.six.moves', + 'google.gax', + 'threading', + 'Queue', + 'selenium', + '_pytest.terminal.', + '_pytest.runner.', + 'gi', +] + + +class Settings: + def __init__(self, default_ignore=None): + self.default_ignore = default_ignore or DEFAULT_IGNORE[:] + + +settings = Settings() + + +def configure(default_ignore=None): + settings.default_ignore = default_ignore diff --git a/tests/test_configure.py b/tests/test_configure.py new file mode 100644 index 00000000..3e994345 --- /dev/null +++ b/tests/test_configure.py @@ -0,0 +1,29 @@ +from unittest import mock +import freezegun + + +def teardown_function(): + freezegun.configure(default_ignore=None) + + +def test_default_ignore_is_overridden(): + freezegun.configure(default_ignore=['threading', 'tensorflow']) + + with mock.patch("freezegun.api._freeze_time.__init__", return_value=None) as _freeze_time_init_mock: + + freezegun.freeze_time("2020-10-06") + + expected_ignore_list = [ + 'threading', + 'tensorflow', + ] + + _freeze_time_init_mock.assert_called_once_with( + time_to_freeze_str="2020-10-06", + tz_offset=0, + ignore=expected_ignore_list, + tick=False, + as_arg=False, + as_kwarg='', + auto_tick_seconds=0, + ) diff --git a/tox.ini b/tox.ini index dc083486..aeb64faa 100644 --- a/tox.ini +++ b/tox.ini @@ -7,5 +7,5 @@ envlist = py35, py36, py37, py38, pypy3 [testenv] -commands = pytest --cov +commands = pytest --cov {posargs} deps = -rrequirements.txt From 1d8326f3a0a266b13509949d0396f338ea2886c1 Mon Sep 17 00:00:00 2001 From: Lukasz Balcerzak Date: Wed, 7 Oct 2020 13:32:24 +0200 Subject: [PATCH 2/2] Refactor + allow to extend default ignore list --- README.rst | 11 +++++++++-- freezegun/api.py | 4 ++-- freezegun/config.py | 24 ++++++++++++++++++----- tests/test_configure.py | 42 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/README.rst b/README.rst index c7bd7ee3..afc5a498 100644 --- a/README.rst +++ b/README.rst @@ -305,7 +305,14 @@ It's possible to set your own default ignore list: import freezegun - freezegun.configure(default_ignore=['threading', 'tensorflow']) + freezegun.configure(default_ignore_list=['threading', 'tensorflow']) -Please note this will override default ignore list. +Please note this will override default ignore list. If you want to extend existing defaults +please use: + +.. code-block:: python + + import freezegun + + freezegun.configure(extend_ignore_list=['tensorflow']) diff --git a/freezegun/api.py b/freezegun/api.py index 58aa825e..ac4c7948 100644 --- a/freezegun/api.py +++ b/freezegun/api.py @@ -810,8 +810,8 @@ def freeze_time(time_to_freeze=None, tz_offset=0, ignore=None, tick=False, as_ar if ignore is None: ignore = [] ignore = ignore[:] - if config.settings.default_ignore: - ignore.extend(config.settings.default_ignore) + if config.settings.default_ignore_list: + ignore.extend(config.settings.default_ignore_list) return _freeze_time( time_to_freeze_str=time_to_freeze, diff --git a/freezegun/config.py b/freezegun/config.py index 33b62279..4a735b6d 100644 --- a/freezegun/config.py +++ b/freezegun/config.py @@ -1,6 +1,6 @@ -DEFAULT_IGNORE = [ +DEFAULT_IGNORE_LIST = [ 'nose.plugins', 'six.moves', 'django.utils.six.moves', @@ -15,12 +15,26 @@ class Settings: - def __init__(self, default_ignore=None): - self.default_ignore = default_ignore or DEFAULT_IGNORE[:] + def __init__(self, default_ignore_list=None): + self.default_ignore_list = default_ignore_list or DEFAULT_IGNORE_LIST[:] settings = Settings() -def configure(default_ignore=None): - settings.default_ignore = default_ignore +class ConfigurationError(Exception): + pass + + +def configure(default_ignore_list=None, extend_ignore_list=None): + if default_ignore_list is not None and extend_ignore_list is not None: + raise ConfigurationError("Either default_ignore_list or extend_ignore_list might be given, not both") + if default_ignore_list: + settings.default_ignore_list = default_ignore_list + if extend_ignore_list: + settings.default_ignore_list = [*settings.default_ignore_list, *extend_ignore_list] + + +def reset_config(): + global settings + settings = Settings() diff --git a/tests/test_configure.py b/tests/test_configure.py index 3e994345..f787fb1b 100644 --- a/tests/test_configure.py +++ b/tests/test_configure.py @@ -1,20 +1,56 @@ from unittest import mock import freezegun +import freezegun.config + + +def setup_function(): + freezegun.config.reset_config() def teardown_function(): - freezegun.configure(default_ignore=None) + freezegun.config.reset_config() + + +def test_default_ignore_list_is_overridden(): + freezegun.configure(default_ignore_list=['threading', 'tensorflow']) + + with mock.patch("freezegun.api._freeze_time.__init__", return_value=None) as _freeze_time_init_mock: + + freezegun.freeze_time("2020-10-06") + + expected_ignore_list = [ + 'threading', + 'tensorflow', + ] + _freeze_time_init_mock.assert_called_once_with( + time_to_freeze_str="2020-10-06", + tz_offset=0, + ignore=expected_ignore_list, + tick=False, + as_arg=False, + as_kwarg='', + auto_tick_seconds=0, + ) -def test_default_ignore_is_overridden(): - freezegun.configure(default_ignore=['threading', 'tensorflow']) +def test_extend_default_ignore_list(): + freezegun.configure(extend_ignore_list=['tensorflow']) with mock.patch("freezegun.api._freeze_time.__init__", return_value=None) as _freeze_time_init_mock: freezegun.freeze_time("2020-10-06") expected_ignore_list = [ + 'nose.plugins', + 'six.moves', + 'django.utils.six.moves', + 'google.gax', 'threading', + 'Queue', + 'selenium', + '_pytest.terminal.', + '_pytest.runner.', + 'gi', 'tensorflow', ]