
    X-Ph%                        U d Z ddlm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mZmZmZmZ ddlmZ  ee          Zd	ed
<    G d de          Z	 	 d)d*dZd+dZd,dZd-d Z G d! d"          Zd.d%Zd/d(ZdS )0z5Routines for finding the sources that mypy will check    )annotationsN)Sequence)Final)FileSystemCache)PYTHON_EXTENSIONSBuildSourcematches_excludematches_gitignore	mypy_path)Optionsr   PY_EXTENSIONSc                      e Zd ZdZdS )InvalidSourceListzDException indicating a problem in the list of sources given to mypy.N)__name__
__module____qualname____doc__     Q/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/mypy/find_sources.pyr   r      s        NNNNr   r   FpathsSequence[str]optionsr   fscacheFileSystemCache | Noneallow_empty_dirboolreturnlist[BuildSource]c           	        |pt                      }t          ||          }g }| D ]}t          j                            |          }|                    t                    r>|                    |          \  }}|                    t          ||d|                     z|
                    |          rB|                    |          }	|	s|st          d| d          |                    |	           |j        rt          j                            |          nd}
|                    t          ||
d                     |S )ztFrom a list of source files/directories, makes a list of BuildSources.

    Raises InvalidSourceList on errors.
    Nz(There are no .py[i] files in directory '')r   SourceFinderospathnormpathendswithr   crawl_upappendr   isdirfind_sources_in_dirr   extendscripts_are_modulesbasename)r   r   r   r   findersourcesr$   namebase_dirsub_sourcesmods              r   create_source_listr4      sH    ***G'7++FG 9 9w%%=='' 	9#__T22ND(NN;tT4BBCCCC]]4   	9 44T::K \ \'(ZSW(Z(Z(Z[[[NN;'''',3,GQ"'""4(((TCNN;tS$778888Nr   r0   strtuple[bool, int, str]c                    t           j                            |           \  }}t          t                    D ]\  }}||k    r|dk    ||fc S |dk    d| fS )zDetermines sort order for directory listing.

    The desirable properties are:
    1) foo < foo.pyi < foo.py
    2) __init__.py[i] < foo
    __init__)r#   r$   splitext	enumerater   )r0   basesuffixiexts        r   keyfuncr@   :   sp     7##D))LD&M** 1 13S==J&40000 JD))r   rootc                    | st           j        } t           j                            |           } |                     t           j                  r
| d d         } | S )Nr9   )r#   curdirr$   abspathr&   sep)rA   s    r   normalise_package_baserF   H   sL     y7??4  D}}RV CRCyKr   list[str] | Nonec                    | j         sdS t                      | j        z   t          j                    gz   }d |D             S )a  Returns explicit package bases to use if the option is enabled, or None if disabled.

    We currently use MYPYPATH and the current directory as the package bases. In the future,
    when --namespace-packages is the default could also use the values passed with the
    --package-root flag, see #9632.

    Values returned are normalised so we can use simple string comparisons in
    SourceFinder.is_explicit_package_base
    Nc                ,    g | ]}t          |          S r   )rF   ).0rA   s     r   
<listcomp>z.get_explicit_package_bases.<locals>.<listcomp>^   s!    ;;;T"4((;;;r   )explicit_package_basesr   r#   getcwd)r   rootss     r   get_explicit_package_basesrO   Q   sF     ) tKK'++ry{{m;E;;U;;;;r   c                  `    e Zd ZddZddZddZddZddZej	        dd            Z
ddZdS )r"   r   r   r   r   r   Nonec                    || _         t          |          | _        |j        | _        |j        | _        |j        | _        |j        | _        d S N)r   rO   rL   namespace_packagesexcludeexclude_gitignore	verbosity)selfr   r   s      r   r8   zSourceFinder.__init__b   sF    &@&I&I#")"<!(!: *r   r$   r5   r   c                @    | j         sJ t          |          | j         v S rS   )rL   rF   )rX   r$   s     r   is_explicit_package_basez%SourceFinder.is_explicit_package_basej   s'    ****%d++t/JJJr   r   c           	     X   g }t                      }t          | j                            |          t                    }|D ]g}|dv s|                    d          rt          j                            ||          }t          || j
        | j        | j        dk              rc| j        r t          || j        | j        dk              r| j                            |          rB|                     |          }|r*|                    |           |                    |           t          j                            |          \  }}	||vr[|	t&          v rR|                    |           |                     |          \  }
}|                    t-          ||
d |                     i|S )N)key)__pycache__zsite-packagesnode_modules.   )setsortedr   listdirr@   
startswithr#   r$   joinr	   rU   rW   rV   r
   r)   r*   addr+   r:   r   r'   r(   r   )rX   r$   r/   seennamesr0   subpathr2   stemr=   moduler1   s               r   r*   z SourceFinder.find_sources_in_dirn   s   t|++D11w??? 	Q 	QDGGG4??[^K_K_Ggll4..GwdlDNVWDWXX % *;t~':+ +  |!!'** 
Q"66w?? 0HHTNNNNN;///!w//55ft##-(?(?HHTNNN'+}}W'='=$FHNN;wh#O#OPPPr   tuple[str, str]c                   t           j                            |          }t           j                            |          \  }}t	          |          p|}|                     |          \  }}|dk    r||fS t          ||          }||fS )a^  Given a .py[i] filename, return module and base directory.

        For example, given "xxx/yyy/foo/bar.py", we might return something like:
        ("foo.bar", "xxx/yyy")

        If namespace packages is off, we crawl upwards until we find a directory without
        an __init__.py

        If namespace packages is on, we crawl upwards until the nearest explicit base directory.
        Failing that, we return one past the highest directory containing an __init__.py

        We won't crawl past directories with invalid package names.
        The base directory returned is an absolute path.
        r8   )r#   r$   rD   splitstrip_pycrawl_up_dirmodule_join)rX   r$   parentfilenamemodule_nameparent_moduler1   rk   s           r   r'   zSourceFinder.crawl_up   s     wt$$7==..x((4H"&"3"3F";";x*$$ (** ]K88xr   dirc                4    |                      |          pd|fS )N )_crawl_up_helper)rX   rv   s     r   rp   zSourceFinder.crawl_up_dir   s    $$S))6b#Y6r   tuple[str, str] | Nonec                $   | j         |                     |          rd|fS t          j                            |          \  }}|                    d          }|                     |          }|P|                                st          | d          | 	                    |          \  }}t          ||          |fS |r|r|                                sdS | j        sdS |                     |          }|dS |\  }}t          ||          |fS )a  Given a directory, maybe returns module and base directory.

        We return a non-None value if we were able to find something clearly intended as a base
        directory (as adjudicated by being an explicit base directory or by containing a package
        with __init__.py).

        This distinction is necessary for namespace packages, so that we know when to treat
        ourselves as a subpackage.
        Nrx   z-stubsz# is not a valid Python package name)rL   rZ   r#   r$   rn   removesuffixget_init_fileisidentifierr   rp   rq   rT   ry   )rX   rv   rr   r0   	init_file
mod_prefixr1   results           r   ry   zSourceFinder._crawl_up_helper   sG    &2t7T7TUX7Y7Y2s7Nw}}S))  ** &&s++	 $$&& V (4(T(T(TUUU#'#4#4V#<#< Jz400(::  	6 	):):)<)< 	4 & 	4 &&v..> 4  &
H:t,,h66r   
str | Nonec                    t           D ]g}t          j                            |d|z             }| j                            |          r|c S |dk    r| j                            |          r|c S hdS )zCheck whether a directory contains a file named __init__.py[i].

        If so, return the file's name (with dir prefixed).  If not, return None.

        This prefers .pyi over .py (because of the ordering of PY_EXTENSIONS).
        r8   z.pyN)r   r#   r$   re   r   isfileinit_under_package_root)rX   rv   r?   fs       r   r}   zSourceFinder.get_init_file   sz     ! 	 	CS*s"233A|""1%% e|| D DQ G G|tr   N)r   r   r   r   r   rQ   )r$   r5   r   r   )r$   r5   r   r   )r$   r5   r   rl   )rv   r5   r   rl   )rv   r5   r   rz   )rv   r5   r   r   )r   r   r   r8   rZ   r*   r'   rp   	functools	lru_cachery   r}   r   r   r   r"   r"   a   s        + + + +K K K K   @       :7 7 7 7 .7 .7 .7 .7`     r   r"   rr   childc                    | r| dz   |z   S |S )z8Join module ids, accounting for a possibly empty parent.r_   r   )rr   r   s     r   rq   rq      s     $|e##Lr   argr   c                x    t           D ]1}|                     |          r| dt          |                    c S 2dS )zVStrip a trailing .py or .pyi suffix.

    Return None if no such suffix is found.
    N)r   r&   len)r   r?   s     r   ro   ro      sN    
  $ $<< 	${#c(({####	$4r   )NF)
r   r   r   r   r   r   r   r   r   r   )r0   r5   r   r6   )rA   r5   r   r5   )r   r   r   rG   )rr   r5   r   r5   r   r5   )r   r5   r   r   )r   
__future__r   r   r#   collections.abcr   typingr   mypy.fscacher   mypy.modulefinderr   r   r	   r
   r   mypy.optionsr   tupler   __annotations__	Exceptionr   r4   r@   rF   rO   r"   rq   ro   r   r   r   <module>r      s   ; ; ; " " " " " "     				 $ $ $ $ $ $       ( ( ( ( ( (              !          u.// / / / /O O O O O	 O O O '+!	    >* * * *   < < < < K K K K K K K K\        r   