o
    b\                     @   s  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mZ ddlm	Z	 ddl
mZ ddl
mZ ejdr9d	Zd
ZndZdZzedejdedejdeddhZW n e	y]   e ZY nw ejdkreejejd zeejejd W n  ey   zeejejd W n	 ey   Y nw Y nw e dkrejejdZee zeejejd W n	 ey   Y nw [ejdkrzejZW n ey   ejZY nw dd Zeed ejdkreed e Ze dkZ e!"ej#dZ$G dd de%Z&dd Z'dd  Z(e fd!d"Z)d#d$ Z*i Z+d%d& Z,dPd'd(Z-dQd)d*Z.dRd+d,Z/d-d. Z0d/d0 Z1dSd1d2Z2dTd3d4Z3dSd5d6Z4dSd7d8Z5dTd9d:Z6dUd<d=Z7dUd>d?Z8d@dA Z9dTdBdCZ:dDdE Z;dSdFdGZ<dHdI Z=dJdK Z>dLdM Z?dNdO Z@dS )VaV  Python modules manipulation utility functions.

:type PY_SOURCE_EXTS: tuple(str)
:var PY_SOURCE_EXTS: list of possible python source file extension

:type STD_LIB_DIRS: set of str
:var STD_LIB_DIRS: directories where standard modules are located

:type BUILTIN_MODULES: dict
:var BUILTIN_MODULES: dictionary with builtin module names has key
    N)get_python_lib)DistutilsPlatformError   )spec)utilwin)pypyw)dllZpyd)r   )soT)standard_libprefix)r   ntZdllsPyPyZlib_pypyposixc                 C   s"   dt jd d  }tjt| |S )Nzpython%d.%d   )sysversion_infoospathjoinr   )r   Zbase_python r   O/var/www/secure340b-portal/env/lib/python3.10/site-packages/astroid/modutils.py_posix_pathh   s   r   libl        Zlib64Jythonc                   @   s   e Zd ZdZdS )NoSourceFilezaexception raised when we are not able to get a python
    source file for a precompiled file
    N)__name__
__module____qualname____doc__r   r   r   r   r   |   s    r   c                 C      t jt j| S N)r   r   normcaseabspathr   r   r   r   _normalize_path      r&   c                 C   r!   r"   )r   r   realpath
expanduserr%   r   r   r   _canonicalize_path   r'   r*   c                 C   sL   |st jdkr	| S | dr| d d S | S | d\}}}|r$|d S | S )N)   r   z.pycz	$py.class.py)r   r   endswith	partition)filenameZ	is_jythonheadZhas_pyclass_r   r   r   _path_from_filename   s   

r3   c                 C   s4   | D ]}||v r| | q||v r| | qdS )z`remove files/directories in the black list

    dirnames/filenames are usually from os.walk
    N)remove)	blacklistdirnames	filenamesZnorecursr   r   r   _handle_blacklist   s   
r8   c                 C   sB   zt |  W S  ty    | st|  Y S t|  }t | < | Y S w )zabspath with caching)_NORM_PATH_CACHEKeyErrorr&   )r   resultr   r   r   _cache_normalize_path   s   
r<   c                 C   s   t | d||S )a"  Load a Python module from its name.

    :type dotted_name: str
    :param dotted_name: python name of a module or package

    :type path: list or None
    :param path:
      optional list of path where the module or package should be
      searched (use sys.path if nothing or None is given)

    :type use_sys: bool
    :param use_sys:
      boolean indicating whether the sys.modules dictionary should be
      used or not


    :raise ImportError: if the module or package is not found

    :rtype: module
    :return: the loaded module
    .)load_module_from_modpathsplit)dotted_namer   use_sysr   r   r   load_module_from_name   s   rB   c                 C   s,  |rz	t jd|  W S  ty   Y nw g }d}| D ]x}|| d|}d}t|t| kr8t j|}n|r@t j|}|du r[t||\}}	}
t	|||	|
}|r[|
  |rct||| t|dd}|}|sst|rsq|st|t| krtdd| t|d  tj|g}q|S )a<  Load a python module from its split name.

    :type parts: list(str) or tuple(str)
    :param parts:
      python name of a module or package split on '.'

    :type path: list or None
    :param path:
      optional list of path where the module or package should be
      searched (use sys.path if nothing or None is given)

    :type use_sys: bool
    :param use_sys:
      boolean indicating whether the sys.modules dictionary should be used or not

    :raise ImportError: if the module or package is not found

    :rtype: module
    :return: the loaded module
    r=   N__file__ zno module in %s)r   modulesr   r:   appendlengetimpfind_moduleload_moduleclosesetattrgetattrr   is_namespaceImportErrorr   r   dirname)partsr   rA   modpathZ
prevmodulepartZcurnamemoduleZmp_fileZmp_filenameZmp_desc_filer   r   r   r>      s>   

r>   c                 C   s   t | |}t|||S )a  Load a Python module from it's path.

    :type filepath: str
    :param filepath: path to the python module or package

    :type path: list or None
    :param path:
      optional list of path where the module or package should be
      searched (use sys.path if nothing or None is given)

    :type use_sys: bool
    :param use_sys:
      boolean indicating whether the sys.modules dictionary should be
      used or not


    :raise ImportError: if the module or package is not found

    :rtype: module
    :return: the loaded module
    )modpath_from_filer>   )filepathr   rA   	extrapathrS   r   r   r   load_module_from_file  s   
rZ   c                 C   sL   g }|D ]}| | tj| |} t| s#td|}|s# dS qdS )z2check there are some __init__.py all along the wayr=   FT)rF   r   r   r   	_has_initr   rO   )r   Zmod_pathrS   rT   Zold_namespacer   r   r   check_modpath_has_init  s   
r\   c                 C   s   d}t j|}t j| }t j||r|}t j| }t j||r*|}|rGt j|d }|t|d }dd |t j	D S dS )a=  Extracts the relative mod path of the file to import from

    Check if a file is within the passed in path and if so, returns the
    relative mod path from the one passed in.

    If the filename is no in path_to_check, returns None

    Note this function will look for both abs and realpath of the file,
    this allows to find the relative base path even if the file is a
    symlink of a file in the passed in path

    Examples:
        _get_relative_base_path("/a/b/c/d.py", "/a/b") ->  ["c","d"]
        _get_relative_base_path("/a/b/c/d.py", "/dev") ->  None
    Nr   c                 S   s   g | ]}|r|qS r   r   ).0pkgr   r   r   
<listcomp>I  s    z+_get_relative_base_path.<locals>.<listcomp>)
r   r   r#   r$   
startswithr(   splitextrG   r?   sep)r0   Zpath_to_checkZimportable_pathZabs_filenameZreal_filename	base_pathZrelative_base_pathr   r   r   _get_relative_base_path,  s   rd   c                 C   s   t jt| } |d ur=ttt||D ]'}t j|}|s qt	| |}|s(q|||d d r<|| 
d|   S qttttjtjD ]}t|}|sQqHt	| |}|sYqH|||d d rf|  S qHtd| dtjf )Nr,   r=   z"Unable to find module for %s in %sz, 
)r   r   r)   r3   	itertoolschainmapr*   r$   rd   r?   r   r<   rP   r   )r0   rY   Zis_package_cbZpath_r   Z
submodpathrS   r   r   r   modpath_from_file_with_callbackN  s2   

rh   c                 C   s   t | |tS )ai  given a file path return the corresponding split module's name
    (i.e name of a module or package split on '.')

    :type filename: str
    :param filename: file's path for which we want the module's name

    :type extrapath: dict
    :param extrapath:
      optional extra search path, with path as key and package name for the path
      as value. This is usually useful to handle package split in multiple
      directories using __path__ trick.


    :raise ImportError:
      if the corresponding module's name has not been found

    :rtype: list(str)
    :return: the corresponding split module's name
    )rh   r\   )r0   rY   r   r   r   rW   k  s   rW   c                 C   s   t | ||jS r"   )file_info_from_modpathlocation)rS   r   context_filer   r   r   file_from_modpath     rl   c                 C   s   |durt j|}n|}| d dkr1ztdg| dd  ||W S  ty0   t| || Y S w | ddgkrBtjdt jjtj	d	S t| ||S )
a  given a mod path (i.e. split module / package name), return the
    corresponding file, giving priority to source file over precompiled
    file if it exists

    :type modpath: list or tuple
    :param modpath:
      split module's name (i.e name of a module or package split
      on '.')
      (this means explicit relative imports that start with dots have
      empty strings in this list!)

    :type path: list or None
    :param path:
      optional list of path where the module or package should be
      searched (use sys.path if nothing or None is given)

    :type context_file: str or None
    :param context_file:
      context file to consider, necessary if the identifier has been
      introduced using a relative import unresolvable in the actual
      context (i.e. modutils)

    :raise ImportError: if there is no such module in the directory

    :rtype: (str or None, import type)
    :return:
      the path to the module's file or None if it's an integrated
      builtin module such as 'sys'
    Nr   xmlZ_xmlplusr   r   r   os.path)namerj   module_type)
r   r   rQ   _spec_from_modpathrP   r   
ModuleSpecrC   rI   	PY_SOURCE)rS   r   rk   contextr   r   r   ri     s   ri   c              	   C   s  |  drdS | d}|dur$|d tv r$t|dkr t| |d S d}d}|d dkr:|dus6J dg }d}|| dkrP|d7 }tj|}|| dks@t|t|D ]1}zt	|||d  ||d	 W qW ty   |t
dt|d k r{ d|d|  Y   S w | S )
a  given a dotted name return the module part of the name :

    >>> get_module_part('astroid.as_string.dump')
    'astroid.as_string'

    :type dotted_name: str
    :param dotted_name: full name of the identifier we are interested in

    :type context_file: str or None
    :param context_file:
      context file to consider, necessary if the identifier has been
      introduced using a relative import unresolvable in the actual
      context (i.e. modutils)


    :raise ImportError: if there is no such module in the directory

    :rtype: str or None
    :return:
      the module part of the name or None if we have not been able at
      all to import the given name

    XXX: deprecated, since it doesn't handle package precedence over module
    (see #10066)
    ro   r=   Nr   r   rD   z.explicit relative import, but no context_file?r   )r   rk   )r`   r?   BUILTIN_MODULESrG   rP   r   r   rQ   rangerl   maxr   )r@   rk   rR   r   Zstartiir   r   r   get_module_part  s@   


rz   Fc           	      C   sx   g }t | D ]2\}}}||v rqt||| |s$d|vr$d|dd< q|D ]}t|r8t j||}|| q&q|S )aN  given a package directory return a list of all available python
    module's files in the package and its subpackages

    :type src_directory: str
    :param src_directory:
      path of the directory corresponding to the package

    :type blacklist: list or tuple
    :param blacklist: iterable
      list of files or directories to ignore.

    :type list_all: bool
    :param list_all:
        get files from all paths, including ones without __init__.py

    :rtype: list
    :return:
      the list of all available python module's files in the package and
      its subpackages
    z__init__.pyr   N)r   walkr8   _is_python_filer   r   rF   )	Zsrc_directoryr5   Zlist_allfiles	directoryr6   r7   r0   srcr   r   r   get_module_files  s   
r   c                 C   sj   t jt| } t j| \}}tD ]}d||f }t j|r$|  S q|r1|s1t j|r1|S t| )a  given a python module's file name return the matching source file
    name (the filename will be returned identically if it's already an
    absolute path to a python source file...)

    :type filename: str
    :param filename: python module's file name


    :raise NoSourceFile: if no source file exists on the file system

    :rtype: str
    :return: the absolute path of the source file if it exists
    z%s.%s)r   r   r$   r3   ra   PY_SOURCE_EXTSexistsr   )r0   Zinclude_no_extbaseZorig_extextsource_pathr   r   r   get_source_file  s   r   c                 C   s   t j| d dd tv S )zN
    rtype: bool
    return: True if the filename is a python source file
    r   N)r   r   ra   r   )r0   r   r   r   is_python_source1  s   r   c                 C   s   |  dd } zt| g}W n
 ty   Y dS w |du r#t|  S t|}|ttr0dS |du r6t	}|D ]}|t|rD dS q8dS )a  try to guess if a module is a standard python module (by default,
    see `std_path` parameter's description)

    :type modname: str
    :param modname: name of the module we are interested in

    :type std_path: list(str) or tuple(str)
    :param std_path: list of path considered has standard


    :rtype: bool
    :return:
      true if the module:
      - is located on the path listed in one of the directory in `std_path`
      - is a built-in module
    r=   r   FNT)
r?   rl   rP   r   rO   r&   r`   r<   EXT_LIB_DIRSTD_LIB_DIRS)modnameZstd_pathr0   r   r   r   r   is_standard_module9  s$   r   c                 C   sl   t j|st j|}|tjv rdS zt| dd |g\}}}|r)|  W dS  t	y5   Y dS w )av  return true if the given module name is relative to the given
    file name

    :type modname: str
    :param modname: name of the module we are interested in

    :type from_file: str
    :param from_file:
      path of the module from which modname has been imported

    :rtype: bool
    :return:
      true if the module has been imported relatively to `from_file`
    Fr=   r   T)
r   r   isdirrQ   r   rI   rJ   r?   rL   rP   )r   	from_filestreamr2   r   r   r   is_relativea  s   
r   c                 C   s   | sJ d}|dur)zt | |g}|j}W n ty(   t | |}|j}Y nw t | |}|jt jjkrUzt|j}|j|t jj	dW S  t
yT   |j|d Y S w |jt jjkrb|jddS |jt jjkrwt|j}|j|t jj	dS |S )zgiven a mod path (i.e. split module / package name), return the
    corresponding spec

    this function is used internally, see `file_from_modpath`'s
    documentation for more information
    N)rj   type)rj   )r   	find_specrj   rP   r   
ModuleTypePY_COMPILEDr   _replacert   r   Z	C_BUILTINPKG_DIRECTORYr[   )rS   r   ru   rj   Z
found_specr   r   r   rr     s4   



rr   c                 C   s   dD ]
}|  |r dS qdS )zkreturn true if the given filename should be considered as a python file

    .pyc and .pyo are ignored
    )r-   z.soz.pydz.pywTF)r.   )r0   r   r   r   r   r|     s
   
r|   c                 C   sD   t j| d}td D ]}t j|d | r|d |   S qdS )z\if the given directory has a valid __init__ file, return its path,
    else return None
    __init__)ZpycZpyor=   N)r   r   r   r   r   )r~   Zmod_or_packr   r   r   r   r[     s   r[   c                 C      | j tjjkS r"   )r   r   r   ZPY_NAMESPACEZspecobjr   r   r   rO     rm   rO   c                 C   r   r"   )r   r   r   r   r   r   r   r   is_directory  rm   r   )NT)Nr   )NTN)NNr"   )F)Ar    rI   r   platformr   re   distutils.sysconfigr   distutils.errorsr   Zinterpreter._importr   r   r`   r   ZPY_COMPILED_EXTSr   exec_prefixr   setrp   addr   r   real_prefixAttributeErrorbase_exec_prefixpython_implementation_rootr   maxsizer   Z	IS_JYTHONdictfromkeysbuiltin_module_namesrv   	Exceptionr   r&   r*   r3   r8   r9   r<   rB   r>   rZ   r\   rd   rh   rW   rl   ri   rz   r   r   r   r   r   rr   r|   r[   rO   r   r   r   r   r   <module>   s   

	







8
"



0
=
%
(
!#