B
    hnd                 @  s  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. dd	l/m0Z0 dd
l1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddlEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP ddlQmRZR ddlSmTZT ddlUmVZW ddlXmYZY ddlZm[Z[ yddlEm\Z\ W n" e]k
r   ddlEmNZ\ Y nX dZ^dZ_dZ`dZadZbdZcdZdd d!d"d#d$d%hZee[eWZfefd&kr6d'nd(Zgd)ZVd*d+d,d-d.ZhG d/d0 d0e6ZiG d1d2 d2Zjd3d4d5d6d7ZkG d8d9 d9ZlG d:d; d;ZmG d<d= d=Zned>d?d@ZoedAdBd@ZpedCdDd@ZqedEdFd@ZredGdHd@ZsedGdId@Ztd*dJdKdLdMdNdOZud*dPdKdLdQdRdSZvdPdKdLdTdUdVZwd*dWdKdLdXdYdZZxdPdKdLdTd[d\ZydJdKdLdTd]d^Zzdmd`dad*dbd4dcdddedLdf	dgdhZ{d*didjdkdlZ|dS )nz^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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FunctionContextMethodContextPluginReportConfigContextSemanticAnalyzerPluginInterface)dataclasses)deserialize_and_fixup_type)set_callable_name)make_wildcard_trigger)state)map_type_from_supertype)AnyTypeCallableTypeInstanceNoneType
OverloadedType	TypeOfAnyTypeTypeTypeVarType	UnionTypeget_proper_type)fill_typevars)get_unique_redefinition_name)__version__)_fields)parse_mypy_version)
TypeVarDef)r?   zpydantic-mypyzpydantic-mypy-metadatazpydantic.main.BaseModelz#pydantic_settings.main.BaseSettingsz5pydantic._internal._model_construction.ModelMetaclasszpydantic.fields.Fieldzpydantic.dataclasses.dataclassz.pydantic.functional_validators.field_validatorz.pydantic.functional_validators.model_validatorz*pydantic.functional_serializers.serializerz0pydantic.functional_serializers.model_serializerz.pydantic.deprecated.class_validators.validatorz3pydantic.deprecated.class_validators.root_validator)r   i  builtins__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)rL    rO   1/tmp/pip-unpacked-wheel-y3jxpnai/pydantic/mypy.pypluginp   s    rQ   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
dddddZdddd d!Zd"d#dd$d%Z  ZS )&rN   zThe Pydantic mypy plugin.r)   None)optionsrM   c               s&   t || _| j | _t | d S )N)PydanticPluginConfigplugin_configto_data_plugin_datasuper__init__)selfrS   )	__class__rO   rP   rY      s    
zPydanticPlugin.__init__rK   z(Callable[[ClassDefContext], bool] | None)fullnamerM   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 )N)r\   BASEMODEL_FULLNAME).0baserO   rO   rP   	<genexpr>   s    z5PydanticPlugin.get_base_class_hook.<locals>.<genexpr>N)lookup_fully_qualified
isinstancenoder'   anymro$_pydantic_model_class_maker_callback)rZ   r\   symrO   rO   rP   get_base_class_hook   s
    
z"PydanticPlugin.get_base_class_hookz(Callable[[ClassDefContext], None] | Nonec             C  s   |t kr| jS dS )z,Update Pydantic `ModelMetaclass` definition.N)MODEL_METACLASS_FULLNAME)_pydantic_model_metaclass_marker_callback)rZ   r\   rO   rO   rP   get_metaclass_hook   s    z!PydanticPlugin.get_metaclass_hookz(Callable[[FunctionContext], Type] | Nonec             C  s"   |  |}|r|jtkr| jS dS )z/Adjust the return type of the `Field` function.N)ra   r\   FIELD_FULLNAME_pydantic_field_callback)rZ   r\   rg   rO   rO   rP   get_function_hook   s    
z PydanticPlugin.get_function_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_callback)rZ   r\   rO   rO   rP   get_method_hook   s    
zPydanticPlugin.get_method_hookc             C  s   |t krtdk rtjS dS )zMark pydantic.dataclasses as dataclass.

        Mypy version 1.1.1 added support for `@dataclass_transform` decorator.
        )   rr   N)DATACLASS_FULLNAMEMYPY_VERSION_TUPLEr1   Zdataclass_class_maker_callback)rZ   r\   rO   rO   rP   get_class_decorator_hook   s    z'PydanticPlugin.get_class_decorator_hookr/   zdict[str, Any])ctxrM   c             C  s   | j S )zjReturn all plugin config data.

        Used by mypy to determine if cache needs to be discarded.
        )rW   )rZ   rv   rO   rO   rP   report_config_data   s    z!PydanticPlugin.report_config_datar+   boolc             C  s   t |j|j|j| j}| S )N)PydanticModelTransformerclsreasonapirU   	transform)rZ   rv   ZtransformerrO   rO   rP   rf      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 )zReset 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)	rU   debug_dataclass_transformrz   infoZdeclared_metaclassAssertionErrorgetattrtyper~   )rZ   rv   Zinfo_metaclassrO   rO   rP   rj      s    
z8PydanticPlugin._pydantic_model_metaclass_marker_callbackr,   r<   c       	        s  |j  |jd dkstd|jd dks2td|jd }|jd }|r`|r`t|j|j  S |r|jd d }|d }t|t	s|S nt|r|jd d }t|t
r|jd }t|tr|j}t|dd}|rtd	d
 |D rt fdd
|D |_|S  S )ao  Extract the type of the `default` argument from the Field function, and use it as the return type.

        In particular:
        * Check whether the default and default_factory argument is specified.
        * Output an error if both are specified.
        * Retrieve the type of the argument which is specified, and use it as return type for the function.
        r   defaultz0"default" is no longer first argument in Field()rr   default_factoryz9"default_factory" is no longer second argument in Field()argsNc             s  s   | ]}t |tV  qd S )N)rb   r?   )r^   argrO   rO   rP   r`      s    z:PydanticPlugin._pydantic_field_callback.<locals>.<genexpr>c             3  s   | ]
} V  qd S )NrO   )r^   _)default_any_typerO   rP   r`      s    )default_return_typeZcallee_arg_namesr   r   +error_default_and_default_factory_specifiedr|   context	arg_typesrb   r   r;   itemsr8   ret_typer   alltuple)	rZ   rv   Zdefault_argsZdefault_factory_argsZdefault_typeZdefault_argZdefault_factory_typer   r   rO   )r   rP   rm      s2    





z'PydanticPlugin._pydantic_field_callback)__name__
__module____qualname____doc__rY   rh   rk   rn   rq   ru   rw   rf   rj   rm   __classcell__rO   rO   )r[   rP   rN      s   		rN   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 )rT   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   rx   r   r   r   r   r)   rR   )rS   rM   c             C  s   |j d krd S t|j }|d k	rv|di di }x~| jD ]4}||d}t|tsdtd| t| || q<W n>t }|	|j  x*| jD ] }|j
t|dd}t| || qW d S )NZtoolzpydantic-mypyFz/Configuration value must be a boolean for key: )fallback)config_file
parse_tomlget	__slots__rb   rx   
ValueErrorsetattrr   read
getbooleanCONFIGFILE_KEY)rZ   rS   Ztoml_configconfigkeyZsettingrU   rO   rO   rP   rY     s    


zPydanticPluginConfig.__init__zdict[str, Any])rM   c               s    fdd j D S )z/Returns a dict of config names to their values.c               s   i | ]}t  ||qS rO   )r   )r^   r   )rZ   rO   rP   
<dictcomp>   s    z0PydanticPluginConfig.to_data.<locals>.<dictcomp>)r   )rZ   rO   )rZ   rP   rV     s    zPydanticPluginConfig.to_dataN)r   r   r   r   r   __annotations__rY   rV   rO   rO   rO   rP   rT      s   
	rT   r-   r<   )rv   rM   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 |di d}|dk	rt|j j| j
| j | jS )z1Raise an error if from_attributes is not enabled.z
ctx.type: z
 (of type )Nr   from_attributesT)r   rb   r>   itemr8   r   r9   r[   r   error_unexpected_behaviorr|   r   r   metadatar   METADATA_KEYerror_from_attributesname)rv   Zctx_typeZ
model_typedetailZpydantic_metadatar   rO   rO   rP   rp   #  s"    

rp   c            	   @  s   e Zd ZdZ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Z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!Zd"S )#PydanticModelFieldz5Based on mypy.plugins.dataclasses.DataclassAttribute.rK   z
str | Nonerx   intzType | Noner'   )r   aliashas_dynamic_aliashas_defaultlinecolumnr   r   c	       	      C  s4   || _ || _|| _|| _|| _|| _|| _|| _d S )N)r   r   r   r   r   r   r   r   )	rZ   r   r   r   r   r   r   r   r   rO   rO   rP   rY   =  s    zPydanticModelField.__init__r   )current_infotypedforce_optional	use_aliasrM   c             C  s:   t | |||r| |nttjd|s.| jr2tntdS )zABased on mypy.plugins.dataclasses.DataclassAttribute.to_argument.N)variabletype_annotationZinitializerkind)	r   to_varr   r7   r=   explicitr   r   r
   )rZ   r   r   r   r   rO   rO   rP   to_argumentQ  s
    
zPydanticModelField.to_argument)r   rM   c             C  s6   | j dk	r0| jjdk	r0t| j | jjjt|iS | j S )zABased on mypy.plugins.dataclasses.DataclassAttribute.expand_type.N)r   r   	self_typer   idrB   )rZ   r   rO   rO   rP   r   Z  s    zPydanticModelField.expand_typer(   )r   r   rM   c             C  s,   |r| j dk	r| j }n| j}t|| |S )z<Based on mypy.plugins.dataclasses.DataclassAttribute.to_var.N)r   r   r(   r   )rZ   r   r   r   rO   rO   rP   r   d  s    zPydanticModelField.to_varr   )rM   c             C  s0   | j s
t| j| j| j| j| j| j| j  dS )z?Based on mypy.plugins.dataclasses.DataclassAttribute.serialize.)r   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r   	serialize)rZ   rO   rO   rP   r   m  s    
zPydanticModelField.serializer0   )r   datar|   rM   c             C  s,   |  }t|d|}| f ||d|S )zABased on mypy.plugins.dataclasses.DataclassAttribute.deserialize.r   )r   r   )copyr2   pop)rz   r   r   r|   typrO   rO   rP   deserializez  s    zPydanticModelField.deserializerR   )sub_typerM   c             C  s    | j dk	rt| j || j| _ dS )zxExpands type vars in the context of a subtype when an attribute is inherited
        from a generic super type.
        N)r   r6   r   )rZ   r   rO   rO   rP   expand_typevar_from_subtype  s    
z.PydanticModelField.expand_typevar_from_subtypeN)r   r   r   r   rY   r   r   r   r   classmethodr   r   rO   rO   rO   rP   r   :  s   	
	r   c               @  sn  e Zd ZU dZ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Z
ddd d!d"Zd#dd$d%d&Zd'dd(d)d*d+Zd,d-d.d/d0d1d2Zd3dddd4d5d6Zd3ddd7d8d9Zd3ddd:d;d<Zd-d=d>d?d@dAZed'dd dBdCZed'dDd dEdFZd3ddddGdHdIdJZd3ddd7dKdLZed3dddMdNdOZdPS )Qry   zTransform 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_generatorzset[str]tracked_config_fieldsr   zExpression | Statementr0   rT   rR   )rz   r{   r|   rU   rM   c             C  s   || _ || _|| _|| _d S )N)_clsZ_reason_apirU   )rZ   rz   r{   r|   rU   rO   rO   rP   rY     s    z!PydanticModelTransformer.__init__rx   )rM   c             C  s   | j j}|  }| |}|dkr&dS x|D ]}|jdkr,dS q,W tdd |jdd D }| ||| | || | j	||j
dk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
        NFc             s  s   | ]}|j tkV  qd S )N)r\   BASESETTINGS_FULLNAME)r^   r_   rO   rO   rP   r`     s    z5PydanticModelTransformer.transform.<locals>.<genexpr>T)r   c             S  s   i | ]}|  |jqS rO   )r   r   )r^   fieldrO   rO   rP   r     s    z6PydanticModelTransformer.transform.<locals>.<dictcomp>)fieldsr   )r   r   collect_configcollect_fieldsr   rd   re   add_initializeradd_model_construct_method
set_frozenr   adjust_decorator_signaturesget_values_dictr   r   )rZ   r   r   r   r   is_settingsrO   rO   rP   r}     s     	


z"PydanticModelTransformer.transformc             C  sd   x^| j jj D ]L\}}t|jtr|jjd }t|trt|j	t
r|j	jtkrd|jj_qW 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   TN)r   r   namesr   rb   rc   r   Zoriginal_decoratorsr   calleer   r\   DECORATOR_FULLNAMESfuncis_class)rZ   r   rg   Z	first_decrO   rO   rP   r     s    
z4PydanticModelTransformer.adjust_decorator_signaturesModelConfigDatac             C  sb  | j }t }d}d}x4|j D ]&\}}| ||}|r d}|| q W d}xh|jjD ]Z}t|t	t
fspqZt|t	r.|jd }	t|	trZ|	jdkrqZt|jtrxt|jj|jjD ]$\}
}|
dkrq|| |
| qW nFt|jtrx|jjD ]*\}}t|tsq|| |j| qW nnt|t
r|jdkrHqZxR|jjD ]F}t|t	sfqR|jd }	t|	tsqR|| |	j|j qRW |r| jd| P d}qZW |s|r|r|jr|js| jjrt| j| xj|jjdd D ]V}t|j krq| j!t"|j# x,|j t d	  D ]\}}|$|| q>W qW |S )
zhCollects the values of the config attributes that are used by the plugin, accounting for parent classes.FTNr   model_configZConfigzYSpecifying config in two places is ambiguous, use either Config attribute or class kwargsrr   r   )%r   r   keywordsr   get_config_updateupdatedefsbodyrb   r   r   lvaluesr   r   rvaluer   zip	arg_namesr   r   r#   valuer   failhas_alias_generatorr   rU   r   error_required_dynamic_aliasesr   re   r   r   add_plugin_dependencyr4   r\   
setdefault)rZ   rz   r   Zhas_config_kwargsZhas_config_from_namespacer   exprZconfig_datastmtlhsarg_namer   Zkey_exprZ
value_exprZsubstmtr   r   rO   rO   rP   r     sp    


z'PydanticModelTransformer.collect_configzlist[PydanticModelField] | None)r   rM   c             C  s6  | j }i }xt|jjdd D ]}t|jkr0q | jt|j	 x|jt d 
 D ]|\}}t||| j}t| jjj ||j W dQ R X |||< |jj|}|rV|jrVt|jtsV| jd|j qVW q W t }	xH| |jD ]8}
| |
|}|dk	r|
jd }|	|j |||j< qW t|  S )zACollects the fields for the model, accounting for parent classes.rr   r   r   Nz7BaseModel field may only be overridden by another fieldr   )!r   reversedr   re   r   r   r   r   r4   r\   r   r   r   r5   strict_optional_setrS   strict_optionalr   r   r   rc   rb   r(   r   set%_get_assignment_statements_from_blockr   collect_field_from_stmtr   addr   listvalues)rZ   r   rz   Zfound_fieldsr   r   r   r   sym_nodeZcurrent_field_namesr   Zmaybe_fieldr   rO   rO   rP   r   %  s0    

z'PydanticModelTransformer.collect_fieldsr   zIterator[AssignmentStmt])r   rM   c             c  sN   x$|j D ]}|js| |E d H  qW |jd k	rJ|jjsJ| |jE d H  d S )N)r   Zis_unreachabler   Z	else_body)rZ   r   r   rO   rO   rP   ,_get_assignment_statements_from_if_statementY  s
    zEPydanticModelTransformer._get_assignment_statements_from_if_statementr   )blockrM   c             c  s@   x:|j D ]0}t|tr|V  qt|tr| |E d H  qW d S )N)r   rb   r   r   r  )rZ   r  r   rO   rO   rP   r   `  s
    

z>PydanticModelTransformer._get_assignment_statements_from_blockr   zPydanticModelField | None)r   r   rM   c          
   C  s  | j }|jd }t|tr0t|jr0|jdkr4dS |jst|jt	rxt|jj
t	rxt|jj
j
trx|jj
j
jtkrxdS t| j| dS |jd }t|tsdS t|jr|jdkrdS |jj|j}|dkrdS |j}t|trdS t|tr| jd| dS t|tsdS |jr$dS t|j}t|trV|jjdkrV| 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%rt&| 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.

        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   rb   r   rE   Zis_valid_field_namer   Z
new_syntaxr   r   r   r\   r   error_untyped_fieldsr   r   r   r   rc   r    r&   r   r(   Zis_classvarrA   r   r9   get_has_defaultr  Zis_inferredZanalyze_simple_literal_typer7   r=   Z
from_errorget_alias_infor   rU   r   r   _infer_dataclass_attr_init_typer   r   r   )rZ   r   r   rz   r   rg   rc   Z	node_typer   r   r   r   Z	init_typerO   rO   rP   r   g  sv    
 




z0PydanticModelTransformer.collect_field_from_stmtr$   rK   r   zType | None)rg   r   r   rM   c       	      C  s   |j }|jr|S t|j }t|ts(|S |j d}|rt|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rt|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__rJ   z(Unsupported signature for "__set__" in ""zUnsupported "__set__" in ")r   ZimplicitrA   rb   r9   r   rc   r   Zget_containing_type_infor   r6   r7   r=   Zunannotatedr8   	arg_kindsr   r	   r   r   r   r   )	rZ   rg   r   r   r   tsetterZ
super_infoZsetter_typerO   rO   rP   r
    s,    


z8PydanticModelTransformer._infer_dataclass_attr_init_typezlist[PydanticModelField])r   r   r   rM   c       	   	   C  s   d| j jjkr"| j jjd js"dS | jj}|jdk	}|pHt|joF|j }t	
| jjj | j||||d}W dQ R X | ||std}|t|ttjdt t| j| j d|t d dS )zAdds a fields-aware `__init__` method to the class.

        The added `__init__` will be annotated with types vs. all `Any` depending on the plugin settings.
        rY   NT)r   force_all_optionalr   kwargs)r   return_type)r   r   r   plugin_generatedrU   r   r   rx   r   r5   r   r   rS   r   get_field_argumentsshould_init_forbid_extrar(   appendr   r7   r=   r   r   
add_methodr:   )	rZ   r   r   r   r   r   r  r   varrO   rO   rP   r     s    
z(PydanticModelTransformer.add_initializer)r   r   rM   c          	   C  s   | j t d| j t dg}t|t g}ttd||dt}t	| j j
j | j|dddd}W dQ R X | ||std}|t|ttjdt |g| }t| j | jd	|t| jjdd
 dS )zAdds 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  Zmodel_construct)r   r  is_classmethod)r   
named_typeBUILTINS_NAMEr@   r:   r   r(   r   r5   r   rS   r   r  r  r  r7   r=   r   r   r  r   rB   r   )rZ   r   r   Zset_strZoptional_set_strZfields_set_argumentr   r  rO   rO   rP   r     s     $

z3PydanticModelTransformer.add_model_construct_method)r   r   rM   c       	   	   C  s   | j j}x|D ]}|j|j}|dk	r|j}t|tr@||_qt|t	r^| j
js^| j
  qy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W dS )zMarks 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: z
 (of type r   F)r   .)r   r   r   r   r   rc   rb   r(   Zis_propertyr    r   Zfinal_iterationdeferrK   	TypeErrorreprr[   r   r   r\   	_fullnamer$   r   )	rZ   r   r   r   r   r  r  Zvar_strr   rO   rO   rP   r   4  s(    

z#PydanticModelTransformer.set_frozenr   zModelConfigData | None)r   r   rM   c             C  s   || j krdS |dkr^t|tr,|jdk}n(t|trB|jdk}nt|| j| dS t|dS |dkrd}t|t	r|j
dkrd}t|d	S t|t	r|j
d
krtf ||j
dkiS t|| j| dS )zDetermines 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   Tzbuiltins.NoneF)r   )zbuiltins.Truezbuiltins.Falsezbuiltins.True)r   rb   r#   r   r   r   error_invalid_config_valuer   r   r   r\   )rZ   r   r   r!  r   rO   rO   rP   r   S  s&    




z*PydanticModelTransformer.get_config_updatec             C  s   | j }t|trdS t|trt|jtr|jjtkrxRt|j	|j
D ]@\}}|dks^|dkrh|jtk	S |dkrFt|to|jdk S qFW dS t|t S )zUReturns a boolean indicating whether the field defined in `stmt` is a required field.FNr   r   zbuiltins.None)r   rb   r%   r   r   r!   r\   rl   r   r   r   r[   r   r   )r   r   r   r   rO   rO   rP   r  m  s    
"
z(PydanticModelTransformer.get_has_defaultz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 xBt|j	D ]4\}}|dkrXqF|j
| }t|trv|jdfS dS qFW d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   rb   r%   r   r   r!   r\   rl   	enumerater   r   r#   r   )r   r   ir   r   rO   rO   rP   r	    s    
"


z'PydanticModelTransformer.get_alias_infozlist[Argument])r   r   r  r   rM   c               s$   | j j fdd|D }|S )zHelper 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 | ] }r|j s|j d qS ))r   r   r   )r   r   )r^   r   )r  r   r   r   rO   rP   
<listcomp>  s   z@PydanticModelTransformer.get_field_arguments.<locals>.<listcomp>)r   r   )rZ   r   r   r  r   	argumentsrO   )r  r   r   r   rP   r    s    z,PydanticModelTransformer.get_field_argumentsc             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_presentrx   r   r!  rU   r   )rZ   r   r   rO   rO   rP   r    s    z1PydanticModelTransformer.should_init_forbid_extra)r   r   rM   c             C  s<   x| D ]}|j rdS qW |r8x| D ]}|jdkr"dS q"W dS )zReturns 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   rO   rO   rP   r'    s    


z1PydanticModelTransformer.is_dynamic_alias_presentN)r   r   r   r   r   r   rY   r}   r   r   r   r  r   r   r
  r   r   r   r   staticmethodr  r	  r  r  r'  rO   rO   rO   rP   ry     s0   
!L4x&ry   c               @  sX   e Zd ZdZ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.Nzbool | None)r!  r   r   r   r   c             C  s"   || _ || _|| _|| _|| _d S )N)r!  r   r   r   r   )rZ   r!  r   r   r   r   rO   rO   rP   rY     s
    zModelConfigData.__init__zdict[str, Any])rM   c             C  s   dd | j  D S )zReturns 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 )NrO   )r^   kvrO   rO   rP   r     s    z3ModelConfigData.get_values_dict.<locals>.<dictcomp>)__dict__r   )rZ   rO   rO   rP   r     s    zModelConfigData.get_values_dictzModelConfigData | NonerR   )r   rM   c             C  s6   |dkrdS x$|   D ]\}}t| || qW dS )z$Update Pydantic model config values.N)r   r   r   )rZ   r   r)  r*  rO   rO   rP   r     s    zModelConfigData.updaterK   r   )r   r   rM   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   )rZ   r   r   rO   rO   rP   r     s    zModelConfigData.setdefault)NNNNN)r   r   r   r   rY   r   r   r   rO   rO   rO   rP   r     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 defaultsr*   r   rR   )
model_namer|   r   rM   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)r,  r|   r   rO   rO   rP   r     s    r   r0   )r   r|   r   rM   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  )r-  N)r   ERROR_CONFIG)r   r|   r   rO   rO   rP   r"    s    r"  )r|   r   rM   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 disallowed)r-  N)r   ERROR_ALIAS)r|   r   rO   rO   rP   r     s    r   z8CheckerPluginInterface | SemanticAnalyzerPluginInterface)r   r|   r   rM   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!)r-  N)r   ERROR_UNEXPECTED)r   r|   r   linkZfull_messagerO   rO   rP   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 disallowed)r-  N)r   ERROR_UNTYPED)r|   r   rO   rO   rP   r    s    r  c             C  s   | j d|td dS )zNEmits an error when `Field` has both `default` and `default_factory` together.z>Field default and default_factory cannot be specified together)r-  N)r   ERROR_FIELD_DEFAULTS)r|   r   rO   rO   rP   r     s    r   Fz8SemanticAnalyzerPluginInterface | CheckerPluginInterfacer   zlist[Argument]zType | NonezTypeVarDef | Nonerx   )	r|   rz   r   r   r  r   tvar_defr  rM   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 |pt|}ttd|dtg}|| }g g g   }}}x@|D ]8}|jstd||j ||jj ||j qW t|||||
}|r"|g|_t||tt g}||_ t|||_||_|jd | |_|j |_ ||jkrt!||j}|j| |j|< |rd|_"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.r  r   ))r   r   r  rb   rc   r   r   r   remover0   r  Znamed_generic_typer>   rB   r   r(   r   r   r   r  r   r   r   r8   	variablesr   r   r3   r   r   r\   r   r   rC   Zis_decoratedr  r   r   r$   r   Zdefn)r|   rz   r   r   r  r   r6  r  r   rg   Zfunction_typefirstr   r   r  r   	signaturer   Zr_namer*  decrO   rO   rP   r    sZ    





r  zdict[str, Any] | None)r   rM   c          	   C  sv   |  dsdS tjdkr"ddl}n4yddl}W n& tk
rT   ddl}|d dS X t| d}|	|S Q R X dS )zReturns 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_rB  rfrO   rO   rP   r   l  s    



r   )NNF)}r   
__future__r   r?  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(   Zmypy.optionsr)   Zmypy.pluginr*   r+   r,   r-   r.   r/   r0   Zmypy.pluginsr1   Zmypy.plugins.commonr2   Zmypy.semanalr3   Zmypy.server.triggerr4   Z
mypy.stater5   Zmypy.typeopsr6   Z
mypy.typesr7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   Zmypy.typevarsrB   Z	mypy.utilrC   Zmypy.versionrD   Zmypy_versionZpydantic._internalrE   Zpydantic.versionrF   rG   rA  r   r   r]   r   ri   rl   rs   r   rt   r  rQ   rN   rT   rp   r   ry   r   r.  r/  r0  r2  r4  r5  r   r"  r   r   r  r   r  r   rO   rO   rO   rP   <module>   s   !$	4v.O    E%   F