U
    nËj.Ü  ã                   @  sd  d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ dd	l0m1Z1 dd
l2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZM ddlNmOZO ddlPmQZQ ddlRmSZT ddlUmVZV ddlWmXZX dZYdZZdZ[dZ\dZ]dZ^dZ_dZ`dZaddd d!d"d#hZbeXeTƒZcd$Zdd%ZSd&d'd(œd)d*„ZeG d+d,„ d,e6ƒZfG d-d.„ d.ƒZgd/d0d1œd2d3„ZhG d4d5„ d5ƒZiG d6d7„ d7ƒZjG d8d9„ d9ƒZkG d:d;„ d;ƒZled<d=d>ƒZmed?d@d>ƒZnedAdBd>ƒZoedCdDd>ƒZpedEdFd>ƒZqedEdGd>ƒZredEdHd>ƒZsd&dIdJdKdLœdMdN„Ztd&dOdJdKdPœdQdR„ZudOdJdKdSœdTdU„Zvd&dVdJdKdWœdXdY„ZwdOdJdKdSœdZd[„ZxdIdJdKdSœd\d]„Zydld_d`d&dad0dbdcdddKdeœ	dfdg„Zzd&dhdiœdjdk„Z{dS )mz^This module includes classes and functions designed specifically for use with the mypy plugin.é    )ÚannotationsN)ÚConfigParser)ÚAnyÚCallableÚIterator)Ú	ErrorCode)Úexpand_typeÚexpand_type_by_instance) Ú	ARG_NAMEDÚARG_NAMED_OPTÚARG_OPTÚARG_POSÚ	ARG_STAR2Ú	INVARIANTÚMDEFÚArgumentÚAssignmentStmtÚBlockÚCallExprÚClassDefÚContextÚ	DecoratorÚDictExprÚEllipsisExprÚ
ExpressionÚFuncDefÚIfStmtÚJsonDictÚ
MemberExprÚNameExprÚPassStmtÚPlaceholderNodeÚRefExprÚ	StatementÚStrExprÚSymbolTableNodeÚTempNodeÚ	TypeAliasÚTypeInfoÚVar)ÚOptions)ÚCheckerPluginInterfaceÚClassDefContextÚMethodContextÚPluginÚReportConfigContextÚSemanticAnalyzerPluginInterface)Údeserialize_and_fixup_type)Úset_callable_name)Úmake_wildcard_trigger)Ústate)Úmap_type_from_supertype)
ÚAnyTypeÚCallableTypeÚInstanceÚNoneTypeÚTypeÚ	TypeOfAnyÚTypeTypeÚTypeVarTypeÚ	UnionTypeÚget_proper_type)Úfill_typevars)Úget_unique_redefinition_name)Ú__version__)Ú_fields)Úparse_mypy_versionúpydantic-mypyzpydantic-mypy-metadatazpydantic.main.BaseModelz#pydantic_settings.main.BaseSettingszpydantic.root_model.RootModelz5pydantic._internal._model_construction.ModelMetaclasszpydantic.fields.Fieldzpydantic.dataclasses.dataclassz.pydantic.functional_validators.model_validatorz.pydantic.functional_validators.field_validatorz*pydantic.functional_serializers.serializerz0pydantic.functional_serializers.model_serializerz.pydantic.deprecated.class_validators.validatorz3pydantic.deprecated.class_validators.root_validatorÚbuiltinsé   Ústrztype[Plugin])ÚversionÚreturnc                 C  s   t S )a!  `version` is the mypy version string.

    We might want to use this to print a warning if the mypy version being used is
    newer, or especially older, than we expect (or need).

    Args:
        version: The mypy version string.

    Return:
        The Pydantic mypy plugin type.
    )ÚPydanticPlugin)rI   © rL   ú1/tmp/pip-unpacked-wheel-zvl9l234/pydantic/mypy.pyÚpluginj   s    rN   c                      sˆ   e Zd ZdZdddœ‡ fdd„Zddd	œd
d„Zddd	œdd„Zddd	œdd„Zdddœdd„Zdddœdd„Z	dddœdd„Z
‡  ZS )rK   zThe Pydantic mypy plugin.r*   ÚNone©ÚoptionsrJ   c                   s&   t |ƒ| _| j ¡ | _tƒ  |¡ d S ©N)ÚPydanticPluginConfigÚplugin_configÚto_dataÚ_plugin_dataÚsuperÚ__init__)ÚselfrQ   ©Ú	__class__rL   rM   rX   |   s    
zPydanticPlugin.__init__rH   z(Callable[[ClassDefContext], None] | None)ÚfullnamerJ   c                 C  s:   |   |¡}|r6t|jtƒr6tdd„ |jjD ƒƒr6| jS dS )zUpdate Pydantic model class.c                 s  s   | ]}|j tkV  qd S rR   ©r\   ÚBASEMODEL_FULLNAME©Ú.0ÚbaserL   rL   rM   Ú	<genexpr>†   s     z5PydanticPlugin.get_base_class_hook.<locals>.<genexpr>N)Úlookup_fully_qualifiedÚ
isinstanceÚnoder(   ÚanyÚmroÚ$_pydantic_model_class_maker_callback)rY   r\   ÚsymrL   rL   rM   Úget_base_class_hook�   s
    
z"PydanticPlugin.get_base_class_hookc                 C  s   |t kr| jS dS )z,Update Pydantic `ModelMetaclass` definition.N)ÚMODEL_METACLASS_FULLNAMEÚ)_pydantic_model_metaclass_marker_callback©rY   r\   rL   rL   rM   Úget_metaclass_hookŠ   s    z!PydanticPlugin.get_metaclass_hookz&Callable[[MethodContext], Type] | Nonec                 C  s   |  d¡rtS dS )z-Adjust return type of `from_orm` method call.z	.from_ormN)ÚendswithÚfrom_attributes_callbackrm   rL   rL   rM   Úget_method_hook�   s    
zPydanticPlugin.get_method_hookr/   údict[str, Any]©ÚctxrJ   c                 C  s   | j S )zjReturn all plugin config data.

        Used by mypy to determine if cache needs to be discarded.
        )rV   )rY   rt   rL   rL   rM   Úreport_config_data–   s    z!PydanticPlugin.report_config_datar,   c                 C  s"   t |j|j|j| jƒ}| ¡  d S rR   )ÚPydanticModelTransformerÚclsÚreasonÚapirT   Ú	transform)rY   rt   ZtransformerrL   rL   rM   rh   �   s    z3PydanticPlugin._pydantic_model_class_maker_callbackc                 C  s<   | j jrdS |jjj}|s"tdƒ‚t|jddƒr8d|j_dS )zÓReset dataclass_transform_spec attribute of ModelMetaclass.

        Let the plugin handle it. This behavior can be disabled
        if 'debug_dataclass_transform' is set to True', for testing purposes.
        Nz-callback not passed from 'get_metaclass_hook'Údataclass_transform_spec)	rT   Údebug_dataclass_transformrw   ÚinfoZdeclared_metaclassÚAssertionErrorÚgetattrÚtyper{   )rY   rt   Zinfo_metaclassrL   rL   rM   rl   ¡   s    
z8PydanticPlugin._pydantic_model_metaclass_marker_callback)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rX   rj   rn   rq   ru   rh   rl   Ú__classcell__rL   rL   rZ   rM   rK   y   s   	rK   c                   @  sT   e Zd ZU dZdZded< ded< ded< ded< dd	d
œdd„Zddœdd„ZdS )rS   aÛ  A Pydantic mypy plugin config holder.

    Attributes:
        init_forbid_extra: Whether to add a `**kwargs` at the end of the generated `__init__` signature.
        init_typed: Whether to annotate fields in the generated `__init__`.
        warn_required_dynamic_aliases: Whether to raise required dynamic aliases error.
        debug_dataclass_transform: Whether to not reset `dataclass_transform_spec` attribute
            of `ModelMetaclass` for testing purposes.
    )Úinit_forbid_extraÚ
init_typedÚwarn_required_dynamic_aliasesr|   Úboolr†   r‡   rˆ   r|   r*   rO   rP   c                 C  s°   |j d krd S t|j ƒ}|d k	rr| di ¡ di ¡}| jD ]4}| |d¡}t|tƒsbtd|› �ƒ‚t| ||ƒ q:n:tƒ }| 	|j ¡ | jD ] }|j
t|dd�}t| ||ƒ qŠd S )NZtoolrE   Fz/Configuration value must be a boolean for key: )Úfallback)Úconfig_fileÚ
parse_tomlÚgetÚ	__slots__rd   r‰   Ú
ValueErrorÚsetattrr   ÚreadÚ
getbooleanÚCONFIGFILE_KEY)rY   rQ   Ztoml_configÚconfigÚkeyZsettingrT   rL   rL   rM   rX   Å   s    




zPydanticPluginConfig.__init__rr   ©rJ   c                   s   ‡ fdd„ˆ j D ƒS )z/Returns a dict of config names to their values.c                   s   i | ]}|t ˆ |ƒ“qS rL   )r   )r`   r•   ©rY   rL   rM   Ú
<dictcomp>Ú   s      z0PydanticPluginConfig.to_data.<locals>.<dictcomp>)rŽ   r—   rL   r—   rM   rU   Ø   s    zPydanticPluginConfig.to_dataN)r�   r‚   rƒ   r„   rŽ   Ú__annotations__rX   rU   rL   rL   rL   rM   rS   ¯   s   

rS   r-   r:   rs   c                 C  sÜ   | j }t|tƒr|j}t|tƒr4t|jtƒr4|j}n<t|tƒrD|}n,d|› d|jj› d�}t	|| j
| jƒ | jS |j j t¡}|dkrŒ| jS tdd„ |j jD ƒƒs¨| jS | di ¡ d¡}|d	k	rÖt|j j| j
| jƒ | jS )
z1Raise an error if from_attributes is not enabled.z
ctx.type: ú
 (of type ú)Nc                 s  s   | ]}|j tkV  qd S rR   r]   r_   rL   rL   rM   rb   î   s     z+from_attributes_callback.<locals>.<genexpr>r”   Úfrom_attributesT)r€   rd   r<   Úitemr7   Zret_typer8   r[   r�   Úerror_unexpected_behaviorry   ÚcontextZdefault_return_typeÚmetadatar�   ÚMETADATA_KEYrf   rg   Úerror_from_attributesÚname)rt   Zctx_typeZ
model_typeÚdetailZpydantic_metadatarœ   rL   rL   rM   rp   Ý   s&    

rp   c                   @  s´   e Zd ZdZddddddddddd	œ
d
d„Zddddddddddœ	dd„Zd%dddddœdd„Zd&ddddddœdd„Zddœdd„Ze	dddd dœdd„ƒZ
ddd d!œd"d#„Zd$S )'ÚPydanticModelFieldz5Based on mypy.plugins.dataclasses.DataclassAttribute.rH   z
str | Noner‰   úbool | NoneÚintúType | Noner(   ©
r£   ÚaliasÚ	is_frozenÚhas_dynamic_aliasÚhas_defaultÚstrictÚlineÚcolumnr€   r}   c                 C  s@   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d S rR   r©   )rY   r£   rª   r«   r¬   r­   r®   r¯   r°   r€   r}   rL   rL   rM   rX   ú   s    zPydanticModelField.__init__r0   r   )	Úcurrent_infoÚtypedÚmodel_strictÚforce_optionalÚ	use_aliasry   Úforce_typevars_invariantÚis_root_model_rootrJ   c	                 C  sj   |   ||||¡}	| jdkr|n| j}
|s,|
r:|  ||¡}n
ttjƒ}t|	|d|rTtn|s^| jrbt	nt
d�S )zABased on mypy.plugins.dataclasses.DataclassAttribute.to_argument.N)ÚvariableÚtype_annotationZinitializerÚkind)Úto_varr®   r   r6   r;   Úexplicitr   r   r­   r   r
   )rY   r±   r²   r³   r´   rµ   ry   r¶   r·   r¸   r®   r¹   rL   rL   rM   Úto_argument  s    
ÿúzPydanticModelField.to_argumentF)r±   ry   r¶   rJ   c              
   C  s°   |r&t | jtƒr&| j ¡ }t|_|| _| jdk	rª| jjdk	rªt 	|j
j¡�Z t|ƒ}t |tƒsbt‚|r‚|jD ]}t |tƒrlt|_qlt| j| jjj|iƒW  5 Q R £ S Q R X | jS )zABased on mypy.plugins.dataclasses.DataclassAttribute.expand_type.N)rd   r€   r=   Zcopy_modifiedr   Zvariancer}   Ú	self_typer4   Ústrict_optional_setrQ   Ústrict_optionalr@   r8   r~   Úargsr   Úid)rY   r±   ry   r¶   Zmodified_typeZfilled_with_typevarsÚargrL   rL   rM   r   /  s    


(zPydanticModelField.expand_typer)   )r±   ry   rµ   r¶   rJ   c                 C  s0   |r| j dk	r| j }n| j}t||  |||¡ƒS )z<Based on mypy.plugins.dataclasses.DataclassAttribute.to_var.N)rª   r£   r)   r   )rY   r±   ry   rµ   r¶   r£   rL   rL   rM   r»   M  s    zPydanticModelField.to_varr   r–   c              
   C  s8   | j s
t‚| j| j| j| j| j| j| j| j	| j  
¡ dœ	S )ú?Based on mypy.plugins.dataclasses.DataclassAttribute.serialize.)	r£   rª   r«   r¬   r­   r®   r¯   r°   r€   )r€   r~   r£   rª   r«   r¬   r­   r®   r¯   r°   Ú	serializer—   rL   rL   rM   rÅ   \  s    
÷zPydanticModelField.serialize)r}   Údatary   rJ   c                 C  s,   |  ¡ }t| d¡|ƒ}| f ||dœ|—ŽS )úABased on mypy.plugins.dataclasses.DataclassAttribute.deserialize.r€   )r€   r}   )Úcopyr1   Úpop)rw   r}   rÆ   ry   ÚtyprL   rL   rM   Údeserializek  s    zPydanticModelField.deserializerO   )Úsub_typery   rJ   c              	   C  s:   | j dk	r6t |jj¡� t| j || jƒ| _ W 5 Q R X dS )zxExpands type vars in the context of a subtype when an attribute is inherited
        from a generic super type.
        N)r€   r4   r¿   rQ   rÀ   r5   r}   )rY   rÌ   ry   rL   rL   rM   Úexpand_typevar_from_subtyper  s    
z.PydanticModelField.expand_typevar_from_subtypeN)F)F)r�   r‚   rƒ   r„   rX   r½   r   r»   rÅ   ÚclassmethodrË   rÍ   rL   rL   rL   rM   r¥   ÷   s     ÿ# ûr¥   c                   @  s:   e Zd ZdZdd„ Zedd dœdd„ƒZddœd	d
„ZdS )ÚPydanticModelClassVarz•Based on mypy.plugins.dataclasses.DataclassAttribute.

    ClassVars are ignored by subclasses.

    Attributes:
        name: the ClassVar name
    c                 C  s
   || _ d S rR   ©r£   )rY   r£   rL   rL   rM   rX   „  s    zPydanticModelClassVar.__init__r   )rÆ   rJ   c                 C  s   |  ¡ }| f |ŽS )rÇ   )rÈ   )rw   rÆ   rL   rL   rM   rË   ‡  s    z!PydanticModelClassVar.deserializer–   c                 C  s
   d| j iS )rÄ   r£   rÐ   r—   rL   rL   rM   rÅ   �  s     ÿzPydanticModelClassVar.serializeN)r�   r‚   rƒ   r„   rX   rÎ   rË   rÅ   rL   rL   rL   rM   rÏ   {  s
   rÏ   c                   @  s²  e Zd ZU dZddddddhZded	< d
dddddœdd„Zddœdd„Zddœdd„Zddœdd„Z	ddddœdd„Z
dd d!œd"d#„Zd$d d%œd&d'„Zd(dd)d*d+œd,d-„Zd.d/d0d1d2œd3d4„Zd5ddddd6œd7d8„Zd5ddddd6œd9d:„Zd5dddd;œd<d=„ZdYd/d?dd@dAœdBdC„Zed(dd!œdDdE„ƒZed(dFd!œdGdH„ƒZed(dId!œdJdK„ƒZed(dd!œdLdM„ƒZdZd5ddddddddNdOœ	dPdQ„Zd5dddRœdSdT„Zed5dddUœdVdW„ƒZdXS )[rv   z¸Transform the BaseModel subclass according to the plugin settings.

    Attributes:
        tracked_config_fields: A set of field configs that the plugin has to track their value.
    ÚextraÚfrozenrœ   Úpopulate_by_nameÚalias_generatorr®   zset[str]Útracked_config_fieldsr   zExpression | Statementr0   rS   rO   )rw   rx   ry   rT   rJ   c                 C  s   || _ || _|| _|| _d S rR   )Ú_clsZ_reasonÚ_apirT   )rY   rw   rx   ry   rT   rL   rL   rM   rX   ¤  s    z!PydanticModelTransformer.__init__r‰   r–   c                 C  sô   | j j}tdd„ |jdd… D ƒƒ}|  ¡ }|  ||¡\}}|dksL|dkrPdS |D ]}|jdkrT dS qTtdd„ |jdd… D ƒƒ}|  ||||¡ |  ||||¡ | j	|| j
|jdkd� |  ¡  d	d
„ |D ƒdd
„ |D ƒ| ¡ dœ|jt< dS )a†  Configures the BaseModel subclass according to the plugin settings.

        In particular:

        * determines the model config and fields,
        * adds a fields-aware signature for the initializer and construct methods
        * freezes the class if frozen = True
        * stores the fields, config, and if the class is settings in the mypy metadata for access by subclasses
        c                 s  s   | ]}t |jkV  qd S rR   )ÚROOT_MODEL_FULLNAMEr\   r_   rL   rL   rM   rb   ¼  s     z5PydanticModelTransformer.transform.<locals>.<genexpr>NéÿÿÿÿFc                 s  s   | ]}|j tkV  qd S rR   )r\   ÚBASESETTINGS_FULLNAMEr_   rL   rL   rM   rb   Æ  s     T)rÒ   c                 S  s   i | ]}|j | ¡ “qS rL   ©r£   rÅ   ©r`   ÚfieldrL   rL   rM   r˜   Î  s      z6PydanticModelTransformer.transform.<locals>.<dictcomp>c                 S  s   i | ]}|j | ¡ “qS rL   rÛ   )r`   Z	class_varrL   rL   rM   r˜   Ï  s      )ÚfieldsÚ
class_varsr”   )rÖ   r}   rf   rg   Úcollect_configÚcollect_fields_and_class_varsr€   Úadd_initializerÚadd_model_construct_methodÚ
set_frozenr×   rÒ   Úadjust_decorator_signaturesÚget_values_dictr    r¡   )rY   r}   Úis_root_modelr”   rÞ   rß   rÝ   Úis_settingsrL   rL   rM   rz   ±  s&    

ýz"PydanticModelTransformer.transformc                   s„   | j jj ¡ D ]p}t|jtƒr|jjd ‰ tˆ tƒrtˆ j	t
ƒrˆ j	jtkrˆ j	jtkrtt‡ fdd„tˆ jƒD ƒƒsd|jj_qdS )a¿  When we decorate a function `f` with `pydantic.validator(...)`, `pydantic.field_validator`
        or `pydantic.serializer(...)`, mypy sees `f` as a regular method taking a `self` instance,
        even though pydantic internally wraps `f` with `classmethod` if necessary.

        Teach mypy this by marking any function whose outermost decorator is a `validator()`,
        `field_validator()` or `serializer()` call as a `classmethod`.
        r   c                 3  s4   | ],\}}ˆ j | d ko*t|tƒo*|jdkV  qdS )ÚmodeÚafterN)Ú	arg_namesrd   r$   Úvalue)r`   ÚirÃ   ©Z	first_decrL   rM   rb   ç  s   ÿzGPydanticModelTransformer.adjust_decorator_signatures.<locals>.<genexpr>TN)rÖ   r}   ÚnamesÚvaluesrd   re   r   Zoriginal_decoratorsr   Úcalleer   r\   ÚDECORATOR_FULLNAMESÚMODEL_VALIDATOR_FULLNAMErf   Ú	enumeraterÁ   ÚfuncÚis_class)rY   ri   rL   rî   rM   rå   Õ  s     ÿ
þ
ý
úþùz4PydanticModelTransformer.adjust_decorator_signaturesÚModelConfigDatac              	   C  sL  | j }tƒ }d}d}|j ¡ D ]&\}}|  ||¡}|rd}| |¡ qd}|jjD �]V}t|t	t
fƒshqRt|t	ƒ�r"|jd }	t|	tƒrR|	jdkr”qRt|jtƒrÞt|jj|jjƒD ](\}
}|
dkrÄq²| | j|
|dd�¡ q²nBt|jtƒ�rŒ|jjD ]*\}}t|tƒ�s
qô| |  |j|¡¡ qônjt|t
ƒ�rŒ|jdk�r<qR|jjD ]F}t|t	ƒ�sX�qD|jd }	t|	tƒ�sr�qD| |  |	j|j¡¡ �qD|�r¦| j d|¡  �q¬d}qR|�s¸|�rä|�rä|j�rä|j�sä| jj�rät| j|ƒ |jjd	d… D ]R}t|j k�r�qô| j !t"|j#ƒ¡ |j t d
  ¡ D ]\}}| $||¡ �q,�qô|S )zhCollects the values of the config attributes that are used by the plugin, accounting for parent classes.FTNr   Úmodel_config)Ú	lax_extraZConfigzYSpecifying config in two places is ambiguous, use either Config attribute or class kwargsé   r”   )%rÖ   r÷   ÚkeywordsÚitemsÚget_config_updateÚupdateÚdefsÚbodyrd   r   r   Úlvaluesr   r£   Úrvaluer   Úziprë   rÁ   r   r$   rì   r×   ÚfailÚhas_alias_generatorrÓ   rT   rˆ   Úerror_required_dynamic_aliasesr}   rg   r¡   r    Úadd_plugin_dependencyr3   r\   Ú
setdefault)rY   rw   r”   Zhas_config_kwargsZhas_config_from_namespacer£   ÚexprZconfig_dataÚstmtÚlhsÚarg_namerÃ   Zkey_exprZ
value_exprZsubstmtr}   rì   rL   rL   rM   rà   ð  sz    

þÿþýüz'PydanticModelTransformer.collect_configzJtuple[list[PydanticModelField] | None, list[PydanticModelClassVar] | None])rø   rç   rJ   c                 C  s¼  | j }i }i }t|jjdd… ƒD ]Ä}t|jkr2q"| j t|j	ƒ¡ |jt d  
¡ D ]d\}}t ||| j¡}	|	 |j| j¡ |	||< |jj |¡}
|
rV|
jrVt|
jtƒsV| j d|
j¡ qV|jt d  
¡ D ]\}}t |¡||< qÎq"tƒ }tƒ }|  |j¡D ]¢}|  |||¡}|dk�r �q |jd }t|tƒ�s:t‚t|tƒ�r~|�rf|jdk�rft| j|ƒ n| |j¡ |||j< n"t|tƒ�r | |j¡ |||j< �q t|  ¡ ƒt|  ¡ ƒfS )	zACollects the fields for the model, accounting for parent classes.rú   rÙ   rÞ   z7BaseModel field may only be overridden by another fieldrß   Nr   Úroot)!rÖ   Úreversedr}   rg   r¡   r    r×   r  r3   r\   rü   r¥   rË   rÍ   rï   r�   re   rd   r)   r  rÏ   ÚsetÚ%_get_assignment_statements_from_blockrÿ   Ú$collect_field_or_class_var_from_stmtr  r   r~   r£   Ú error_extra_fields_on_root_modelÚaddÚlistrð   )rY   rø   rç   rw   Zfound_fieldsZfound_class_varsr}   r£   rÆ   rÝ   Úsym_nodeZcurrent_field_namesZcurrent_class_vars_namesr
  Zmaybe_fieldr  rL   rL   rM   rá   <  sH    
þ

z6PydanticModelTransformer.collect_fields_and_class_varsr   zIterator[AssignmentStmt])r
  rJ   c                 c  sJ   |j D ]}|js|  |¡E d H  q|jd k	rF|jjsF|  |j¡E d H  d S rR   )r   Zis_unreachabler  Z	else_body)rY   r
  r   rL   rL   rM   Ú,_get_assignment_statements_from_if_statement€  s
    
zEPydanticModelTransformer._get_assignment_statements_from_if_statementr   )ÚblockrJ   c                 c  s<   |j D ]0}t|tƒr|V  qt|tƒr|  |¡E d H  qd S rR   )r   rd   r   r   r  )rY   r  r
  rL   rL   rM   r  ‡  s
    


z>PydanticModelTransformer._get_assignment_statements_from_blockr   z dict[str, PydanticModelClassVar]z1PydanticModelField | PydanticModelClassVar | None)r
  rø   rß   rJ   c                 C  sD  | j }|jd }t|tƒr0t |j¡r0|jdkr4dS |js–t|jt	ƒrxt|jj
t	ƒrxt|jj
j
tƒrx|jj
j
jtkrxdS |j|kr†dS t| j|ƒ dS |jd }t|tƒs®dS t |j¡rÄ|jdkrÈdS |jj |j¡}|dkrädS |j}t|tƒrødS t|tƒ�r| j d|¡ dS t|tƒ�s&dS |j�r8t|jƒS t|jƒ}t|tƒ�rj|jjdk�rj| j d|¡ |  |¡}	|  |¡}
|jdk�rÔ|j�rÔ|j�rÔ| jj |jdd�}|�rº||_n| j d	|¡ t!t"j#ƒ|_|  $|¡\}}|�r|j%�s| j&j'�rt(| j|ƒ |  )|¡}|  *||j|¡}t+|j||	|
|||j,|j-||jd
�
S )a^  Get pydantic model field from statement.

        Args:
            stmt: The statement.
            model_config: Configuration settings for the model.
            class_vars: ClassVars already known to be defined on the model.

        Returns:
            A pydantic model field if it could find the field in statement. Otherwise, `None`.
        r   rø   NzFType aliases inside BaseModel definitions are not supported at runtimezdataclasses.InitVarz%InitVar is not supported in BaseModelT)Úis_finalzGNeed type argument for Final[...] with non-literal default in BaseModel)
r£   r¬   r­   r®   rª   r«   r¯   r°   r€   r}   ).rÖ   r  rd   r   rC   Zis_valid_field_namer£   Z
new_syntaxr  r   rñ   r\   rò   Úerror_untyped_fieldsr×   r}   rï   r�   re   r!   r'   r  r)   Zis_classvarrÏ   r?   r€   r8   Úget_has_defaultÚ
get_strictr  Zis_inferredZanalyze_simple_literal_typer6   r;   Z
from_errorÚget_alias_inforÓ   rT   rˆ   r  Úis_field_frozenÚ_infer_dataclass_attr_init_typer¥   r¯   r°   )rY   r
  rø   rß   rw   r  ri   re   Z	node_typer­   r®   rÊ   rª   r¬   r«   Z	init_typerL   rL   rM   r  Ž  s’    
 
ÿþýü	



þ

þ

þ
öz=PydanticModelTransformer.collect_field_or_class_var_from_stmtr%   rH   r   r¨   )ri   r£   rŸ   rJ   c           	      C  sâ   |j }|jr|S t|j ƒ}t|tƒs(|S |j  d¡}|rÞt|jtƒrÄ|j  d¡}|sXt	‚|j rttt
|j |j |ƒƒ}n
ttjƒS t|tƒr¨|jtttgkr¨t|jd |ƒS | j d|j j› d�|¡ n| j d|j j› d�|¡ |S )zvInfer __init__ argument type for an attribute.

        In particular, possibly use the signature of __set__.
        Ú__set__rG   z(Unsupported signature for "__set__" in "ú"zUnsupported "__set__" in ")r€   Zimplicitr?   rd   r8   r�   re   r   Zget_containing_type_infor~   r5   r6   r;   Zunannotatedr7   Ú	arg_kindsr   r	   Ú	arg_typesr×   r  r£   )	rY   ri   r£   rŸ   ÚdefaultÚtÚsetterZ
super_infoZsetter_typerL   rL   rM   r    s.    


ýz8PydanticModelTransformer._infer_dataclass_attr_init_typezlist[PydanticModelField])rÞ   r”   rè   rç   rJ   c              
   C  sŒ  d| j jjkr"| j jjd js"dS | jj}t|jƒ}|jdk	}t|j	oL|j ƒ}| j
|||||||dd�}	|�r@| j t¡j}
t|
tƒsŒt‚d|
jk�r@|
jd j}t|tƒs²t‚|dk	�r@|jdk	�r@|j}t|tƒsÜt‚t|jƒD ]X\}}|dksæ| d¡sæ| d¡�sqæ| j |j| ¡}t||ƒ}|	 t||dtƒ¡ qæ|  ||¡�sptdƒ}|	 t|tt j!ƒdt"ƒ¡ t#| j| j d|	t$ƒ d� dS )	z§Adds a fields-aware `__init__` method to the class.

        The added `__init__` will be annotated with types vs. all `Any` depending on the plugin settings.
        rX   NT)r²   r³   Úrequires_dynamic_aliasesrµ   rè   rç   r¶   Ú__Ú_Úkwargs)rÁ   Úreturn_type)%rÖ   r}   rï   Úplugin_generatedrT   r‡   r‰   r®   rÓ   r  Úget_field_argumentsr×   rc   rÚ   re   rd   r(   r~   r   r€   r7   rô   rë   Ú
startswithZ	anal_typer"  r)   Úappendr   r   Úshould_init_forbid_extrar6   r;   r¼   r   Ú
add_methodr9   )rY   rÞ   r”   rè   rç   r²   r³   rµ   r&  rÁ   Zbase_settings_nodeZbase_settings_init_nodeZ	func_typeZarg_idxr  Zanalyzed_variable_typer¸   ÚvarrL   rL   rM   râ   5  sF    

ø
z(PydanticModelTransformer.add_initializerc           
   
   C  sê   | j  t› d�| j  t› d�¡g¡}t|tƒ gƒ}ttd|ƒ|dtƒ}t 	| j j
j¡�$ | j|dt|jƒdd||d�}W 5 Q R X |  ||¡s®tdƒ}	| t|	ttjƒdtƒ¡ |r¼||g n|g| }t| j | jd	|t| jjƒdd
� dS )zäAdds a fully typed `model_construct` classmethod to the class.

        Similar to the fields-aware __init__ method, but always uses the field names (not aliases),
        and does not treat settings fields as optional.
        z.setz.strZ_fields_setNTF)r²   r³   r&  rµ   rè   rç   r)  Zmodel_construct)rÁ   r*  Úis_classmethod)r×   Ú
named_typeÚBUILTINS_NAMEr>   r9   r   r)   r   r4   r¿   rQ   rÀ   r,  r‰   r®   r/  r.  r6   r;   r¼   r   r0  rÖ   r@   r}   )
rY   rÞ   r”   rè   rç   Zset_strZoptional_set_strZfields_set_argumentrÁ   r1  rL   rL   rM   rã   d  s2    $ù	
úz3PydanticModelTransformer.add_model_construct_method)rÞ   ry   rÒ   rJ   c           
   	   C  sø   | j j}|D ]æ}|j |j¡}|dk	r²|j}t|tƒrD|p>|j|_	qòt|t
ƒrb| jjsb| j ¡  qòzt|ƒ}W n tk
rŠ   t|ƒ}Y nX d|› d|j› d�}	t|	| j| j ƒ q|j||dd�}||_||_	|jd |j |_tt|ƒ|j|j< qdS )z§Marks all fields as properties so that attempts to set them trigger mypy errors.

        This is the same approach used by the attrs and dataclasses plugins.
        Nzsym_node.node: rš   r›   F)rµ   Ú.)rÖ   r}   rï   r�   r£   re   rd   r)   r«   Zis_propertyr!   r×   Zfinal_iterationÚdeferrH   Ú	TypeErrorÚreprr[   rž   r»   r\   Ú	_fullnamer%   r   )
rY   rÞ   ry   rÒ   r}   rÝ   r  r1  Zvar_strr¤   rL   rL   rM   rä   Œ  s(    
z#PydanticModelTransformer.set_frozenFr   úModelConfigData | None)r£   rÃ   rù   rJ   c                 C  sÊ   || j krdS |dkrbt|tƒr,|jdk}n,t|tƒrB|jdk}n|sTt|| j|ƒ dS t|d�S |dkr�d}t|t	ƒr†|j
dkr†d}t|d	�S t|t	ƒr¸|j
d
kr¸tf ||j
dkiŽS t|| j|ƒ dS )zÐDetermines the config update due to a single kwarg in the ConfigDict definition.

        Warns if a tracked config attribute is set to a value the plugin doesn't know how to interpret (e.g., an int)
        NrÑ   Zforbid)Úforbid_extrarÔ   Túbuiltins.NoneF)r  )úbuiltins.Trueúbuiltins.Falser=  )rÕ   rd   r$   rì   r   r£   Úerror_invalid_config_valuer×   r÷   r   r\   )rY   r£   rÃ   rù   r;  r  rL   rL   rM   rý   «  s(    


	

z*PydanticModelTransformer.get_config_updatec                 C  sž   | j }t|tƒrdS t|tƒr’t|jtƒr’|jjtkr’t|j	|j
ƒD ]H\}}|dks\|dkrj|jtk	  S |dkrDt|tƒo„|jdk   S qDdS t|tƒ S )zUReturns a boolean indicating whether the field defined in `stmt` is a required field.FNr#  Údefault_factoryr<  )r  rd   r&   r   rñ   r"   r\   ÚFIELD_FULLNAMEr  rÁ   rë   r[   r   r   ©r
  r	  rÃ   r£   rL   rL   rM   r  Î  s    
"z(PydanticModelTransformer.get_has_defaultr¦   c                 C  s|   | j }t|tƒrxt|jtƒrx|jjtkrxt|j|j	ƒD ]@\}}|dkrHq6t|t
ƒrr|jdkrb dS |jdkrr dS  dS dS )zEReturns a the `strict` value of a field if defined, otherwise `None`.r®   r=  Tr>  FN)r  rd   r   rñ   r"   r\   rA  r  rÁ   rë   r   rB  rL   rL   rM   r  ä  s    "


z#PydanticModelTransformer.get_strictztuple[str | None, bool]c                 C  s„   | j }t|tƒrdS t|tƒr6t|jtƒr6|jjtks:dS t|j	ƒD ]:\}}|dkrVqD|j
| }t|tƒrx|jdf  S  dS qDdS )a  Returns a pair (alias, has_dynamic_alias), extracted from the declaration of the field defined in `stmt`.

        `has_dynamic_alias` is True if and only if an alias is provided, but not as a string literal.
        If `has_dynamic_alias` is True, `alias` will be None.
        )NFrª   F)NT)r  rd   r&   r   rñ   r"   r\   rA  rô   rë   rÁ   r$   rì   ©r
  r	  rí   r  rÃ   rL   rL   rM   r  ô  s$    
ÿ
ÿ
ÿ

z'PydanticModelTransformer.get_alias_infoc                 C  s|   | j }t|tƒrdS t|tƒr6t|jtƒr6|jjtks:dS t|j	ƒD ]2\}}|dkrD|j
| }t|tƒop|jdk  S qDdS )al  Returns whether the field is frozen, extracted from the declaration of the field defined in `stmt`.

        Note that this is only whether the field was declared to be frozen in a `<field_name> = Field(frozen=True)`
        sense; this does not determine whether the field is frozen because the entire model is frozen; that is
        handled separately.
        FrÒ   r=  )r  rd   r&   r   rñ   r"   r\   rA  rô   rë   rÁ   r   rC  rL   rL   rM   r    s    
ÿ
ÿ
ÿ
z(PydanticModelTransformer.is_field_frozenúlist[Argument])	rÞ   r²   r³   rµ   r&  rè   rç   r¶   rJ   c	           
   	     s.   ˆj j‰‡ ‡‡‡‡‡‡‡‡f	dd„|D ƒ}	|	S )zÈHelper function used during the construction of the `__init__` and `model_construct` method signatures.

        Returns a list of mypy Argument instances for use in the generated signatures.
        c                   s@   g | ]8}ˆr|j s|jˆˆˆˆp"ˆˆˆjˆ ˆo6|jd kd�‘qS )r  )r²   r³   r´   rµ   ry   r¶   r·   )r¬   r½   r×   r£   rÜ   ©	r¶   r}   rç   rè   r³   r&  rY   r²   rµ   rL   rM   Ú
<listcomp>9  s    õøz@PydanticModelTransformer.get_field_arguments.<locals>.<listcomp>)rÖ   r}   )
rY   rÞ   r²   r³   rµ   r&  rè   rç   r¶   Ú	argumentsrL   rE  rM   r,  )  s
    õz,PydanticModelTransformer.get_field_arguments)rÞ   r”   rJ   c                 C  s.   |j s|  |t|jƒ¡rdS |jr&dS | jjS )a@  Indicates whether the generated `__init__` should get a `**kwargs` at the end of its signature.

        We disallow arbitrary kwargs if the extra config setting is "forbid", or if the plugin config says to,
        *unless* a required dynamic alias is present (since then we can't determine a valid signature).
        FT)rÓ   Úis_dynamic_alias_presentr‰   r  r;  rT   r†   )rY   rÞ   r”   rL   rL   rM   r/  I  s    z1PydanticModelTransformer.should_init_forbid_extra)rÞ   r  rJ   c                 C  s8   | D ]}|j r dS q|r4| D ]}|jdkr dS qdS )z‘Returns whether any fields on the model have a "dynamic alias", i.e., an alias that cannot be
        determined during static analysis.
        TNF)r¬   rª   )rÞ   r  rÝ   rL   rL   rM   rH  V  s    
z1PydanticModelTransformer.is_dynamic_alias_presentN)F)F)r�   r‚   rƒ   r„   rÕ   r™   rX   rz   rå   rà   rá   r  r  r  r  râ   rã   rä   rý   Ústaticmethodr  r  r  r  r,  r/  rH  rL   rL   rL   rM   rv   ”  sF   
ú	$LD &/(#! ÷  rv   c                   @  sZ   e Zd ZdZddddddddœdd„Zddœd	d
„Zdddœdd„Zddddœdd„ZdS )r÷   z(Pydantic mypy plugin model config class.Nr¦   ©r;  rÒ   rœ   rÓ   r  r®   c                 C  s(   || _ || _|| _|| _|| _|| _d S rR   rJ  )rY   r;  rÒ   rœ   rÓ   r  r®   rL   rL   rM   rX   h  s    	zModelConfigData.__init__rr   r–   c                 C  s   dd„ | j  ¡ D ƒS )z†Returns a dict of Pydantic model config names to their values.

        It includes the config if config value is not `None`.
        c                 S  s   i | ]\}}|d k	r||“qS rR   rL   )r`   ÚkÚvrL   rL   rM   r˜   }  s       z3ModelConfigData.get_values_dict.<locals>.<dictcomp>)Ú__dict__rü   r—   rL   rL   rM   ræ   x  s    zModelConfigData.get_values_dictr:  rO   )r”   rJ   c                 C  s2   |dkrdS |  ¡  ¡ D ]\}}t| ||ƒ qdS )z$Update Pydantic model config values.N)ræ   rü   r�   )rY   r”   rK  rL  rL   rL   rM   rþ     s    zModelConfigData.updaterH   r   )r•   rì   rJ   c                 C  s   t | |ƒdkrt| ||ƒ dS )zFSet default value for Pydantic model config if config value is `None`.N)r   r�   )rY   r•   rì   rL   rL   rM   r  †  s    zModelConfigData.setdefault)NNNNNN)r�   r‚   rƒ   r„   rX   ræ   rþ   r  rL   rL   rL   rM   r÷   e  s         ùr÷   zpydantic-ormzInvalid from_attributes callZPydanticzpydantic-configzInvalid config valuezpydantic-aliaszDynamic alias disallowedzpydantic-unexpectedzUnexpected behaviorzpydantic-fieldzUntyped field disallowedzInvalid Field defaultsz!Extra field on RootModel subclassr+   r   rO   )Ú
model_namery   rŸ   rJ   c                 C  s   |j d| › d�|td� dS )zCEmits an error when the model does not have `from_attributes=True`.r   z$" does not have from_attributes=True©ÚcodeN)r  Ú	ERROR_ORM)rN  ry   rŸ   rL   rL   rM   r¢   •  s    r¢   r0   )r£   ry   rŸ   rJ   c                 C  s   |j d| › d�|td� dS )z0Emits an error when the config value is invalid.zInvalid value for "Config.r   rO  N)r  ÚERROR_CONFIG)r£   ry   rŸ   rL   rL   rM   r?  š  s    r?  )ry   rŸ   rJ   c                 C  s   | j d|td� dS )znEmits required dynamic aliases error.

    This will be called when `warn_required_dynamic_aliases=True`.
    z#Required dynamic aliases disallowedrO  N)r  ÚERROR_ALIAS©ry   rŸ   rL   rL   rM   r  Ÿ  s    r  z8CheckerPluginInterface | SemanticAnalyzerPluginInterface)r¤   ry   rŸ   rJ   c                 C  s4   d}d| › d�}|d|› d�7 }|j ||td� dS )z Emits unexpected behavior error.z6https://github.com/pydantic/pydantic/issues/new/choosez7The pydantic mypy plugin ran into unexpected behavior: Ú
z&Please consider reporting this bug at z so we can try to fix it!rO  N)r  ÚERROR_UNEXPECTED)r¤   ry   rŸ   ÚlinkZfull_messagerL   rL   rM   rž   §  s    rž   c                 C  s   | j d|td� dS )z;Emits an error when there is an untyped field in the model.zUntyped fields disallowedrO  N)r  ÚERROR_UNTYPEDrT  rL   rL   rM   r  ²  s    r  c                 C  s   | j d|td� dS )z]Emits an error when there is more than just a root field defined for a subclass of RootModel.z2Only `root` is allowed as a field of a `RootModel`rO  N)r  ÚERROR_EXTRA_FIELD_ROOT_MODELrT  rL   rL   rM   r  ·  s    r  Fz8SemanticAnalyzerPluginInterface | CheckerPluginInterfacer   rD  r¨   zTypeVarType | Noner‰   )	ry   rw   r£   rÁ   r*  r¾   Útvar_defr2  rJ   c                 C  s
  |j }||jkr<|j| }	|	jr<t|	jtƒr<|jj |	j¡ t| t	ƒrR|  
d¡}
n|  dg ¡}
|rŠ|pptt|ƒƒ}ttdƒ|dtdƒg}n |p”t|ƒ}ttdƒ|dtƒg}|| }g g g   }}}|D ]8}|jsØtdƒ‚| |j¡ | |jj¡ | |j¡ qÆt|||||
ƒ}|�r|g|_t||ttƒ gƒƒ}||_ t||ƒ|_||_|jd | |_|j |_ ||jk�rŠt!||jƒ}|j| |j|< |�rÜd|_"t||jƒ}||_ |j|_d|_#t$|t%dƒg|ƒ}|j |_ t&t'|ƒ}	n
t&t'|ƒ}	d|	_|	|j|< |j(jj |¡ dS )	zhVery closely related to `mypy.plugins.common.add_method_to_class`, with a few pydantic-specific changes.zbuiltins.functionrÖ   NTZ__pydantic_self__z"All arguments must be fully typed.r5  rÎ   ))r}   rï   r+  rd   re   r   rÿ   r   Úremover0   r3  Znamed_generic_typer<   r@   r   r)   r   r¹   r~   r.  r¸   r£   rº   r7   Ú	variablesr   r    r2   r€   rö   r\   r9  r¯   rA   Zis_decoratedr2  r   r   r%   r   Zdefn)ry   rw   r£   rÁ   r*  r¾   rZ  r2  r}   ri   Zfunction_typeÚfirstr"  rë   r!  rÃ   Ú	signaturerõ   Zr_namerL  ÚdecrL   rL   rM   r0  ¼  sZ    




r0  zdict[str, Any] | None)r‹   rJ   c              
   C  s„   |   d¡sdS tjdkr"ddl}n6zddl}W n( tk
rV   ddl}| d¡ Y dS X t| dƒ�}| 	|¡W  5 Q R £ S Q R X dS )z…Returns a dict of config keys to values.

    It reads configs from toml file and returns `None` if the file is not a toml file.
    z.tomlN)é   é   r   zJNo TOML parser installed, cannot read configuration from `pyproject.toml`.Úrb)
ro   ÚsysÚversion_infoZtomllibZtomliÚImportErrorÚwarningsÚwarnÚopenÚload)r‹   Ztoml_rf  ÚrfrL   rL   rM   rŒ     s    



rŒ   )NNF)|r„   Ú
__future__r   rc  Úconfigparserr   Útypingr   r   r   Zmypy.errorcodesr   Zmypy.expandtyper   r	   Z
mypy.nodesr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   Zmypy.optionsr*   Zmypy.pluginr+   r,   r-   r.   r/   r0   Zmypy.plugins.commonr1   Zmypy.semanalr2   Zmypy.server.triggerr3   Z
mypy.stater4   Zmypy.typeopsr5   Z
mypy.typesr6   r7   r8   r9   r:   r;   r<   r=   r>   r?   Zmypy.typevarsr@   Z	mypy.utilrA   Zmypy.versionrB   Zmypy_versionZpydantic._internalrC   Zpydantic.versionrD   r“   r¡   r^   rÚ   rØ   rk   rA  ZDATACLASS_FULLNAMEró   rò   ZMYPY_VERSION_TUPLEr4  rN   rK   rS   rp   r¥   rÏ   rv   r÷   rQ  rR  rS  rV  rX  ZERROR_FIELD_DEFAULTSrY  r¢   r?  r  rž   r  r  r0  rŒ   rL   rL   rL   rM   Ú<module>   sŽ   ˆ" 0ú
6.      V'   ø X