'L i<rdZddlmZddlmZddlmZddlmZddlmZddl Z ddl m Z ddl Z ddl Z dd lmZdd lmZdd lmZdd lmZddlZdd lmZddlmZddlmZe j4dZedZedZeddZddZddZ ddZ!GddZ"e"Z#eGddZ$y)z)Monkeypatching and mocking functionality.) annotations) Generator)Mapping)MutableMapping)contextmanagerN)Path)Any)final)overload)TypeVar)%MONKEYPATCH_LEGACY_NAMESPACE_PACKAGES)fixture) PytestWarningz^No module named (.*)$KVc#HKt}||jyw)a 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() `. N) MonkeyPatchundo)mpatchs Y/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/_pytest/monkeypatch.py monkeypatchr s2]F L KKMs "cv|jd}|jd}t|}|D]}|d|zz } t||}|S#t$rYnwxYw t|nE#t $r9}t |jd}||k(rt d|d||d}~wwxYwt|||})N.rzimport error in z: )splitpop __import__getattrAttributeError ImportErrorstrannotated_getattr)namepartsusedfoundpartexexpecteds rresolver*>s JJsOE 99Qselfs r__repr__zNotset.__repr__osr=N)returnr!)r. __module__ __qualname__rDrAr=rr?r?nsr=r?ceZdZdZddZeeddZe d ddZ e d ddZ e df ddZ e df ddZ dd Z ddd Z ddd Zddd ZddZddZddZy ) raHelper 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. c<g|_g|_d|_d|_yN)_setattr_setitem_cwd _savesyspathrBs r__init__zMonkeyPatch.__init__s:< HJ $ .2r=c#nK|} ||jy#|jwxYww)a]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`). N)r)clsms rcontextzMonkeyPatch.contexts+* E G FFHAFFHs5 525cyrJrArCr;r#valuer8s rsetattrzMonkeyPatch.setattrr=cyrJrArUs rrWzMonkeyPatch.setattrrXr=Tcd}ddl}t|tr-t|ts t d|}t ||\}}nt|ts t dt ||t}|r|turt|d||j|r |jj|t}|jj|||ft|||y)a 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. TrNzcuse setattr(target, name, value) or setattr(target, value) with target being a dotted import stringz|use setattr(target, name, value) with name being a string or setattr(target, value) with target being a dotted import stringr,)inspectr4r?r!r5r<rnotsetrisclass__dict__getrKappendrW)rCr;r#rVr8__tracebackhide__r[oldvals rrWzMonkeyPatch.setattrsT! eV $fc*$ E,VW=LD&dC($ v. v' F:-?x!HI I ??6 "__((v6F fdF34e$r=cd}ddl}t|tr*t|ts t dt ||\}}t ||s|r t|yt||t}|j|r |jj|t}|jj|||ft||y)aKDelete 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. TrNzUuse delattr(target, name) or delattr(target) with target being a dotted import string)r[r4r?r!r5r<hasattrrrr\r]r^r_rKr`delattr)rCr;r#r8rar[rbs rrezMonkeyPatch.delattrs! dF #fc*$ -VW=LD&vt$$T**VT62Fv&,,T6: MM &$!7 8 FD !r=cr|jj|||j|tf|||<y)z'Set dictionary entry ``name`` to value.N)rLr`r_r\)rCdicr#rVs rsetitemzMonkeyPatch.setitem%s/ c4v)>?@D r=c||vr|r t|y|jj|||j|tf||=y)zDelete ``name`` from dict. Raises ``KeyError`` if it doesn't exist, unless ``raising`` is set to False. N)KeyErrorrLr`r_r\)rCrgr#r8s rdelitemzMonkeyPatch.delitem+sJ s?tn$ MM #tSWWT6-B!C DD r=Nc Pt|tsHtjt d|d|dt |j ddt|}|r+|tjvr||ztj|z}|jtj||y)zSet 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. zValue of environment variable z type should be str, but got z (type: z); converted to str implicitly stacklevelN) r4r!warningswarnrr-r.osenvironrh)rCr#rVprepends rsetenvzMonkeyPatch.setenv9s%% MM4TF:WixU (<(<'==[]  JE trzz)GObjj&66E RZZu-r=cLtj}|j|||y)zDelete ``name`` from the environment. Raises ``KeyError`` if it does not exist, unless ``raising`` is set to False. )r8N)rrrsrk)rCr#r8rss rdelenvzMonkeyPatch.delenvMs -/JJ WdG 4r=c2|jtjdd|_tjjdt |dtj vrddl}ddlm}t|dr|jrxtt |}|jD]U}|||jdtjz }|js:tj t"dn|t |dd lm}|y) z:Prepend ``path`` to ``sys.path`` list of import locations.Nr pkg_resources)fixup_namespace_packages_namespace_packagesrrmrn)invalidate_caches)rNsyspathinsertr!modulesryrzrdr{rreplacerrsepis_dirrprqr importlibr|)rCr~ryrzpath_objns_pkg ns_pkg_pathr|s rsyspath_prependzMonkeyPatch.syspath_prependVs    $ # D  3t9% ckk ) >  '<=!55D ?+??F~ "*V^^C-H"HK"))+ Aa %SY / 0r=cx|jtj|_tj|y)zChange the current working directory to the specified path. :param path: The path to change into. N)rMrrgetcwdchdir)rCr~s rrzMonkeyPatch.chdirs& 99  DI r=ct|jD](\}}}|turt|||t ||*g|jddt|j D]\}}}|tur ||=|||<g|j dd|j$|jtjddd|_|j'tj|jd|_ yy#t $rYwxYw)aUndo 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. N) reversedrKr\rWrerLrjrNr}r~rMrrr)rCr/r#rV dictionarykeys rrzMonkeyPatch.undos$!) 7 # CuF"T5)T"  #  a&.t}}&= ( "JU"3 #( 3 ( a    (++CHHQK $D  99 HHTYY DI ! s5C33 C?>C?)rENonerEzGenerator[MonkeyPatch])..) r;r!r#objectrVr?r8boolrEr).) r;rr#r!rVrr8rrEr) r;z str | objectr# object | strrVrr8rrEr)r;rr#z str | Notsetr8rrEr)rg Mapping[K, V]r#rrVrrEr)T)rgrr#rr8rrErrJ)r#r!rVr!rtz str | NonerEr)r#r!r8rrEr)r~zstr | os.PathLike[str]rEr)r.rFrG__doc__rO classmethodrrSr rWr\rerhrkrurwrrrrAr=rrrvsY 3 2               F%F%F% F%  F%  F%V$ $"$"$" $"  $"L .(5(T)r=rr)r#r!rEr)r/rr#r!r0r!rEr)r7r!r8rrEztuple[str, object])%r __future__rcollections.abcrrr contextlibrrrpathlibrrer}typingr r r r rp_pytest.deprecatedr _pytest.fixturesr_pytest.warning_typesrcompileRE_IMPORT_ERROR_NAMErrrr*r"r<r?r\rrAr=rrs/"%#*%  D$/"rzz";< CL CL  :8 |||r=