B
    |b-                 @   s   d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZ ddlmZ dZd	d
 Zdd Zi add Zdd Zejdd ZG dd deZG dd deeeZG dd dejZe ZdS )z:mod:`wand.resource` --- Global resource management
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is the global resource to manage in MagickWand API. This module
implements automatic global resource management through reference counting.

    N   )library)abcstring_type)TYPE_MAPWandException)MAGICK_VERSION_NUMBER)genesislimitsshutdownterminusDestroyedResourceErrorResourceResourceLimitsc               C   s   t   dS )zInstantiates the MagickWand API.

    .. warning::

       Don't call this function directly. Use :func:`increment_refcount()` and
       :func:`decrement_refcount()` functions instead.

    N)r   ZMagickWandGenesis r   r   P/home/ankuromar296_gmail_com/.local/lib/python3.7/site-packages/wand/resource.pyr	      s    	r	   c               C   s(   t jdkrt   nt  r$t   dS )zCleans up the MagickWand API.

    .. warning::

       Don't call this function directly. Use :func:`increment_refcount()` and
       :func:`decrement_refcount()` functions instead.

    N)r   ZIsMagickWandInstantiatedZMagickWandTerminusr   r   r   r   r   "   s    	

r   c             C   s"   t tdkrt  | r|t| < d S )Nr   )lenallocation_mapr	   )addrdeallocatorr   r   r   allocate_ref4   s    r   c             C   s*   | t tkr&t| }t|r&||  d S )N)listr   popcallable)r   r   r   r   r   deallocate_ref<   s    
r   c           	   C   sP   xDt tD ]8} yt| }t|r*||  W q
 tk
r@   Y q
X q
W t  d S )N)r   r   r   r   KeyErrorr   )r   r   r   r   r   r   D   s    

r   c               @   s   e Zd ZdZeZeZeZeZe	dd Z
e
jdd Z
e
jdd Z
ejdd Zdd	 Zd
d ZdddZdddZdd Zdd Zdd ZdS )r   a  Abstract base class for MagickWand object that requires resource
    management. Its all subclasses manage the resource semiautomatically
    and support :keyword:`with` statement as well::

        with Resource() as resource:
            # use the resource...
            pass

    It doesn't implement constructor by itself, so subclasses should
    implement it. Every constructor should assign the pointer of its
    resource data into :attr:`resource` attribute inside of :keyword:`with`
    :meth:`allocate()` context.  For example::

        class Pizza(Resource):
            '''My pizza yummy.'''

            def __init__(self):
                with self.allocate():
                    self.resource = library.NewPizza()

    .. versionadded:: 0.1.2

    c             C   s&   t | dddkr tt| d | jS )zInternal pointer to the resource instance. It may raise
        :exc:`DestroyedResourceError` when the resource has destroyed already.

        
c_resourceNz is destroyed already)getattrr   reprr   )selfr   r   r   resource   s    zResource.resourcec             C   sH   t | dd r|   | |r4|| _t| j| j ntt|d d S )Nr   z is an invalid resource)r   destroyc_is_resourcer   r   c_destroy_resource	TypeErrorr   )r   r    r   r   r   r       s    
c             C   s    t | dd rt| j d | _d S )Nr   )r   r   r   )r   r   r   r   r       s    
c             c   s
   | V  dS )a$  Allocates the memory for the resource explicitly. Its subclasses
        should assign the created resource into :attr:`resource` attribute
        inside of this context. For example::

            with resource.allocate():
                resource.resource = library.NewResource()

        Nr   )r   r   r   r   allocate   s    
zResource.allocatec             C   s   | ` dS )zCleans up the resource explicitly. If you use the resource in
        :keyword:`with` statement, it was called implicitly so have not to
        call it.

        N)r    )r   r   r   r   r!      s    zResource.destroyc             C   s   t  }| | jt |}|jdkr8|r4t|}dS | | j t	|j }|rht 
|}t|}nd}t|ts|jdd}||S )zGets a current exception instance.

        :returns: a current exception. it can be ``None`` as well if any
                  errors aren't occurred
        :rtype: :class:`wand.exceptions.WandException`

        r   N    replace)errors)ctypesc_intc_get_exceptionr    byrefvaluer   ZMagickRelinquishMemoryc_clear_exceptionr   	string_at
isinstancer   decode)r   ZseveritydescZexc_clsmessager   r   r   get_exception   s    




zResource.get_exceptionr   c             C   s8   |   }t|tr&tj||d d nt|tr4|dS )z2Raises an exception or warning if it has occurred.r   )
stacklevelN)r4   r0   Warningwarningswarn	Exception)r   r5   er   r   r   raise_exception   s
    

zResource.raise_exceptionNc             C   s   t d S )N)NotImplementedError)r   formatr   r   r   	make_blob   s    zResource.make_blobc             C   s   | S )Nr   )r   r   r   r   	__enter__   s    zResource.__enter__c             C   s   |    d S )N)r!   )r   typer-   	tracebackr   r   r   __exit__   s    zResource.__exit__c             C   s&   y|    W n tk
r    Y nX d S )N)r!   r   )r   r   r   r   __del__   s    zResource.__del__)r   )N)__name__
__module____qualname____doc__NotImplementedr"   r#   r+   r.   propertyr    setterdeleter
contextlibcontextmanagerr%   r!   r4   r;   r>   r?   rB   rC   r   r   r   r   r   Q   s    
			


r   c               @   s   e Zd ZdZdS )r   zAn error that rises when some code tries access to an already
    destroyed resource.

    .. versionchanged:: 0.3.0
       It becomes a subtype of :exc:`wand.exceptions.WandException`.

    N)rD   rE   rF   rG   r   r   r   r   r      s   r   c               @   sh   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )r   a  Wrapper for MagickCore resource limits.
    Useful for dynamically reducing system resources before attempting risky,
    or slow running, :class:`~wand.image.Image` operations.

    For example::

       from wand.image import Image
       from wand.resource import limits

       # Use 100MB of ram before writing temp data to disk.
       limits['memory'] = 1024 * 1024 * 100
       # Reject images larger than 1000x1000.
       limits['width'] = 1000
       limits['height'] = 1000

       # Debug resources used.
       with Image(filename='user.jpg') as img:
           print('Using {0} of {1} memory'.format(limits.resource('memory'),
                                                  limits['memory']))

       # Dump list of all limits.
       for label in limits:
           print('{0} => {1}'.format(label, limits[label]))

    Available resource keys:

    - ``'area'`` - Maximum `width * height` of a pixel cache before writing to
      disk.
    - ``'disk'`` - Maximum bytes used by pixel cache on disk before exception
      is thrown.
    - ``'file'`` - Maximum cache files opened at any given time.
    - ``'height'`` - Maximum height of image before exception is thrown.
    - ``'list_length'`` - Maximum images in sequence. Only available with
      recent version of ImageMagick.
    - ``'map'`` - Maximum memory map in bytes to allocated for pixel cache
      before using disk.
    - ``'memory'`` - Maximum bytes to allocated for pixel cache before using
      disk.
    - ``'thread'`` - Maximum parallel task sub-routines can spawn - if using
      OpenMP.
    - ``'throttle'`` - Total milliseconds to yield to CPU - if possible.
    - ``'time'`` - Maximum seconds before exception is thrown.
    - ``'width'`` - Maximum width of image before exception is thrown.

    .. versionadded:: 0.5.1
    )	undefinedareadiskfilemapmemorythreadtimethrottlewidthheight)rN   rO   rP   rQ   rX   rR   rS   rT   rV   rU   rW   Zlist_lengthc             C   s   t dk r| j| _n| j| _d S )Ni   )r   _limits6r
   _limits7)r   r   r   r   __init__2  s    
zResourceLimits.__init__c             C   s
   |  |S )N)get_resource_limit)r   rr   r   r   __getitem__8  s    zResourceLimits.__getitem__c             C   s   |  || d S )N)set_resource_limit)r   r]   vr   r   r   __setitem__;  s    zResourceLimits.__setitem__c             C   s   d| |< d S )Nr   r   )r   r]   r   r   r   __delitem__>  s    zResourceLimits.__delitem__c             C   s
   t | jS )N)iterr
   )r   r   r   r   __iter__A  s    zResourceLimits.__iter__c             C   s
   t | jS )N)r   r
   )r   r   r   r   __len__D  s    zResourceLimits.__len__c             C   s   | j |S )z3Helper method to map resource string to enum value.)r
   index)r   r    r   r   r   _to_idxG  s    zResourceLimits._to_idxc             C   s   t | |S )zGet the current value for the resource type.

        :param resource: Resource type.
        :type resource: :class:`basestring`
        :rtype: :class:`numeric.Integral`

        .. versionadded:: 0.5.1
        )r   ZMagickGetResourcerg   )r   r    r   r   r   r    K  s    	zResourceLimits.resourcec             C   s   t   t| |S )zGet the current limit for the resource type.

        :param resource: Resource type.
        :type resource: :class:`basestring`
        :rtype: :class:`numeric.Integral`

        .. versionadded:: 0.5.1
        )r	   r   ZMagickGetResourceLimitrg   )r   r    r   r   r   r\   V  s    	z!ResourceLimits.get_resource_limitc             C   s&   t   t|}t| || dS )a  Sets a new limit for resource type.

        .. note::

            The new limit value must be equal to or less than the maximum
            limit defined by the :file:`policy.xml`. Any values set outside
            normal bounds will be ignored silently.

        :param resource: Resource type.
        :type resource: :class:`basestring`
        :param limit: New limit value.
        :type limit: :class:`numeric.Integral`

        .. versionadded:: 0.5.1
        N)r	   r)   c_ulonglongr   ZMagickSetResourceLimitrg   )r   r    limitZullr   r   r   r_   b  s    
z!ResourceLimits.set_resource_limitN)rD   rE   rF   rG   rY   rZ   r[   r^   ra   rb   rd   re   rg   r    r\   r_   r   r   r   r   r      s   .r   )rG   atexitrL   r)   r7   apir   compatr   r   
exceptionsr   r   versionr   __all__r	   r   r   r   r   registerr   objectr   ReferenceErrorAttributeErrorr   MutableMappingr   r
   r   r   r   r   <module>   s*     
 