/usr/lib/imh-dnskeyapi/venv/lib/python3.13/site-packages/_pytest
NameSizeModeActions
assertion/-0755rm
config/-0755rm
mark/-0755rm
_code/-0755rm
_io/-0755rm
_py/-0755rm
cacheprovider.py223730644editdlrm
capture.py353300644editdlrm
compat.py114670644editdlrm
debugging.py132600644editdlrm
deprecated.py31470644editdlrm
doctest.py262550644editdlrm
faulthandler.py36740644editdlrm
fixtures.py735500644editdlrm
freeze_support.py12910644editdlrm
helpconfig.py88950644editdlrm
hookspec.py428310644editdlrm
junitxml.py255740644editdlrm
legacypath.py165880644editdlrm
logging.py351240644editdlrm
main.py374160644editdlrm
monkeypatch.py145980644editdlrm
nodes.py264830644editdlrm
outcomes.py105320644editdlrm
pastebin.py39780644editdlrm
pathlib.py375690644editdlrm
py.typed00644editdlrm
pytester.py615520644editdlrm
pytester_assertions.py22440644editdlrm
python.py648510644editdlrm
python_api.py401220644editdlrm
python_path.py7450644editdlrm
recwarn.py132270644editdlrm
reports.py213310644editdlrm
runner.py194360644editdlrm
scope.py27980644editdlrm
setuponly.py33060644editdlrm
setupplan.py11840644editdlrm
skipping.py102170644editdlrm
stash.py30900644editdlrm
stepwise.py45960644editdlrm
terminal.py573930644editdlrm
threadexception.py30050644editdlrm
timing.py4130644editdlrm
tmpdir.py113750644editdlrm
unittest.py156140644editdlrm
unraisableexception.py32520644editdlrm
warnings.py52110644editdlrm
warning_types.py43880644editdlrm
_argcomplete.py37760644editdlrm
_version.py5110644editdlrm
__init__.py3910644editdlrm
Edit: /usr/lib/imh-dnskeyapi/venv/lib/python3.13/site-packages/_pytest/monkeypatch.py (14598B)
# mypy: allow-untyped-defs """Monkeypatching and mocking functionality.""" from __future__ import annotations from contextlib import contextmanager import os import re import sys from typing import Any from typing import final from typing import Generator from typing import Mapping from typing import MutableMapping from typing import overload from typing import TypeVar import warnings from _pytest.fixtures import fixture from _pytest.warning_types import PytestWarning RE_IMPORT_ERROR_NAME = re.compile(r"^No module named (.*)$") K = TypeVar("K") V = TypeVar("V") @fixture def monkeypatch() -> Generator[MonkeyPatch]: """A convenient fixture for monkey-patching. The fixture provides these methods to modify objects, dictionaries, or :data:`os.environ`: * :meth:`monkeypatch.setattr(obj, name, value, raising=True) ` * :meth:`monkeypatch.delattr(obj, name, raising=True) ` * :meth:`monkeypatch.setitem(mapping, name, value) ` * :meth:`monkeypatch.delitem(obj, name, raising=True) ` * :meth:`monkeypatch.setenv(name, value, prepend=None) ` * :meth:`monkeypatch.delenv(name, raising=True) ` * :meth:`monkeypatch.syspath_prepend(path) ` * :meth:`monkeypatch.chdir(path) ` * :meth:`monkeypatch.context() ` All modifications will be undone after the requesting test function or fixture has finished. The ``raising`` parameter determines if a :class:`KeyError` or :class:`AttributeError` will be raised if the set/deletion operation does not have the specified target. To undo modifications done by the fixture in a contained scope, use :meth:`context() `. """ mpatch = MonkeyPatch() yield mpatch mpatch.undo() def resolve(name: str) -> object: # Simplified from zope.dottedname. parts = name.split(".") used = parts.pop(0) found: object = __import__(used) for part in parts: used += "." + part try: found = getattr(found, part) except AttributeError: pass else: continue # We use explicit un-nesting of the handling block in order # to avoid nested exceptions. try: __import__(used) except ImportError as ex: expected = str(ex).split()[-1] if expected == used: raise else: raise ImportError(f"import error in {used}: {ex}") from ex found = annotated_getattr(found, part, used) return found def annotated_getattr(obj: object, name: str, ann: str) -> object: try: obj = getattr(obj, name) except AttributeError as e: raise AttributeError( f"{type(obj).__name__!r} object at {ann} has no attribute {name!r}" ) from e return obj def derive_importpath(import_path: str, raising: bool) -> tuple[str, object]: if not isinstance(import_path, str) or "." not in import_path: raise TypeError(f"must be absolute import path string, not {import_path!r}") module, attr = import_path.rsplit(".", 1) target = resolve(module) if raising: annotated_getattr(target, attr, ann=module) return attr, target class Notset: def __repr__(self) -> str: return "" notset = Notset() @final class MonkeyPatch: """Helper to conveniently monkeypatch attributes/items/environment variables/syspath. Returned by the :fixture:`monkeypatch` fixture. .. versionchanged:: 6.2 Can now also be used directly as `pytest.MonkeyPatch()`, for when the fixture is not available. In this case, use :meth:`with MonkeyPatch.context() as mp: ` or remember to call :meth:`undo` explicitly. """ def __init__(self) -> None: self._setattr: list[tuple[object, str, object]] = [] self._setitem: list[tuple[Mapping[Any, Any], object, object]] = [] self._cwd: str | None = None self._savesyspath: list[str] | None = None @classmethod @contextmanager def context(cls) -> Generator[MonkeyPatch]: """Context manager that returns a new :class:`MonkeyPatch` object which undoes any patching done inside the ``with`` block upon exit. Example: .. code-block:: python import functools def test_partial(monkeypatch): with monkeypatch.context() as m: m.setattr(functools, "partial", 3) Useful in situations where it is desired to undo some patches before the test ends, such as mocking ``stdlib`` functions that might break pytest itself if mocked (for examples of this see :issue:`3290`). """ m = cls() try: yield m finally: m.undo() @overload def setattr( self, target: str, name: object, value: Notset = ..., raising: bool = ..., ) -> None: ... @overload def setattr( self, target: object, name: str, value: object, raising: bool = ..., ) -> None: ... def setattr( self, target: str | object, name: object | str, value: object = notset, raising: bool = True, ) -> None: """ Set attribute value on target, memorizing the old value. For example: .. code-block:: python import os monkeypatch.setattr(os, "getcwd", lambda: "/") The code above replaces the :func:`os.getcwd` function by a ``lambda`` which always returns ``"/"``. For convenience, you can specify a string as ``target`` which will be interpreted as a dotted import path, with the last part being the attribute name: .. code-block:: python monkeypatch.setattr("os.getcwd", lambda: "/") Raises :class:`AttributeError` if the attribute does not exist, unless ``raising`` is set to False. **Where to patch** ``monkeypatch.setattr`` works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test. See the section :ref:`Where to patch ` in the :mod:`unittest.mock` docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but applies to ``monkeypatch.setattr`` as well. """ __tracebackhide__ = True import inspect if isinstance(value, Notset): if not isinstance(target, str): raise TypeError( "use setattr(target, name, value) or " "setattr(target, value) with target being a dotted " "import string" ) value = name name, target = derive_importpath(target, raising) else: if not isinstance(name, str): raise TypeError( "use setattr(target, name, value) with name being a string or " "setattr(target, value) with target being a dotted " "import string" ) oldval = getattr(target, name, notset) if raising and oldval is notset: raise AttributeError(f"{target!r} has no attribute {name!r}") # avoid class descriptors like staticmethod/classmethod if inspect.isclass(target): oldval = target.__dict__.get(name, notset) self._setattr.append((target, name, oldval)) setattr(target, name, value) def delattr( self, target: object | str, name: str | Notset = notset, raising: bool = True, ) -> None: """Delete attribute ``name`` from ``target``. If no ``name`` is specified and ``target`` is a string it will be interpreted as a dotted import path with the last part being the attribute name. Raises AttributeError it the attribute does not exist, unless ``raising`` is set to False. """ __tracebackhide__ = True import inspect if isinstance(name, Notset): if not isinstance(target, str): raise TypeError( "use delattr(target, name) or " "delattr(target) with target being a dotted " "import string" ) name, target = derive_importpath(target, raising) if not hasattr(target, name): if raising: raise AttributeError(name) else: oldval = getattr(target, name, notset) # Avoid class descriptors like staticmethod/classmethod. if inspect.isclass(target): oldval = target.__dict__.get(name, notset) self._setattr.append((target, name, oldval)) delattr(target, name) def setitem(self, dic: Mapping[K, V], name: K, value: V) -> None: """Set dictionary entry ``name`` to value.""" self._setitem.append((dic, name, dic.get(name, notset))) # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict dic[name] = value # type: ignore[index] def delitem(self, dic: Mapping[K, V], name: K, raising: bool = True) -> None: """Delete ``name`` from dict. Raises ``KeyError`` if it doesn't exist, unless ``raising`` is set to False. """ if name not in dic: if raising: raise KeyError(name) else: self._setitem.append((dic, name, dic.get(name, notset))) # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict del dic[name] # type: ignore[attr-defined] def setenv(self, name: str, value: str, prepend: str | None = None) -> None: """Set environment variable ``name`` to ``value``. If ``prepend`` is a character, read the current environment variable value and prepend the ``value`` adjoined with the ``prepend`` character. """ if not isinstance(value, str): warnings.warn( # type: ignore[unreachable] PytestWarning( f"Value of environment variable {name} type should be str, but got " f"{value!r} (type: {type(value).__name__}); converted to str implicitly" ), stacklevel=2, ) value = str(value) if prepend and name in os.environ: value = value + prepend + os.environ[name] self.setitem(os.environ, name, value) def delenv(self, name: str, raising: bool = True) -> None: """Delete ``name`` from the environment. Raises ``KeyError`` if it does not exist, unless ``raising`` is set to False. """ environ: MutableMapping[str, str] = os.environ self.delitem(environ, name, raising=raising) def syspath_prepend(self, path) -> None: """Prepend ``path`` to ``sys.path`` list of import locations.""" if self._savesyspath is None: self._savesyspath = sys.path[:] sys.path.insert(0, str(path)) # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171 # this is only needed when pkg_resources was already loaded by the namespace package if "pkg_resources" in sys.modules: from pkg_resources import fixup_namespace_packages fixup_namespace_packages(str(path)) # A call to syspathinsert() usually means that the caller wants to # import some dynamically created files, thus with python3 we # invalidate its import caches. # This is especially important when any namespace package is in use, # since then the mtime based FileFinder cache (that gets created in # this case already) gets not invalidated when writing the new files # quickly afterwards. from importlib import invalidate_caches invalidate_caches() def chdir(self, path: str | os.PathLike[str]) -> None: """Change the current working directory to the specified path. :param path: The path to change into. """ if self._cwd is None: self._cwd = os.getcwd() os.chdir(path) def undo(self) -> None: """Undo previous changes. This call consumes the undo stack. Calling it a second time has no effect unless you do more monkeypatching after the undo call. There is generally no need to call `undo()`, since it is called automatically during tear-down. .. note:: The same `monkeypatch` fixture is used across a single test function invocation. If `monkeypatch` is used both by the test function itself and one of the test fixtures, calling `undo()` will undo all of the changes made in both functions. Prefer to use :meth:`context() ` instead. """ for obj, name, value in reversed(self._setattr): if value is not notset: setattr(obj, name, value) else: delattr(obj, name) self._setattr[:] = [] for dictionary, key, value in reversed(self._setitem): if value is notset: try: # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict del dictionary[key] # type: ignore[attr-defined] except KeyError: pass # Was already deleted, so we have the desired state. else: # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict dictionary[key] = value # type: ignore[index] self._setitem[:] = [] if self._savesyspath is not None: sys.path[:] = self._savesyspath self._savesyspath = None if self._cwd is not None: os.chdir(self._cwd) self._cwd = None