summaryrefslogtreecommitdiffstats
path: root/contrib/python
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-05-31 11:00:32 +0300
committerrobot-piglet <[email protected]>2025-05-31 11:10:07 +0300
commit50318ed167506d485732c24a959f9c0711258047 (patch)
treedf4b55e9192a6a05d14d7d906d28d4475d9fce5f /contrib/python
parent0d86826871d3d0ce988823be681473aeacdf26b9 (diff)
Intermediate changes
commit_hash:0b67855d017f0b9d79b9ae4b931a252f94318014
Diffstat (limited to 'contrib/python')
-rw-r--r--contrib/python/pluggy/py3/.dist-info/METADATA27
-rw-r--r--contrib/python/pluggy/py3/pluggy/__init__.py9
-rw-r--r--contrib/python/pluggy/py3/pluggy/_callers.py181
-rw-r--r--contrib/python/pluggy/py3/pluggy/_hooks.py43
-rw-r--r--contrib/python/pluggy/py3/pluggy/_manager.py71
-rw-r--r--contrib/python/pluggy/py3/pluggy/_result.py15
-rw-r--r--contrib/python/pluggy/py3/pluggy/_tracing.py5
-rw-r--r--contrib/python/pluggy/py3/pluggy/_version.py13
-rw-r--r--contrib/python/pluggy/py3/ya.make2
9 files changed, 172 insertions, 194 deletions
diff --git a/contrib/python/pluggy/py3/.dist-info/METADATA b/contrib/python/pluggy/py3/.dist-info/METADATA
index 2d697b0d721..12345f88ebe 100644
--- a/contrib/python/pluggy/py3/.dist-info/METADATA
+++ b/contrib/python/pluggy/py3/.dist-info/METADATA
@@ -1,15 +1,9 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: pluggy
-Version: 1.5.0
+Version: 1.6.0
Summary: plugin and hook calling mechanisms for python
-Home-page: https://github.com/pytest-dev/pluggy
-Author: Holger Krekel
-Author-email: [email protected]
+Author-email: Holger Krekel <[email protected]>
License: MIT
-Platform: unix
-Platform: linux
-Platform: osx
-Platform: win32
Classifier: Development Status :: 6 - Mature
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
@@ -23,19 +17,22 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
-Requires-Python: >=3.8
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Requires-Python: >=3.9
Description-Content-Type: text/x-rst
License-File: LICENSE
Provides-Extra: dev
-Requires-Dist: pre-commit ; extra == 'dev'
-Requires-Dist: tox ; extra == 'dev'
+Requires-Dist: pre-commit; extra == "dev"
+Requires-Dist: tox; extra == "dev"
Provides-Extra: testing
-Requires-Dist: pytest ; extra == 'testing'
-Requires-Dist: pytest-benchmark ; extra == 'testing'
+Requires-Dist: pytest; extra == "testing"
+Requires-Dist: pytest-benchmark; extra == "testing"
+Requires-Dist: coverage; extra == "testing"
+Dynamic: license-file
====================================================
pluggy - A minimalist production ready plugin system
diff --git a/contrib/python/pluggy/py3/pluggy/__init__.py b/contrib/python/pluggy/py3/pluggy/__init__.py
index 36ce1680621..8a651f499d9 100644
--- a/contrib/python/pluggy/py3/pluggy/__init__.py
+++ b/contrib/python/pluggy/py3/pluggy/__init__.py
@@ -1,10 +1,3 @@
-try:
- from ._version import version as __version__
-except ImportError:
- # broken installation, we don't even try
- # unknown only works because we do poor mans version compare
- __version__ = "unknown"
-
__all__ = [
"__version__",
"PluginManager",
@@ -21,7 +14,6 @@ __all__ = [
"PluggyWarning",
"PluggyTeardownRaisedWarning",
]
-
from ._hooks import HookCaller
from ._hooks import HookImpl
from ._hooks import HookimplMarker
@@ -33,5 +25,6 @@ from ._manager import PluginManager
from ._manager import PluginValidationError
from ._result import HookCallError
from ._result import Result
+from ._version import version as __version__
from ._warnings import PluggyTeardownRaisedWarning
from ._warnings import PluggyWarning
diff --git a/contrib/python/pluggy/py3/pluggy/_callers.py b/contrib/python/pluggy/py3/pluggy/_callers.py
index d01f925cca2..472d5dd05be 100644
--- a/contrib/python/pluggy/py3/pluggy/_callers.py
+++ b/contrib/python/pluggy/py3/pluggy/_callers.py
@@ -4,13 +4,11 @@ Call loop machinery
from __future__ import annotations
+from collections.abc import Generator
+from collections.abc import Mapping
+from collections.abc import Sequence
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
import warnings
from ._hooks import HookImpl
@@ -21,22 +19,47 @@ from ._warnings import PluggyTeardownRaisedWarning
# Need to distinguish between old- and new-style hook wrappers.
# Wrapping with a tuple is the fastest type-safe way I found to do it.
-Teardown = Union[
- Tuple[Generator[None, Result[object], None], HookImpl],
- Generator[None, object, object],
-]
+Teardown = Generator[None, object, object]
+
+
+def run_old_style_hookwrapper(
+ hook_impl: HookImpl, hook_name: str, args: Sequence[object]
+) -> Teardown:
+ """
+ backward compatibility wrapper to run a old style hookwrapper as a wrapper
+ """
+
+ teardown: Teardown = cast(Teardown, hook_impl.function(*args))
+ try:
+ next(teardown)
+ except StopIteration:
+ _raise_wrapfail(teardown, "did not yield")
+ try:
+ res = yield
+ result = Result(res, None)
+ except BaseException as exc:
+ result = Result(None, exc)
+ try:
+ teardown.send(result)
+ except StopIteration:
+ pass
+ except BaseException as e:
+ _warn_teardown_exception(hook_name, hook_impl, e)
+ raise
+ else:
+ _raise_wrapfail(teardown, "has second yield")
+ finally:
+ teardown.close()
+ return result.get_result()
def _raise_wrapfail(
- wrap_controller: (
- Generator[None, Result[object], None] | Generator[None, object, object]
- ),
+ wrap_controller: Generator[None, object, object],
msg: str,
) -> NoReturn:
- co = wrap_controller.gi_code
+ co = wrap_controller.gi_code # type: ignore[attr-defined]
raise RuntimeError(
- "wrap_controller at %r %s:%d %s"
- % (co.co_name, co.co_filename, co.co_firstlineno, msg)
+ f"wrap_controller at {co.co_name!r} {co.co_filename}:{co.co_firstlineno} {msg}"
)
@@ -47,7 +70,7 @@ def _warn_teardown_exception(
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)
+ warnings.warn(PluggyTeardownRaisedWarning(msg), stacklevel=6)
def _multicall(
@@ -64,31 +87,26 @@ def _multicall(
__tracebackhide__ = True
results: list[object] = []
exception = None
- only_new_style_wrappers = True
try: # run impl and wrapper setup functions in a loop
teardowns: list[Teardown] = []
try:
for hook_impl in reversed(hook_impls):
try:
args = [caller_kwargs[argname] for argname in hook_impl.argnames]
- except KeyError:
- for argname in hook_impl.argnames:
+ except KeyError as e:
+ # coverage bug - this is tested
+ for argname in hook_impl.argnames: # pragma: no cover
if argname not in caller_kwargs:
raise HookCallError(
f"hook call must provide argument {argname!r}"
- )
+ ) from e
if hook_impl.hookwrapper:
- only_new_style_wrappers = False
- try:
- # If this cast is not valid, a type error is raised below,
- # which is the desired response.
- res = hook_impl.function(*args)
- wrapper_gen = cast(Generator[None, Result[object], None], res)
- next(wrapper_gen) # first yield
- teardowns.append((wrapper_gen, hook_impl))
- except StopIteration:
- _raise_wrapfail(wrapper_gen, "did not yield")
+ function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
+
+ next(function_gen) # first yield
+ teardowns.append(function_gen)
+
elif hook_impl.wrapper:
try:
# If this cast is not valid, a type error is raised below,
@@ -108,75 +126,44 @@ def _multicall(
except BaseException as exc:
exception = exc
finally:
- # Fast path - only new-style wrappers, no Result.
- if only_new_style_wrappers:
- if firstresult: # first result hooks return a single value
- result = results[0] if results else None
- else:
- result = results
-
- # run all wrapper post-yield blocks
- for teardown in reversed(teardowns):
- try:
- if exception is not None:
- teardown.throw(exception) # type: ignore[union-attr]
- else:
- teardown.send(result) # type: ignore[union-attr]
- # Following is unreachable for a well behaved hook wrapper.
- # Try to force finalizers otherwise postponed till GC action.
- # Note: close() may raise if generator handles GeneratorExit.
- teardown.close() # type: ignore[union-attr]
- except StopIteration as si:
- result = si.value
- exception = None
- continue
- except BaseException as e:
- exception = e
- continue
- _raise_wrapfail(teardown, "has second yield") # type: ignore[arg-type]
-
- if exception is not None:
- raise exception.with_traceback(exception.__traceback__)
- else:
- return result
-
- # Slow path - need to support old-style wrappers.
+ if firstresult: # first result hooks return a single value
+ result = results[0] if results else None
else:
- if firstresult: # first result hooks return a single value
- outcome: Result[object | list[object]] = Result(
- results[0] if results else None, exception
- )
- else:
- outcome = Result(results, exception)
+ result = results
- # run all wrapper post-yield blocks
- for teardown in reversed(teardowns):
- if isinstance(teardown, tuple):
+ # run all wrapper post-yield blocks
+ for teardown in reversed(teardowns):
+ try:
+ if exception is not None:
try:
- teardown[0].send(outcome)
- 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:
- teardown.throw(outcome._exception)
+ teardown.throw(exception)
+ except RuntimeError as re:
+ # StopIteration from generator causes RuntimeError
+ # even for coroutine usage - see #544
+ if (
+ isinstance(exception, StopIteration)
+ and re.__cause__ is exception
+ ):
+ teardown.close()
+ continue
else:
- teardown.send(outcome._result)
- # Following is unreachable for a well behaved hook wrapper.
- # Try to force finalizers otherwise postponed till GC action.
- # Note: close() may raise if generator handles GeneratorExit.
- teardown.close()
- except StopIteration as si:
- outcome.force_result(si.value)
- continue
- except BaseException as e:
- outcome.force_exception(e)
- continue
- _raise_wrapfail(teardown, "has second yield")
+ raise
+ else:
+ teardown.send(result)
+ # Following is unreachable for a well behaved hook wrapper.
+ # Try to force finalizers otherwise postponed till GC action.
+ # Note: close() may raise if generator handles GeneratorExit.
+ teardown.close()
+ except StopIteration as si:
+ result = si.value
+ exception = None
+ continue
+ except BaseException as e:
+ exception = e
+ continue
+ _raise_wrapfail(teardown, "has second yield")
- return outcome.get_result()
+ if exception is not None:
+ raise exception
+ else:
+ return result
diff --git a/contrib/python/pluggy/py3/pluggy/_hooks.py b/contrib/python/pluggy/py3/pluggy/_hooks.py
index 362d791823e..97fef0d75fc 100644
--- a/contrib/python/pluggy/py3/pluggy/_hooks.py
+++ b/contrib/python/pluggy/py3/pluggy/_hooks.py
@@ -4,21 +4,19 @@ Internal hook annotation, representation and calling machinery.
from __future__ import annotations
+from collections.abc import Generator
+from collections.abc import Mapping
+from collections.abc import Sequence
+from collections.abc import Set
import inspect
import sys
from types import ModuleType
-from typing import AbstractSet
from typing import Any
from typing import Callable
from typing import Final
from typing import final
-from typing import Generator
-from typing import List
-from typing import Mapping
from typing import Optional
from typing import overload
-from typing import Sequence
-from typing import Tuple
from typing import TYPE_CHECKING
from typing import TypedDict
from typing import TypeVar
@@ -34,7 +32,7 @@ _Namespace = Union[ModuleType, type]
_Plugin = object
_HookExec = Callable[
[str, Sequence["HookImpl"], Mapping[str, object], bool],
- Union[object, List[object]],
+ Union[object, list[object]],
]
_HookImplFunction = Callable[..., Union[_T, Generator[None, Result[_T], None]]]
@@ -302,12 +300,12 @@ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]:
if inspect.isclass(func):
try:
func = func.__init__
- except AttributeError:
+ except AttributeError: # pragma: no cover - pypy special case
return (), ()
elif not inspect.isroutine(func): # callable object?
try:
func = getattr(func, "__call__", func)
- except Exception:
+ except Exception: # pragma: no cover - pypy special case
return (), ()
try:
@@ -315,7 +313,7 @@ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]:
sig = inspect.signature(
func.__func__ if inspect.ismethod(func) else func # type:ignore[arg-type]
)
- except TypeError:
+ except TypeError: # pragma: no cover
return (), ()
_valid_param_kinds = (
@@ -347,7 +345,7 @@ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]:
# pypy3 uses "obj" instead of "self" for default dunder methods
if not _PYPY:
implicit_names: tuple[str, ...] = ("self",)
- else:
+ else: # pragma: no cover
implicit_names = ("self", "obj")
if args:
qualname: str = getattr(func, "__qualname__", "")
@@ -376,7 +374,7 @@ class HookRelay:
_HookRelay = HookRelay
-_CallHistory = List[Tuple[Mapping[str, object], Optional[Callable[[Any], None]]]]
+_CallHistory = list[tuple[Mapping[str, object], Optional[Callable[[Any], None]]]]
class HookCaller:
@@ -485,12 +483,13 @@ class HookCaller:
notincall = ", ".join(
repr(argname)
for argname in self.spec.argnames
- # Avoid self.spec.argnames - kwargs.keys() - doesn't preserve order.
+ # Avoid self.spec.argnames - kwargs.keys()
+ # it doesn't preserve order.
if argname not in kwargs.keys()
)
warnings.warn(
- "Argument(s) {} which are declared in the hookspec "
- "cannot be found in this hook call".format(notincall),
+ f"Argument(s) {notincall} which are declared in the hookspec "
+ "cannot be found in this hook call",
stacklevel=2,
)
break
@@ -504,9 +503,9 @@ class HookCaller:
Returns the result(s) of calling all registered plugins, see
:ref:`calling`.
"""
- assert (
- not self.is_historic()
- ), "Cannot directly call a historic hook - use call_historic instead."
+ assert not self.is_historic(), (
+ "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
# Copy because plugins may register other plugins during iteration (#438).
@@ -545,9 +544,9 @@ class HookCaller:
"""Call the hook with some additional temporarily participating
methods using the specified ``kwargs`` as call parameters, see
:ref:`call_extra`."""
- assert (
- not self.is_historic()
- ), "Cannot directly call a historic hook - use call_historic instead."
+ assert not self.is_historic(), (
+ "Cannot directly call a historic hook - use call_historic instead."
+ )
self._verify_all_args_are_provided(kwargs)
opts: HookimplOpts = {
"wrapper": False,
@@ -608,7 +607,7 @@ class _SubsetHookCaller(HookCaller):
"_remove_plugins",
)
- def __init__(self, orig: HookCaller, remove_plugins: AbstractSet[_Plugin]) -> None:
+ def __init__(self, orig: HookCaller, remove_plugins: Set[_Plugin]) -> None:
self._orig = orig
self._remove_plugins = remove_plugins
self.name = orig.name # type: ignore[misc]
diff --git a/contrib/python/pluggy/py3/pluggy/_manager.py b/contrib/python/pluggy/py3/pluggy/_manager.py
index 9998dd815b5..ff1e3ce6e30 100644
--- a/contrib/python/pluggy/py3/pluggy/_manager.py
+++ b/contrib/python/pluggy/py3/pluggy/_manager.py
@@ -1,14 +1,14 @@
from __future__ import annotations
+from collections.abc import Iterable
+from collections.abc import Mapping
+from collections.abc import Sequence
import inspect
import types
from typing import Any
from typing import Callable
from typing import cast
from typing import Final
-from typing import Iterable
-from typing import Mapping
-from typing import Sequence
from typing import TYPE_CHECKING
import warnings
@@ -70,7 +70,7 @@ class DistFacade:
name: str = self.metadata["name"]
return name
- def __getattr__(self, attr: str, default=None):
+ def __getattr__(self, attr: str, default: Any | None = None) -> Any:
return getattr(self._dist, attr, default)
def __dir__(self) -> list[str]:
@@ -138,14 +138,14 @@ class PluginManager:
if self._name2plugin.get(plugin_name, -1) is None:
return None # blocked plugin, return None to indicate no registration
raise ValueError(
- "Plugin name already registered: %s=%s\n%s"
- % (plugin_name, plugin, self._name2plugin)
+ "Plugin name already registered: "
+ f"{plugin_name}={plugin}\n{self._name2plugin}"
)
if plugin in self._name2plugin.values():
raise ValueError(
- "Plugin already registered under a different name: %s=%s\n%s"
- % (plugin_name, plugin, self._name2plugin)
+ "Plugin already registered under a different name: "
+ f"{plugin_name}={plugin}\n{self._name2plugin}"
)
# XXX if an error happens we should make sure no state has been
@@ -188,11 +188,11 @@ class PluginManager:
res: HookimplOpts | None = getattr(
method, self.project_name + "_impl", None
)
- except Exception:
- res = {} # type: ignore[assignment]
+ except Exception: # pragma: no cover
+ res = {} # type: ignore[assignment] #pragma: no cover
if res is not None and not isinstance(res, dict):
# false positive
- res = None # type:ignore[unreachable]
+ res = None # type:ignore[unreachable] #pragma: no cover
return res
def unregister(
@@ -329,8 +329,8 @@ class PluginManager:
if hook.is_historic() and (hookimpl.hookwrapper or hookimpl.wrapper):
raise PluginValidationError(
hookimpl.plugin,
- "Plugin %r\nhook %r\nhistoric incompatible with yield/wrapper/hookwrapper"
- % (hookimpl.plugin_name, hook.name),
+ f"Plugin {hookimpl.plugin_name!r}\nhook {hook.name!r}\n"
+ "historic incompatible with yield/wrapper/hookwrapper",
)
assert hook.spec is not None
@@ -342,15 +342,10 @@ class PluginManager:
if notinspec:
raise PluginValidationError(
hookimpl.plugin,
- "Plugin %r for hook %r\nhookimpl definition: %s\n"
- "Argument(s) %s are declared in the hookimpl but "
- "can not be found in the hookspec"
- % (
- hookimpl.plugin_name,
- hook.name,
- _formatdef(hookimpl.function),
- notinspec,
- ),
+ f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"
+ f"hookimpl definition: {_formatdef(hookimpl.function)}\n"
+ f"Argument(s) {notinspec} are declared in the hookimpl but "
+ "can not be found in the hookspec",
)
if hook.spec.warn_on_impl_args:
@@ -364,18 +359,18 @@ class PluginManager:
) and not inspect.isgeneratorfunction(hookimpl.function):
raise PluginValidationError(
hookimpl.plugin,
- "Plugin %r for hook %r\nhookimpl definition: %s\n"
+ f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"
+ f"hookimpl definition: {_formatdef(hookimpl.function)}\n"
"Declared as wrapper=True or hookwrapper=True "
- "but function is not a generator function"
- % (hookimpl.plugin_name, hook.name, _formatdef(hookimpl.function)),
+ "but function is not a generator function",
)
if hookimpl.wrapper and hookimpl.hookwrapper:
raise PluginValidationError(
hookimpl.plugin,
- "Plugin %r for hook %r\nhookimpl definition: %s\n"
- "The wrapper=True and hookwrapper=True options are mutually exclusive"
- % (hookimpl.plugin_name, hook.name, _formatdef(hookimpl.function)),
+ f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"
+ f"hookimpl definition: {_formatdef(hookimpl.function)}\n"
+ "The wrapper=True and hookwrapper=True options are mutually exclusive",
)
def check_pending(self) -> None:
@@ -383,16 +378,16 @@ class PluginManager:
hook specification are optional, otherwise raise
:exc:`PluginValidationError`."""
for name in self.hook.__dict__:
- if name[0] != "_":
- hook: HookCaller = getattr(self.hook, name)
- if not hook.has_spec():
- for hookimpl in hook.get_hookimpls():
- if not hookimpl.optionalhook:
- raise PluginValidationError(
- hookimpl.plugin,
- "unknown hook %r in plugin %r"
- % (name, hookimpl.plugin),
- )
+ if name[0] == "_":
+ continue
+ hook: HookCaller = getattr(self.hook, name)
+ if not hook.has_spec():
+ for hookimpl in hook.get_hookimpls():
+ if not hookimpl.optionalhook:
+ raise PluginValidationError(
+ hookimpl.plugin,
+ f"unknown hook {name!r} in plugin {hookimpl.plugin!r}",
+ )
def load_setuptools_entrypoints(self, group: str, name: str | None = None) -> int:
"""Load modules from querying the specified setuptools ``group``.
diff --git a/contrib/python/pluggy/py3/pluggy/_result.py b/contrib/python/pluggy/py3/pluggy/_result.py
index f9a081c4f68..656a58416ca 100644
--- a/contrib/python/pluggy/py3/pluggy/_result.py
+++ b/contrib/python/pluggy/py3/pluggy/_result.py
@@ -10,12 +10,10 @@ from typing import cast
from typing import final
from typing import Generic
from typing import Optional
-from typing import Tuple
-from typing import Type
from typing import TypeVar
-_ExcInfo = Tuple[Type[BaseException], BaseException, Optional[TracebackType]]
+_ExcInfo = tuple[type[BaseException], BaseException, Optional[TracebackType]]
ResultType = TypeVar("ResultType")
@@ -28,7 +26,7 @@ class Result(Generic[ResultType]):
"""An object used to inspect and set the result in a :ref:`hook wrapper
<hookwrappers>`."""
- __slots__ = ("_result", "_exception")
+ __slots__ = ("_result", "_exception", "_traceback")
def __init__(
self,
@@ -38,6 +36,8 @@ class Result(Generic[ResultType]):
""":meta private:"""
self._result = result
self._exception = exception
+ # Exception __traceback__ is mutable, this keeps the original.
+ self._traceback = exception.__traceback__ if exception is not None else None
@property
def excinfo(self) -> _ExcInfo | None:
@@ -46,7 +46,7 @@ class Result(Generic[ResultType]):
if exc is None:
return None
else:
- return (type(exc), exc, exc.__traceback__)
+ return (type(exc), exc, self._traceback)
@property
def exception(self) -> BaseException | None:
@@ -75,6 +75,7 @@ class Result(Generic[ResultType]):
"""
self._result = result
self._exception = None
+ self._traceback = None
def force_exception(self, exception: BaseException) -> None:
"""Force the result to fail with ``exception``.
@@ -85,6 +86,7 @@ class Result(Generic[ResultType]):
"""
self._result = None
self._exception = exception
+ self._traceback = exception.__traceback__ if exception is not None else None
def get_result(self) -> ResultType:
"""Get the result(s) for this hook call.
@@ -94,10 +96,11 @@ class Result(Generic[ResultType]):
"""
__tracebackhide__ = True
exc = self._exception
+ tb = self._traceback
if exc is None:
return cast(ResultType, self._result)
else:
- raise exc.with_traceback(exc.__traceback__)
+ raise exc.with_traceback(tb)
# Historical name (pluggy<=1.2), kept for backward compatibility.
diff --git a/contrib/python/pluggy/py3/pluggy/_tracing.py b/contrib/python/pluggy/py3/pluggy/_tracing.py
index cd238ad7e54..f0b36db1524 100644
--- a/contrib/python/pluggy/py3/pluggy/_tracing.py
+++ b/contrib/python/pluggy/py3/pluggy/_tracing.py
@@ -4,14 +4,13 @@ Tracing utils
from __future__ import annotations
+from collections.abc import Sequence
from typing import Any
from typing import Callable
-from typing import Sequence
-from typing import Tuple
_Writer = Callable[[str], object]
-_Processor = Callable[[Tuple[str, ...], Tuple[Any, ...]], object]
+_Processor = Callable[[tuple[str, ...], tuple[Any, ...]], object]
class TagTracer:
diff --git a/contrib/python/pluggy/py3/pluggy/_version.py b/contrib/python/pluggy/py3/pluggy/_version.py
index c565007eec7..6b8420c0cf0 100644
--- a/contrib/python/pluggy/py3/pluggy/_version.py
+++ b/contrib/python/pluggy/py3/pluggy/_version.py
@@ -1,8 +1,13 @@
-# file generated by setuptools_scm
+# file generated by setuptools-scm
# don't change, don't track in version control
+
+__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
+
TYPE_CHECKING = False
if TYPE_CHECKING:
- from typing import Tuple, Union
+ from typing import Tuple
+ from typing import Union
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
else:
VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
__version_tuple__: VERSION_TUPLE
version_tuple: VERSION_TUPLE
-__version__ = version = '1.5.0'
-__version_tuple__ = version_tuple = (1, 5, 0)
+__version__ = version = '1.6.0'
+__version_tuple__ = version_tuple = (1, 6, 0)
diff --git a/contrib/python/pluggy/py3/ya.make b/contrib/python/pluggy/py3/ya.make
index ac57e7a2b75..a2eb19c45d1 100644
--- a/contrib/python/pluggy/py3/ya.make
+++ b/contrib/python/pluggy/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(1.5.0)
+VERSION(1.6.0)
LICENSE(MIT)