o
    3g                     @  s   d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZ ddlmZmZmZmZ d.ddZdZddlmZ ee v sJJ d/ddZd0ddZd1ddZd2d3d!d"Zd4d$d%Zd5d'd(Zd6d*d+Zd6d,d-ZdS )7    )annotationsN)Iterable)chain)Path)
ModuleType   )	HPIModule_is_not_module_src	has_statsignoredreturnIterable[HPIModule]c                  c  s    dd l } t| E d H  d S )Nr   )my_iter_all_importables)r    r   &/home/garg/my-data/HPI/my/core/util.pymodules   s   r   zGImport this to mark a python file as a helper, not an actual HPI module)NOT_HPI_MODULE_VARmodulestr
str | Nonec              
   C  s   ddl }d}z|j| }|dusJ |j}W n ty* } zW Y d}~dS d}~ww |dus1J tt|r=dt dS tt|sEdS dS )z4
    None if a module, otherwise returns reason
    r   Nz,import error (possibly missing config entry)zmarked explicitly (via )has no 'stats()' function)	importlib.utilutil	find_specorigin	Exceptionr	   r   r   r
   )r   	importlibpathspecer   r   r   is_not_hpi_module   s    
r"   pkgr   c                 #  s*    t  fddt jD E d H  d S )Nc                 3  s     | ]}t t| jV  qd S N)_discover_path_importablesr   __name__.0pr#   r   r   	<genexpr>6   s
    
z(_iter_all_importables.<locals>.<genexpr>)r   from_iterableset__path__r*   r   r*   r   r   4   s   r   pkg_pthr   pkg_namec           	      c  s    ddl m} t| D ]A\}}}|  |  t|}|jd dkr%qtdd |D r/q|| }d	|g|jR }t
t|f| ddE d	H  qd	S )
z5Yield all importables under a given path and package.r   config__pycache__c                 s  s    | ]
}t |jd kV  qdS )z.pyN)r   suffix)r(   _r   r   r   r+   M   s    z-_discover_path_importables.<locals>.<genexpr>.)prefixN)core_configr2   oswalksortr   partsallrelative_tojoin_walk_packagesr   )	r/   r0   r2   dir_pathdirs
file_namespkg_dir_pathrel_ptpkg_prefr   r   r   r%   >   s    
r%    r   Iterable[str]r8   c           
   	   #  sB   ddl m} i fdd t| |D ]}|j}|du rqt|r"q||}d}|du r0d}n|du r?t|}|dur>|}n	 t||dV  |j	sKq||d	 }	|	sUqzt
| W n# tyl   |durj|| Y q ty~   |dur{|| n Y qw ttj| d
dpg }  fdd| D } t| |d	 |E dH  qdS )z
    Modified version of https://github.com/python/cpython/blob/d50a0700265536a20bcce3fb108c954746d97625/Lib/pkgutil.py#L53,
    to avoid importing modules that are skipped
    r   r1   c                 S  s   | |v rdS d|| < d S )NTr   )r)   mr   r   r   seeni   s   z_walk_packages.<locals>.seenNFsuppressed in the user config)nameskip_reasonr7   r.   c                   s   g | ]} |s|qS r   r   r'   rK   r   r   
<listcomp>   s    z"_walk_packages.<locals>.<listcomp>)r9   r2   pkgutiliter_modulesrM   r   _is_module_activer"   r   ispkg
__import__ImportErrorr   getattrsysr   rA   )
r   r8   onerrorr2   infomnameactiverN   is_not_modulerecurser   rO   r   rA   b   sX   

rA   list[HPIModule]c                   C  s
   t t S r$   )listr   r   r   r   r   get_modules   s   
ra   Nonec                  C  s   ddl m}  |  }g d|_dd t D }|d jdks J W d    n1 s*w   Y  |  ,}g d|_dg|_d	d t D }|d jd u sMJ |d
 jdksVJ W d    d S 1 saw   Y  d S )Nr   )_reset_config)my.location.*	my.body.*my.workouts.*my.private.*c                 S     i | ]}|j |qS r   rM   r(   rJ   r   r   r   
<dictcomp>       z)test_module_detection.<locals>.<dictcomp>zmy.demor   )rd   re   rf   rg   	my.lastfmc                 S  rh   r   ri   rj   r   r   r   rk      rl   rm   rL   )r9   rc   disabled_modulesr   rN   enabled_modules)resetccmodsr   r   r   test_module_detection   s   

"rs   tmp_pathc                 C  s   | d }|d }|j dd |d d |d d |d	 d
 dd l}t|j}z|jdt| td}td}td}W ||_n||_w |d u sQJ |d usWJ d|v s]J |d uscJ d|v siJ d S )Ngoodr   Tparentszgood.pyzdef stats(): passzdisabled.pyz(
from my.core import __NOT_HPI_MODULE__
z
nostats.pyz
# no stats!
r   zmy.goodzmy.disabledz
my.nostatszmarked explicitlystats)mkdir
write_textrX   r`   r   insertr   r"   )rt   badpparrX   	orig_pathru   disablednostatsr   r   r   test_good_modules   s&   

r   c                 C  s   | d }| d | d }|d }|jdd |d  d| d	 d
d l}t|j}z|jd
t| td}W ||_n||_w |d u sHJ | dksPJ d S )Nprecious_datazsome precious databadr   Trv   zmalicious.pyz!
from pathlib import Path
Path(r'z}').write_text('aaand your data is gone!')

raise RuntimeError("FAIL ON IMPORT! naughty.")

def stats():
    return [1, 2, 3]
r   zmy.malicious)	rz   ry   rX   r`   r   r{   r   r"   	read_text)rt   xxr|   r}   rX   r~   resr   r   r   test_bad_modules   s    





r   )r   r   )r   r   r   r   )r#   r   r   r   )r/   r   r0   r   r   r   )rH   N)r   rI   r8   r   r   r   )r   r_   )r   rb   )rt   r   r   rb   )
__future__r   r:   rQ   rX   collections.abcr   	itertoolsr   pathlibr   typesr   discovery_purer   r	   r
   r   r   __NOT_HPI_MODULE__r   globalsr"   r   r%   rA   ra   rs   r   r   r   r   r   r   <module>   s*    




$
A
	
