From e618785e475adc1413effa2a24d91e6d6e88f928 Mon Sep 17 00:00:00 2001 From: TH3 S0RC3RER 4PPR3NT1C3 Date: Thu, 2 Jan 2025 09:13:28 +0100 Subject: [PATCH] Improved documentation for real_asyncio parameter and added docstrings Fixes #561 Add documentation for the `real_asyncio` parameter and improve API documentation. * **README.rst** - Add documentation for the `real_asyncio` parameter in the "Usage" section. - Add succinct API documentation with all options listed in the "Usage" section. * **freezegun/api.py** - Add docstrings to the `_freeze_time` class and its methods. - Add docstrings to the `freeze_time` function. * **CHANGELOG** - Add an entry mentioning the `real_asyncio` parameter in the "1.4.0" section. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/spulec/freezegun/issues/561?shareId=XXXX-XXXX-XXXX-XXXX). --- CHANGELOG | 1 + README.rst | 40 +++++++++++++++++++++++++++++++++++++++ freezegun/api.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index fc27c900..1081bc6f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,7 @@ Freezegun Changelog ----- * `asyncio`-support from 1.3.x introduced quite a few bugs, so that functionality is now hidden behind a flag: `with freeze_time('1970-01-02', real_asyncio=True):` + * Added documentation for the `real_asyncio` parameter in the `README.rst` file. 1.3.1 ----- diff --git a/README.rst b/README.rst index 1545d18b..b8f5eedb 100644 --- a/README.rst +++ b/README.rst @@ -231,6 +231,46 @@ FreezeGun allows moving time to specific dates. Parameter for ``move_to`` can be any valid ``freeze_time`` date (string, date, datetime). +``real_asyncio`` parameter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +FreezeGun has an additional ``real_asyncio`` parameter which allows asyncio event loops to see real monotonic time even though time.monotonic() is frozen. This is useful to avoid breaking asyncio.sleep() and other asyncio functions that rely on monotonic time. + +.. code-block:: python + + @freeze_time("2012-01-14", real_asyncio=True) + async def test_asyncio(): + await asyncio.sleep(1) + assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) + +API Documentation +~~~~~~~~~~~~~~~~~ + +Here is a succinct API documentation with all options listed: + +.. code-block:: python + + freeze_time(time_to_freeze: Optional[_Freezable]=None, tz_offset: Union[int, datetime.timedelta]=0, ignore: Optional[List[str]]=None, tick: bool=False, as_arg: bool=False, as_kwarg: str='', auto_tick_seconds: float=0, real_asyncio: bool=False) -> _freeze_time + + _freeze_time(time_to_freeze_str: Optional[_Freezable], tz_offset: Union[int, datetime.timedelta], ignore: List[str], tick: bool, as_arg: bool, as_kwarg: str, auto_tick_seconds: float, real_asyncio: Optional[bool]) + + _freeze_time.start() -> Union[StepTickTimeFactory, TickingDateTimeFactory, FrozenDateTimeFactory] + + _freeze_time.stop() -> None + + _freeze_time.move_to(target_datetime: _Freezable) -> None + + _freeze_time.tick(delta: Union[datetime.timedelta, float]=datetime.timedelta(seconds=1)) -> datetime.datetime + + _freeze_time.decorate_class(klass: Type[T2]) -> Type[T2] + + _freeze_time.decorate_coroutine(coroutine: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]] + + _freeze_time.decorate_callable(func: Callable[P, T]) -> Callable[P, T] + + _freeze_time.__enter__() -> Union[StepTickTimeFactory, TickingDateTimeFactory, FrozenDateTimeFactory] + + _freeze_time.__exit__(*args: Any) -> None Default arguments ~~~~~~~~~~~~~~~~~ diff --git a/freezegun/api.py b/freezegun/api.py index d2352926..757f0af2 100644 --- a/freezegun/api.py +++ b/freezegun/api.py @@ -580,6 +580,35 @@ def move_to(self, target_datetime: _Freezable) -> None: class _freeze_time: + """ + A class to freeze time for testing purposes. + + This class can be used as a context manager or a decorator to freeze time + during the execution of a block of code or a function. It provides various + options to customize the behavior of the frozen time. + + Attributes: + time_to_freeze (datetime.datetime): The datetime to freeze time at. + tz_offset (datetime.timedelta): The timezone offset to apply to the frozen time. + ignore (List[str]): A list of module names to ignore when freezing time. + tick (bool): Whether to allow time to tick forward. + auto_tick_seconds (float): The number of seconds to auto-tick the frozen time. + undo_changes (List[Tuple[types.ModuleType, str, Any]]): A list of changes to undo when stopping the frozen time. + modules_at_start (Set[str]): A set of module names that were loaded at the start of freezing time. + as_arg (bool): Whether to pass the frozen time as an argument to the decorated function. + as_kwarg (str): The name of the keyword argument to pass the frozen time to the decorated function. + real_asyncio (Optional[bool]): Whether to allow asyncio event loops to see real monotonic time. + + Methods: + __call__(func): Decorates a function or class to freeze time during its execution. + decorate_class(klass): Decorates a class to freeze time during its execution. + __enter__(): Starts freezing time and returns the time factory. + __exit__(*args): Stops freezing time. + start(): Starts freezing time and returns the time factory. + stop(): Stops freezing time and restores the original time functions. + decorate_coroutine(coroutine): Decorates a coroutine to freeze time during its execution. + decorate_callable(func): Decorates a callable to freeze time during its execution. + """ def __init__( self, @@ -890,6 +919,26 @@ def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> T: def freeze_time(time_to_freeze: Optional[_Freezable]=None, tz_offset: Union[int, datetime.timedelta]=0, ignore: Optional[List[str]]=None, tick: bool=False, as_arg: bool=False, as_kwarg: str='', auto_tick_seconds: float=0, real_asyncio: bool=False) -> _freeze_time: + """ + Freezes time for testing purposes. + + This function can be used as a decorator or a context manager to freeze time + during the execution of a block of code or a function. It provides various + options to customize the behavior of the frozen time. + + Args: + time_to_freeze (Optional[_Freezable]): The datetime to freeze time at. + tz_offset (Union[int, datetime.timedelta]): The timezone offset to apply to the frozen time. + ignore (Optional[List[str]]): A list of module names to ignore when freezing time. + tick (bool): Whether to allow time to tick forward. + as_arg (bool): Whether to pass the frozen time as an argument to the decorated function. + as_kwarg (str): The name of the keyword argument to pass the frozen time to the decorated function. + auto_tick_seconds (float): The number of seconds to auto-tick the frozen time. + real_asyncio (bool): Whether to allow asyncio event loops to see real monotonic time. + + Returns: + _freeze_time: An instance of the _freeze_time class. + """ acceptable_times: Any = (type(None), str, datetime.date, datetime.timedelta, types.FunctionType, types.GeneratorType)