K i| JdZddlZddlZddlZddlmZddlZddlZddl Z ddl m Z ddl m Z ddl Z ddlZddlmZmZmZmZmZmZddlmZddlmZdd lmZ ddlZddlZdd lmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)ejTr dd lm+Z+m,Z,m-Z-m.Z.ej^d Z0e de&e#e&e'e!e&fejbj fZ2Gd de3Z4Gdde3Z5Gdde3Z6Gdde3Z7Gdde3Z8de e9dfde!fdZ:defdZ;de"de0fde!de!de0fd Zfd'Z?Gd(de3Z@Gd)d*ZAe) dDd+e(e2d,e e$e3e%e$e3dffdee#fd-ZBe) dDd+ee!e2fd,e e$e3e%e$e3dffdee'fd.ZB dDd+e e(e2ee!e2ffd,d/dd0fd1ZBeBZC dDd+e e(e2ee!e2ffd,d/dd0fd2ZDd3e!defd4ZE dDd5e eFejfd6e2d,d/defd7ZHd8eFdd9fd:ZIGd;d<ZJejeeJZLejeeJZMd=eM_Gd>d?ZNd@e&defdAZOdBe2defdCZPe ePZPy#e$rdZYEwxYw)Ea* ``tornado.gen`` implements generator-based coroutines. .. note:: The "decorator and generator" approach in this module is a precursor to native coroutines (using ``async def`` and ``await``) which were introduced in Python 3.5. Applications that do not require compatibility with older versions of Python should use native coroutines instead. Some parts of this module are still useful with native coroutines, notably `multi`, `sleep`, `WaitIterator`, and `with_timeout`. Some of these functions have counterparts in the `asyncio` module which may be used as well, although the two may not necessarily be 100% compatible. Coroutines provide an easier way to work in an asynchronous environment than chaining callbacks. Code using coroutines is technically asynchronous, but it is written as a single generator instead of a collection of separate functions. For example, here's a coroutine-based handler: .. testcode:: class GenAsyncHandler(RequestHandler): @gen.coroutine def get(self): http_client = AsyncHTTPClient() response = yield http_client.fetch("http://example.com") do_something_with_response(response) self.render("template.html") Asynchronous functions in Tornado return an ``Awaitable`` or `.Future`; yielding this object returns its result. You can also yield a list or dict of other yieldable objects, which will be started at the same time and run in parallel; a list or dict of results will be returned when they are all finished: .. testcode:: @gen.coroutine def get(self): http_client = AsyncHTTPClient() response1, response2 = yield [http_client.fetch(url1), http_client.fetch(url2)] response_dict = yield dict(response3=http_client.fetch(url3), response4=http_client.fetch(url4)) response3 = response_dict['response3'] response4 = response_dict['response4'] If ``tornado.platform.twisted`` is imported, it is also possible to yield Twisted's ``Deferred`` objects. See the `convert_yielded` function to extend this mechanism. .. versionchanged:: 3.2 Dict support added. .. versionchanged:: 4.1 Support added for yielding ``asyncio`` Futures and Twisted Deferreds via ``singledispatch``. N) Generator)singledispatch) isawaitable)Future is_future chain_futurefuture_set_exc_infofuture_add_done_callback"future_set_result_unless_cancelled)IOLoop)app_log) TimeoutError) MappingUnionAnyCallableListTypeTuple AwaitableDictSequenceoverload)DequeOptionalSetIterable_Tc eZdZy) KeyReuseErrorN__name__ __module__ __qualname__Q/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/tornado/gen.pyr r vr&r c eZdZy)UnknownKeyErrorNr!r%r&r'r*r*zr(r&r*c eZdZy)LeakedCallbackErrorNr!r%r&r'r,r,~r(r&r,c eZdZy) BadYieldErrorNr!r%r&r'r.r.r(r&r.c eZdZy)ReturnValueIgnoredErrorNr!r%r&r'r0r0r(r&r0eReturnreturnc |jS#t$rYnwxYw |jdS#ttf$rYywxYw)Nr)valueAttributeErrorargs IndexError)r1s r'_value_from_stopiterationr9sP ww    vvay J 's  -??cnt}t|dd}|r|dd}|tk(r|d=n |S|r|S)N_source_tracebackr%r)rgetattr__file__)futuresource_tracebackfilenames r'_create_futurerBsQ XFv':B? $B'* x  $  M  Mr&f.r7kwc||i|SNr%)rCr7rDs r' _fake_ctx_runrGs d>b>r&func).zGenerator[Any, Any, _T]). Future[_T]cyrFr%rHs r' coroutinerLs#&r&cyrFr%rKs r'rLrLsGJr&c^tjfd}|_d|_|S)a>Decorator for asynchronous generators. For compatibility with older versions of Python, coroutines may also "return" by raising the special exception `Return(value) `. Functions with this decorator return a `.Future`. .. warning:: When exceptions occur inside a coroutine, the exception information will be stored in the `.Future` object. You must examine the result of the `.Future` object, or the exception may go unnoticed by your code. This means yielding the function if called from another coroutine, using something like `.IOLoop.run_sync` for top-level calls, or passing the `.Future` to `.IOLoop.add_future`. .. versionchanged:: 6.0 The ``callback`` argument was removed. Use the returned awaitable object instead. ct}ttjj}nt} |g|i|}t |t r7 |t|}t|||||jfdd} |d}St|||S#ttf$r}t|t|Yd}~>d}~wt$r!t|t!j"YjwxYw#d}wxYw#ttf$r}t|}Yd}~d}~wt$r-t|t!j" |d}cYS#d}wxYwwxYw)NcSrFr%)_runners r'z,coroutine..wrapper..svr&)rB contextvars copy_contextrunrG isinstancernextRunneradd_done_callback StopIterationr2r r9 Exceptionr sysexc_info) r7kwargsr?ctx_runresultyieldedr1rRrHs @r'wrapperzcoroutine..wrappersG  !  "!..044G#G1 "T3D3F3F&), ?%dF3G $GVVWEF,,-=> "!"F*66: ?&v.6 9! <!@' ?@2"F_ & 2.q1F    7   sY C: BC3C0)C*C0/C03C7:E D*EE E EET) functoolswraps __wrapped____tornado_coroutine__)rHrcs` r'rLrLs88__T<<|G$(G! Nr&ct|ddS)zReturn whether *func* is a coroutine function, i.e. a function wrapped with `~.gen.coroutine`. .. versionadded:: 4.5 rgF)r=rKs r'is_coroutine_functionris 40% 88r&c.eZdZdZddeddffd ZxZS)r2a&Special exception to return a value from a `coroutine`. This exception exists for compatibility with older versions of Python (before 3.3). In newer code use the ``return`` statement instead. If this exception is raised, its value argument is used as the result of the coroutine:: @gen.coroutine def fetch_json(url): response = yield AsyncHTTPClient().fetch(url) raise gen.Return(json_decode(response.body)) By analogy with the return statement, the value argument is optional. Nr5r3c@t|||_|f|_yrF)super__init__r5r7)selfr5 __class__s r'rmzReturn.__init__1s  H r&rF)r"r#r$__doc__rrm __classcell__)ros@r'r2r2s "cTr&ceZdZdZiZdededdfdZdefdZdefdZ d eddfd Z d edefd Z de jfd Zdefd Zy) WaitIteratoraProvides an iterator to yield the results of awaitables as they finish. Yielding a set of awaitables like this: ``results = yield [awaitable1, awaitable2]`` pauses the coroutine until both ``awaitable1`` and ``awaitable2`` return, and then restarts the coroutine with the results of both awaitables. If either awaitable raises an exception, the expression will raise that exception and all the results will be lost. If you need to get the result of each awaitable as soon as possible, or if you need the result of some awaitables even if others produce errors, you can use ``WaitIterator``:: wait_iterator = gen.WaitIterator(awaitable1, awaitable2) while not wait_iterator.done(): try: result = yield wait_iterator.next() except Exception as e: print("Error {} from {}".format(e, wait_iterator.current_future)) else: print("Result {} received from {} at {}".format( result, wait_iterator.current_future, wait_iterator.current_index)) Because results are returned as soon as they are available the output from the iterator *will not be in the same order as the input arguments*. If you need to know which future produced the current result, you can use the attributes ``WaitIterator.current_future``, or ``WaitIterator.current_index`` to get the index of the awaitable from the input list. (if keyword arguments were used in the construction of the `WaitIterator`, ``current_index`` will use the corresponding keyword). `WaitIterator` implements the async iterator protocol, so it can be used with the ``async for`` statement (note that in this version the entire iteration is aborted if any value raises an exception, while the previous example can continue past individual errors):: async for result in gen.WaitIterator(future1, future2): print("Result {} received from {} at {}".format( result, wait_iterator.current_future, wait_iterator.current_index)) .. versionadded:: 4.1 .. versionchanged:: 4.3 Added ``async for`` support in Python 3.5. r7r_r3Nc|r |r td|rC|jDcic]\}}|| c}}|_t|j }n&t |Dcic]\}}|| c}}|_|}t j|_d|_ d|_ d|_ |D]}t||jycc}}wcc}}w)Nz)You must provide args or kwargs, not both) ValueErroritems _unfinishedlistvalues enumerate collectionsdeque _finished current_indexcurrent_future_running_futurer _done_callback)rnr7r_krCfuturesir?s r'rmzWaitIterator.__init__qs FHI I 39<<>B!Q1BD 6==?+G3>T--377T0r&ct|_|jr)|j|jj S|jS)zReturns a `.Future` that will yield the next available result. Note that this `.Future` will not be the same object as any of the inputs. )rrr}_return_resultpopleftrs r'rXzWaitIterator.nexts? &x >>&&t~~'='='?@ @###r&rc|jr,|jjs|j|y|jj |yrF)rrrr}append)rnrs r'rzWaitIterator._done_callbacks<   (<(<(A(A(C    % NN ! !$ 'r&c|j tdt||j|j}d|_||_|jj ||_|S)zCalled set the returned future's state that of the future we yielded, and set the current future for the iterator. Nzno future is running)rr\rrrwpopr~)rnrress r'rzWaitIterator._return_resultse    '23 3T4//0""#"!--11$7 r&c|SrFr%rs r' __aiter__zWaitIterator.__aiter__s r&cl|jrttd|jS)NStopAsyncIteration)rr=builtinsrXrs r' __anext__zWaitIterator.__anext__s* 99;9'($89; ;yy{r&)r"r#r$rprwrrmboolrrXrrtyping AsyncIteratorrrr%r&r'rsrs8s4lKBfBB4B&d $f $(6(d( 6 f 6//6r&rschildrenquiet_exceptionscyrFr%rrs r'multirr&cyrFr%rs r'rrrr&z3Union[Type[Exception], Tuple[Type[Exception], ...]]z!Union[Future[List], Future[Dict]]ct||S)aRuns multiple asynchronous operations in parallel. ``children`` may either be a list or a dict whose values are yieldable objects. ``multi()`` returns a new yieldable object that resolves to a parallel structure containing their results. If ``children`` is a list, the result is a list of results in the same order; if it is a dict, the result is a dict with the same keys. That is, ``results = yield multi(list_of_futures)`` is equivalent to:: results = [] for future in list_of_futures: results.append(yield future) If any children raise exceptions, ``multi()`` will raise the first one. All others will be logged, unless they are of types contained in the ``quiet_exceptions`` argument. In a ``yield``-based coroutine, it is not normally necessary to call this function directly, since the coroutine runner will do it automatically when a list or dict is yielded. However, it is necessary in ``await``-based coroutines, or to pass the ``quiet_exceptions`` argument. This function is available under the names ``multi()`` and ``Multi()`` for historical reasons. Cancelling a `.Future` returned by ``multi()`` does not cancel its children. `asyncio.gather` is similar to ``multi()``, but it does cancel its children. .. versionchanged:: 4.2 If multiple yieldables fail, any exceptions after the first (which is raised) will be logged. Added the ``quiet_exceptions`` argument to suppress this logging for selected exception types. .. versionchanged:: 4.3 Replaced the class ``Multi`` and the function ``multi_future`` with a unified function ``multi``. Added support for yieldables other than ``YieldPoint`` and `.Future`. )r) multi_futurers r'rrs` 3C DDr&c t|tr*t|j|j }nd|}tt t |tdDsJt tstingdtddf fd }t}D]$}||vs|j|t||&S)aWait for multiple asynchronous futures in parallel. Since Tornado 6.0, this function is exactly the same as `multi`. .. versionadded:: 4.0 .. versionchanged:: 4.2 If multiple ``Futures`` fail, any exceptions after the first (which is raised) will be logged. Added the ``quiet_exceptions`` argument to suppress this logging for selected exception types. .. deprecated:: 4.3 Use `multi` instead. Nc3VK|]!}t|xst|t#ywrF)rrW _NullFuture).0rs r' zmulti_future..s#Qay|9z![99Qs')futr3c j|sig}D]"} |j|j$j s/ ttt|yt|yyy#t$r\}j r$t |s6t jddnttjYd}~d}~wwxYw)Nz!Multiple exceptions in yield listTr^)removerrar\rrWr errorr r]r^r dictzip) r result_listrCr1 children_futsr?keysrunfinished_childrens r'callbackzmulti_future..callbacks""3'"K" D D&&qxxz2 D;;=#6S{%; <7v{K !# !D{{})!-=>#MM Cd,FCLLNCDsA?? C$ACC$)rWrrxrrymapconvert_yieldedallsetrBr raddr ) rr children_seqr listeningrCrr?rrs ` @@@@r'rrs$(D!HMMO$(  _l;.error_callbacksZ  MMO%%   a!12 :FT3 sA$A$$AA$crjsjtdty)NTimeout)r set_exceptionrr )rfuture_convertedrasr'timeout_callbackz&with_timeout..timeout_callbacks*{{}  i!8 9 !1>Br&c&jSrFremove_timeoutr?io_looptimeout_handles r'rSzwith_timeout..W-C-CN-Sr&c&jSrFrrs r'rSzwith_timeout..rr&r3N) rrBrr currentr add_timeoutrWr add_future) rr?rrrrrrars ` @@@@@r' with_timeoutrPsT'v.  F!6*nnG v $ C ((2BCN"F+ ! S  M  S  Mr&durationz Future[None]cjttjj|fdS)aReturn a `.Future` that resolves after the given number of seconds. When used with ``yield`` in a coroutine, this is a non-blocking analogue to `time.sleep` (which should not be used in coroutines because it is blocking):: yield gen.sleep(0.5) Note that calling this function on its own does nothing; you must wait on the `.Future` it returns (usually by yielding it). .. versionadded:: 4.1 ctdSrF)r )rCsr'rSzsleep..s#$788{{}V!DLU# $ & & #!%$&*hhnnS&9G!$"&((--"6 ((1!DL]%545 5"&!$&v.$(DM".DK6**,Ea,H*.D&!DL!$(DM".DK'(:(:CLLNK)-D& !DL!DLs1FFC .C"0C/5C)C/-FF CCC"CC""C&&C/)C,,C//F>8E6FA FFFF F%rbc t|_jtur1jjjjyj tdjjs5dtddffd }jjj|yy#t$r:t_t jt j YwxYw)NFzno pending futurerCr3c@d}jjyrF)r`rV)rCrns r'innerz"Runner.handle_yield..innerFs TXX&r&T)rr?r.rr r]r^momentr add_callbackr`rVr\rrr)rnrbrs` r'rzRunner.handle_yield8s =)'2DK ;;& LL % %dllDHH = [[ /0 0!!# ' ' ' LL # #DKK 7% = (DK  S\\^ < =sB==AD?Dtypr5tbc|jsP|jsDt|_t |j|||f|j |j yy)NTF)rrrr?r r`rV)rnrr5rs r'handle_exceptionzRunner.handle_exceptionOsE||DMM (DK  c5"-= > LL "r&r)r"r#r$rpr _YieldablermrVrrrr\types TracebackTyperr%r&r'rYrYs##.#$ # " #  #$8!tJ4.  ? +4 :?:M:M   r&rY awaitablectj|}tjj ||j fd|S)Nc&j|SrF)_unregister_task)rCloops r'rSz!_wrap_awaitable..dsD$9$9!$<r&)r ensure_futurer r_register_taskrZ)rrrs @r'_wrap_awaitabler[sC    *C >> D<= Jr&rbc||turtS|turtSt|ttfr t |St |rtjt|St|r t|Std|)a?Convert a yielded object into a `.Future`. The default implementation accepts lists, dictionaries, and Futures. This has the side effect of starting any coroutines that did not start themselves, similar to `asyncio.ensure_future`. If the `~functools.singledispatch` library is available, this function may be extended to support additional types. For example:: @convert_yielded.register(asyncio.Future) def _(asyncio_future): return tornado.platform.asyncio.to_tornado_future(asyncio_future) .. versionadded:: 4.1 zyielded unknown object ) rrrWrxrrrrcastrrrr.)rbs r'rrhsz"'V+ L  GdD\ *W~ 7 {{67++ W w''5g[ABBr&)r%)Qrprrr{collections.abcrconcurrent.futures concurrentdatetimerdrinspectrr]rtornado.concurrentrrrr r r tornado.ioloopr tornado.logr tornado.utilrrT ImportErrorrrrrrrrrrrrr TYPE_CHECKINGrrrrTypeVarrrrr\r r*r,r.r0r[r9rBrGrLrrir2rsrMultirrfloat timedeltarrrrrrrYrrr%r&r'rsF=~%$ "%     55V^^D )T)_d3 >&:J!? C   Xc2g&s#" & 1 2&  & &  JHS"W%J(3D*EJ J] 78(37:KK L]  ]@999Y2}}@ MOz"DOU4 ?C3G-HHI D\   MOc:o&DOU4 ?C3G-HHI D\ OQ0EHZ('#z/*BBC0EK0E)0Ef  OQ<HZ('#z/*BBC<K<)<~CF0OQN 5(,,, -N NLN Nb E n *.v{{6;=1 V[] +&uup y V CZCFC>!1[KsJJ"!J"