Ë
    šÓ^jŽ)  ã            	       óT  — 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mZ dedeeef   fd	„Zd
edededee   fd„Zdededee   fd„Zdedee   fd„Zddedee   dee   fd„Zdedefd„Zdedee   fd„Ze	deded   fd„«       Zdedefd„Zdedefd„Zy)a‘  Package and filesystem helpers for pyDeprecate's CLI.

Internal utilities that resolve a package's version, locate package directories, and manage ``sys.path`` for scanning.

Version resolution uses a local ``pyproject.toml`` (development checkout) when available, falling back to installed
distribution metadata via ``importlib.metadata``.

TOML parsing uses ``tomllib`` (stdlib on Python 3.11+) or ``tomli`` (backport, via ``pip install 'pyDeprecate[audit]'``
on Python 3.10). When not available the helpers return ``None`` and callers fall back to ``importlib.metadata``.

This module is private (no ``__all__``); its surface may change without notice.

é    N)Ú	Generator)Úcontextmanager)ÚPath)ÚAnyÚOptionalÚpathÚreturnc                 óÎ   — 	 	 ddl }t        | d«      5 }t	        |j                  |«      «      cddd«       S # t        $ r ddl}Y Œ?w xY w# 1 sw Y   yxY w# t        $ r i cY S w xY w)a  Load a TOML file using ``tomllib`` (Python 3.11+) or ``tomli`` (Python 3.10 backport).

    Returns an empty dict on any failure (missing library, parse error, IO).

    Examples:
        >>> import os, tempfile
        >>> with tempfile.NamedTemporaryFile(suffix=".toml", mode="w", delete=False) as f:
        ...     _ = f.write('[project]\nname = "mypkg"\nversion = "1.2.3"\n')
        ...     name = f.name
        >>> _load_toml(name).get("project", {}).get("version")
        '1.2.3'
        >>> os.unlink(name)

    r   NÚrb)ÚtomllibÚImportErrorÚtomliÚopenÚdictÚloadÚ	Exception)r   r   Úfhs      úY/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/deprecate/_pkg.pyÚ
_load_tomlr      so   € ð	ð	$Ûô �$˜Óð 	* Ü˜Ÿ™ RÓ(Ó)÷	*ñ 	*øô ò 	$Ý#ð	$ú÷	*ð 	*ûäò ØŠ	ðúsH   ƒ7 ‡A “A
­	A ·AÁA ÁAÁA Á
AÁA ÁA ÁA$Á#A$Úpkg_nameÚ	scan_pathÚpyproject_dirc                 ót  — t         j                  j                  |«      rt         j                  j                  |«      n;t         j                  j	                  t         j                  j                  |«      «      }t        t        j                  «      }g }|t         j                  j	                  |«      |t         j                  j                  |d«      fD ][  }|sŒt         j                  j                  |«      sŒ&||vsŒ+|j                  |«       t        j                  j                  d|«       Œ] 	 t        j                  | «      }t        |dd«      }t        |t        «      r|nd	 |t        j                  dd S # t        $ r Y |t        j                  dd yw xY w# |t        j                  dd w xY w)ax  Import *pkg_name* and return its ``__version__``, or ``None`` on any failure.

    Adds candidate import roots (scan dir, its parent, pyproject dir, ``src/``
    sub-dir) to ``sys.path`` before importing, then restores the original
    ``sys.path`` unconditionally via ``finally``.

    Args:
        pkg_name: Importable package name declared in ``[project].name``.
        scan_path: File-system path originally passed to the CLI (used to
            locate the package root).
        pyproject_dir: Directory containing the ``pyproject.toml`` file.

    Returns:
        Version string from ``pkg.__version__`` or ``None``.

    Úsrcr   Ú__version__N)Úosr   ÚisdirÚabspathÚdirnameÚlistÚsysÚjoinÚappendÚinsertÚ	importlibÚimport_moduleÚgetattrÚ
isinstanceÚstrr   )	r   r   r   Ú	scan_rootÚoriginalÚaddedÚrootÚmoduleÚversions	            r   Ú_version_from_dynamicr0   5   s:  € ô" /1¯g©g¯m©m¸IÔ.F”—‘—‘ 	Ô*ÌBÏGÉGÏOÉOÔ\^×\cÑ\c×\kÑ\kÐluÓ\vÓLw€IÜ”C—H‘H‹~€HØ€EØœBŸG™GŸO™O¨IÓ6¸ÄrÇwÁwÇ|Á|ÐTaÐchÓGiÐjò %ˆÚ”B—G‘G—M‘M $Õ'¨D¸Ò,=Ø�L‰L˜ÔÜ�H‰H�O‰O˜A˜tÕ$ð%ðÜ×(Ñ(¨Ó2ˆÜ˜& -°Ó6ˆÜ$ W¬cÔ2‰w¸Ð<ð Œ�‰‘‰øô ò ØàŒ�‰‘‰ðûð Œ�‰‘‰ús$   Ä65F  Æ 	FÆ	F" ÆFÆF" Æ"F7Ú	toml_pathc                 óL  — t        | «      }|j                  di «      }|sy|j                  d«      }t        |t        «      r|S d|j                  dg «      v rM|j                  d«      }t        |t        «      r,|r*t	        ||t
        j                  j                  | «      «      S y)a·  Extract ``[project].version`` from *toml_path*, or ``None``.

    Falls back to importing the package for ``dynamic = ["version"]`` projects.

    Args:
        toml_path: Absolute path to a ``pyproject.toml`` file.
        scan_path: Original file-system path passed to the CLI (forwarded to
            :func:`_version_from_dynamic` for import-root resolution).

    Returns:
        Version string or ``None`` when not resolvable.

    ÚprojectNr/   ÚdynamicÚname)r   Úgetr(   r)   r0   r   r   r   )r1   r   Údatar3   r/   r   s         r   Ú_version_from_tomlr8   W   s�   € ô �iÓ €DØ�h‰h�y "Ó%€GÙØà�k‰k˜)Ó$€GÜ�'œ3ÔØˆà�G—K‘K 	¨2Ó.Ñ.Ø—;‘;˜vÓ&ˆÜ�h¤Ô$©Ü(¨°9¼b¿g¹g¿o¹oÈiÓ>XÓYÐYàó    c                 óÐ  — t         j                  j                  | «      }t         j                  j                  |«      st         j                  j	                  |«      }t        d«      D ]{  }t         j                  j                  |d«      }t         j                  j                  |«      rt        || «      }|�|c S t         j                  j	                  |«      }||k(  r y|}Œ} y)u“  Return ``[project].version`` from the nearest ``pyproject.toml`` up to 2 levels above *path*.

    Searches the directory itself, its parent, and its grandparent â€” stops
    as soon as a resolvable version is found or the limit is reached.

    Args:
        path: File-system path to start the upward search from.

    Returns:
        Version string or ``None`` when not found within 2 levels.

    é   zpyproject.tomlN)	r   r   r   r   r   Úranger"   Úisfiler8   )r   Ú	candidateÚ_r1   r/   Úparents         r   Ú_read_pyproject_versionrA   v   s³   € ô —‘—‘ Ó%€IÜ�7‰7�=‰=˜Ô#Ü—G‘G—O‘O IÓ.ˆ	Ü�1‹Xò 	ˆÜ—G‘G—L‘L Ð,<Ó=ˆ	Ü�7‰7�>‰>˜)Ô$Ü(¨°DÓ9ˆGØÐ"Ø’Ü—‘—‘ Ó+ˆØ�YÒØàð ‰	ð	ð r9   Úmodule_namec                 ó‚   — |�t        |«      }|�|S 	 t        j                  j                  | «      S # t        $ r Y yw xY w)uò  Return the version for *module_name*, or ``None`` on any failure.

    Priority order:

    1. ``[project].version`` in the nearest ``pyproject.toml`` above *path* (reflects
       local development checkouts whose version may differ from the installed dist).
    2. ``importlib.metadata.version(module_name)`` â€” the installed distribution.

    Args:
        module_name: Importable package name whose installed version to look up.
        path: Optional file-system path used to locate a local ``pyproject.toml``.
            When provided, the local file takes precedence over installed metadata.

    Returns:
        Version string (e.g. ``"1.2.3"``) or ``None`` when the package is not
        installed or the version cannot be determined.

    N)rA   r%   Úmetadatar/   r   )rB   r   Ú	local_vers      r   Ú_auto_detect_versionrF   “   sN   € ð& ÐÜ+¨DÓ1ˆ	ØÐ ØÐðÜ×!Ñ!×)Ñ)¨+Ó6Ð6øÜò Ùðús   “2 ²	>½>Úpthc                 ó(   — | dz  j                  «       S )zSReturn True if *pth* is an importable package directory (contains ``__init__.py``).z__init__.py)Úexists)rG   s    r   Ú_is_package_dirrJ   °   s   € à�-Ñ×'Ñ'Ó)Ð)r9   c                 ó2  — | dz  }|j                  «       r>|j                  «       D �cg c]!  }|j                  «       sŒt        |«      sŒ |‘Œ# }}|r|S | j                  «       D �cg c]!  }|j                  «       sŒt        |«      sŒ |‘Œ# c}S c c}w c c}w )aÜ  Return package sub-directories of *pth*, checking ``src/`` when none found directly.

    Resolution order:
    1. Immediate child directories of ``pth/src/`` that contain ``__init__.py``
       (standard ``src/``-layout projects take precedence).
    2. If none, immediate child directories of *pth* that contain ``__init__.py``.

    Args:
        pth: Directory to search.

    Returns:
        List of :class:`~pathlib.Path` objects for each package directory found.

    r   )Úis_dirÚiterdirrJ   )rG   Úsrc_dirÚcÚin_srcs       r   Ú_find_child_packagesrQ   µ   s{   € ð �E‰k€GØ‡~�~ÔØ$Ÿ_™_Ó.ÖT˜°!·(±(µ*ÄÐQRÕAS’!ÐTˆÐTÙØˆMØ—{‘{“}ÖJ�!¨¯©­
´ÀqÕ7IŠAÒJÐJùò Uùò Ks"   ¨B¾BÁ
BÁ&BÁ<BÂB)NNNc              #   óÒ  K  — t        | «      j                  «       }t        t        j                  «      }|j                  «       r�t        |«      rt        |j                  «      }nO|dz  }|j                  «       xr  t        d„ |j                  «       D «       «      }|rt        |«      n
t        |«      }t        j                  j                  d|«       	 t        j                  «       5  t        j                  dt        d¬«       t        j                  dt         d¬«       d–— ddd«       |t        j                  dd y# 1 sw Y   ŒxY w# |t        j                  dd w xY w­w)aP  Context manager that prepends the import root to ``sys.path`` and restores it after scanning.

    For package directories (containing ``__init__.py``), inserts the parent directory so the package name resolves as
    an importable module. For plain directories, inserts the directory itself. Importable module name strings are passed
    through unchanged.

    Warning:
        Not thread-safe. ``sys.path`` is a process-global list; concurrent use from multiple threads will corrupt
        the restored state. Each scan should run in a dedicated process or be serialized via a lock.

    r   c              3   óV   K  — | ]!  }|j                  «       xr t        |«      –— Œ# y ­w©N)rL   rJ   ©Ú.0rO   s     r   ú	<genexpr>z$_managed_sys_path.<locals>.<genexpr>à   s$   è ø€ Ò-kÐTU¨a¯h©h«jÒ.O¼_ÈQÓ=OÓ.OÑ-kùs   ‚')r   Úignorezdeprecate.*)Úcategoryr.   N)r   Úresolver    r!   r   rL   rJ   r)   r@   ÚanyrM   r$   ÚwarningsÚcatch_warningsÚfilterwarningsÚDeprecationWarningÚFutureWarning)r   Úabs_pathr+   Úimport_rootrN   rP   s         r   Ú_managed_sys_pathrc   Ì   s  è ø€ ô ˜$“Z×'Ñ'Ó)€HÜ”C—H‘H‹~€HØ‡�ÔÜ˜8Ô$Ü˜hŸo™oÓ.‰Kà Ñ&ˆGØ—^‘^Ó%Òk¬#Ñ-kÐY`×YhÑYhÓYjÔ-kÓ*kˆFÙ*0œ#˜gœ,´c¸(³mˆKÜ�‰�‰˜˜;Ô'ðÜ×$Ñ$Ó&ñ 	Ü×#Ñ# HÔ7IÐR_Õ`Ü×#Ñ# H´}È]Õ[Û÷	ð
 Œ�‰‘‰÷	ð 	ûð
 Œ�‰‘‰üs6   ‚CE'ÃE Ã*=EÄ'E Ä/E'ÅEÅE ÅE$Å$E'c                 ó´  — t        | «      }|j                  «       rt        d| ›d�«      ‚|j                  «       r�t	        |«      r|j                  «       j                  S t        |«      }t        |«      dk(  r|d   j                  S t        |«      dkD  r3dj                  t        d„ |D «       «      «      }t        d| ›d|› d	�«      ‚t        d
| ›d�«      ‚| S )a›  Convert a filesystem path to an importable module name.

    Accepts a package directory (with ``__init__.py``) or an importable module
    name string. Plain directories and individual ``.py`` files are not supported
    because ``validate_deprecation_expiry`` and ``validate_deprecation_chains``
    require an importable module name, not a filesystem path.

    Args:
        path: Package directory path or importable module name string.

    Returns:
        Importable module name string.

    Raises:
        ValueError: If path is a plain directory without ``__init__.py``, a ``.py``
            file, or cannot be resolved to an importable module name.

    zFile paths are not supported: z@. Pass an importable module/package name or a directory instead.é   r   z, c              3   ó4   K  — | ]  }|j                   –— Œ y ­wrT   )r5   rU   s     r   rW   z'_resolve_module_name.<locals>.<genexpr>  s   è ø€ Ò$@° Q§V¥VÑ$@ùs   ‚z
Directory z contains multiple packages (z3). Pass the specific package sub-directory instead.zVPlain directories without '__init__.py' are not supported for expiry or chain checks: za. Use an importable package layout with '__init__.py', or pass an importable module name instead.)r   Úis_fileÚ
ValueErrorrL   rJ   rZ   r5   rQ   Úlenr"   Úsorted)r   rG   Ú
child_pkgsÚnamess       r   Ú_resolve_module_namerm   ì   sô   € ô& ˆt‹*€CØ
‡{�{„}ÜØ,¨T¨HÐ4tÐuó
ð 	
ð ‡z�z„|Ü˜3ÔØ—;‘;“=×%Ñ%Ð%ä)¨#Ó.ˆ
Üˆz‹?˜aÒØ˜a‘=×%Ñ%Ð%Üˆz‹?˜QÒØ—I‘IœfÑ$@°ZÔ$@Ó@ÓAˆEÜØ˜T˜HÐ$AÀ%Àð ICð Cóð ô ØdÐeiÐdlð mnð nó
ð 	
ð €Kr9   c                 ó<   — 	 t        | «      S # t        $ r | cY S w xY w)zLReturn the importable module name for *path*, falling back to *path* itself.)rm   rh   )r   s    r   Ú_safe_module_namero     s&   € ðÜ# DÓ)Ð)øÜò ØŠðús   ‚
 �šrT   )Ú__doc__r%   Úimportlib.metadatar   r!   r\   Úcollections.abcr   Ú
contextlibr   Úpathlibr   Útypingr   r   r)   r   r   r0   r8   rA   rF   ÚboolrJ   r    rQ   rc   rm   ro   © r9   r   ú<module>rx      s?  ðñó Û Û 	Û 
Û Ý %Ý %Ý ß  ð�Sð ˜T # s (™^ó ð6 Cð °Cð Èð ÐPXÐY\ÑP]ó ðD #ð °#ð ¸(À3¹-ó ð> #ð ¨(°3©-ó ñ: cð °¸#±ð È(ÐSVÉ-ó ð:*˜ð * $ó *ð
K˜dð K t¨D¡zó Kð. ð˜Cð  IÐ.>Ñ$?ò ó ðð>)˜sð ) só )ðX˜Cð  Cô r9   