o
    ϯig                     @   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 dlm	Z	 d dl
mZ zd dlmZ W n eyK   zd dlZW n eyH   dZY nw Y nw zd dl
mZ W n ey_   eZY nw d dlmZ zd d	lmZ W n ey   G d
d deZY nw ejd  dkZejd  dkZerG dd dZdd ZeZefZeZdd Znd dlmZ e Ze!ZeZe"fZdd Zdd Z#eddZ$dd Z%dd Z&dd Z'ejdd d k pejdd d!koejdd d"k Z(zd dlZ)W n ey   dZ)Y nw e)duoe)jd  d#k Z*e(pe*Z+G d$d% d%e,Z-d&d' Z.ed(d)Z/G d*d( d(e/Z0G d+d, d,eZ1d-d. Z2dFd0d1Z3d2d3 Z4d4d5 Z5da6d6a7e8g d7Z9d8d9iZ:d:d; Z;d<d= Z<G d>d? d?e,Z=dGd@dAZ>dBdC Z?dDdE Z@dS )H    N)Iterablewraps
MethodType)
namedtuple)mock)OrderedDict)TestCaseSkipTestc                   @      e Zd ZdS )r   N__name__
__module____qualname__ r   r   O/home/ubuntu/.local/lib/python3.10/site-packages/parameterized/parameterized.pyr          r         c                   @   r   )InstanceTypeNr   r   r   r   r   r   (   r   r   c                  G   s   t t|  S N)listzip)ar   r   r   <lambda>*       r   c                 C   s   |d u r| S t | |S r   r   funcinstancetyper   r   r   make_method.   s   
r"   )r   c                 C   s   t | ||S r   r   r   r   r   r   r"   8   s   c                 C   s8   t | tr| S zt| dW S  ty   t| d Y S w )Nzutf-8latin1)
isinstance	text_typeUnicodeDecodeError)xr   r   r   to_text;   s   
r(   CompatArgSpeczargs varargs keywords defaultsc                 C   s@   t r	tt|  S t| }|jrtd| f t|d d  S )Nzparameterized does not (yet) support functions with keyword only arguments, but %r has keyword only arguments. Please open an issue with your usecase if this affects you: https://github.com/wolever/parameterized/issues/new   )PY2r)   inspect
getargspecgetfullargspec
kwonlyargs	TypeError)r   argsr   r   r   r-   F   s   
r-   c                  O   s   t d)Nzparameterized input is emptyr   r   kwr   r   r   skip_on_empty_helperT      r4   c                 C   s\   dd }t | dr,t| }|| } | j}t| d |D ]}|r&|| } q|| } q| S )Nc                    s   t   fdd}|S )Nc                     s    | i |S r   r   r1   kwargsorgfuncr   r   
dummy_func[   s   zBreapply_patches_if_need.<locals>.dummy_wrapper.<locals>.dummy_funcr   )r9   r:   r   r8   r   dummy_wrapperZ   s   z.reapply_patches_if_need.<locals>.dummy_wrapper	patchings)hasattrr,   iscoroutinefunctionr<   delattrdecorate_async_callabledecorate_callable)r   r;   is_original_asynctmp_patchings	patch_objr   r   r   reapply_patches_if_needX   s   


rE   )r         )r   rG   )r   rG   r   r*   c                   @   s   e Zd ZdZedd ZdS )DummyPatchTargetNc                   C   s$   t d urt jjt dd dS td)Ndummy_attribute)newzMissing mock package)r   patchobjectrH   ImportErrorr   r   r   r   create_dummy_patch   s   z#DummyPatchTarget.create_dummy_patch)r   r   r   rI   staticmethodrN   r   r   r   r   rH      s    rH   c                 C   s<   t | drtrt g| jd d < d S g | jd d < d S d S )Nr<   )r=   AVOID_CLEARING_MOCK_PATCHESrH   rN   r<   r   r   r   r   delete_patches_if_need   s
   
rR   paramzargs kwargsc                   @   s:   e Zd ZdZdd ZedddZedd Zd	d
 ZdS )rS   a   Represents a single parameter to a test case.

        For example::

            >>> p = param("foo", bar=16)
            >>> p
            param("foo", bar=16)
            >>> p.args
            ('foo', )
            >>> p.kwargs
            {'bar': 16}

        Intended to be used as an argument to ``@parameterized``::

            @parameterized([
                param("foo", bar=16),
            ])
            def test_stuff(foo, bar=16):
                pass
        c                 O   s   t | ||S r   )_param__new__clsr1   r7   r   r   r   rU      s   zparam.__new__Nc                 C   s   |pd}|pi }| |i |S )a   Creates a ``param`` by explicitly specifying ``args`` and
            ``kwargs``::

                >>> param.explicit([1,2,3])
                param(*(1, 2, 3))
                >>> param.explicit(kwargs={"foo": 42})
                param(*(), **{"foo": "42"})
            r   r   rV   r   r   r   explicit   s   
zparam.explicitc              
   C   sn   t |tr|S t |ttfst |ts|f}z| | W S  ty6 } zdt|vr* td||f d}~ww )a(   Returns an instance of ``param()`` for ``@parameterized`` argument
            ``args``::

                >>> param.from_decorator((42, ))
                param(args=(42, ), kwargs={})
                >>> param.from_decorator("foo")
                param(args=("foo", ), kwargs={})
            zafter * must bez=Parameters must be tuples, but %r is not (hint: use '(%r, )')N)r$   rS   strbytesr   r0   )rW   r1   er   r   r   from_decorator   s    


zparam.from_decoratorc                 C   s   d|  S )Nzparam(*%r, **%r)r   )selfr   r   r   __repr__   r5   zparam.__repr__)NN)	r   r   r   __doc__rU   classmethodrX   r\   r^   r   r   r   r   rS      s    
c                   @   s   e Zd ZdZejZejZdS )QuietOrderedDictzu When OrderedDict is available, use it to make sure that the kwargs in
        doc strings are consistently ordered. N)r   r   r   r_   dict__str__r^   r   r   r   r   ra      s    
ra   c                    s   t | }|jdd dgkrdnd}|j|d }t| j}|jt|| d } jt|d }| fddt||jp@g D  tdd |D tt	 fdd j
D }|rl|d	|jf t|f |ry|d
|jf |f |S )a   Return tuples of parameterized arguments and their values.

        This is useful if you are writing your own doc_func
        function and need to know the values for each parameter name::

            >>> def func(a, foo=None, bar=42, **kwargs): pass
            >>> p = param(1, foo=7, extra=99)
            >>> parameterized_argument_value_pairs(func, p)
            [("a", 1), ("foo", 7), ("bar", 42), ("**kwargs", {"extra": 99})]

        If the function's first argument is named ``self`` then it will be
        ignored::

            >>> def func(self, a): pass
            >>> p = param(1)
            >>> parameterized_argument_value_pairs(func, p)
            [("a", 1)]

        Additionally, empty ``*args`` or ``**kwargs`` will be ignored::

            >>> def func(foo, *args): pass
            >>> p = param(1)
            >>> parameterized_argument_value_pairs(func, p)
            [("foo", 1)]
            >>> p = param(1, 16)
            >>> parameterized_argument_value_pairs(func, p)
            [("foo", 1), ("*args", (16, ))]
    N   r]   r   c                    s"   g | ]\}}| j ||fqS r   )r7   get).0namedefault)pr   r   
<listcomp>  s    z6parameterized_argument_value_pairs.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r   r   )rf   n_r   r   r   rj     s    c                    s"   g | ]}|vr| j | fqS r   )r7   )rf   rg   ri   seen_arg_namesr   r   rj     s
    z*%sz**%s)r-   r1   lziplenextendr   defaultssetra   sortedr7   appendvarargstuplekeywords)r   ri   argspec
arg_offset
named_argsresultrv   rx   r   rm   r   "parameterized_argument_value_pairs   s$   
r}   @   c                 C   sH   t t| }t||kr"|d|d  d |t||d  d  }|S )z A shortened repr of ``x`` which is guaranteed to be ``unicode``::

            >>> short_repr("foo")
            u"foo"
            >>> short_repr("123456789", n=4)
            u"12...89"
    Nr   z...)r(   reprrp   )r'   rk   x_reprr   r   r   
short_repr'  s   	,r   c           
      C   s   | j d u rd S t| |}dd |D }| j  d\}}}d}|dr-d}|d d }dt|r4dp5dd	|f }	dd
d | |	|||fD S )Nc                 S   s    g | ]\}}d |t |f qS )z%s=%s)r   )rf   rk   vr   r   r   rj   =  s     z$default_doc_func.<locals>.<listcomp>
 .z%s[with %s] , c                 s   s    | ]}t |V  qd S r   )r(   )rf   r'   r   r   r   	<genexpr>H  s
    
z#default_doc_func.<locals>.<genexpr>)r_   r}   lstrip	partitionendswithrp   joinrstrip)
r   numri   all_args_with_valuesdescsfirstnlrestsuffixr1   r   r   r   default_doc_func6  s   



r   c                 C   sN   | j }d|f }t|jdkr#t|jd tr#|dt|jd  7 }|| S )Nz_%sr   rl   )r   rp   r1   r$   string_typesparameterizedto_safe_name)r   r   ri   	base_namename_suffixr   r   r   default_name_funcN  s
   
r   F)unittest	unittest2nosenose2pytest_pytestr   c                 C   s&   | t vrtd| dt f | ad S )Nz,Invalid test runner: %r (must be one of: %s)r   )_test_runnersr0   r   _test_runner_override)rg   r   r   r   set_test_runner_  s   r   c                  C   s   t durt S tdu rCt } t| D ].}|d }|jddd }|tv r+t| }|t	v r4|a tS |d 
dr@da tS qdatS )	a
   Guess which test runner we're using by traversing the stack and looking
        for the first matching module. This *should* be reasonably safe, as
        it's done during test discovery where the test runner should be the
        stack frame immediately outside. NFr   r   r   rd   zpython2.6/unittest.pyr   )r   _test_runner_guessr,   stackreversed	f_globalsre   r   _test_runner_aliasesr   r   )r   recordframemoduler   r   r   detect_runneri  s(   r   c                   @   s|   e Zd ZdZdddZdd Zdd	 Zd
d Zdd Ze	dd Z
e	dd Ze			dddZe	dd Ze	dd ZdS )r   aE   Parameterize a test case::

            class TestInt(object):
                @parameterized([
                    ("A", 10),
                    ("F", 15),
                    param("10", 42, base=42)
                ])
                def test_int(self, input, expected, base=16):
                    actual = int(input, base=base)
                    assert_equal(actual, expected)

            @parameterized([
                (2, 3, 5)
                (3, 5, 8),
            ])
            def test_add(a, b, expected):
                assert_equal(a + b, expected)
        NFc                 C   s    |  || _|p	t| _|| _d S r   )input_as_callable	get_inputr   doc_funcskip_on_empty)r]   inputr   r   r   r   r   __init__  s   

zparameterized.__init__c                    sf       td fdd	  }|s$ jstdtt|__djf _S )Nc              
   3   s    | ot | }| d urt|trtd| f j}tjD ]D\}}t|} 	| ||\}}z#|d j_| d urDt
|j| |V  W | d urRt|j |_q| d ur`t|j |_w d S )Nz@parameterized can't be used with old-style classes, but %r has an old-style class. Consider using a new-style class, or '@parameterized.expand' (see http://stackoverflow.com/q/54867/71522 for more information on old-style classes).r   )r!   
issubclassr   r0   r_   	enumerateparameterized_inputrS   r\   param_as_nose_tuplesetattrr   r?   )	test_selftest_clsoriginal_docr   r1   ri   unbound_func
nose_tupler]   	test_funcwrapperr   r   r     s0   

z'parameterized.__call__.<locals>.wrapperzzParameters iterable is empty (hint: use `parameterized([], skip_on_empty=True)` to skip this test when the input is empty)z_parameterized_original_%sr   )	assert_not_in_testcase_subclassr   r   r   
ValueErrorr4   r   parameterized_funcr   )r]   r   r   r   r   r   __call__  s   zparameterized.__call__c                    sr   t   fdd}|  |||_|}|d ur+tr!t dkr!d n|}t||t|}||f|j |jp5i f fS )Nc                     s    | d d i | d S )Nr   r   )r1   rQ   r   r   r         z3parameterized.param_as_nose_tuple.<locals>.<lambda>r   )	r   r   r_   r+   r   r"   r!   r1   r7   )r]   r   r   r   ri   	nose_funcr   	func_selfr   rQ   r   r     s   z!parameterized.param_as_nose_tuplec                 C   s&   |   }tdd |D rtdd S )Nc                 s   s    | ]}t |tV  qd S r   )r   r
   )rf   rW   r   r   r   r     s    z@parameterized.assert_not_in_testcase_subclass.<locals>.<genexpr>zqWarning: '@parameterized' tests won't work inside subclasses of 'TestCase' - use '@parameterized.expand' instead.)$_terrible_magic_get_defining_classesany	Exception)r]   parent_classesr   r   r   r     s   z-parameterized.assert_not_in_testcase_subclassc                 C   s   t  }t|dkrg S |d }|d o|d d  }|r#|ds%g S |d\}}}|d\}}}td| d |d j|d jS )a?   Returns the set of parent classes of the class currently being defined.
            Will likely only work if called from the ``parameterized`` decorator.
            This function is entirely @brandon_rhodes's fault, as he suggested
            the implementation: http://stackoverflow.com/a/8793684/71522
            r*   r   zclass ()[])	r,   r   rp   strip
startswithr   evalr   f_locals)r]   r   r   code_contextrl   parentsr   r   r   r     s    z2parameterized._terrible_magic_get_defining_classesc                    s,   t r fddS  fddS )Nc                      s      S r   )check_input_valuesr   rW   r   r   r   r     r   z1parameterized.input_as_callable.<locals>.<lambda>c                      s    S r   r   r   )input_valuesr   r   r     s    )callabler   r   r   )rW   r   r   r   r     s   
zparameterized.input_as_callablec                 C   s    t |ts	t|}dd |D S )Nc                 S   s   g | ]}t |qS r   )rS   r\   )rf   ri   r   r   r   rj     s    z4parameterized.check_input_values.<locals>.<listcomp>)r$   r   )rW   r   r   r   r   r     s   
z parameterized.check_input_valuesc                    st   d|v rt jdtdd s|d d|v r$t jdtdd s$|d p'tp+td
 fdd		}|S )a   A "brute force" method of parameterizing test cases. Creates new
            test cases and injects them into the namespace that the wrapped
            function is being defined in. Useful for parameterizing tests in
            subclasses of 'UnitTest', where Nose test generators don't work.

            :param input: An iterable of values to pass to the test function.
            :param name_func: A function that takes a single argument (the
                value from the input iterable) and returns a string to use as
                the name of the test case. If not provided, the name of the
                test case will be the name of the test function with the
                parameter value appended.
            :param doc_func: A function that takes a single argument (the
                value from the input iterable) and returns a string to use as
                the docstring of the test case. If not provided, the docstring
                of the test case will be the docstring of the test function.
            :param skip_on_empty: If True, the test will be skipped if the
                input iterable is empty. If False, a ValueError will be raised
                if the input iterable is empty.
            :param namespace: The namespace (dict-like) to inject the test cases
                into. If not provided, the namespace of the test function will
                be used.

            >>> @parameterized.expand([("foo", 1, 2)])
            ... def test_add1(name, input, expected):
            ...     actual = add1(input)
            ...     assert_equal(actual, expected)
            ...
            >>> locals()
            ... 'test_add1_foo_0': <function ...> ...
            >>>
            testcase_func_namez1testcase_func_name= is deprecated; use name_func=r   
stackleveltestcase_func_docz/testcase_func_doc= is deprecated; use doc_func=Nc           	         s   }|d u rt  jj}  }|s stdt| tS tt	t|d }t
|D ]%\}}| dj||d|}t| } |||||< | |||| _q.t|  d| _d S )NzParameters iterable is empty (hint: use `parameterized.expand([], skip_on_empty=True)` to skip this test when the input is empty)rd   z{num:0>{digits}})digitsr   F)r,   currentframef_backr   r   r   r   r4   rp   rY   r   formatrE   param_as_standalone_funcr_   rR   __test__)	fr    frame_locals
parametersr   r   ri   rg   nfrW   r   r   	name_func	namespacer   r   r   parameterized_expand_wrapper@  s$   
z:parameterized.expand.<locals>.parameterized_expand_wrapperr   )warningswarnDeprecationWarningr   r   )rW   r   r   r   r   r   legacyr   r   r   r   expand  s    #!zparameterized.expandc                    sd   t  rt  fdd}nt  fdd}||_ |_z|`W |S  ty1   Y |S w )Nc                     s"    | j  i j|I d H S r   r6   r2   r   ri   r   r   standalone_funcf  s    z?parameterized.param_as_standalone_func.<locals>.standalone_funcc                     s    | j  i j|S r   r6   r2   r   r   r   r   j  s   )r,   r>   r   r   place_as__wrapped__AttributeError)rW   ri   r   rg   r   r   r   r   r   c  s   
z&parameterized.param_as_standalone_funcc                 C   s$   t |ts	t|}ttdd|S )Nz[^a-zA-Z0-9_]+rl   )r$   rY   resub)rW   sr   r   r   r   }  s   
zparameterized.to_safe_name)NF)NNFN)r   r   r   r_   r   r   r   r   r   r`   r   r   r   r   r   r   r   r   r   r     s&    
3


T
r   c                    sj   t  tr g |du r n fdd|D ptr,tjdtdd fddfd	d
}|S )a   Parameterizes a test class by setting attributes on the class.

        Can be used in two ways:

        1) With a list of dictionaries containing attributes to override::

            @parameterized_class([
                { "username": "foo" },
                { "username": "bar", "access_level": 2 },
            ])
            class TestUserAccessLevel(TestCase):
                ...

        2) With a tuple of attributes, then a list of tuples of values:

            @parameterized_class(("username", "access_level"), [
                ("foo", 1),
                ("bar", 2)
            ])
            class TestUserAccessLevel(TestCase):
                ...

    Nc                    s   g | ]	}t t |qS r   )rb   r   )rf   vals)attrsr   r   rj     r   z'parameterized_class.<locals>.<listcomp>zclassname_func= is deprecated; use class_name_func= instead. See: https://github.com/wolever/parameterized/pull/74#issuecomment-613577057r   r   c                    s    | |S r   r   )rW   idxr   )classname_funcinput_dictsr   r   r     r   z%parameterized_class.<locals>.<lambda>c                    sz   t j| j j}tD ]\}}t| j}||  | ||}t|| f|||< qt| jD ]}|	dr:t
| | q.| S )Ntest)sysmodulesr   __dict__r   rb   updater!   r   r   r?   )
base_classtest_class_moduler   
input_dicttest_class_dictrg   method_name)class_name_funcr   r   r   	decorator  s   



z&parameterized_class.<locals>.decorator)r$   r   default_class_name_funcr   r   r   )r   r   r	  r   r
  r   )r   r	  r   r   r   parameterized_class  s   
r  c                 C   sR   d| v rt | d S tr|  n
dd t|  D }t tdd |D dS )Nrg   c                 s   s    | ]\}}|V  qd S r   r   )rf   rl   r   r   r   r   r     s    z(get_class_name_suffix.<locals>.<genexpr>c                 s   s    | ]
}t |tr|V  qd S r   )r$   r   )rf   r   r   r   r   r     s    
r   )r   r   PY3valuesrt   itemsnext)params_dictparams_valsr   r   r   get_class_name_suffix  s   r  c                 C   s    t |}d| j||od| f S )Nz%s_%s%srl   )r  r   )rW   r   r  r   r   r   r   r    s   
r  )r~   )NNN)Ar   r   r,   r   typingr   	functoolsr   typesr   collectionsr   r   r   rM   r	   MaybeOrderedDictrb   r
   r   r   version_infor  r+   r   ro   rY   r%   r   rZ   
bytes_typer"   r   unicode
basestringr(   r)   r-   r4   rE   $PYTHON_DOESNT_HAVE_FIX_FOR_BPO_40126_mock_backport+MOCK_BACKPORT_DOESNT_HAVE_FIX_FOR_BPO_40126rP   rL   rH   rR   rT   rS   ra   r}   r   r   r   r   r   rs   r   r   r   r   r   r  r  r  r   r   r   r   <module>   s    

4'

C
<	
  
D