aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-02-08 17:10:05 +0300
committerAlexander Smirnov <alex@ydb.tech>2024-02-09 19:18:57 +0300
commitc3aeaf50a59a913402896eaddfe07ef0b9312e83 (patch)
treeb1b1e1c112459e0ff307ca363116636f7477e6ec /contrib/python
parent05cec57c0cf6f640048593124d360162ade5efba (diff)
downloadydb-c3aeaf50a59a913402896eaddfe07ef0b9312e83.tar.gz
Intermediate changes
Diffstat (limited to 'contrib/python')
-rw-r--r--contrib/python/pluggy/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/pluggy/py3/pluggy/__init__.py6
-rw-r--r--contrib/python/pluggy/py3/pluggy/_callers.py39
-rw-r--r--contrib/python/pluggy/py3/pluggy/_hooks.py22
-rw-r--r--contrib/python/pluggy/py3/pluggy/_manager.py18
-rw-r--r--contrib/python/pluggy/py3/pluggy/_result.py15
-rw-r--r--contrib/python/pluggy/py3/pluggy/_version.py16
-rw-r--r--contrib/python/pluggy/py3/pluggy/_warnings.py27
-rw-r--r--contrib/python/pluggy/py3/ya.make3
9 files changed, 117 insertions, 31 deletions
diff --git a/contrib/python/pluggy/py3/.dist-info/METADATA b/contrib/python/pluggy/py3/.dist-info/METADATA
index 684704f432..c4c3312518 100644
--- a/contrib/python/pluggy/py3/.dist-info/METADATA
+++ b/contrib/python/pluggy/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pluggy
-Version: 1.3.0
+Version: 1.4.0
Summary: plugin and hook calling mechanisms for python
Home-page: https://github.com/pytest-dev/pluggy
Author: Holger Krekel
diff --git a/contrib/python/pluggy/py3/pluggy/__init__.py b/contrib/python/pluggy/py3/pluggy/__init__.py
index 9d9e873bd0..2adf9454f8 100644
--- a/contrib/python/pluggy/py3/pluggy/__init__.py
+++ b/contrib/python/pluggy/py3/pluggy/__init__.py
@@ -18,6 +18,8 @@ __all__ = [
"HookspecMarker",
"HookimplMarker",
"Result",
+ "PluggyWarning",
+ "PluggyTeardownRaisedWarning",
]
from ._manager import PluginManager, PluginValidationError
@@ -31,3 +33,7 @@ from ._hooks import (
HookimplOpts,
HookImpl,
)
+from ._warnings import (
+ PluggyWarning,
+ PluggyTeardownRaisedWarning,
+)
diff --git a/contrib/python/pluggy/py3/pluggy/_callers.py b/contrib/python/pluggy/py3/pluggy/_callers.py
index 6498eaed64..787f56bac2 100644
--- a/contrib/python/pluggy/py3/pluggy/_callers.py
+++ b/contrib/python/pluggy/py3/pluggy/_callers.py
@@ -3,27 +3,52 @@ Call loop machinery
"""
from __future__ import annotations
+import warnings
from typing import cast
from typing import Generator
from typing import Mapping
+from typing import NoReturn
from typing import Sequence
from typing import Tuple
from typing import Union
from ._hooks import HookImpl
-from ._result import _raise_wrapfail
from ._result import HookCallError
from ._result import Result
+from ._warnings import PluggyTeardownRaisedWarning
# Need to distinguish between old- and new-style hook wrappers.
-# Wrapping one a singleton tuple is the fastest type-safe way I found to do it.
+# Wrapping with a tuple is the fastest type-safe way I found to do it.
Teardown = Union[
- Tuple[Generator[None, Result[object], None]],
+ Tuple[Generator[None, Result[object], None], HookImpl],
Generator[None, object, object],
]
+def _raise_wrapfail(
+ wrap_controller: (
+ Generator[None, Result[object], None] | Generator[None, object, object]
+ ),
+ msg: str,
+) -> NoReturn:
+ co = wrap_controller.gi_code
+ raise RuntimeError(
+ "wrap_controller at %r %s:%d %s"
+ % (co.co_name, co.co_filename, co.co_firstlineno, msg)
+ )
+
+
+def _warn_teardown_exception(
+ hook_name: str, hook_impl: HookImpl, e: BaseException
+) -> None:
+ msg = "A plugin raised an exception during an old-style hookwrapper teardown.\n"
+ msg += f"Plugin: {hook_impl.plugin_name}, Hook: {hook_name}\n"
+ msg += f"{type(e).__name__}: {e}\n"
+ msg += "For more information see https://pluggy.readthedocs.io/en/stable/api_reference.html#pluggy.PluggyTeardownRaisedWarning" # noqa: E501
+ warnings.warn(PluggyTeardownRaisedWarning(msg), stacklevel=5)
+
+
def _multicall(
hook_name: str,
hook_impls: Sequence[HookImpl],
@@ -60,7 +85,7 @@ def _multicall(
res = hook_impl.function(*args)
wrapper_gen = cast(Generator[None, Result[object], None], res)
next(wrapper_gen) # first yield
- teardowns.append((wrapper_gen,))
+ teardowns.append((wrapper_gen, hook_impl))
except StopIteration:
_raise_wrapfail(wrapper_gen, "did not yield")
elif hook_impl.wrapper:
@@ -128,9 +153,13 @@ def _multicall(
if isinstance(teardown, tuple):
try:
teardown[0].send(outcome)
- _raise_wrapfail(teardown[0], "has second yield")
except StopIteration:
pass
+ except BaseException as e:
+ _warn_teardown_exception(hook_name, teardown[1], e)
+ raise
+ else:
+ _raise_wrapfail(teardown[0], "has second yield")
else:
try:
if outcome._exception is not None:
diff --git a/contrib/python/pluggy/py3/pluggy/_hooks.py b/contrib/python/pluggy/py3/pluggy/_hooks.py
index 916ca70489..7c8420f4de 100644
--- a/contrib/python/pluggy/py3/pluggy/_hooks.py
+++ b/contrib/python/pluggy/py3/pluggy/_hooks.py
@@ -389,6 +389,13 @@ class HookCaller:
#: Name of the hook getting called.
self.name: Final = name
self._hookexec: Final = hook_execute
+ # The hookimpls list. The caller iterates it *in reverse*. Format:
+ # 1. trylast nonwrappers
+ # 2. nonwrappers
+ # 3. tryfirst nonwrappers
+ # 4. trylast wrappers
+ # 5. wrappers
+ # 6. tryfirst wrappers
self._hookimpls: Final[list[HookImpl]] = []
self._call_history: _CallHistory | None = None
# TODO: Document, or make private.
@@ -490,7 +497,8 @@ class HookCaller:
), "Cannot directly call a historic hook - use call_historic instead."
self._verify_all_args_are_provided(kwargs)
firstresult = self.spec.opts.get("firstresult", False) if self.spec else False
- return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
+ # Copy because plugins may register other plugins during iteration (#438).
+ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
def call_historic(
self,
@@ -511,7 +519,8 @@ class HookCaller:
self._call_history.append((kwargs, result_callback))
# Historizing hooks don't return results.
# Remember firstresult isn't compatible with historic.
- res = self._hookexec(self.name, self._hookimpls, kwargs, False)
+ # Copy because plugins may register other plugins during iteration (#438).
+ res = self._hookexec(self.name, self._hookimpls.copy(), kwargs, False)
if result_callback is None:
return
if isinstance(res, list):
@@ -541,10 +550,11 @@ class HookCaller:
hookimpl = HookImpl(None, "<temp>", method, opts)
# Find last non-tryfirst nonwrapper method.
i = len(hookimpls) - 1
- while (
- i >= 0
- and hookimpls[i].tryfirst
- and not (hookimpls[i].hookwrapper or hookimpls[i].wrapper)
+ while i >= 0 and (
+ # Skip wrappers.
+ (hookimpls[i].hookwrapper or hookimpls[i].wrapper)
+ # Skip tryfirst nonwrappers.
+ or hookimpls[i].tryfirst
):
i -= 1
hookimpls.insert(i + 1, hookimpl)
diff --git a/contrib/python/pluggy/py3/pluggy/_manager.py b/contrib/python/pluggy/py3/pluggy/_manager.py
index 84717e6eaa..ce1e107a60 100644
--- a/contrib/python/pluggy/py3/pluggy/_manager.py
+++ b/contrib/python/pluggy/py3/pluggy/_manager.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import importlib.metadata
import inspect
import types
import warnings
@@ -11,6 +10,7 @@ from typing import Final
from typing import Iterable
from typing import Mapping
from typing import Sequence
+from typing import TYPE_CHECKING
from . import _tracing
from ._callers import _multicall
@@ -26,6 +26,10 @@ from ._hooks import HookspecOpts
from ._hooks import normalize_hookimpl_opts
from ._result import Result
+if TYPE_CHECKING:
+ # importtlib.metadata import is slow, defer it.
+ import importlib.metadata
+
_BeforeTrace = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None]
_AfterTrace = Callable[[Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None]
@@ -231,6 +235,16 @@ class PluginManager:
"""Return whether the given plugin name is blocked."""
return name in self._name2plugin and self._name2plugin[name] is None
+ def unblock(self, name: str) -> bool:
+ """Unblocks a name.
+
+ Returns whether the name was actually blocked.
+ """
+ if self._name2plugin.get(name, -1) is None:
+ del self._name2plugin[name]
+ return True
+ return False
+
def add_hookspecs(self, module_or_class: _Namespace) -> None:
"""Add new hook specifications defined in the given ``module_or_class``.
@@ -384,6 +398,8 @@ class PluginManager:
:return:
The number of plugins loaded by this call.
"""
+ import importlib.metadata
+
count = 0
for dist in list(importlib.metadata.distributions()):
for ep in dist.entry_points:
diff --git a/contrib/python/pluggy/py3/pluggy/_result.py b/contrib/python/pluggy/py3/pluggy/_result.py
index 29859eb92d..aa21fa1380 100644
--- a/contrib/python/pluggy/py3/pluggy/_result.py
+++ b/contrib/python/pluggy/py3/pluggy/_result.py
@@ -7,9 +7,7 @@ from types import TracebackType
from typing import Callable
from typing import cast
from typing import final
-from typing import Generator
from typing import Generic
-from typing import NoReturn
from typing import Optional
from typing import Tuple
from typing import Type
@@ -20,19 +18,6 @@ _ExcInfo = Tuple[Type[BaseException], BaseException, Optional[TracebackType]]
ResultType = TypeVar("ResultType")
-def _raise_wrapfail(
- wrap_controller: (
- Generator[None, Result[ResultType], None] | Generator[None, object, object]
- ),
- msg: str,
-) -> NoReturn:
- co = wrap_controller.gi_code
- raise RuntimeError(
- "wrap_controller at %r %s:%d %s"
- % (co.co_name, co.co_filename, co.co_firstlineno, msg)
- )
-
-
class HookCallError(Exception):
"""Hook was called incorrectly."""
diff --git a/contrib/python/pluggy/py3/pluggy/_version.py b/contrib/python/pluggy/py3/pluggy/_version.py
index 4a742d246f..ee6c4d7d05 100644
--- a/contrib/python/pluggy/py3/pluggy/_version.py
+++ b/contrib/python/pluggy/py3/pluggy/_version.py
@@ -1,4 +1,16 @@
# file generated by setuptools_scm
# don't change, don't track in version control
-__version__ = version = '1.3.0'
-__version_tuple__ = version_tuple = (1, 3, 0)
+TYPE_CHECKING = False
+if TYPE_CHECKING:
+ from typing import Tuple, Union
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
+else:
+ VERSION_TUPLE = object
+
+version: str
+__version__: str
+__version_tuple__: VERSION_TUPLE
+version_tuple: VERSION_TUPLE
+
+__version__ = version = '1.4.0'
+__version_tuple__ = version_tuple = (1, 4, 0)
diff --git a/contrib/python/pluggy/py3/pluggy/_warnings.py b/contrib/python/pluggy/py3/pluggy/_warnings.py
new file mode 100644
index 0000000000..6356c770c7
--- /dev/null
+++ b/contrib/python/pluggy/py3/pluggy/_warnings.py
@@ -0,0 +1,27 @@
+from typing import final
+
+
+class PluggyWarning(UserWarning):
+ """Base class for all warnings emitted by pluggy."""
+
+ __module__ = "pluggy"
+
+
+@final
+class PluggyTeardownRaisedWarning(PluggyWarning):
+ """A plugin raised an exception during an :ref:`old-style hookwrapper
+ <old_style_hookwrappers>` teardown.
+
+ Such exceptions are not handled by pluggy, and may cause subsequent
+ teardowns to be executed at unexpected times, or be skipped entirely.
+
+ This is an issue in the plugin implementation.
+
+ If the exception is unintended, fix the underlying cause.
+
+ If the exception is intended, switch to :ref:`new-style hook wrappers
+ <hookwrappers>`, or use :func:`result.force_exception()
+ <pluggy.Result.force_exception>` to set the exception instead of raising.
+ """
+
+ __module__ = "pluggy"
diff --git a/contrib/python/pluggy/py3/ya.make b/contrib/python/pluggy/py3/ya.make
index 7302e7c37d..8dc442cdd1 100644
--- a/contrib/python/pluggy/py3/ya.make
+++ b/contrib/python/pluggy/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(1.3.0)
+VERSION(1.4.0)
LICENSE(MIT)
@@ -17,6 +17,7 @@ PY_SRCS(
pluggy/_result.py
pluggy/_tracing.py
pluggy/_version.py
+ pluggy/_warnings.py
)
RESOURCE_FILES(