
    Ng                        d Z ddlmZ ddlZddlZddlmZmZmZm	Z	  G d de          Z
dd	Zdd
ZddZddZ e	d          Z e	d          ZddZdS )zLA peculiar method of monkeypatching C++ binding classes with Python methods.    )annotationsN)AnyCallableProtocolTypeVarc                  0    e Zd ZU dZded<   ded<   d	dZdS )
AugmentedCallablez0Protocol for any method, with attached booleans.bool_augment_override_cpp_augment_if_no_cppreturnr   c                    dS )zAny function.N )selfargskwargss      M/var/www/html/ai-engine/env/lib/python3.11/site-packages/pikepdf/_augments.py__call__zAugmentedCallable.__call__   s          N)r   r   )__name__
__module____qualname____doc____annotations__r   r   r   r   r	   r	      sH         ::     r   r	   fnr   c                    d| _         | S )z0Replace the C++ implementation, if there is one.T)r   r   s    r   augment_override_cppr      s    #BIr   c                    d| _         | S )z@Provide a Python implementation if no C++ implementation exists.T)r   r   s    r   augment_if_no_cppr       s     BIr   methr   r
   c                6    | j                             d          S )Nzobject.)r   
startswith)r!   s    r   _is_inherited_methodr$   #   s     ''	222r   mr   c                r    t          j        |           ot          |            pt          j        |           S )N)inspect
isfunctionr$   isdatadescriptor)r%   s    r   _is_augmentabler*   )   s9    1=&:1&=&="=%		!!	$	$%r   TcppTcls_cpp
type[Tcpp]c                Z    h dt          j                    dk    rdhz  | fd
fd	}|S )a   Attach methods of a Python support class to an existing class.

    This monkeypatches all methods defined in the support class onto an
    existing class. Example:

    .. code-block:: python

        @augments(ClassDefinedInCpp)
        class SupportClass:
            def foo(self):
                pass

    The Python method 'foo' will be monkeypatched on ClassDefinedInCpp. SupportClass
    has no meaning on its own and should not be used, but gets returned from
    this function so IDE code inspection doesn't get too confused.

    We don't subclass because it's much more convenient to monkeypatch Python
    methods onto the existing Python binding of the C++ class. For one thing,
    this allows the implementation to be moved from Python to C++ or vice
    versa. It saves having to implement an intermediate Python subclass and then
    ensures that the C++ superclass never 'leaks' to pikepdf users. Finally,
    wrapper classes and subclasses can become problematic if the call stack
    crosses the C++/Python boundary multiple times.

    Any existing methods may be used, regardless of whether they are defined
    elsewhere in the support class or in the target class.

    For data fields to work, the target class must be
    tagged ``py::dynamic_attr`` in pybind11.

    Strictly, the target class does not have to be C++ or derived from pybind11.
    This works on pure Python classes too.

    THIS DOES NOT work for class methods.

    (Alternative ideas: https://github.com/pybind/pybind11/issues/1074)
    >   __eq____hash____repr__PyPy__getattr__clstype[T]r-   r.   r   c                \   t          j        | t                    D ]\  }}|dk    rt          ||          rt          | |          r|t	          | dt                                vr|vr{t	          t	          | |          dd          s\t	          t	          | |          dd          rt          d| d|  d	| d
t	          ||d          dt	          | |d          
          t          j        |          rt          ||          r"t          |d| t	          ||                     t          |||           t	          ||          }|j	        
                    | j        |j                  |_	        ^t          j        |          rt          |||           d }|| _        | S )N)	predicate__weakref____abstractmethods__r   Fr   zC++ z and Python z* both define the same non-abstract method z:  z, _cppc                :    t          | j        j        dz             )Nz	.__init__)NotImplementedError	__class__r   )r   s    r   disable_initz5augments.<locals>.class_augment.<locals>.disable_init   s    %dn&=&KLLLr   )r'   
getmembersr*   hasattrgetattrsetRuntimeErrorr(   setattrr   replacer   r)   __init__)r5   r-   namememberinstalled_memberr@   OVERRIDE_WHITELISTs         r   class_augmentzaugments.<locals>.class_augment^   s    $.soNNN *	/ *	/LD&}$$&&C&& -BCEE J JJJ 222T 2 24KUSS 3 73--/CUKK 
  #27 2 2 2 2+/2 2wb112 2 sD"--2 2   !&)) /7D)) L G]D]]GGT4J4JKKKv...#*7D#9#9 060C0K0KL'"21 1 -- )&11 /v...	M 	M 	M $
r   )r5   r6   r-   r.   r   r6   )platformpython_implementation)r-   rM   rL   s     @r   augmentsrP   3   sb    L <;;%''611}o-:A 5 5 5 5 5 5 5n r   )r   r	   r   r	   )r!   r   r   r
   )r%   r   r   r
   )r-   r.   )r   
__future__r   r'   rN   typingr   r   r   r   r	   r   r    r$   r*   r+   r,   rP   r   r   r   <module>rS      s   S R " " " " " "   3 3 3 3 3 3 3 3 3 3 3 3             3 3 3 3% % % % wvGCLLb b b b b br   