ó U!¶\c@s‰ddlZddlZddlZddlmZddlmZmZmZm Z m Z ej e ƒZ ie e eegd6Zd„Zd„Zdd„Zdd„Zdd „Zd „Zd „Zd „Zd efd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZ dS(iÿÿÿÿN(tcrc32(t ChecksumErrortEndpointConnectionErrortReadTimeoutErrortConnectionErrortConnectionClosedErrortGENERAL_CONNECTION_ERRORcCsP|dkrtjƒ}n|dkr:td|ƒ‚n|||d}|S(s1Calculate time to sleep based on exponential function. The format is:: base * growth_factor ^ (attempts - 1) If ``base`` is set to 'rand' then a random number between 0 and 1 will be used as the base. Base must be greater than 0, otherwise a ValueError will be raised. trandis0The 'base' param must be greater than 0, got: %si(trandomt ValueError(tbaset growth_factortattemptst time_to_sleep((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pytdelay_exponential's   cCstjtd|d|ƒS(s§Create an exponential delay function based on the attempts. This is used so that you only have to pass it the attempts parameter to calculate the delay. R R (t functoolstpartialR(R R ((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyt!create_exponential_delay_function=scCs7t|d|ƒ}t|d|ƒ}td|d|ƒS(Ntoperation_nametcheckertaction(t create_checker_from_retry_configtcreate_retry_action_from_configt RetryHandler(tconfigRRR((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pytcreate_retry_handlerHs cCs=|dd}|ddkr9td|dd|dƒSdS(Nt __default__tdelayttypet exponentialR R (R(RRt delay_config((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRPs  c Cssg}d}g}d|kr›|djdgƒ}|dd}xV|D]K}||}|jt|ƒƒt|ƒ}|dk rI|j|ƒqIqIWn|dk r!|j|ƒdk r!||d} xT| D]I}|jt| |ƒƒt| |ƒ}|dk rÑ|j|ƒqÑqÑWnt|ƒdkrGt|dd|ƒSt|ƒ} t| d|dt |ƒƒSdS(NRtpoliciest max_attemptsiitretryable_exceptions( tNonetgettappendt_create_single_checkert_extract_retryable_exceptiontextendtlentMaxAttemptsDecoratort MultiCheckerttuple( RRtcheckersR R!Rtkeytcurrent_configtretry_exceptiontoperation_policiest multi_checker((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR\s4     !     cCs=d|dkr"t|ddƒSd|dkr9tƒSdS(Ntresponset applies_whent socket_errors(t_create_single_response_checkertExceptionRaiser(R((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR%{s cCs„d|kr,td|dd|dƒ}nTd|krNtd|dƒ}n2d|krptd|dƒ}ntdtƒ‚|S(Ntservice_error_codet status_codethttp_status_codet error_codet crc32bodytheadersUnknown retry policy: %s(tServiceErrorCodeCheckertHTTPStatusCodeCheckert CRC32CheckerR R(R2R((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR5ƒs    cCsi|d}d|jdiƒkr)tgSd|kreg}x#|dD]}|jt|ƒqFW|SdS(NR3R;R2R4(R#RR't EXCEPTION_MAP(RR3t exceptionstname((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR&“s  RcBs eZdZd„Zd„ZRS(s¯Retry handler. The retry handler takes two params, ``checker`` object and an ``action`` object. The ``checker`` object must be a callable object and based on a response and an attempt number, determines whether or not sufficient criteria for a retry has been met. If this is the case then the ``action`` object (which also is a callable) determines what needs to happen in the event of a retry. cCs||_||_dS(N(t_checkert_action(tselfRR((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyt__init__¬s cKsL|j|||ƒr;|jd|ƒ}tjd|ƒ|StjdƒdS(s›Handler for a retry. Intended to be hooked up to an event handler (hence the **kwargs), this will process retries appropriately. R sRetry needed, action of: %ssNo retry needed.N(RCRDtloggertdebug(RER R2tcaught_exceptiontkwargstresult((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyt__call__°s (t__name__t __module__t__doc__RFRL(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRžs  t BaseCheckercBs)eZdZd„Zd„Zd„ZRS(s Base class for retry checkers. Each class is responsible for checking a single criteria that determines whether or not a retry should not happen. cCsH|dk r|j||ƒS|dk r8|j||ƒStdƒ‚dS(sÄDetermine if retry criteria matches. Note that either ``response`` is not None and ``caught_exception`` is None or ``response`` is None and ``caught_exception`` is not None. :type attempt_number: int :param attempt_number: The total number of times we've attempted to send the request. :param response: The HTTP response (if one was received). :type caught_exception: Exception :param caught_exception: Any exception that was caught while trying to send the HTTP response. :return: True, if the retry criteria matches (and therefore a retry should occur. False if the criteria does not match. s,Both response and caught_exception are None.N(R"t_check_responset_check_caught_exceptionR (REtattempt_numberR2RI((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRLÅs    cCsdS(N((RERSR2((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRQãscCsdS(N((RERSRI((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRRæs(RMRNRORLRQRR(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRP¾s  R)cBs,eZdZdd„Zd„Zd„ZRS(s“Allow retries up to a maximum number of attempts. This will pass through calls to the decorated retry checker, provided that the number of attempts does not exceed max_attempts. It will also catch any retryable_exceptions passed in. Once max_attempts has been exceeded, then False will be returned or the retryable_exceptions that was previously being caught will be raised. cCs||_||_||_dS(N(RCt _max_attemptst_retryable_exceptions(RERR R!((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRFôs  cCs~|j|||ƒ}|rv||jkro|dk r[d|dkr[t|dddcBseZd„Zd„ZRS(cCs ||_dS(N(t _status_code(RER8((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRFscCs5|dj|jkr-tjd|jƒtStSdS(Nis5retry needed: retryable HTTP status code received: %s(R8R^RGRHRYRZ(RERSR2((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRQs  (RMRNRFRQ(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR>s R=cBseZd„Zd„ZRS(cCs||_||_dS(N(R^t _error_code(RER8R:((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRF's cCsh|dj|jkrd|djdiƒjdƒ}||jkrdtjd|j|jƒtSntS(NiitErrortCodes>retry needed: matching HTTP status and error code seen: %s, %s(R8R^R#R_RGRHRYRZ(RERSR2tactual_error_code((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRQ+s(RMRNRFRQ(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR=&s R*cBseZd„Zd„ZRS(cCs ||_dS(N(t _checkers(RER,((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRF7scCs4x-|jD]"}||||ƒ}|r |Sq WtS(N(RcRZ(RERSR2RIRtchecker_response((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRL:s   (RMRNRFRL(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR*6s R?cBseZd„Zd„ZRS(cCs ||_dS(N(t _header_name(RER<((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRFDscCs«|d}|jj|jƒ}|dkrAtjd|jƒnft|djƒd@}|t|ƒks§tjdt|ƒ|ƒt dddt|ƒd|ƒ‚ndS( Nis?crc32 check skipped, the %s header is not in the http response.Iÿÿÿÿs>retry needed: crc32 check failed, expected != actual: %s != %st checksum_typeRtexpected_checksumtactual_checksum( theadersR#ReR"RGRHRtcontenttintR(RERSR2t http_responset expected_crct actual_crc32((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRQHs      (RMRNRFRQ(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR?Cs R6cBseZdZd„ZRS(s`Raise any caught exceptions. This class will raise any non None ``caught_exception``. cCs |‚dS(N((RERSRI((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyRR_s(RMRNRORR(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyR6Ys(!RRtloggingtbinasciiRtbotocore.exceptionsRRRRRt getLoggerRMRGR@RRR"RRRR%R5R&tobjectRRPR)R>R=R*R?R6(((s9/tmp/pip-install-usGedi/botocore/botocore/retryhandler.pyts0   (         ,.