§
    €Øj£  ã                   óâ  — d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZ ddlmZ ddlmZ ddlmZ d„ Zd„ Z ej        ed	¬
¦  «         ej        ed¬
¦  «        gZej                             de¦  «        d„ ¦   «         Zej                             de¦  «        d„ ¦   «         Zd„ Zd„ Z G d„ dej        ¦  «        Zd„ Zej                             de¦  «        d„ ¦   «         ZdS )zûCommon pickle round-trip tests for callbacks.

These tests guard the contract that callbacks (and estimators they are attached to)
must be picklable, and that an estimator pickled after a successful fit can be
unpickled in a fresh Python interpreter.
é    N)ÚProgressBarÚScoringMonitor)Ú_message_consumers)ÚMaxIterEstimator)Úmake_regressionc                  óF   — t          j        d¦  «         t          ¦   «         S )NÚrich)ÚpytestÚimportorskipr   © ó    ú—/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/sklearn/callback/tests/test_pickle.pyÚ_pbr      s   € Ý
Ô˜ÑÔÐÝ‰=Œ=Ðr   c                  ó"   — t          d¬¦  «        S )NÚr2©Úscoring)r   r   r   r   Ú_smr       s   € Ý $Ð'Ñ'Ô'Ð'r   r   ©Úidr   Úfactoryc                 ó  — t          ¦   «                               | ¦   «         ¦  «        }t          j        t          j        |¦  «        ¦  «        }t          |¦  «        t          |¦  «        u sJ ‚t          |j        ¦  «        dk    sJ ‚dS )zJAn estimator with the callback registered but not yet fitted is picklable.é   N)r   Úset_callbacksÚpickleÚloadsÚdumpsÚtypeÚlenÚ_skl_callbacks)r   Ú	estimatorÚrestoreds      r   Ú5test_estimator_with_callback_pickle_roundtrip_pre_fitr#   *   s{   € õ !Ñ"Ô"×0Ò0°°±´Ñ;Ô;€IÝŒ|�FœL¨Ñ3Ô3Ñ4Ô4€HÝ�‰>Œ>�T )™_œ_Ð,Ð,Ð,Ð,ÝˆxÔ&Ñ'Ô'¨1Ò,Ð,Ð,Ð,Ð,Ð,r   c                 óH  —  | ¦   «         }t          d¬¦  «                             |¦  «        }|                     ¦   «          t          j        t          j        |¦  «        ¦  «        }t          |¦  «        t          |¦  «        u sJ ‚t          |j        ¦  «        dk    sJ ‚dS )zBAn estimator with the callback registered and fitted is picklable.é   ©Úmax_iterr   N)	r   r   Úfitr   r   r   r   r   r    )r   Úcallbackr!   r"   s       r   Ú6test_estimator_with_callback_pickle_roundtrip_post_fitr*   3   s’   € ð ˆw‰yŒy€HÝ ¨!Ð,Ñ,Ô,×:Ò:¸8ÑDÔD€IØ‡M‚M�O„O€OÝŒ|�FœL¨Ñ3Ô3Ñ4Ô4€HÝ�‰>Œ>�T )™_œ_Ð,Ð,Ð,Ð,ÝˆxÔ&Ñ'Ô'¨1Ò,Ð,Ð,Ð,Ð,Ð,r   c                 ó®  — t          j        d¦  «         t          ddd¬¦  «        \  }}t          d¬¦  «        }t	          d¬	¦  «                             t          ¦   «         |¦  «        }|                     ||¬
¦  «         |                      ¦   «         }t          j
        d|j        ¦  «        sJ ‚t          j
        d|j        ¦  «        sJ ‚|                     d¬¦  «        }t          |¦  «        dk    sJ ‚t          j        t          j        |¦  «        ¦  «        }|                     ||¬
¦  «         |                      ¦   «         }t          j
        d|j        ¦  «        sJ ‚t          j
        d|j        ¦  «        sJ ‚|j        d                              d¬¦  «        }t          |¦  «        dk    sJ ‚|d         j        |d         j        k    sJ ‚dS )z¼An estimator with callbacks survives an in-process pickle round-trip.

    It also supports re-fitting after being unpickled and the callbacks accumulate new
    data from the re-fit.
    r	   é   é   r   ©Ú	n_samplesÚ
n_featuresÚrandom_stater   r   r%   r&   ©ÚXÚyúMaxIterEstimator - fitú100%Úall©Úselectr   N)r
   r   r   r   r   r   r   r(   Ú
readouterrÚreÚsearchÚoutÚget_logsr   r   r   r   r    Údata)	Úcapsysr3   r4   Úsmr!   ÚcapturedÚoriginal_logsr"   Úrestored_logss	            r   Ú1test_callbacks_refit_after_pickle_in_same_processrE   >   s¼  € õ Ô˜ÑÔÐå R°AÀAÐFÑFÔF�D€A€qå	 Ð	%Ñ	%Ô	%€BÝ ¨!Ð,Ñ,Ô,×:Ò:½;¹=¼=È"ÑMÔM€IØ‡M‚M�A˜€MÑÔÐà× Ò Ñ"Ô"€HÝŒ9Ð.°´Ñ=Ô=Ð=Ð=Ð=ÝŒ9�W˜hœlÑ+Ô+Ð+Ð+Ð+à—K’K u�KÑ-Ô-€MÝˆ}ÑÔ Ò"Ð"Ð"Ð"åŒ|�FœL¨Ñ3Ô3Ñ4Ô4€HØ‡L‚L�1˜€LÑÔÐà× Ò Ñ"Ô"€HÝŒ9Ð.°´Ñ=Ô=Ð=Ð=Ð=ÝŒ9�W˜hœlÑ+Ô+Ð+Ð+Ð+àÔ+¨AÔ.×7Ò7¸uÐ7ÑEÔE€MÝˆ}ÑÔ Ò"Ð"Ð"Ð"Ø˜ÔÔ  M°!Ô$4Ô$9Ò9Ð9Ð9Ð9Ð9Ð9r   c                 ó´  — t          j        d¦  «         t          ddd¬¦  «        \  }}t          d¬¦  «        }t	          d¬¦  «                             t          ¦   «         |¦  «        }|                     ||¬	¦  «         |                     ¦   «         }t          j
        d
|j        ¦  «        sJ ‚t          j
        d|j        ¦  «        sJ ‚|                     d¬¦  «        }t          |¦  «        dk    sJ ‚| dz  }t          |d¦  «        5 }	t          j        ||	¦  «         ddd¦  «         n# 1 swxY w Y   t#          j        dt'          |¦  «        ›d|d         j        › d�¦  «        }
t+          j        t.          j        d|
gdd¬¦  «        }|j                             ¦   «         }t          j
        d
|¦  «        sJ ‚t          j
        d|¦  «        sJ ‚dS )z¾An estimator with callbacks survives unpickling in a fresh interpreter.

    It also supports re-fitting after being unpickled and the callbacks accumulate new
    data from the re-fit.
    r	   é   r%   r   r.   r   r   r&   r2   r5   r6   r7   r8   r   zest.pklÚwbNz“
        import pickle
        from sklearn.callback import ScoringMonitor
        from sklearn.datasets import make_regression

        with open(a*  , "rb") as f:
            est = pickle.load(f)

        X, y = make_regression(n_samples=20, n_features=3, random_state=1)
        est.fit(X=X, y=y)

        restored_logs = est._skl_callbacks[1].get_logs(select="all")
        assert len(restored_logs) == 2
        assert restored_logs[0].data == z	
        z-cTéx   )Úcapture_outputÚtimeout)r
   r   r   r   r   r   r   r(   r:   r;   r<   r=   r>   r   Úopenr   ÚdumpÚtextwrapÚdedentÚstrr?   Ú
subprocessÚrunÚsysÚ
executableÚstdoutÚdecode)Útmp_pathr@   r3   r4   rA   r!   rB   rC   Úpkl_pathÚfÚload_scriptÚresultrU   s                r   Ú0test_callbacks_refit_after_load_in_fresh_processr\   _   s$  € õ Ô˜ÑÔÐå R°AÀAÐFÑFÔF�D€A€qå	 Ð	%Ñ	%Ô	%€BÝ ¨!Ð,Ñ,Ô,×:Ò:½;¹=¼=È"ÑMÔM€IØ‡M‚M�A˜€MÑÔÐà× Ò Ñ"Ô"€HÝŒ9Ð.°´Ñ=Ô=Ð=Ð=Ð=ÝŒ9�W˜hœlÑ+Ô+Ð+Ð+Ð+à—K’K u�KÑ-Ô-€MÝˆ}ÑÔ Ò"Ð"Ð"Ð"à˜)Ñ#€HÝ	ˆh˜Ñ	Ô	ð " ÝŒ�I˜qÑ!Ô!Ð!ð"ð "ð "ñ "ô "ð "ð "ð "ð "ð "ð "øøøð "ð "ð "ð "õ ”/ð	õ
 �x‘=”=ð	ð 	ð *7°qÔ)9Ô)>ð	ð 	ð 	ñô €Kõ$ Œ^Ý	Œ˜˜{Ð+¸DÈ#ðñ ô €Fð Œ]×!Ò!Ñ#Ô#€FÝŒ9Ð.°Ñ7Ô7Ð7Ð7Ð7ÝŒ9�W˜fÑ%Ô%Ð%Ð%Ð%Ð%Ð%s   ÄD/Ä/D3Ä6D3c                   ó(   ‡ — e Zd ZdZˆ fd„Zd„ Zˆ xZS )Ú_TraversalRecorderaa  A pickler that records the id of every object it walks through.

    `persistent_id` is called for every object the pickler encounters, so an object is
    recorded whichever path leads to it, not only when it is a direct attribute of the
    object being pickled,
    see https://docs.python.org/3/library/pickle.html#pickle.Pickler.persistent_id.
    c                 óª   •— t          ¦   «                              t          j        ¦   «         t          j        ¬¦  «         t          ¦   «         | _        d S )N)Úprotocol)ÚsuperÚ__init__ÚioÚBytesIOr   ÚHIGHEST_PROTOCOLÚsetÚwalked_through)ÚselfÚ	__class__s    €r   rb   z_TraversalRecorder.__init__œ   s;   ø€ Ý‰Œ×Ò�œ™œµÔ0GÐÑHÔHÐHÝ!™eœeˆÔÐÐr   c                 óT   — | j                              t          |¦  «        ¦  «         d S )N)rg   Úaddr   )rh   Úobjs     r   Úpersistent_idz _TraversalRecorder.persistent_id    s$   € ØÔ×Ò¥ 3¡¤Ñ(Ô(Ð(Øˆtr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rb   rm   Ú__classcell__)ri   s   @r   r^   r^   “   sQ   ø€ € € € € ðð ð$ð $ð $ð $ð $ðð ð ð ð ð ð r   r^   c                 óF   ‡ — t          j        ‰ ¦  «        ˆ fd„¦   «         }|S )a  Wrap a callback hook so that it first checks the callback it is called on.

    The check is that the pickler does not walk through the objects that listener
    threads mutate. They are found through the registered consumers: a consumer is
    normally a method bound to the container it fills, e.g. `self._log.append` for
    ScoringMonitor or `queue.put` for ProgressBar, so the container is what it is bound
    to. A consumer bound to nothing, e.g. a closure, is skipped, since there is then no
    way to tell what it mutates.
    c                 ó  •— t          t          j        ¦   «         ¦  «        }d„ |D ¦   «         }t          ¦   «         }|                     | ¦  «         |j        d„ |D ¦   «         z  }|rJ d| j        j        › d�¦   «         ‚ ‰| g|¢R i |¤ŽS )Nc                 ó<   — g | ]}t          |d ¦  «        ¯|j        ‘ŒS )Ú__self__)Úhasattrrv   )Ú.0Úcs     r   ú
<listcomp>z2_checked.<locals>.checked_hook.<locals>.<listcomp>¶   s)   € ÐKÐKÐK !µG¸A¸zÑ4JÔ4JÐK�1”:ÐKÐKÐKr   c                 ó,   — h | ]}t          |¦  «        ’ŒS r   r   )rx   Ú	containers     r   ú	<setcomp>z1_checked.<locals>.checked_hook.<locals>.<setcomp>»   s   € Ð.VÐ.VÐ.VÀ­r°)©}¬}Ð.VÐ.VÐ.Vr   z	Pickling zß walks through a container that a listener thread mutates concurrently. Keep it away from the pickler, either by handing over a copy of it in the callback's `__getstate__`, or by storing it outside of the callback instance.)Úlistr   Úvaluesr^   rM   rg   ri   rn   )rh   ÚargsÚkwargsÚ	consumersÚwatchedÚrecorderÚ	offendersÚhooks          €r   Úchecked_hookz_checked.<locals>.checked_hook±   s¾   ø€ õ Õ+Ô2Ñ4Ô4Ñ5Ô5ˆ	àKÐK yÐKÑKÔKˆå%Ñ'Ô'ˆØ�Š�dÑÔÐàÔ+Ð.VÐ.VÈgÐ.VÑ.VÔ.VÑVˆ	Øð 	
ð 	
ð?˜œÔ/ð ?ð ?ð ?ñ	
ô 	
ˆ}ð ˆt�DÐ*˜4Ð*Ð*Ð* 6Ð*Ð*Ð*r   )Ú	functoolsÚwraps)r†   r‡   s   ` r   Ú_checkedrŠ   ¥   s;   ø€ õ „_�TÑÔð+ð +ð +ð +ñ Ôð+ð& Ðr   c                 ó
  —  | ¦   «         }dD ]@}t          |j        |¦  «        }|                     |j        |t          |¦  «        ¦  «         ŒAt	          d¬¦  «                             |¦  «                             ¦   «          dS )aJ  Check that pickling a callback never traverses state its listener mutates.

    An estimator carrying a callback can be pickled by a background thread, e.g. loky's
    queue feeder dispatching a task to a worker, while the listener thread of that same
    callback mutates the callback's state as messages come in. Pickling a container that
    another thread mutates breaks the dump, which joblib reports as "Could not pickle
    the task to send it to the workers".

    The check runs from a hook, i.e. while the listeners are up, which is when such a
    dispatch would happen.
    )Úon_fit_task_beginÚon_fit_task_endr%   r&   N)Úgetattrri   ÚsetattrrŠ   r   r   r(   )r   Úmonkeypatchr)   Ú	hook_namer†   s        r   Ú0test_listener_state_is_not_walked_by_the_picklerr’   È   s‡   € ð ˆw‰yŒy€Hà=ð Kð Kˆ	Ý�xÔ)¨9Ñ5Ô5ˆØ×Ò˜HÔ.°	½8ÀD¹>¼>ÑJÔJÐJÐJå˜aÐ Ñ Ô ×.Ò.¨xÑ8Ô8×<Ò<Ñ>Ô>Ð>Ð>Ð>r   ) rq   rˆ   rc   r   r;   rQ   rS   rN   r
   Úsklearn.callbackr   r   Úsklearn.callback._transportr   Úsklearn.callback.tests._utilsr   Úsklearn.datasetsr   r   r   ÚparamÚCALLBACK_FACTORIESÚmarkÚparametrizer#   r*   rE   r\   ÚPicklerr^   rŠ   r’   r   r   r   ú<module>rœ      sñ  ððð ð Ð Ð Ð Ø 	€	€	€	Ø €€€Ø 	€	€	€	Ø Ð Ð Ð Ø 
€
€
€
Ø €€€à €€€à 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø :Ð :Ð :Ð :Ð :Ð :Ø :Ð :Ð :Ð :Ð :Ð :Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,ðð ð ð
(ð (ð (ð
 €F„L�˜Ð'Ñ'Ô'Ø€F„L�Ð)Ð*Ñ*Ô*ðÐ ð „×Ò˜Ð$6Ñ7Ô7ð-ð -ñ 8Ô7ð-ð „×Ò˜Ð$6Ñ7Ô7ð-ð -ñ 8Ô7ð-ð:ð :ð :ðB1&ð 1&ð 1&ðhð ð ð ð ˜œñ ô ð ð$ ð  ð  ðF „×Ò˜Ð$6Ñ7Ô7ð?ð ?ñ 8Ô7ð?ð ?ð ?r   