
    z	i              	           S r SSKrSSKrSSKrSSKJrJr  S1rSS1r " S S5      r	 " S	 S
5      r
SSS.S\S\S\S\4S jjrg)zETools useful for creating decorators, and other high-level callables.    N)TypeCallable__new____init_subclass____prepare__c                   <   ^  \ rS rSrSrSrU 4S jrS rS rSr	U =r
$ )_lift_to_method   aA  A decorator that ensures that an input callable object implements ``__get__``.  It is
returned unchanged if so, otherwise it is turned into the default implementation for functions,
which makes them bindable to instances.

Python-space functions and lambdas already have this behavior, but builtins like ``print``
don't; using this class allows us to do::

    wrap_method(MyClass, "maybe_mutates_arguments", before=print, after=print)

to simply print all the arguments on entry and exit of the function, which otherwise wouldn't be
valid, since ``print`` isn't a descriptor.
_methodc                 H   > [        US5      (       a  U$ [        TU ]	  U 5      $ )N__get__)hasattrsuperr   )clsmethod	__class__s     Q/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/utils/classtools.pyr   _lift_to_method.__new__-   s$    69%%Mws##    c                     XL a  g Xl         g Nr   )selfr   s     r   __init___lift_to_method.__init__2   s    >r   c                 b    Uc  U R                   $ [        R                  " U R                   U5      $ r   )r   types
MethodType)r   objobjtypes      r   r   _lift_to_method.__get__8   s*     ;<<c22r   )__name__
__module____qualname____firstlineno____doc__	__slots__r   r   r   __static_attributes____classcell__)r   s   @r   r	   r	      s#     I$
3 3r   r	   c                   0    \ rS rSrSrSrSS jrS	S jrSrg)
_WrappedMethodA   al  Descriptor which calls its two arguments in succession, correctly handling instance- and
class-method calls.

It is intended that this class will replace the attribute that ``inner`` previously was on a
class or instance.  When accessed as that attribute, this descriptor will behave it is the same
function call, but with the ``function`` called before or after.
)_method_decorator_method_has_getr   _before_afterNc                    [        U[        [        45      (       a  [        U5      U l        Oy[        U[        U 5      5      (       a  UR                  U l        OM[        USS 5      [        ;   a  [        U l        O,[        USS 5      [        ;   a  [        U l        O[        U l        Ub  U R	                  U5      4OSnUb  U R	                  U5      4OSn[        U[        U 5      5      (       a9  UR                  U l	        X!R                  -   U l
        UR                  U-   U l        OX l
        X0l        Xl	        [        U R                  S5      U l        g )Nr"    r   )
isinstanceclassmethodstaticmethodtyper-   getattr_MAGIC_STATICMETHODS_MAGIC_CLASSMETHODSr	   r   r/   r0   r   r.   )r   r   beforeafters       r   r   _WrappedMethod.__init__L   s   f{L9::%)&\D"T
++%+%=%=D"VZ.2FF%1D"VZ.2EE%0D"%4D"6<6H$((02b494E''.02fd4j))!>>DL!NN2DL --%/DK!LK!L  't||Y?r   c                    ^ ^^^ T R                   (       a  T R                  R                  TT5      OT R                  m[        R                  " T5      UUUU 4S j5       nU$ )Nc                     > TR                    H  nUR                  TT5      " U 0 UD6  M     T" U 0 UD6nTR                   H  nUR                  TT5      " U 0 UD6  M     U$ r   )r/   r   r0   )argskwargscallbackretvalr   r   r    r   s       r   out#_WrappedMethod.__get__.<locals>.outl   sg     LL  g.?? )T,V,F KK  g.?? (Mr   )r.   r   r   	functoolswraps)r   r   r    rC   r   s   ``` @r   r   _WrappedMethod.__get__f   sN     8<7K7K%%c73QUQ]Q]		 	 
!	 
r   )r0   r/   r   r-   r.   )NNr   )	r"   r#   r$   r%   r&   r'   r   r   r(   r2   r   r   r+   r+   A   s     YI@4r   r+   )r:   r;   r   namer:   r;   c          	      \    [         R                  " X5      n[        X[        XBU5      5        g)a  Wrap the functionality the instance- or class method ``cls.name`` with additional behavior
``before`` and ``after``.

This mutates ``cls``, replacing the attribute ``name`` with the new functionality.  This is
useful when creating class decorators.  The method is allowed to be defined on any parent class
instead.

If either ``before`` or ``after`` are given, they should be callables with a compatible
signature to the method referred to.  They will be called immediately before or after the method
as appropriate, and any return value will be ignored.

Args:
    cls: the class to modify.
    name: the name of the method on the class to wrap.
    before: a callable that should be called before the method that is being wrapped.
    after: a callable that should be called after the method that is being wrapped.

Raises:
    ValueError: if the named method is not defined on the class or any parent class.
N)inspectgetattr_staticsetattrr+   )r   rH   r:   r;   r   s        r   wrap_methodrM   x   s%    2 ##C.FC~fe<=r   )r&   rE   rJ   r   typingr   r   r8   r9   r	   r+   strrM   r2   r   r   <module>rP      sl    L    ! "{ *M: !3 !3H4 4n =ATX >T > > > >r   