3 �P\$Q � @ s� d Z ddlZddlZddlZddlmZ ddlZddlmZ G dd� de �Z G dd � d e�Zd d� Z G dd � d e�Zdd� Zdd� Zdd� Zejdd� �Zdd� Zdd� ZG dd� de�ZG dd� dej�ZG dd� de�ZG d d!� d!e�ZdS )"z� requests_toolbelt.multipart.encoder =================================== This holds all of the implementation details of the MultipartEncoder � N)�uuid4� )�fieldsc @ s e Zd ZdZdS )�FileNotSupportedErrorzFile not supported error.N)�__name__� __module__�__qualname__�__doc__� r r �/usr/lib/python3.6/encoder.pyr s r c @ s� e Zd ZdZd%dd�Zedd� �Zdd � Zd d� Zdd � Z dd� Z dd� Zdd� Zdd� Z dd� Zdd� Zdd� Zdd� Zedd� �Zd d!� Zd'd#d$�ZdS )(�MultipartEncodera� The ``MultipartEncoder`` object is a generic interface to the engine that will create a ``multipart/form-data`` body for you. The basic usage is: .. code-block:: python import requests from requests_toolbelt import MultipartEncoder encoder = MultipartEncoder({'field': 'value', 'other_field', 'other_value'}) r = requests.post('https://httpbin.org/post', data=encoder, headers={'Content-Type': encoder.content_type}) If you do not need to take advantage of streaming the post body, you can also do: .. code-block:: python r = requests.post('https://httpbin.org/post', data=encoder.to_string(), headers={'Content-Type': encoder.content_type}) If you want the encoder to use a specific order, you can use an OrderedDict or more simply, a list of tuples: .. code-block:: python encoder = MultipartEncoder([('field', 'value'), ('other_field', 'other_value')]) .. versionchanged:: 0.4.0 You can also provide tuples as part values as you would provide them to requests' ``files`` parameter. .. code-block:: python encoder = MultipartEncoder({ 'field': ('file_name', b'{"a": "b"}', 'application/json', {'X-My-Header': 'my-value'}) ]) .. warning:: This object will end up directly in :mod:`httplib`. Currently, :mod:`httplib` has a hard-coded read size of **8192 bytes**. This means that it will loop until the file has been read and your upload could take a while. This is **not** a bug in requests. A feature is being considered for this object to allow you, the user, to specify what size should be returned on a read. If you have opinions on this, please weigh in on `this issue`_. .. _this issue: https://github.com/requests/toolbelt/issues/75 N�utf-8c C s� |p t � j| _dj| j�| _|| _djt| j| j�td| j�g�| _|| _ d| _ g | _tg �| _ d | _d | _t|d�| _| j� | j� d S )Nz--{0}� z F)�encoding)r �hex�boundary_value�format�boundaryr �join�encode_with�_encoded_boundaryr �finished�parts�iter�_iter_parts� _current_part�_len� CustomBytesIO�_buffer�_prepare_parts�_write_boundary)�selfr r r r r r �__init__W s zMultipartEncoder.__init__c C s | j p| j� S )ai Length of the multipart/form-data body. requests will first attempt to get the length of the body by calling ``len(body)`` and then by checking for the ``len`` attribute. On 32-bit systems, the ``__len__`` method cannot return anything larger than an integer (in C) can hold. If the total size of the body is even slightly larger than 4GB users will see an OverflowError. This manifested itself in `bug #80`_. As such, we now calculate the length lazily as a property. .. _bug #80: https://github.com/requests/toolbelt/issues/80 )r �_calculate_length)r! r r r �len� s zMultipartEncoder.lenc C s dj | j�S )Nz<MultipartEncoder: {0!r}>)r r )r! r r r �__repr__� s zMultipartEncoder.__repr__c s2 t | j�� t� fdd�| jD ��� d | _| jS )z� This uses the parts to calculate the length of the body. This returns the calculated length so __len__ can be lazy. c 3 s | ]}� t |� d V qdS )� N)� total_len)�.0�p)�boundary_lenr r � <genexpr>� s z5MultipartEncoder._calculate_length.<locals>.<genexpr>r&