fL iFdZddlZddlZddlZddlmZddlmZ ddlmZddl m Z m Z m Z mZmZmZmZmZmZmZmZddlmZddlmZdd lmZmZmZmZdd lm Z dd l!m"Z"dd l#m$Z$m%Z%m&Z&m'Z'dd l(m)Z)m*Z*ddl+m,Z,e r,ddl(m-Z-ddl.m/Z/m0Z0eddZ1eeddfZ2GddZ3gdZ4edZ5ejldk\reejne$feddddddddddd de8de8d e8d!e8d"e8d#e8d$eeee9dfd%ee8d&ee8d'e8d(e ee5gd)ffd*Z:eejne$feddddddddddd d+ee5de8de8d e8d!e8d"e8d#e8d$eeee9dfd%ee8d&ee8d'e8d(d)fd,Z:neejne$fedddddddddd- de8de8d e8d!e8d"e8d#e8d$eeee9dfd%ee8d&ee8d(e ee5gd)ffd.Z:eejne$fedddddddddd- d+ee5de8de8d e8d!e8d"e8d#e8d$eeee9dfd%ee8d&ee8d(d)fd/Z:eejne$f dIddddddddddd d+eee5de8de8d e8d!e8d"e8d#e8d$eeee9dfd%ee8d&ee8d'e8d(ee ee5gd)fd)ffd0Z:ed1edd2e8d(eedddffd3Z;Gd4dZdJd9Z?d1edd:e d(dfd;Z@edfd5edd$ee d6ee=d(ed<fd=ZAejld>k\r d?dd@e=d(e8fdAZBn d?dd@e=d(e8fdBZBdKdDZCdCddEe=d2e d(dfdFZDd+ee d(e8fdGZEd5edd$eed(d8fdHZFy#e $rY"wxYw)LaX The main purpose is to enhance stdlib dataclasses by adding validation A pydantic dataclass can be generated from scratch or from a stdlib one. Behind the scene, a pydantic dataclass is just like a regular one on which we attach a `BaseModel` and magic methods to trigger the validation of the data. `__init__` and `__post_init__` are hence overridden and have extra logic to be able to validate input data. When a pydantic dataclass is generated from scratch, it's just a plain dataclass with validation triggered at initialization The tricky part if for stdlib dataclasses that are converted after into pydantic ones e.g. ```py @dataclasses.dataclass class M: x: int ValidatedM = pydantic.dataclasses.dataclass(M) ``` We indeed still want to support equality, hashing, repr, ... as if it was the stdlib one! ```py assert isinstance(ValidatedM(x=1), M) assert ValidatedM(x=1) == M(x=1) ``` This means we **don't want to create a new dataclass that inherits from it** The trick is to create a wrapper around `M` that will act as a proxy to trigger validation without altering default `M` behaviour. N)contextmanager)wraps)cached_property) TYPE_CHECKINGAnyCallableClassVarDict GeneratorOptionalTypeTypeVarUnionoverload)dataclass_transform)gather_all_validators) BaseConfig ConfigDictExtra get_config)ValidationError)DataclassTypeError)Field FieldInfoRequired Undefined) create_modelvalidate_model)ClassAttribute) BaseModel)CallableGeneratorNoArgAnyCallable DataclassT Dataclass)boundDataclassProxyceZdZUeeeefed<eeed<eeded<ee ed<eeded<ee ed<ee e ed<eedgd fed <ee ed <d e d e dd fdZ ede dddfdZede ddeddfdZy )r$__dataclass_fields____dataclass_params__).N __post_init____pydantic_run_validation____post_init_post_parse____pydantic_initialised____pydantic_model__N__pydantic_validate_values__#__pydantic_has_field_info_default__argskwargsreturncyNselfr1r2s ]/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/pydantic/v1/dataclasses.py__init__zDataclass.__init__Ps clsr!cyr5r6r<s r9__get_validators__zDataclass.__get_validators__S r;r#vcyr5r6r<rAs r9 __validate__zDataclass.__validate__Wr@r;)__name__ __module__ __qualname__r r strr__annotations__rboolr r objectr: classmethodr?rDr6r;r9r$r$Bs&tCH~66&sm+ 344&.d^3"*8I+>"??"*4.0$T)_55&.x t8K/L&MM-5d^; & F t   D$5 :M     d<0 S \   r;) dataclassset_validation$create_pydantic_model_from_dataclassis_builtin_dataclassmake_dataclass_validator_T )field_specifiersTF. initrepreqorder unsafe_hashfrozenconfigvalidate_on_init use_proxykw_onlyrXrYrZr[r\r]r^r_r`rar3DataclassClassOrWrapperc yr5r6rWs r9rMrMh r;_clsc yr5r6) rerXrYrZr[r\r]r^r_r`ras r9rMrMys r; rXrYrZr[r\r]r^r_r`c yr5r6rgs r9rMrMs r;c yr5r6) rerXrYrZr[r\r]r^r_r`s r9rMrMrdr;c  t| dttddf   f d } || S| |S)a Like the python standard lib dataclasses but with type validation. The result is either a pydantic dataclass that will validate input data or a wrapper that will trigger validation around a stdlib dataclass to avoid modifying it directly r<r3rbc  nYt|xrM|jdtuxs6tt |tt |jdk(}|rd}t |}d}n_|j xsd}tjdk\rtj|   }ntj|  }d}|n}t| |||jjdi|j|i|S) NrFrS)rXrYrZr[r\r]ra)rXrYrZr[r\r]Tr6)rP __bases__rKsetdirr&__doc__sys version_info dataclassesrM#_add_pydantic_validation_attributesr.__try_update_forward_refs__rE)r<should_use_proxy dc_cls_docdc_clsdefault_validate_on_initshould_validate_on_initrZr]rXrar[rY the_configr\r`r_s r9wrapzdataclass..wraps*$ %S)`]]1%/^3s3x=CCMMZ[L\H]D^3^  J#C(F', $*J7*$.. +!# %..d"E{ci(, $>N>V":\l+C=TV`a=!!==Ts@ST r;)rr r) rerXrYrZr[r\r]r^r_r`rar|r{s `````` ``` @r9rMrMsD*F#J#$s)# 9##J | :r;r<valuec#bK|j} ||_|||_y#||_wxYwwr5)r+)r<r}original_run_validations r9rNrNs6!==B*/' *A'*A's / #/ ,/ceZdZdZdedddfdZdededefd Zd edefd Z d ed eddfdZ dede fdZ ddZ deddfdZy)r& __dataclass__rxr$r3Nc2tj|d|y)Nr)rK __setattr__)r8rxs r9r:zDataclassProxy.__init__s4&9r;r1r2c~t|jd5|j|i|cdddS#1swYyxYw)NT)rNrr7s r9__call__zDataclassProxy.__call__s< D.. 5 7%4%%t6v6 7 7 7s3<namec.t|j|Sr5)getattrr)r8rs r9 __getattr__zDataclassProxy.__getattr__st))400r;_DataclassProxy__name_DataclassProxy__valuec0t|j||Sr5)setattrr)r8rrs r9rzDataclassProxy.__setattr__st))67;;r;instancec.t||jSr5) isinstancer)r8rs r9__instancecheck__z DataclassProxy.__instancecheck__ s(D$6$677r;cRttj|jSr5)r&copyr)r8s r9__copy__zDataclassProxy.__copy__sdii(:(:;<,>EFFr;)r3r&)rErFrG __slots__r r:rrrHrrrJrrrr6r;r9r&r&sI:tK0:T:7c7S7S7111<#<<<8#8$8=GG)9Gr;rxrwc b|jtdddtdtddffd t|drW |jj tdddtdtddffd }t|d t|d|n1tdddtdtddffd }t|d |t|d td |t|d dt|dt||t|dtt|dttt|dtt|jjj r)|j"j$st|dt&yyy#t $r|jYTwxYw)a We need to replace the right method. If no `__post_init__` has been set in the stdlib dataclass it won't even exist (code is generated on the fly by `dataclasses`) By default, we run validation after `__init__` or `__post_init__` if defined r8r$r1r2r3Nc  jtjk(r>|g|i|jDcic]\}}||jvs||c}}yjtj k(rr|jD]!\}}|j j||#|g|i|jDcic]\}}||jvs||c}}y|g|i|ycc}}wcc}}wr5)extrarignoreitemsr(allow__dict__ setdefault)r8r1r2krAr^rXs r9handle_extra_initz>_add_pydantic_validation_attributes..handle_extra_init"s <<5<< '  d d&,,. c$!QAIbIbDbA c d \\U[[ (  /1 ((A. /  d d&,,. c$!QAIbIbDbA c d  ' ' '!d !dsC9C9 C? C?r*cjdk(r |g|i||jjr.|jt |dr|j |i|jdk(r |g|i|yy)Nbefore_validationr,after_validation)post_init_call __class__r+r/hasattrr,)r8r1r2r^ post_inits r9 new_post_initz:_add_pydantic_validation_attributes..new_post_init5s$$(;;$000~~991134!;<1D114B6B$$(::$000;r;r:c|g|i||jjr|jt|drzi}t |jj j D]5\}}|jtjus# ||||j<7|jdi|yy#t$r6|j|j|j||j<YwxYw)Nr,r6)rr+r/r enumerater(values _field_typers_FIELD_INITVARr IndexErrorgetdefaultr,)r8r1r2initvars_and_valuesifrs r9new_initz5_add_pydantic_validation_attributes..new_initGs d 4T 4V 4~~99113t78 79#%dnn&I&I&P&P&RSXDAq}} (B(BBX:>q'/7 X.--D0CD9 *X:@**QVVQYY:W/7XsB;;B_aq3rs F.6 F(*NvW]_i*jk F24NO FNK0C$DE F(+o*FG   ++??HcHcHjHj 'MNIk?k -,,I -sFF.-F.r!c#(K|jywr5)rDr>s r9rrks  srAc8t|d5t||r|j|cdddSt|ttfr||cdddSt|t r|di|cdddSt |j#1swYyxYw)NT) class_namer6)rNrr/listtupledictrrErCs r9rros T " > a  * * , > >D%= )7 > > 4 88 > >% = = > >sBBB:BBr c<i}tj|D]}t}d}|jtjur |j}n/|j tjur |j }nt }t|tr |}d|_ ntd||d|j}|j|f||j<t|}t|j f||j"|ddid|} | || _| S|j$xsd| _| S)NT)rdefault_factory__resolve_forward_refs__F)rrF__validators____cls_kwargs__rlr6)rsfieldsrrMISSINGrrrrr0rmetadatatyperrrrErFrp) rxr^rwfield_definitionsfieldrr field_info validatorsmodels r9rOrO|s* )+##F+A 8< == 3 3 3mmG  " "+*=*= =#33OG gy ) J9=F 6bwbSXSaSabJ).Z(@%**%%A('v.J+ $$!2E:     E#-"8JEM L?Enn>RPREM Lr;)rTobjrcJttt||dtSr5)rrrrrrs r9_is_field_cached_propertyrs'$s)Q5GGr;cy)NFr6rs r9rrsr;r8ct|dryt|ddrJ|jjDcic]$\}}t|tst ||s||&}}}n:|jjDcic]\}}t ||r||}}}t |j||j\}}}|r||jj|tj|ddycc}}wcc}}w)Nr-r0Fr>T) rrrrrrrr.rupdaterKr)r8rrA input_datad_validation_errors r9rrst/0t:EB  ++- 1q),0I$PQ0R qD  (,}}':':'<gtq!D]^bdeDfadg g+D,C,CZUYUcUcdAq MM t7> hs)C<DDrc^|jrt|j}|j|d|jj j |d}|r;|j||||j\}}|rt|g|jtj|||y)N)locr<) r-rrpopr. __fields__rvalidaterrrKr)r8rr}r known_fielderror_s r9rrs $$   dD--88<rs B  % ) uttt1>HH61DD9,*F[9J#D$57G$GH4  T]w;+<+     48*77 8  F  ;+<+   # F $;+<+   48*77 8  F  ;+<+   #  F  {'8'8%&@A#>48'+ $> 48 > >  > >  >> > *d6lD0 1>tn>~>> 8T"XJ 99 :B>BB\*B4BIdT,/ >C >L ># $$  $ I$ $ + $NvH{HsHtH {st?, * *C *PS *X\ *tCyT:QT+%6QZ@PQUhQI  sL<<MM