diff options
author | robot-piglet <[email protected]> | 2025-07-31 10:39:17 +0300 |
---|---|---|
committer | robot-piglet <[email protected]> | 2025-07-31 10:56:23 +0300 |
commit | b4deb8011118aa31d8047a444fb319afb9f31647 (patch) | |
tree | 0f568230f55dabbb8a2ca8198f5bc24bcb34cba5 | |
parent | b54bc0fda715484467236f8e33a366d33542b816 (diff) |
Intermediate changes
commit_hash:f841538cc0357cbb3522ece7882769295dd11074
-rw-r--r-- | contrib/python/freezegun/py3/.dist-info/METADATA | 2 | ||||
-rw-r--r-- | contrib/python/freezegun/py3/freezegun/__init__.py | 2 | ||||
-rw-r--r-- | contrib/python/freezegun/py3/freezegun/api.py | 58 | ||||
-rw-r--r-- | contrib/python/freezegun/py3/ya.make | 2 |
4 files changed, 49 insertions, 15 deletions
diff --git a/contrib/python/freezegun/py3/.dist-info/METADATA b/contrib/python/freezegun/py3/.dist-info/METADATA index fc6e39814b0..f60a9464d46 100644 --- a/contrib/python/freezegun/py3/.dist-info/METADATA +++ b/contrib/python/freezegun/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: freezegun -Version: 1.5.2 +Version: 1.5.4 Summary: Let your Python tests travel through time Home-page: https://github.com/spulec/freezegun Author: Steve Pulec diff --git a/contrib/python/freezegun/py3/freezegun/__init__.py b/contrib/python/freezegun/py3/freezegun/__init__.py index ca3524f77fd..4deed88047f 100644 --- a/contrib/python/freezegun/py3/freezegun/__init__.py +++ b/contrib/python/freezegun/py3/freezegun/__init__.py @@ -9,7 +9,7 @@ from .api import freeze_time from .config import configure __title__ = 'freezegun' -__version__ = '1.5.2' +__version__ = '1.5.4' __author__ = 'Steve Pulec' __license__ = 'Apache License 2.0' __copyright__ = 'Copyright 2012 Steve Pulec' diff --git a/contrib/python/freezegun/py3/freezegun/api.py b/contrib/python/freezegun/py3/freezegun/api.py index 0799162fdb0..1b118812513 100644 --- a/contrib/python/freezegun/py3/freezegun/api.py +++ b/contrib/python/freezegun/py3/freezegun/api.py @@ -632,6 +632,13 @@ class _freeze_time: self.as_kwarg = as_kwarg self.real_asyncio = real_asyncio + # mypy objects to this because Type is Callable, but Pytype needs it because + # (unlike mypy's) its inference does not assume class decorators always leave + # the type unchanged. + @overload + def __call__(self, func: Type[T2]) -> Type[T2]: # type: ignore[overload-overlap] + ... + @overload def __call__(self, func: "Callable[P, Awaitable[Any]]") -> "Callable[P, Awaitable[Any]]": ... @@ -645,6 +652,8 @@ class _freeze_time: return self.decorate_class(func) elif inspect.iscoroutinefunction(func): return self.decorate_coroutine(func) + elif inspect.isgeneratorfunction(func): + return self.decorate_generator_function(func) # type: ignore return self.decorate_callable(func) # type: ignore def decorate_class(self, klass: Type[T2]) -> Type[T2]: @@ -693,7 +702,6 @@ class _freeze_time: klass.tearDown = tearDown # type: ignore[method-assign] else: - seen = set() klasses = klass.mro() @@ -707,7 +715,20 @@ class _freeze_time: continue try: - setattr(klass, attr, self(attr_value)) + if attr_value.__dict__.get("_pytestfixturefunction") and hasattr(attr_value, "__pytest_wrapped__"): + # PYTEST==8.2.x (and maybe others) + # attr_value is a pytest fixture + # In other words: attr_value == fixture(original_method) + # We need to keep the fixture itself intact to ensure pytest still treats it as a fixture + # We still want to freeze time inside the original_method though + attr_value.__pytest_wrapped__.obj = self(attr_value.__pytest_wrapped__.obj) + elif attr_value.__dict__.get("_fixture_function"): + # PYTEST==8.4.x + # Same + attr_value._fixture_function = self(attr_value._fixture_function) + else: + # Wrap the entire method inside 'freeze_time' + setattr(klass, attr, self(attr_value)) except (AttributeError, TypeError): # Sometimes we can't set this for built-in types and custom callables continue @@ -895,20 +916,33 @@ class _freeze_time: def decorate_coroutine(self, coroutine: "Callable[P, Awaitable[T]]") -> "Callable[P, Awaitable[T]]": return wrap_coroutine(self, coroutine) + def _call_with_time_factory(self, time_factory: Union[StepTickTimeFactory, TickingDateTimeFactory, FrozenDateTimeFactory], func: "Callable[P, T]", *args: "P.args", **kwargs: "P.kwargs") -> T: + if self.as_arg and self.as_kwarg: + assert False, "You can't specify both as_arg and as_kwarg at the same time. Pick one." + if self.as_arg: + result = func(time_factory, *args, **kwargs) # type: ignore + if self.as_kwarg: + kwargs[self.as_kwarg] = time_factory + result = func(*args, **kwargs) + else: + result = func(*args, **kwargs) + return result + + def decorate_generator_function(self, func: "Callable[P, Iterator[T]]") -> "Callable[P, Iterator[T]]": + + @functools.wraps(func) + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> Iterator[T]: + with self as time_factory: + yield from self._call_with_time_factory(time_factory, func, *args, **kwargs) + + return wrapper + def decorate_callable(self, func: "Callable[P, T]") -> "Callable[P, T]": + @functools.wraps(func) def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> T: with self as time_factory: - if self.as_arg and self.as_kwarg: - assert False, "You can't specify both as_arg and as_kwarg at the same time. Pick one." - elif self.as_arg: - result = func(time_factory, *args, **kwargs) # type: ignore - elif self.as_kwarg: - kwargs[self.as_kwarg] = time_factory - result = func(*args, **kwargs) - else: - result = func(*args, **kwargs) - return result + return self._call_with_time_factory(time_factory, func, *args, **kwargs) return wrapper diff --git a/contrib/python/freezegun/py3/ya.make b/contrib/python/freezegun/py3/ya.make index 4bec269f46c..0331582e632 100644 --- a/contrib/python/freezegun/py3/ya.make +++ b/contrib/python/freezegun/py3/ya.make @@ -4,7 +4,7 @@ PY3_LIBRARY() PROVIDES(freezegun) -VERSION(1.5.2) +VERSION(1.5.4) LICENSE(Apache-2.0) |