Ë
    r™ãjU,  ã                  ó  — 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	 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 dZdddddddœZ	 eZded<   	 i Zded<    ej*                  d«      ZdZ G d„ de	«      Z G d„ d«      Zy)a  Format of the call count file used by ``test/aaa_profiling/``.

``test/profiles.txt`` stores the expected function call counts asserted by
the profiling suite.  Each line is keyed to a "platform key" that encodes
the machine architecture, operating system, Python implementation and
version, the database / DBAPI in use, and whether or not the C extensions
were built:

.. sourcecode:: text

    test.aaa_profiling.test_orm.MergeTest.test_merge_load x86_64_linux_cpython_3.14_sqlite_pysqlite_dbapiunicode_cextensions 1234

The key covers anything that moves the counts, which includes compiled
code that isn't SQLAlchemy's own: a DBAPI that ships both a pure Python
and a C accelerated build carries a ``pydbapi`` / ``cdbapi`` token naming
which one was loaded, since the difference between them can be tens of
thousands of calls.

A call count is only asserted when the running environment matches a key
that's present in the file; otherwise the test is skipped.

Two different things read and write this file: :mod:`.testing.profiling`,
which records counts as the suite runs, and ``tools/profiles.py``, which
maintains the file from the outside.  Both use this module so that the
format is spelled out in exactly one place.

.. note::

    ``tools/profiles.py`` loads this module directly from the source tree,
    without importing the ``sqlalchemy`` package, so that the maintenance
    tooling and the noxfile that drives it work in an environment where
    SQLAlchemy itself isn't installed.  Keep the imports here to the
    standard library only.

é    )ÚannotationsN)ÚDict)ÚKeysView)ÚList)Ú
NamedTuple)ÚOptional)ÚSet)ÚTuple)Ú	TypeAlias)ÚUniona$  # SQLAlchemy call count profiles.
# This file is written out on a per-environment basis.
# For each test in aaa_profiling, the corresponding function and
# environment is located within this file.  If it doesn't exist,
# the test is skipped.
# If a callcount does exist, it is compared to what we received.
# assertions are raised if the counts do not match.
#
# To add a new callcount test, apply the function_call_count
# decorator and re-run the tests using the --write-profiles
# option - this file will be rewritten including the new count.
#
ÚsqliteÚ
postgresqlÚmysqlÚoracleÚmssql)r   r   r   Úmariadbr   r   r   ÚTestKeyzDict[PlatformKey, List[int]]Ú_EMPTY_COUNTSz^\d+\.\d+t?$Údbapiunicodec                  ó°   — e Zd ZU dZded<   	 ded<   	 ded<   	 ded<   	 ded<   	 ded<   	 d	ed
<   	 ded<   	 dd„Zedd„«       Zedd„«       Z	edd„«       Z
y)ÚPlatformKeyz8The environment half of a line in ``test/profiles.txt``.ÚstrÚmachineÚsystemÚimplementationÚpythonÚdialectÚdriverzTuple[str, ...]Údbapi_flagsÚboolÚcextensionsc                óä   — dj                  | j                  | j                  | j                  | j                  | j
                  | j                  g| j                  ¢t        ‘| j                  ‘«      S )NÚ_)
Újoinr   r   r   r   r   r   r   Ú_UNICODE_TOKENÚ
cext_token©Úselfs    úk/var/www/html/python-recuperauto-other/env/lib/python3.12/site-packages/sqlalchemy/testing/profiles_file.pyÚ__str__zPlatformKey.__str__‹   sl   € Ø�x‰xà—‘Ø—‘Ø×#Ñ#Ø—‘Ø—‘Ø—‘ð
ð ×!Ñ!ð
ô ð
ð —‘ð
ó
ð 	
ó    c                ó,  — |j                  d«      }|d   dvrt        d|›�«      ‚|j                  «       dk(  }|d   t        k7  rt        dt        › d|›�«      ‚|j                  «        t	        |«      D ]  \  }}t
        j                  |«      sŒ n t        d|›�«      ‚|d	k  st        |«      |d	z   k  rt        d
|›�«      ‚ | dj                  |d|dz
   «      ||dz
     ||dz
     ||   ||dz      ||dz      t        ||d	z   d «      |¬«      S )z•Parse a platform key string.

        Raises ``ValueError`` if the key isn't in the format written by
        :meth:`.PlatformKey.__str__`.

        r#   éÿÿÿÿ)r!   Únocextensionsz"unrecognized cextensions token in r!   zunrecognized z
 token in zno python version found in é   zcan't parse platform key Né   é   )r   r   r   r   r   r   r   r!   )
ÚsplitÚ
ValueErrorÚpopr%   Ú	enumerateÚ_PY_VERSIONÚmatchÚlenr$   Útuple)ÚclsÚkeyÚtokensr!   ÚidxÚtokens         r)   ÚparsezPlatformKey.parseš   sE  € ð —‘˜3“ˆà�"‰:Ð=Ñ=ÜÐAÀ#ÀÐIÓJÐJØ—j‘j“l mÑ3ˆà�"‰:œÒ'Ü˜}¬^Ð,<¸JÀsÀgÐNÓOÐOØ�
‰
Œä# FÓ+ò 	D‰JˆC�Ü× Ñ  Õ'Ùð	Dô Ð:¸3¸'ÐBÓCÐCà�Š7”c˜&“k C¨!¡GÒ+ÜÐ8¸¸Ð@ÓAÐAáØ—H‘H˜V I c¨A¡gÐ.Ó/Ø˜# ™'‘?Ø! #¨¡'™?Ø˜#‘;Ø˜3 ™7‘OØ˜# ™'‘?Ü˜f S¨1¡W YÐ/Ó0Ø#ô	
ð 		
r+   c                óV   — t         j                  | j                  | j                  «      S )z1the ``--db`` name that would regenerate this key.)ÚDB_TOKEN_TO_DATABASEÚgetr   r'   s    r)   ÚdatabasezPlatformKey.databaseÁ   s   € ô $×'Ñ'¨¯©°d·l±lÓCÐCr+   c                ó"   — | j                   rdS dS )Nr!   r.   )r!   r'   s    r)   r&   zPlatformKey.cext_tokenÇ   s   € à $× 0Ò 0ˆ}ÐE°oÐEr+   N)Úreturnr   )r;   r   rE   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r*   Úclassmethodr?   ÚpropertyrC   r&   © r+   r)   r   r   h   s’   … ÙBàƒLØKàƒKØ;àÓØLàƒKØLàƒLØEàƒKØ+à Ó ðð ÓØ7ó
ð ò$
ó ð$
ðL òDó ðDð
 òFó ñFr+   r   c                  óÄ   — e Zd ZU dZded<   ded<   	 ded<   	 dd„Zdd	„Zdd
„Zdd„Zdd„Z		 	 	 	 	 	 dd„Z
	 	 	 	 	 	 dd„Z	 	 	 	 	 	 dd„Zdd„Zdd„Zdd„Z	 	 	 	 	 	 dd„Zy) ÚProfilesFilea«  The parsed contents of ``test/profiles.txt``.

    The entries are reached through the accessors below rather than through
    the underlying dictionary; :meth:`.ProfilesFile.setdefault_counts` and
    :meth:`.ProfilesFile.counts_for` hand back the live list of call counts
    for a test on a platform, which the caller is free to mutate in place,
    and :meth:`.ProfilesFile.write` then serializes whatever is present.

    r   Úpathz+Dict[TestKey, Dict[PlatformKey, List[int]]]Ú_dataz&Dict[Tuple[TestKey, PlatformKey], int]Úlinenosc                óˆ   — t         j                  j                  |«      | _        i | _        i | _        | j                  «        y ©N)ÚosrP   ÚabspathrQ   rR   Úread)r(   rP   s     r)   Ú__init__zProfilesFile.__init__ß   s-   € Ü—G‘G—O‘O DÓ)ˆŒ	ØˆŒ
ØˆŒØ�	‰	�r+   c                óÆ  — | j                   j                  «        | j                  j                  «        	 t        | j                  «      }|5  t        |d«      D ]ª  \  }}|j                  «       }|r|j                  d«      rŒ*	 |j                  «       \  }}}t        j                  |«      }|j                  d«      D �cg c]  }t        |«      ‘Œ }	}|	| j                   j                  |i «      |<   || j                  ||f<   Œ¬ 	 ddd«       y# t
        $ r Y yw xY wc c}w # t        $ r&}
t        | j                  › d|› d|›d|
› �«      |
‚d}
~
ww xY w# 1 sw Y   yxY w)zöPopulate from the file, if it exists.

        Raises ``ValueError`` for a line that isn't in the format written
        by :meth:`.ProfilesFile.write`, including a platform key that
        :meth:`.PlatformKey.parse` doesn't recognize.

        Nr1   ú#ú,ú:z: can't parse z: )rQ   ÚclearrR   ÚopenrP   ÚOSErrorr5   ÚstripÚ
startswithr2   r   r?   Úintr3   Ú
setdefault)r(   Ú	profile_fÚlinenoÚlineÚtest_keyÚraw_keyÚcountsÚplatform_keyÚcountÚcall_countsÚves              r)   rW   zProfilesFile.readå   s[  € ð 	�
‰
×ÑÔØ�‰×ÑÔð	Ü˜TŸY™Y›ˆIð ñ 	>Ü )¨)°QÓ 7ò >‘�˜Ø—z‘z“|�Ù˜tŸ™¨sÔ3ØðØ04·
±
³Ñ-�H˜g vÜ#.×#4Ñ#4°WÓ#=�LØ;A¿<¹<ÈÓ;LÖ"M°%¤3 u¥:Ð"M�KÐ"Mð EP�—
‘
×%Ñ% h°Ó3°LÑAØ7=�—‘˜X |Ð3Ò4ñ>÷	>ð 	>øô ò 	Ùð	üò #NøÜ!ò Ü$ØŸ9™9˜+ Q v h¨n¸T¸HÀBÀrÀdÐKóàðûðú÷	>ð 	>úsS   ¶D Á7EÂ<D%ÃD ÃD%Ã2EÄ	DÄDÄ D%Ä%	EÄ.!EÅEÅEÅE c                ó–  — t        | j                  d«      5 }|j                  t        «       t	        | j
                  «      D ]p  }| j
                  |   }|j                  d|z  «       t	        |t        ¬«      D ]7  }dj                  d„ ||   D «       «      }|j                  |›d|›d|›d�«       Œ9 Œr 	 ddd«       y# 1 sw Y   yxY w)	z0Rewrite the file from what's currently recorded.Úwz
# TEST: %s

)r;   r[   c              3  ó2   K  — | ]  }t        |«      –— Œ y ­wrT   )r   )Ú.0rk   s     r)   ú	<genexpr>z%ProfilesFile.write.<locals>.<genexpr>  s   è ø€ ò &Ø',œ˜EŸ
ñ&ùó   ‚ú ú
N)r^   rP   ÚwriteÚHEADERÚsortedrQ   r   r$   )r(   rd   rg   Úper_fnrj   ri   s         r)   rv   zProfilesFile.write  s»   € ô �$—)‘)˜SÓ!ð 	 YØ�O‰OœFÔ#Ü" 4§:¡:Ó.ò 	�ØŸ™ HÑ-�Ø—‘Ð 2°XÑ =Ô>Ü$*¨6´sÔ$;ò �LØ ŸX™Xñ &Ø06°|Ñ0Dô&ó �Fð —O‘OÚ(0²,ÂÐGõñ	ñ	÷	÷ 	ñ 	ús   —BB?Â?Cc                ó6   — | j                   j                  «       S )z"All test keys present in the file.)rQ   Úkeysr'   s    r)   Ú	test_keyszProfilesFile.test_keys  s   € ð �z‰z�‰Ó Ð r+   c                ó^   — | j                   j                  |t        «      j                  «       S )z(The platform keys recorded for one test.)rQ   rB   r   r{   ©r(   rg   s     r)   Úplatforms_forzProfilesFile.platforms_for  s"   € ð �z‰z�~‰~˜h¬Ó6×;Ñ;Ó=Ð=r+   c                ó`   — | j                   j                  |t        «      j                  |«      S )zÍThe call counts recorded for a test on a platform, or ``None``.

        The list returned is the one stored here; mutating it in place
        updates what :meth:`.ProfilesFile.write` will emit.

        )rQ   rB   r   ©r(   rg   rj   s      r)   Ú
counts_forzProfilesFile.counts_for"  s$   € ð �z‰z�~‰~˜h¬Ó6×:Ñ:¸<ÓHÐHr+   c                óZ   — | j                   j                  |i «      j                  |g «      S )z€Like :meth:`.ProfilesFile.counts_for`, adding an empty entry for
        the test and platform if there isn't one yet.

        )rQ   rc   r�   s      r)   Úsetdefault_countszProfilesFile.setdefault_counts.  s(   € ð �z‰z×$Ñ$ X¨rÓ2×=Ñ=¸lÈBÓOÐOr+   c                ó„   — | j                   j                  |«      }|€y|j                  |d«       |s| j                   |= yy)zmDrop one test / platform entry.

        The test itself is dropped once its last platform is gone.

        N)rQ   rB   r4   )r(   rg   rj   ry   s       r)   Úremove_entryzProfilesFile.remove_entry8  s@   € ð —‘—‘ Ó)ˆØˆ>ØØ�
‰
�< Ô&ÙØ—
‘
˜8Ñ$ð r+   c                óL   — t        | j                  j                  |i «      «      S )z=Drop every entry for one test, returning how many there were.)r8   rQ   r4   r~   s     r)   Úremove_testzProfilesFile.remove_testH  s   € ô �4—:‘:—>‘> (¨BÓ/Ó0Ð0r+   c                óp   — | j                   j                  «       D ��ch c]  }|D ]  }|’Œ Œ c}}S c c}}w )z/All platform keys present anywhere in the file.)rQ   Úvalues)r(   ry   rj   s      r)   Úplatform_keyszProfilesFile.platform_keysM  sF   € ð
 Ÿ*™*×+Ñ+Ó-÷
àØ &ò
ð ò ð
Øó
ð 	
ùó 
s   ž2c                óV   — t        d„ | j                  j                  «       D «       «      S )zTotal number of recorded lines.c              3  ó2   K  — | ]  }t        |«      –— Œ y ­wrT   )r8   )rq   ry   s     r)   rr   z+ProfilesFile.entry_count.<locals>.<genexpr>Y  s   è ø€ ÒA 6”3�v—;ÑAùrs   )ÚsumrQ   rŠ   r'   s    r)   Úentry_countzProfilesFile.entry_countV  s"   € ô ÑA¨T¯Z©Z×->Ñ->Ó-@ÔAÓAÐAr+   c                ó<   — | j                   j                  ||f«      S rT   )rR   rB   r�   s      r)   Ú
lineno_forzProfilesFile.lineno_for[  s   € ð �|‰|×Ñ ¨<Ð 8Ó9Ð9r+   N)rP   zUnion[str, os.PathLike[str]])rE   ÚNone)rE   zKeysView[TestKey])rg   r   rE   zKeysView[PlatformKey])rg   r   rj   r   rE   zOptional[List[int]])rg   r   rj   r   rE   z	List[int])rg   r   rj   r   rE   r’   )rg   r   rE   rb   )rE   zSet[PlatformKey])rE   rb   )rg   r   rj   r   rE   zOptional[int])rF   rG   rH   rI   rJ   rX   rW   rv   r|   r   r‚   r„   r†   rˆ   r‹   r�   r‘   rM   r+   r)   rO   rO   Ì   sÆ   … ñð ƒIà6Ó6Ø2à3Ó3ØDóó!>óFó !ó
>ð

IØð
IØ/:ð
Ià	ó
IðPØðPØ/:ðPà	óPð%Øð%Ø/:ð%à	ó%ó 1ó

óBð
:Øð:Ø/:ð:à	ô:r+   rO   )rI   Ú
__future__r   rU   ÚreÚtypingr   r   r   r   r   r	   r
   r   r   rw   rA   r   r   rJ   r   Úcompiler6   r%   r   rO   rM   r+   r)   ú<module>r—      s©   ðò#õJ #ã 	Û 	Ý Ý Ý Ý Ý Ý Ý Ý Ý ð
€ð  ØØØØØñÐ ðð €ˆÓ ðð /1€Ð+Ó 0àˆb�j‰j˜Ó)€à€ôaF�*ô aF÷HR:ò R:r+   