U
    #i_2                     @   s   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 dZddddd	gZ	d
Z
G dd deZG dd	 d	eZdddZdd ZdS )    N)version)datez2.1.0
deprecatedmessage_locationfail_if_not_removedDeprecatedWarningUnsupportedWarningZbottomc                       s*   e Zd ZdZd fdd	Zdd Z  ZS )r   aw  A warning class for deprecated methods

    This is a specialization of the built-in :class:`DeprecationWarning`,
    adding parameters that allow us to get information into the __str__
    that ends up being sent through the :mod:`warnings` system.
    The attributes aren't able to be retrieved after the warning gets
    raised and passed through the system as only the class--not the
    instance--and message are what gets preserved.

    :param function: The function being deprecated.
    :param deprecated_in: The version that ``function`` is deprecated in
    :param removed_in: The version or :class:`datetime.date` specifying
                       when ``function`` gets removed.
    :param details: Optional details about the deprecation. Most often
                    this will include directions on what to use instead
                    of the now deprecated code.
     c                    s2   || _ || _|| _|| _tt| |||| d S )N)functiondeprecated_in
removed_indetailssuperr   __init__)selfr
   r   r   r   	__class__ //tmp/pip-unpacked-wheel-jw9ffvn4/deprecation.pyr   5   s     zDeprecatedWarning.__init__c                 C   s   t t}| j|d< | jr(d| j |d< | jrPdt| jtrBdnd| j|d< t	| j| j| j
grld|d	< | j
rd
| j
 |d< d| S )Nr
   z	 as of %sr   z and will be removed {} {}oninremoved.Zperiod %sr   zH%(function)s is deprecated%(deprecated)s%(removed)s%(period)s%(details)s)collectionsdefaultdictstrr
   r   r   format
isinstancer   anyr   r   partsr   r   r   __str__@   s    

zDeprecatedWarning.__str__)r	   )__name__
__module____qualname____doc__r   r"   __classcell__r   r   r   r   r   "   s   c                   @   s   e Zd ZdZdd ZdS )r   a  A warning class for methods to be removed

    This is a subclass of :class:`~deprecation.DeprecatedWarning` and is used
    to output a proper message about a function being unsupported.
    Additionally, the :func:`~deprecation.fail_if_not_removed` decorator
    will handle this warning and cause any tests to fail if the system
    under test uses code that raises this warning.
    c                 C   s:   t t}| j|d< | j|d< | jr2d| j |d< d| S )Nr
   r   r   r   z9%(function)s is unsupported as of %(removed)s.%(details)s)r   r   r   r
   r   r   r    r   r   r   r"   ^   s    


zUnsupportedWarning.__str__N)r#   r$   r%   r&   r"   r   r   r   r   r   T   s   	r	   c                    s    dkrdk	rt dd}dttrBt kr<dqd}nB|rt|}rh|tkrhdq r|t krd}nd}t|g fdd}|S )a	  Decorate a function to signify its deprecation

    This function wraps a method that will soon be removed and does two things:
        * The docstring of the method will be modified to include a notice
          about deprecation, e.g., "Deprecated since 0.9.11. Use foo instead."
        * Raises a :class:`~deprecation.DeprecatedWarning`
          via the :mod:`warnings` module, which is a subclass of the built-in
          :class:`DeprecationWarning`. Note that built-in
          :class:`DeprecationWarning`s are ignored by default, so for users
          to be informed of said warnings they will need to enable them--see
          the :mod:`warnings` module documentation for more details.

    :param deprecated_in: The version at which the decorated method is
                          considered deprecated. This will usually be the
                          next version to be released when the decorator is
                          added. The default is **None**, which effectively
                          means immediate deprecation. If this is not
                          specified, then the `removed_in` and
                          `current_version` arguments are ignored.
    :param removed_in: The version or :class:`datetime.date` when the decorated
                       method will be removed. The default is **None**,
                       specifying that the function is not currently planned
                       to be removed.
                       Note: This parameter cannot be set to a value if
                       `deprecated_in=None`.
    :param current_version: The source of version information for the
                            currently running code. This will usually be
                            a `__version__` attribute on your library.
                            The default is `None`.
                            When `current_version=None` the automation to
                            determine if the wrapped function is actually
                            in a period of deprecation or time for removal
                            does not work, causing a
                            :class:`~deprecation.DeprecatedWarning`
                            to be raised in all cases.
    :param details: Extra details to be added to the method docstring and
                    warning. For example, the details may point users to
                    a replacement method, such as "Use the foo_bar
                    method instead". By default there are no details.
    NzCCannot set removed_in to a value without also setting deprecated_inFTc                    s   rƈ j pd}rd ndr:dttr2dndndrHd ndd}djf |}d}|d	d}t|dkrt|d |d< ||d	 t	d
krd}||| ||d d
| _ t  fdd}|S )Nr	   r   z
   This will be removed {} {}.r   r   )r   r   r   z3.. deprecated::{deprecated_in}{removed_in}{details}   
top   z

c                     s<   r2rt }nt}|j }tj|tdd | |S )N   )category
stacklevel)r   r   r#   warningswarnDeprecationWarning)argskwargsclsZthe_warning)r   r   r
   is_unsupportedr   should_warnr   r   _inner   s     z5deprecated.<locals>._function_wrapper.<locals>._inner)r&   r   r   r   splitlentextwrapdedentinsertr   join	functoolswraps)r
   Zexisting_docstringr!   Zdeprecation_notelocZstring_listr7   r   r   r5   r   r6   )r
   r   _function_wrapper   s4    
	z%deprecated.<locals>._function_wrapper)	TypeErrorr   r   todayr   parser   )r   r   current_versionr   Zis_deprecatedrB   r   rA   r   r   j   s,    ,

Kc                    s   t   fdd}|S )a  Decorate a test method to track removal of deprecated code

    This decorator catches :class:`~deprecation.UnsupportedWarning`
    warnings that occur during testing and causes unittests to fail,
    making it easier to keep track of when code should be removed.

    :raises: :class:`AssertionError` if an
             :class:`~deprecation.UnsupportedWarning`
             is raised while running the test method.
    c               	      sZ   t jdd}t d  | |}W 5 Q R X |D ]$}|jtkr0td t|jf q0|S )NT)recordalwaysz-%s uses a function that should be removed: %s)r/   catch_warningssimplefilterr-   r   AssertionErrorr   message)r2   r3   Zcaught_warningsrvwarningmethodr   r   
test_inner  s    

z'fail_if_not_removed.<locals>.test_inner)r>   r?   )rP   rQ   r   rO   r   r   	  s    )NNNr	   )r   r>   r:   r/   	packagingr   datetimer   __version____all__r   r1   r   r   r   r   r   r   r   r   <module>   s$    2  
  