
    SOg"                     t    S SK r S SKrS SKrS SKrSSKJr  S SKJr  \R                  " 5          " S S\	5      r
g)    N   )load_source)utilc                   x    \ rS rSrSrSS jrS rSS jrS rS r	SS	 jr
S
 rS rS rS rS rS rS rS rSrg)ModuleManager   a  
`ModuleManager` manages the module plugin filter state and is responsible
for both loading the modules from source code and collecting the plugins
from each of the modules.

`ModuleManager` can also optionally manage modules explicitly through
the use of the add/get/set loaded modules methods. The default
implementation is hardwired to use the tracked loaded modules if no
modules are passed into the `collect_plugins` method.
Nc                     Uc  / n[         R                  " U5      n[        5       U l        [	        5       U l        Xl        [        R                  " [        5      U l
        SU l        g)aJ  
`module_plugin_filters` are callable filters. Each filter must take
in a list of plugins and a list of plugin names in the form of:

::

    def my_module_plugin_filter(plugins: list, plugin_names: list):
        pass

`module_plugin_filters` should return a list of the plugins and may
be either a single object or an iterable.
Nz"pluginmanager unable to import {}
)r   return_listsetloaded_modulesdictprocessed_filepathsmodule_plugin_filterslogging	getLogger__name___log_error_stringselfr   s     a/Users/admin/workspace/ai/Jarvis/env/lib/python3.13/site-packages/pluginmanager/module_manager.py__init__ModuleManager.__init__   sV     !($&! $ 0 01F G!e#'6 %:"%%h/	B    c                 z   U R                  5         [        R                  " U5      n/ nU H  nU R                  U5      nU R	                  U5      (       a  M,  [        R
                  " U5      n[        R                  " U5      n [        XS5      nU R                  R!                  UR"                  5        UR%                  U5        X0R&                  UR"                  '   M     U$ ! [         aM    [        R                  " 5       nU R                  R                  U R                  R                  U5      US9   GM  f = f)z
Loads the modules from their `filepaths`. A filepath may be
a directory filepath if there is an `__init__.py` file in the
directory.

If a filepath errors, the exception will be caught and logged
in the logger.

Returns a list of modules.
)msgexc_info)_update_loaded_modulesr   
return_set_clean_filepath_processed_filepathget_module_namecreate_unique_module_namer   	Exceptionsysr   r   errorr   formatr   addr   appendr   )r   	filepathsmodulesfilepathmodule_nameplugin_module_namemoduler   s           r   load_modulesModuleManager.load_modules-   s    	##%OOI.	!H++H5H''11..x8K!%!?!?!L$%7B ##FOO4NN6"8@$$V__5+ ".   <<>		D$6$6$=$=h$G)1   3	s   C##AD:9D:c                 \   Uc  U R                  5       nO[        R                  " U5      n/ nU Ht  n[        R                  " U5       Vs/ s H$  nUS   (       d  M  US   S:w  d  M  US   US   4PM&     nn[        U6 u  pVU R                  XV5      nUR                  U5        Mv     U$ s  snf )z
Collects all the plugins from `modules`.
If modules is None, collects the plugins from the loaded modules.

All plugins are passed through the module filters, if any are any,
and returned as a list.
r   r   __builtins__)get_loaded_modulesr   r
   inspect
getmemberszip_filter_modulesextend)r   r+   pluginsr/   itemmodule_pluginsnamess          r   collect_pluginsModuleManager.collect_pluginsV   s     ?--/G&&w/GF ")!3!3F!;H!; #'!%a 1 .2!W-F 1tAwQ0!;  H %($8!N!11.HNNN>*  Hs   
B)B)'B)c                 <    [         R                  " U5      nXl        g)z
Sets the internal module filters to `module_plugin_filters`
`module_plugin_filters` may be a single object or an iterable.

Every module filters must be a callable and take in
a list of plugins and their associated names.
N)r   r
   r   r   s     r   set_module_plugin_filters'ModuleManager.set_module_plugin_filterso   s     !% 0 01F G%:"r   c                 f    [         R                  " U5      nU R                  R                  U5        g)z
Adds `module_plugin_filters` to the internal module filters.
May be a single object or an iterable.

Every module filters must be a callable and take in
a list of plugins and their associated names.
N)r   r
   r   r9   r   s     r   add_module_plugin_filters'ModuleManager.add_module_plugin_filtersz   s+     !% 0 01F G""))*?@r   c                 D    Uc  U R                   $ U" U R                   5      $ )z
Gets the internal module filters. Returns a list object.

If supplied, the `filter_function` should take in a single
list argument and return back a list. `filter_function` is
designed to given the option for a custom filter on the module filters.
)r   )r   filter_functions     r   get_module_plugin_filters'ModuleManager.get_module_plugin_filters   s'     "---"4#=#=>>r   c                 F    [         R                  " U R                  U5        g)z
Removes `module_plugin_filters` from the internal module filters.
If the filters are not found in the internal representation,
the function passes on silently.

`module_plugin_filters` may be a single object or an iterable.
N)r   remove_from_listr   r   s     r   remove_module_plugin_filters*ModuleManager.remove_module_plugin_filters   s     	d883	5r   c                 `    / nU H%  nUR                  [        R                  U   5        M'     U$ )zV
An internal method that gets the `names` from sys.modules and returns
them as a list
)r)   r%   r+   )r   r=   r   names       r   _get_modulesModuleManager._get_modules   s0    
 D!!#++d"34 r   c                     [         R                  " U5      nU H?  n[        U[        5      (       d  UR                  nU R
                  R                  U5        MA     g)zr
Manually add in `modules` to be tracked by the module manager.

`modules` may be a single object or an iterable.
N)r   r   
isinstancestrr   r   r(   )r   r+   r/   s      r   add_to_loaded_modules#ModuleManager.add_to_loaded_modules   sF     //'*Ffc**##F+ r   c                 8    U R                  U R                  5      $ )z.
Returns all modules loaded by this instance.
)rP   r   )r   s    r   r4    ModuleManager.get_loaded_modules   s       !4!455r   c                 $   U R                   (       a~  [        U5      n[        5       nU R                    HW  nUR                  U" X5      5        [        U5      U:  d  M+  SnU R                  R                  UR                  U5      5        MY     UnU$ )za
Internal helper method to parse all of the plugins and names
through each of the module filters
aN  Module Filter removing plugins from original
                    data member! Suggest creating a new list in each module
                    filter and returning new list instead of modifying the
                    original data member so subsequent module filters can have
                    access to all the possible plugins.
 {})r   lenr   updater   infor'   )r   r:   r=   original_length_pluginsr<   module_filterwarnings          r   r8   ModuleManager._filter_modules   s}    
 %%&)'l# UN!%!;!;%%mG&CDw<"99@G IINN7>>-#@A "< %Gr   c                    [         R                  R                  U5      (       ab  [         R                  R                  [         R                  R	                  US5      5      (       a   [         R                  R	                  US5      nUR                  S5      (       d,  [         R                  R                  US-   5      (       a  US-  nU$ )za
processes the filepath by checking if it is a directory or not
and adding `.py` if not present.
z__init__.pyz.py)ospathisdirisfilejoinendswith)r   r,   s     r   r    ModuleManager._clean_filepath   s    
 GGMM(##rww||HmDEEww||Hm<H!!%((x%/00Hr   c                 H    SnXR                   R                  5       ;   a  SnU$ )z:
checks to see if the filepath has already been processed
FT)r   values)r   r,   	processeds      r   r!   !ModuleManager._processed_filepath   s)     	//6688Ir   c                     [         R                  R                  5       n[        U R                  5       H@  nX!;  d  M
  U R
                  R                  U5        U R                  R                  U5        MB     g)zI
Updates the loaded modules by checking if they are still in sys.modules
N)r%   r+   keyslistr   r   popremove)r   system_modulesr/   s      r   r   $ModuleManager._update_loaded_modules   sY     ))+4../F+((,,V4##**62 0r   )r   r   r   r   r   )N)r   
__module____qualname____firstlineno____doc__r   r0   r>   rA   rD   rH   rL   rP   rU   r4   r8   r    r!   r   __static_attributes__ r   r   r   r      sP    	C,'R2	;	A?	5
,6.3r   r   )rb   r%   r   r5   compatr   pluginmanagerr   basicConfigobjectr   ry   r   r   <module>r~      s1    	 
        e3F e3r   