o
    wi                     @   s   d dl Z d dlmZ d dlmZ d dlmZ dd Zdd Z	d	d
 Z
dd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )    N)	MagicMock)Callback)BaseCallbackc                  C   s2   t d} G dd dt}t| d| d| j_| S )a  Reset the CallbackGroup singleton and stub OneLoggerNeMoCallback safely.

    This avoids deleting modules from sys.modules. We import the module,
    replace the OneLoggerNeMoCallback symbol with a lightweight stub,
    and reset the internal singleton so a new instance is built.
    znemo.lightning.callback_groupc                   @      e Zd Zdd Zdd ZdS )z3_fresh_group_module.<locals>._StubOneLoggerCallbackc                 _      d S N selfargskwargsr   r   a/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/tests/lightning/test_callbacks_group.py__init__!      z<_fresh_group_module.<locals>._StubOneLoggerCallback.__init__c                 _   r   r   r   r	   r   r   r   update_config$   r   zA_fresh_group_module.<locals>._StubOneLoggerCallback.update_configN__name__
__module____qualname__r   r   r   r   r   r   _StubOneLoggerCallback    s    r   OneLoggerNeMoCallbackN)	importlibimport_moduler   setattrCallbackGroup	_instance)modr   r   r   r   _fresh_group_module   s
   
r   c                  C   sz   t  } |   |   |   |   |   |   |   |   | 	  | 
  |   |   |   |   dS )z?Test BaseCallback hooks are no-ops and do not raise exceptions.N)r   on_app_start
on_app_endon_model_init_starton_model_init_endon_dataloader_init_starton_dataloader_init_endon_optimizer_init_starton_optimizer_init_endon_load_checkpoint_starton_load_checkpoint_endon_save_checkpoint_starton_save_checkpoint_endon_save_checkpoint_successr   )cbr   r   r   %test_base_callback_noops_do_not_raise-   s   r,   c                   C   s   t t tsJ dS )z6Test BaseCallback derives from Lightning PTL Callback.N)
isinstancer   PTLCallbackr   r   r   r   "test_base_callback_is_ptl_callbackA   s   r/   c                  C   s*   t  } | j }| j }||u sJ dS )z7Test CallbackGroup returns the same singleton instance.N)r   r   get_instance)r   abr   r   r   &test_callback_group_singleton_identityF   s   

r3   c           	      C   s   t  }|j }G dd dt}| }|g|_G dd d}| }t }|jd||d |js1J |j}|d dks<J |d |u sDJ |d	 |u sLJ |j	d
 |u sUJ dS )zFTest update_config fans out to callbacks and attaches them to trainer.c                   @   r   )zJtest_callback_group_update_config_fanout_and_attach.<locals>._StubCallbackc                 S   s   d| _ d | _d S )NFcalledr   r
   r   r   r   r   T      
zStest_callback_group_update_config_fanout_and_attach.<locals>._StubCallback.__init__c                 _   s   d| _ || _d S )NTr4   r	   r   r   r   r   X   r7   zXtest_callback_group_update_config_fanout_and_attach.<locals>._StubCallback.update_configNr   r   r   r   r   _StubCallbackS   s    r8   c                   @      e Zd Zdd ZdS )zDtest_callback_group_update_config_fanout_and_attach.<locals>.Trainerc                 S   s
   g | _ d S r   )	callbacksr6   r   r   r   r   `      
zMtest_callback_group_update_config_fanout_and_attach.<locals>.Trainer.__init__Nr   r   r   r   r   r   r   r   Trainer_       r=   v2)datanemo_versiontrainerr@   r   N)
r   r   r0   r   
_callbacksobjectr   r5   r   r:   )	monkeypatchr   groupr8   stub_cbr=   rB   markerr   r   r   r   3test_callback_group_update_config_fanout_and_attachN   s   
	
rI   c                  C   s6   t  } | j }t }|g|_|  |jjsJ dS )z>Test dynamic dispatch calls methods when present on callbacks.N)r   r   r0   r   rC   r   r5   )r   rF   mock_cbr   r   r   7test_callback_group_dynamic_dispatch_calls_when_presento   s   
rK   c                  C   s4   t  } | j }G dd d}| g|_|  dS )z>Test dynamic dispatch ignores missing methods without raising.c                   @   s   e Zd ZdS )zKtest_callback_group_dynamic_dispatch_ignores_missing_methods.<locals>.DummyN)r   r   r   r   r   r   r   Dummy   s    rL   N)r   r   r0   rC   on_nonexistent_method)r   rF   rL   r   r   r   <test_callback_group_dynamic_dispatch_ignores_missing_methods{   s
   

rN   c           	         s   t    j }t }t }| |d| | |d| G  fddd}G dd d|}G dd d|}| }|jd	ks?J t|jd
ddu sJJ | }|jd	ksTJ |jdks[J |j	dksbJ |j	dksiJ t|jd
ddu stJ dS )zSTest inheritance-based hook via __init_subclass__ emits start/end once (e2e-style).r    r!   c                          e Zd Z fddZ  ZS )zAtest_hook_class_init_with_callbacks_wraps_and_emits.<locals>.Basec                    $   t  jdi | | dd d S Nr    r!   r   super__init_subclass__hook_class_init_with_callbacksclsr   	__class__r   r   r   rT      s   zStest_hook_class_init_with_callbacks_wraps_and_emits.<locals>.Base.__init_subclass__r   r   r   rT   __classcell__r   r   rY   r   Base       r^   c                   @   r9   )zBtest_hook_class_init_with_callbacks_wraps_and_emits.<locals>.Childc                 S   s
   d| _ d S )N   )xr6   r   r   r   r      r;   zKtest_hook_class_init_with_callbacks_wraps_and_emits.<locals>.Child.__init__Nr<   r   r   r   r   Child   r>   rb   c                       s   e Zd Z fddZ  ZS )zGtest_hook_class_init_with_callbacks_wraps_and_emits.<locals>.GrandChildc                    s   d| _ t   d S )N   )yrS   r   r6   r]   r   r   r      s   zPtest_hook_class_init_with_callbacks_wraps_and_emits.<locals>.GrandChild.__init__)r   r   r   r   r[   r   r   r]   r   
GrandChild   s    re   r`   _init_wrapped_for_callbacksFTrc   N)
r   r   r0   r   r   ra   getattrr   rd   
call_count)	rE   rF   startendr^   rb   re   cdr   r\   r   3test_hook_class_init_with_callbacks_wraps_and_emits   s$   
rm   c                     sR   t   G  fddd} G dd d| }|j} |dd |j}||u s'J dS )zQTest inheritance-based hook is idempotent and does not re-wrap on repeated calls.c                       rO   )z<test_hook_class_init_with_callbacks_idempotent.<locals>.Basec                    rP   rQ   rR   rV   rX   r   r   rT      s   zNtest_hook_class_init_with_callbacks_idempotent.<locals>.Base.__init_subclass__rZ   r   r\   r]   r   r^      r_   r^   c                   @   r9   )z=test_hook_class_init_with_callbacks_idempotent.<locals>.Childc                 S   r   r   r   r6   r   r   r   r      r   zFtest_hook_class_init_with_callbacks_idempotent.<locals>.Child.__init__Nr<   r   r   r   r   rb      r>   rb   r    r!   N)r   r   rU   )r^   rb   firstsecondr   r\   r   .test_hook_class_init_with_callbacks_idempotent   s   rp   c                 C   sB   t  }|j }t }|g|_|  |  |jjdksJ dS )zATest on_app_end fans out only once even if called multiple times.r`   N)r   r   r0   r   rC   r   rh   )rE   r   rF   rJ   r   r   r   test_on_app_end_is_idempotent   s   
rq   )r   unittest.mockr   lightning.pytorch.callbacksr   r.   nemo.lightning.base_callbackr   r   r,   r/   r3   rI   rK   rN   rm   rp   rq   r   r   r   r   <module>   s   !)