add-determinism 0.7.3

RPM buildroot helper to strip nondeterministic bits in files
Documentation
�

��Vc�:csH�dZdgZddlZddlZddlZejd��Zejd��ZGd�de��Z	d�Z
d	�Zd
�ZGd�d��Z
Gd
�d��ZGd�d��ZGd�d��ZGd�d��Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�ZdS)a&
Middleware to check for obedience to the WSGI specification.

Some of the things this checks:

* Signature of the application and start_response (including that
  keyword arguments are not used).

* Environment checks:

  - Environment is a dictionary (and not a subclass).

  - That all the required keys are in the environment: REQUEST_METHOD,
    SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors,
    wsgi.multithread, wsgi.multiprocess, wsgi.run_once

  - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the
    environment (these headers should appear as CONTENT_LENGTH and
    CONTENT_TYPE).

  - Warns if QUERY_STRING is missing, as the cgi module acts
    unpredictably in that case.

  - That CGI-style variables (that don't contain a .) have
    (non-unicode) string values

  - That wsgi.version is a tuple

  - That wsgi.url_scheme is 'http' or 'https' (@@: is this too
    restrictive?)

  - Warns if the REQUEST_METHOD is not known (@@: probably too
    restrictive).

  - That SCRIPT_NAME and PATH_INFO are empty or start with /

  - That at least one of SCRIPT_NAME or PATH_INFO are set.

  - That CONTENT_LENGTH is a positive integer.

  - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should
    be '/').

  - That wsgi.input has the methods read, readline, readlines, and
    __iter__

  - That wsgi.errors has the methods flush, write, writelines

* The status is a string, contains a space, starts with an integer,
  and that integer is in range (> 100).

* That the headers is a list (not a subclass, not another kind of
  sequence).

* That the items of the headers are tuples of strings.

* That there is no 'status' header (that is used in CGI, but not in
  WSGI).

* That the headers don't contain newlines or colons, end in _ or -, or
  contain characters codes below 037.

* That Content-Type is given if there is content (CGI often has a
  default content type, but WSGI does not).

* That no Content-Type is given when there is no content (@@: is this
  too restrictive?)

* That the exc_info argument to start_response is a tuple or None.

* That all calls to the writer are with strings, and no other methods
  on the writer are accessed.

* That wsgi.input is used properly:

  - .read() is called with exactly one argument

  - That it returns a string

  - That readline, readlines, and __iter__ return strings

  - That .close() is not called

  - No other methods are provided

* That wsgi.errors is used properly:

  - .write() and .writelines() is called with a string

  - That .close() is not called, and no other methods are provided.

* The response iterator:

  - That it is not a string (it should be a list of a single string; a
    string will work, but perform horribly).

  - That .__next__() returns a string

  - That the iterator is not iterated over until start_response has
    been called (that can signal either a server or application
    error).

  - That .close() is called (doesn't raise exception, only prints to
    sys.stderr, because we only know it isn't called when the object
    is garbage collected).
�	validator�Nz^[a-zA-Z][a-zA-Z0-9\-_]*$z[\000-\037]cs�eZdZdZdS)�WSGIWarningz:
    Raised in response to WSGI-spec-related warnings
    N)�__name__�
__module__�__qualname__�__doc__���)/usr/lib64/python3.11/wsgiref/validate.pyrrys���������rrcs�|s	t|��dS�N)�AssertionError)Zcond�args�  r	�assert_r~s���$��d�#�#�$�$rcs��t|��tur|Std�|t	|�������)Nz!{0} must be of type str (got {1}))�type�strrZformatZrepr)�valueZtitler
r	�check_string_typer�sH���U�|�|�s�����
�+�2�2�5�$�u�+�+�F�F�H�H�Hrcs���fd�}|S)a�
    When applied between a WSGI server and a WSGI application, this
    middleware will check for WSGI compliance on a number of levels.
    This middleware does not modify the request or response in any
    way, but will raise an AssertionError if anything seems off
    (except for a failure to close the application iterator, which
    will be printed to stderr -- there's no way to raise an exception
    at that point).
    cs�����tt|��dkd��t|d��|\}�t|��g���fd�}t|d��|d<t	|d��|d<�||��}t|duo|dkd��t|��t
|���S)	N�zTwo arguments required�No keyword arguments allowedcs���tt|��dkpt|��dkd|����t|d��|d}|d}t|��dkr	|d}nd}t|��t|��t	||��t|����d��t�|���S)Nr�zInvalid number of arguments: rr�)r�len�check_status�
check_headers�check_content_type�check_exc_infoZappend�WriteWrapper)r�kw�status�headers�exc_info�start_response�start_response_starteds     ��r	�start_response_wrapperz;validator.<locals>.lint_app.<locals>.start_response_wrapper�s�����C��I�I��N�4�c�$�i�i�1�n��59�T�;�
>�
>�
>���F�:�;�;�;��!�W�F��1�g�G��4�y�y�A�~�
 ���7������� � � ��'�"�"�"��v�w�/�/�/��8�$�$�$�"�)�)�$�/�/�/����� 5�6�6�6r�
wsgi.input�wsgi.errorsFz>The application must return an iterator, if only an empty list)rr�
check_environ�InputWrapper�ErrorWrapper�check_iterator�IteratorWrapper)rr�environr#�iteratorr!r"�applications     @@�r	�lint_appzvalidator.<locals>.lint_app�s��������D�	�	�Q�� 8�9�9�9��B��6�7�7�7�"&�����g����"$��	7�	7�	7�	7�	7�	7�&!-�W�\�-B� C� C����!-�g�m�.D�!E�!E��
���;�w�(>�?�?�����$�:��U�):�L�	N�	N�	N�	�x� � � ��x�)?�@�@�@rr)r-r.s` r	rr�s)���'A�'A�'A�'A�'A�R�Orcs2�eZdZd�Zd�Zd�Zd�Zd�Zd�ZdS)r'c��||_dSr
)�input)�self�
wsgi_inputr
r	�__init__zInputWrapper.__init__�s
����
�
�
rcs��tt|��dk��|jj|�}tt	|��t
u��|S�Nr)rrr0�readr�bytes�r1r�v�   r	r5zInputWrapper.read�sH����D�	�	�Q������D�J�O�T�"����Q���5� �!�!�!��rcs��tt|��dk��|jj|�}tt	|��t
u��|Sr4)rrr0�readlinerr6r7r9r	r:zInputWrapper.readline�sI����D�	�	�Q������D�J���&����Q���5� �!�!�!��rcs��tt|��dk��|jj|�}tt	|��t
u��|D]%}tt	|��tu���&|Sr4)rrr0�	readlinesr�listr6)r1rZlines�line�    r	r;zInputWrapper.readlines�st����D�	�	�Q�����$��
�$�d�+����U���t�#�$�$�$��	)�	)�D��D��J�J�%�'�(�(�(�(��rc#sBK�	|���}|sdS|V��r
)r:)r1r=r
r	�__iter__zInputWrapper.__iter__�s3����	��=�=�?�?�D��
����J�J�J�		rc�&�tdd��dS)Nrz input.close() must not be called�r�r1� r	�closezInputWrapper.close�s����5�6�6�6�6�6rN)	rrrr3r5r:r;r?rDrrr	r'r'�sn������ � � �������������7�7�7�7�7rr'c�,�eZdZd�Zd�Zd�Zd�Zd�ZdS)r(cr/r
)�errors)r1�wsgi_errorsr
r	r3zErrorWrapper.__init__��
��!����rcs��tt|��tu��|j�|��dSr
)rrrrF�write�r1Zsr
r	rIzErrorWrapper.write�s6����Q���3���������!�����rcs8�|j���dSr
)rF�flushrBrCr	rKzErrorWrapper.flush�s����������rcs:�|D]}|�|���dSr
)rI)r1Zseqr=r9r	�
writelineszErrorWrapper.writelines�s0���	�	�D��J�J�t�����	�	rcr@)Nrz!errors.close() must not be calledrArBrCr	rDzErrorWrapper.close�s����6�7�7�7�7�7rN)rrrr3rIrKrLrDrrr	r(r(�s_������"�"�"����������8�8�8�8�8rr(c��eZdZd�Zd�ZdS)rcr/r
)�writer)r1Zwsgi_writerr
r	r3zWriteWrapper.__init__�rHrcsv�tt|��tu��|�|��dSr
)rrr6rNrJr
r	�__call__zWriteWrapper.__call__�s.����Q���5� �!�!�!����A�����rN)rrrr3rOrrr	rr�s2������"�"�"�����rrcrM)�PartialIteratorWrappercr/r
�r,)r1�
wsgi_iteratorr
r	r3zPartialIteratorWrapper.__init__s
��%��
�
�
rcs,�t|jd��Sr
)r*r,rBrCr	r?zPartialIteratorWrapper.__iter__s���t�}�d�3�3�3rN)rrrr3r?rrr	rPrP�s2������&�&�&�4�4�4�4�4rrPcrE)r*csX�||_t|��|_d|_||_dS)NF)�original_iteratorZiterr,�closed�check_start_response)r1rRrUr9r	r3zIteratorWrapper.__init__	s.��!.����]�+�+��
����$8��!�!�!rcs�|Sr
rrBrCr	r?zIteratorWrapper.__iter__s���rcs��t|jd��t|j��}t	|��t
urtdd|�d���|j�t|jd��d|_|S)NzIterator read after closedFz!Iterator yielded non-bytestring (�)zjThe application returns and we started iterating over its body, but start_response has not yet been called)rrTZnextr,rr6rU)r1r8r
r	�__next__zIteratorWrapper.__next__s����D�K��(�	*�	*�	*���������7�7�%��	J��E�E�Q�Q�Q�H�I�I�I��$�	-��D�-�|�
~�
~�
~�(,�D�%��rcst�d|_t|jd��r|j���dSdS)NTrD)rT�hasattrrSrDrBrCr	rDzIteratorWrapper.closesC������4�)�7�3�3�	+��"�(�(�*�*�*�*�*�	+�	+rcs|�|jstj�d��t	|jd��dS)Nz/Iterator garbage collected without being closed)rT�sysZstderrrIrrBrCr	�__del__zIteratorWrapper.__del__#sP���{�	C��J���A�
C�
C�
C����=�	?�	?�	?�	?�	?rN)rrrr3r?rWrDrZrrr	r*r*s_������9�9�9����
�
�
�+�+�+�
?�?�?�?�?rr*cs��tt|��tudt|���d|�d���dD]}t||vd|�����dD]#}t||vd|�d|d	d��d
����$d|vrtjdt
��|���D]T}d
|vr�tt||��tud|�dt||���d||�d����Utt|d��tud|d�d���t|ddvd|dz��t|d��t|d��|ddvr#tjd|dzt
��t|�d��p|d�d��d|dz��t|�d��p|d�d��d|dz��|�d ��r0tt|d ��d!kd"|d z��|�d��std|vd#��t|�d��dkd$��dS)%Nz&Environment is not of the right type: z (environment: rV)	�REQUEST_METHODZSERVER_NAMEZSERVER_PORT�wsgi.versionr$r%zwsgi.multithreadzwsgi.multiprocessz
wsgi.run_oncez"Environment missing required key: )ZHTTP_CONTENT_TYPEZHTTP_CONTENT_LENGTHz%Environment should not have the key: z (use iz	 instead)ZQUERY_STRINGz�QUERY_STRING is not in the WSGI environment; the cgi module will use sys.argv when this variable is missing, so application errors are more likelyz.zEnvironmental variable z is not a string: z	 (value: r\z wsgi.version should be a tuple (zwsgi.url_scheme)ZhttpZhttpszwsgi.url_scheme unknown: %rr$r%r[)ZGETZHEADZPOSTZOPTIONSZPATCHZPUTZDELETEZTRACEzUnknown REQUEST_METHOD: %rZSCRIPT_NAMEz/z$SCRIPT_NAME doesn't start with /: %rZ	PATH_INFOz"PATH_INFO doesn't start with /: %rZCONTENT_LENGTHrzInvalid CONTENT_LENGTH: %rzgOne of SCRIPT_NAME or PATH_INFO are required (PATH_INFO should at least be '/' if SCRIPT_NAME is empty)zOSCRIPT_NAME cannot be '/'; it should instead be '', and PATH_INFO should be '/')rrZdict�warnings�warnrZkeysr�tuple�check_input�check_errorsZgetZ
startswith�int)r+Zkeyr
r	r&r&*s����D��M�M�T�!�!���=�=�=�=�'�'�'�	#�$�$�$�!�=�=��	��w���69�c�;�	=�	=�	=�	=�<�1�1����7�"�"�"%�#�#�s�1�2�2�w�w�w�
0�	1�	1�	1�	1��W�$���
�
4�
�		�	�	��|�|�~�~�7�7���#�:�	����W�S�\�"�"�c�)�)��s�s�D����&�&�&�&������
6�	7�	7�	7�	7��D���(�)�)�U�2�2�18��1H�1H�1H�J�L�L�L��G�%�&�*;�;�%��0A�(B�B�D�D�D����%�&�&�&����'�(�(�(��� �)M�M���
�(�7�3C�+D�D��	�	�	�����M�*�*�*�
6��}�%�0�0��5�5�.���1G�G�I�I�I�����K�(�(�(�
4��{�#�.�.�s�3�3�,�w�{�/C�C�E�E�E��{�{�#�$�$�F���G�,�-�.�.�!�3�(�7�3C�+D�D�	F�	F�	F��;�;�}�%�%�?���w�&�
>�	?�	?�	?��G�K�K�
�&�&�#�-�	"�#�#�#�#�#rc�X�dD]&}tt||��d|�d|�����'dS)N)r5r:r;r?zwsgi.input (�) doesn't have the attribute �rrX)r2�attrr
r	r`r`ksQ��=�"�"����
�D�)�)�)��z�z�4�4�
!�	"�	"�	"�	"�"�"rcrc)N)rKrIrLz
wsgi.errors (rdre)rGrfr
r	raraqsQ��0�#�#�����T�*�*�*��{�{�D�D�
"�	#�	#�	#�	#�#�#rcsn�t|d��}|�dd��d}tt|��dkd|z��t	|��}t|dkd|z��t|��dks|dd	krtjd
|zt��dSdS)N�Statusrrrz)Status codes must be three characters: %ridzStatus code is invalid: %riz zjThe status string (%r) should be a three-digit integer followed by a single space and a status explanation)r�splitrrrbr]r^r)rZstatus_codeZ
status_intr9r	rrws���
�v�x�
0�
0�F��,�,�t�Q�'�'��*�K��C�����!�3�k�A�C�C�C��[�!�!�J��J�#��;�j�H�I�I�I�
�6�{�{�Q��#�&��)�s�*�#��
�
B��
�!�	#�	#�	#�	#�	#�#�#rc
s��tt|��tud|�dt|������|D�]�}tt|��tud|�dt|������tt	|��dk��|\}}t|d��}t|d��}t|���dkd	|z��td
|vod|vd|z��tt�|��d
|z��t|�	d��o|�	d��d|z��t�|��rBtdd|�dt�|���d���d������dS)Nz	Headers (z) must be of type list: zIndividual headers (z) must be of type tuple: r�Header namezHeader valuerzyThe Status header cannot be used; it conflicts with CGI script, and HTTP status is not given through headers (value: %r).z
z:z,Header names may not contain ':' or '\n': %rzBad header name: %rz-Z_z#Names may not end in '-' or '_': %rrzBad header value: z (bad char: rV)rrr<r_rr�lower�	header_reZsearchZendswith�bad_header_value_reZgroup)rZitem�namerr>r	rr�s����D��M�M�T�!�!��7�7�D��M�M�M�	#�$�$�$��C�C����T�
�
�e�#�#��t�t�T�$�Z�Z�Z�
!�	"�	"�	"�	��D�	�	�Q��������e� ��}�5�5��!�%��8�8����
�
����(�
�"�
#�	$�	$�	$�	��D� �4�S��_�;�d�B�	D�	D�	D��	� � ��&�&�(=��(D�E�E�E��D�M�M�#�&�&�&�A�t�}�}�S�/A�/A�+A�1�D�8�	:�	:�	:��%�%�e�,�,�	C��A�A��u�u�)�0�0��7�7�=�=�a�@�@�@�@�B�
C�
C�
C��%C�CrcsB�t|d��}t|�dd��d��}d}|D]G\}}t|d��}|���dkr||vrdSt	dd|z���H||vrt	dd|z��dSdS)	Nrgrr)i�i0rizcontent-typezJContent-Type header found in a %s response, which must not return content.z,No Content-Type header found in headers (%s))rrbrhrjr)rrZcodeZNO_MESSAGE_BODYrmrs      r	rr�s���
�v�x�
0�
0�F��v�|�|�D�!�$�$�Q�'�(�(�D�!�O��B�B���e� ��}�5�5���:�:�<�<�>�)�	B��?�*�
�����A�9�<@�A�
B�
B�
B���?�"�M���A�G�K�L�L�L�L�L�M�Mrc	s|�t|dupt|��tud|�dt|������dS)Nz
exc_info (z) is not a tuple: )rrr_)r rCr	rr�sO���H���7��X���%� 7��.6�h�h��X����G�I�I�I�I�Ircs\�tt|ttf��d��dS)NzwYou should not return a string as your application iterator, instead return a single-item list containing a bytestring.)rZ
isinstancerr6rQrCr	r)r)�s>���
�8�c�5�\�2�2�2�	E�F�F�F�F�Fr)rZ__all__ZrerYr]ZcompilerkrlZWarningrrrrr'r(rrPr*r&r`rarrrrr)rrr	�<module>rns��
i�i�T�-��
�	�	�	�
�
�
�
������B�J�3�4�4�	� �b�j��0�0�������'����
$�$�$�H�H�H�5�5�5�n!7�!7�!7�!7�!7�!7�!7�!7�F8�8�8�8�8�8�8�8�&��������4�4�4�4�4�4�4�4�!?�!?�!?�!?�!?�!?�!?�!?�F?#�?#�?#�B"�"�"�#�#�#�#�#�#�C�C�C�2M�M�M� I�I�I�
F�F�F�F�Fr