
    OAi,                        S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	J
r
   " S S\	5      rSS jrSS	 jrSS
 jrSS jr\
" S5      r\
" S5      rSS jrg)zLA peculiar method of monkeypatching C++ binding classes with Python methods.    )annotationsN)Callable)AnyProtocolTypeVarc                  8    \ rS rSr% SrS\S'   S\S'   S	S jrSrg)
AugmentedCallable   z0Protocol for any method, with attached booleans.bool_augment_override_cpp_augment_if_no_cppc                    g)zAny function.N )selfargskwargss      M/var/www/html/land-ocr/venv/lib/python3.13/site-packages/pikepdf/_augments.py__call__AugmentedCallable.__call__   s        r   N)returnr   )__name__
__module____qualname____firstlineno____doc____annotations__r   __static_attributes__r   r   r   r	   r	      s    :r   r	   c                    SU l         U $ )z0Replace the C++ implementation, if there is one.T)r   fns    r   augment_override_cppr"      s    #BIr   c                    SU l         U $ )z@Provide a Python implementation if no C++ implementation exists.T)r   r    s    r   augment_if_no_cppr$      s     BIr   c                8    U R                   R                  S5      $ )Nzobject.)r   
startswith)meths    r   _is_inherited_methodr(   $   s     ''	22r   c                    [         R                  " U 5      =(       a    [        U 5      (       + =(       d    [         R                  " U 5      $ )N)inspect
isfunctionr(   isdatadescriptor)ms    r   _is_augmentabler.   *   s6    1=&:1&="=%		!	!!	$%r   TcppTc                d   ^ 1 Skm[         R                  " 5       S:X  a  TS1-  mU 4SU4S jjjnU$ )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__c                :  > [         R                  " U [        S9 GHr  u  p#US:X  a  M  [        X5      (       a  [        X5      (       a  U[	        U S[        5       5      ;  an  UT;  ah  [	        [	        X5      SS5      (       dM  [	        [	        X5      SS5      (       a  M  [        SU SU  S	U S
[	        XS5      < S[	        XS5      < 3
5      e[         R                  " U5      (       ax  [        X5      (       a  [        USU 3[	        X5      5        [        XU5        [	        X5      nUR                  R                  U R                  UR                  5      Ul	        GMH  [         R                  " U5      (       d  GMf  [        XU5        GMu     S nXPl        U $ )N)	predicate__weakref____abstractmethods__r   Fr   zC++ z and Python z* both define the same non-abstract method z:  z, _cppc                F    [        U R                  R                  S-   5      e)Nz	.__init__)NotImplementedError	__class__r   )r   s    r   disable_init5augments.<locals>.class_augment.<locals>.disable_init   s    %dnn&=&=&KLLr   )r*   
getmembersr.   hasattrgetattrsetRuntimeErrorr+   setattrr   replacer   r,   __init__)clscls_cppnamememberinstalled_memberr@   OVERRIDE_WHITELISTs         r   class_augmentaugments.<locals>.class_augment_   s{    $..soNLD}$&&C&&-BCE JJ 22 24KUSS73-/CUKK
  #7)<u 5++/&wb14Bs"-02  !!&))7)) GtD6]GG4JKv.#*7#9 060C0C0K0KLL'"2"21 - ))&11v.U OX	M $
r   )rJ   type[T]rK   
type[Tcpp]r   rR   )platformpython_implementation)rK   rP   rO   s     @r   augmentsrV   4   s@    L <%%'61}o-:A 5 5n r   )r!   r	   r   r	   )r'   r   r   r   )r-   r   r   r   )rK   rS   )r   
__future__r   r*   rT   collections.abcr   typingr   r   r   r	   r"   r$   r(   r.   r/   r0   rV   r   r   r   <module>rZ      sW    S "   $ ) ) 3% vCLbr   