U
    ¶ÜŸ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-3sxb4rlg/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   )Ú_clsÚ_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®   r0  r/  r6   r;   r¼   r   r1  rÖ   r@   r}   )
rY   rß   r”   ré   rè   Zset_strZoptional_set_strZfields_set_argumentrÁ   r2  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  r2  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\   rB  r  rÁ   rì   r   rC  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\   rB  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\   rB  rõ   rì   rÁ   r   rD  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   rF  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   r0  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   rI  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-  r0  rI  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   rK  )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”   rL  rM  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)rO  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!  rP  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 disallowedrP  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!rP  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 disallowedrP  N)r  ÚERROR_UNTYPEDrU  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`rP  N)r  ÚERROR_EXTRA_FIELD_ROOT_MODELrU  rL   rL   rM   r  ·  s    r  Fz8SemanticAnalyzerPluginInterface | CheckerPluginInterfacer   rE  r¨   zTypeVarType | Noner‰   )	ry   rw   r£   rÁ   r+  r¾   Útvar_defr3  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.r6  rÎ   ))r}   rð   r,  rd   re   r   r   r  Úremover0   r4  Znamed_generic_typer<   r@   r   r)   r   r¹   r~   r/  r¸   r£   rº   r7   Ú	variablesr   r    r2   r€   r÷   r\   r:  r¯   rA   Zis_decoratedr3  r   r   r%   r   Zdefn)ry   rw   r£   rÁ   r+  r¾   r[  r3  r}   ri   Zfunction_typeÚfirstr#  rì   r"  rÃ   Ú	signaturerö   Zr_namerM  ÚdecrL   rL   rM   r1  ¼  sZ    




r1  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_rg  ÚrfrL   rL   rM   rŒ     s    



rŒ   )NNF)|r„   Ú
__future__r   rd  Ú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   rB  ZDATACLASS_FULLNAMErô   ró   ZMYPY_VERSION_TUPLEr5  rN   rK   rS   rp   r¥   rÏ   rv   rø   rR  rS  rT  rW  rY  ZERROR_FIELD_DEFAULTSrZ  r¢   r@  r  rž   r  r  r1  rŒ   rL   rL   rL   rM   Ú<module>   sŽ   ˆ" 0ú
6.      V'   ø X