o w[e-@s^dZddlZddlmZddlmZededdGdd d ejZGd d d Z d d Z dS)aA class supporting chat-style (command/response) protocols. This class adds support for 'chat' style protocols - where one side sends a 'command', and the other sends a response (examples would be the common internet protocols - smtp, nntp, ftp, etc..). The handle_read() method looks at the input stream for the current 'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n' for multi-line output), calling self.found_terminator() on its receipt. for example: Say you build an async nntp client using this class. At the start of the connection, you'll have self.terminator set to '\r\n', in order to process the single-line greeting. Just before issuing a 'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST command will be accumulated (using your own 'collect_incoming_data' method) up to the terminator, and then control will be returned to you - by calling your self.found_terminator() method. N)deque)warnzlThe asynchat module is deprecated and will be removed in Python 3.12. The recommended replacement is asyncio) stacklevelc@seZdZdZdZdZdZdZd(ddZdd Z d d Z d d Z ddZ ddZ ddZddZddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'ZdS)) async_chatzThis is an abstract class. You must derive from this class, and add the two methods collect_incoming_data() and found_terminator()irzlatin-1NcCs(d|_g|_t|_tj|||dSN) ac_in_bufferincomingr producer_fifoasyncore dispatcher__init__)selfsockmapr/usr/lib/python3.10/asynchat.pyrKszasync_chat.__init__cCtdNzmust be implemented in subclassNotImplementedErrorrdatarrrcollect_incoming_dataYz async_chat.collect_incoming_datacCs|j|dSN)r appendrrrr_collect_incoming_data\sz!async_chat._collect_incoming_datacCsd|j}|jdd=|Sr)joinr )rdrrr _get_data_s  zasync_chat._get_datacCrrrrrrrfound_terminatordrzasync_chat.found_terminatorcCsBt|tr|jrt||j}n t|tr|dkrtd||_dS)zdSet the input delimiter. Can be a fixed string of any length, an integer, or None. rz-the number of received bytes must be positiveN) isinstancestr use_encodingbytesencodingint ValueError terminator)rtermrrrset_terminatorgs  zasync_chat.set_terminatorcCs|jSr)r+r"rrrget_terminatorrszasync_chat.get_terminatorcCsz||j}WntyYdSty|YdSwt|tr.|jr.tt|j }|j ||_ |j rt |j }| }|sL| |j d|_ nt|tr|}||krg| |j d|_ |j||_np| |j d||j |d|_ d|_|nVt |}|j |}|dkr|dkr| |j d||j ||d|_ |n+t|j |}|r||kr| |j d| |j | d|_ dS| |j d|_ |j s7dSdS)Nrr)recvac_in_buffer_sizeBlockingIOErrorOSError handle_errorr$r%r&r'r(r lenr.rr)r+r#findfind_prefix_at_end)rrlbr+nterminator_lenindexrrr handle_readzsV             zasync_chat.handle_readcC |dSr) initiate_sendr"rrr handle_write zasync_chat.handle_writecCr=r)closer"rrr handle_closer@zasync_chat.handle_closecCsxt|tttfstdt||j}t||kr0tdt||D]}|j ||||q n|j || dS)Nz#data argument must be byte-ish (%r)r) r$r' bytearray memoryview TypeErrortypeac_out_buffer_sizer5ranger rr>)rrsabsirrrpushs   zasync_chat.pushcCs|j||dSr)r rr>)rproducerrrrpush_with_producers  zasync_chat.push_with_producercCsdS)z4predicate for inclusion in the readable for select()rr"rrrreadableszasync_chat.readablecCs|jp|j S)z4predicate for inclusion in the writable for select())r connectedr"rrrwritableszasync_chat.writablecCs|jddS)zAautomatically close this channel once the outgoing queue is emptyN)r rr"rrrclose_when_doneszasync_chat.close_when_donecCs|jr|jr|jd}|s|jd=|dur|dS|j}z|d|}Wnty@|}|r:|j|n|jd=Yqwt|trO|j rOt ||j }z| |}Wnt yd|YdSw|r|t|kss|t|kr~||d|jd<dS|jd=dSdSdS)Nr)r rPrBrGrEmore appendleftr$r%r&r'r(sendr3r4r5)rfirstobsrnum_sentrrrr>s@     zasync_chat.initiate_sendcCs d|_|jdd=|jdSr)r r r clearr"rrrdiscard_bufferss zasync_chat.discard_buffers)NN)__name__ __module__ __qualname____doc__r1rGr&r(rrrr!r#r-r.r<r?rBrKrMrOrQrRr>rZrrrrr<s.  H  (rc@seZdZdddZddZdS)simple_producercCs||_||_dSr)r buffer_size)rrrarrrrs zsimple_producer.__init__cCsFt|j|jkr|jd|j}|j|jd|_|S|j}d|_|Sr)r5rra)rresultrrrrSszsimple_producer.moreN)r`)r[r\r]rrSrrrrr_s  r_cCsDt|d}|r ||d|s |d8}|r ||d|r|S)NrN)r5endswith)haystackneedlelrrrr77s r7) r^r collectionsrwarningsrDeprecationWarningr rr_r7rrrrs  \