
    iM                        U d Z ddlZddlZddlmZmZmZ ddlmZ ddlm	Z
 ej                  dk\  rdZdZn	 ddlmZ dd	lmZ 	 ddlmZ dd	lmZ  G d
 d      Z G d d      Z G d d      Z G d d      Zd'dddZ G d de      Z G d d      Z G d d      Zd(dZd Zd Z d Z!d(dZ"i Z#e$e%d<   d  Z&d! Z'd" Z(d# Z)d$ Z*d% Z+d& Z,y# eef$ r dZdZY w xY w# eef$ r dZdZY w xY w))zLightweight type validation system replacing Pydantic.

Provides Schema base class, dynamic schema creation, and type validation
for config values against function signatures.
    N)AnyOptionalget_type_hints   )Ctx)
check_type)      )	BaseModel)ValidationErrorc                       e Zd ZdZy)
StrictBoolz.Only accepts actual bool values (not int 0/1).N__name__
__module____qualname____doc__     f/var/www/vps2.regionflexible.com/Desarrollo/venv/lib/python3.12/site-packages/confection/validation.pyr   r   .   s    8r   r   c                       e Zd ZdZy)PositiveIntz/Only accepts positive integers (> 0, not bool).Nr   r   r   r   r   r   4   s    9r   r   c                       e Zd ZdZy)StrictFloatz+Only accepts actual float values (not int).Nr   r   r   r   r   r   :   s    5r   r   c                   (    e Zd ZdZdZddddZd Zy)	FieldInfoz!Information about a schema field.defaultalias
annotationNr   c                .    || _         || _        d | _        y Nr   )selfr   r   s      r   __init__zFieldInfo.__init__H   s    
#r   c                     | j                   du S )N.r   r$   s    r   is_requiredzFieldInfo.is_requiredM   s    ||s""r   .)r   r   r   r   	__slots__r%   r)   r   r   r   r   r   C   s    +2I$T $
#r   r   r!   c                    t        | |      S )zCreate a field definition.r   r   )r   r-   s     r   Fieldr.   Q   s    WE22r   c                   (     e Zd ZdZ fdZd Z xZS )r   z$Raised when schema validation fails.c                 b    || _         dj                  d |D              }t        |   |       y )Nz; c              3   @   K   | ]  }|j                  d d        yw)msg N)get).0es     r   	<genexpr>z+ValidationError.__init__.<locals>.<genexpr>^   s     >aub)>s   )_errorsjoinsuperr%   )r$   
error_listmsgs	__class__s      r   r%   zValidationError.__init__\   s+    !yy>:>>r   c                     | j                   S r#   )r8   r(   s    r   errorszValidationError.errorsa   s    ||r   )r   r   r   r   r%   r?   __classcell__r=   s   @r   r   r   Y   s    .
r   r   c                       e Zd ZdZd Zy)_ValidatedResultz0Attribute-accessible result from model_validate.c                 :    | j                   j                  |       y r#   )__dict__update)r$   datas     r   r%   z_ValidatedResult.__init__k   s    T"r   N)r   r   r   r   r%   r   r   r   rC   rC   h   s
    :#r   rC   c                   x     e Zd ZU dZdddZeed<   i Zeed<    fdZd Z	e
d	        Ze
d
dd       Zd Z xZS )SchemazFBase class for config validation schemas. Replaces pydantic.BaseModel.allowTextraarbitrary_types_allowedmodel_configmodel_fieldsc           	      L   t        |   di | i }i }t        | j                        D ]   }t	        |di       }|j                  |       " |j                         D ]  \  }}|dv s|j                  d      rd}d }	| j                  D ]w  }
||
j                  v s|
j                  |   }t        |t              r|j                  }|j                  }	n-t        |t        t        t        t         f      st#        |      s|} n t        ||	      }||_        |||<    || _        y )N__annotations__)rN   rO   _.r-   r   )r:   __init_subclass__reversed__mro__getattrrF   items
startswithrE   
isinstancer   r   r   typeclassmethodstaticmethodpropertycallabler    rO   )clskwargsfields	all_hintsbasebase_annotationsnamer    r   r   klassvalfieldr=   s                r   rS   zSchema.__init_subclass__u   s+   !+F+	S[[) 	/D&t->C-.	/ !* 1 	!D*774??3;OGE 5>>)...C!#y1"%++ #		'dKxH  (}&)G gU;E)E F4L'	!* "r   c                     | j                   j                  j                         D ]B  \  }}||v rt        | |||          |j	                         r,t        | ||j
                         D y r#   )r=   rO   rW   setattrr)   r   )r$   r`   re   rh   s       r   r%   zSchema.__init__   s[    >>66<<> 	3KD%v~dF4L1&&(dEMM2		3r   c                    | j                   j                  d      }t        || j                  | j                   |      }|rt	        |      t        |      }| j                  j                         D ]O  \  }}|}|j                  |j                  }n
|r ||      }||vs0|j                         rA|j                  ||<   Q t        |      S )z$Validate a dict against this schema.alias_generator)rN   r4   _validate_schemarO   r   dictrW   r   r)   r   rC   )r_   rG   	alias_genr?   result_datare   rh   data_keys           r   model_validatezSchema.model_validate   s     $$(():;	!$(8(8#:J:JIV!&))4j++113 	6KD%H{{& ;;$T?{*53D3D3F(-H%	6  ,,r   N)configc                   ddl m} |ddd}t        |      }i }t        j                  |      j
                  j                         D ]  }|j                  |j                  |j                        }|t        j                  j                  u rt        }|j                  t        j                  j                  u rd}n|j                  }|j                  t        j                  j                  k(  r||   }|j                  t        j                  j                   k(  rt#        |      }	||	_	        |	||j                  <    t%        |j&                  fd|i|j)                         D 
ci c]  \  }
}|
|j                  |f c}}
S c c}}
w )	a'  Build a Schema subclass from a function's signature.

        Each parameter becomes a field.  The annotation is used as the type
        (defaulting to ``Any`` when missing) and the default value is
        preserved (parameters without defaults become required fields).

        ``*args`` parameters are wrapped in ``Sequence[annotation]`` and
        stored under the ``VARIABLE_POSITIONAL_ARGS`` field name.

        Forward-reference annotations are resolved via
        ``typing.get_type_hints`` against the function's module namespace.
        r   )SequenceforbidTrK   .r'   
__config__)typingru   resolve_type_hintsinspect	signature
parametersvaluesr4   re   r    	Parameteremptyr   r   kindVAR_POSITIONALVAR_KEYWORDr   create_schemar   rW   )r_   funcrs   _Seqresolvedra   paramr    r   rh   re   fs               r   from_functionzSchema.from_function   sU   & 	,>'DIF%d+&&t,77>>@ 	'E!ejj%2B2BCJW..444 
}} 1 1 7 77--zzW..===!*-
zzW..:::g.E)E!&F5::	'  MM

 7=llnE74tallA&&E
 	
 Fs   'Fc                     i }| j                   j                  D ]D  }t        | |      st        | |      }t	        |t
              r|j                         ||<   @|||<   F |S )zConvert instance to dict.)r=   rO   hasattrrV   rY   rI   
model_dump)r$   resultre   rg   s       r   r   zSchema.model_dump   s`    NN// 	'DtT"dD)c6*#&>>#3F4L#&F4L	' r   )r   r   r   r   rN   rn   rQ   rO   rS   r%   r[   rr   r   r   r@   rA   s   @r   rI   rI   o   s\    P#*tLL$LL$">3 - -$ 
 	-
 -
^
r   rI   c                 T   |ddi}i }i }i }|j                         D ]  \  }}t        |t              r0t        |      dk(  r"|\  }}	t        |	t              st	        |	      }	nt        d| d      ||	_        |	||<   |||<   |	j                         rw|	j                  ||<    ||d}
|
j                  |       t        | t        f|
      }|r|j                  d	      nd}|r=t        |      r2|j                         D ]  \  }}|j                   ||      |_        ! ||_        |S )
zkDynamically create a Schema subclass.

    Each field value should be a (annotation, FieldInfo) tuple.
    NrL   rJ      r'   zField z& must be (annotation, FieldInfo) tuple)rQ   rN   rl   )rW   rY   tuplelenr   
ValueErrorr    r)   r   rF   rZ   rI   r4   r^   r   rO   )__namerw   ra   	processedannotationsdefaultsre   	field_defr    
field_info	namespacer_   ro   rh   s                 r   r   r      sD   
 w'
IKH!<<> 0ii'C	Na,?%."J
j)4&z:
vdV+QRSS *
$	$&D%%''//HTN0 '"I X
vy)
,C5?
01TIXi($??, 	.KD%{{"'o	. !CJr   c                     	 t        | dd      }|rt        j                  j                  |      nd}|rt	        |      nd}t        | |      S # t        t        t        t        f$ r i cY S w xY w)z|Resolve type hints for a function, handling forward references.

    Falls back to raw annotations if resolution fails.
    r   N)globalns)
rV   sysmodulesr4   varsr   	NameErrorAttributeError	TypeErrorRecursionError)r   mod_namemoduler   s       r   ry   ry     sd    

4t4.6*D#)4<tdX66~y.A 
 	s   AA A,+A,c                 |    | t         u s| t        u ry| t        u ry| t        u s| t        u ry| t
        u s| t        u ryy)z+Get an error type string for an annotation.int_parsingstring_typefloat_parsing	bool_typevalue_error)intr   strfloatr   boolr   )r    s    r   _error_type_forr   /  sF    SJ+5	s		u	
k 9	t	zZ7r   c                     t               }t        | ||      ry|j                  rt        |j                  d         S | d| S )zqValidate value against a type annotation.

    Returns None if valid, or an error message string if invalid.
    )ctxNr   z does not match )r   _tc2_check_typer?   r   )valuer    r   s      r   validate_typer   <  sF    
 %Cujc2
zz3::a=!!Y&zl33r   c                 \   g }|j                  dd      }i }t               }|j                         D ]C  \  }}	|	j                  |	j                  }
n|r	 ||      }
n|}
|j	                  |
       ||	f||
<   E |dk(  r"| D ]  }||vs|j                  |fddd        |j                         D ]{  \  }
\  }}	|
| v rH| |
   }t        ||	j                        }|s+|j                  |
f|t        |	j                        d       U|	j                         sf|j                  |
fddd       } |S )	zcValidate a data dict against schema fields.

    Returns list of error dicts (empty if valid).
    rL   rJ   rv   zExtra inputs are not permittedextra_forbidden)locr2   rZ   zField requiredmissing)
r4   setrW   r   addappendr   r    r   r)   )rG   ra   rs   rl   r?   
extra_modekey_to_field
known_keysre   rh   rq   keyr   errs                 r   rm   rm   L  s]   
 FGW-J LJ||~ 	/e;;"{{H&t,HHx "&X	/ X 	C*$ #v? 1	 $0#5#5#7 -4tNEu'7'78C ({" /0@0@ A  MM$;+%* Mr   _pydantic_cachec                      g } t         | j                  t                t        | j                  t               | rt        |       S t        fS )zReturn the pydantic ValidationError class(es) to catch.

    Tries both pydantic.v1 and pydantic so we catch the right exception
    regardless of which API the caller's model was built with.
    )_PydanticV1ValidationErrorr   _PydanticV2ValidationErrorr   	Exception)r?   s    r   _get_pydantic_validation_errorr     sF     F!-01!-01V} <r   c                     t        | t              syt        | t              ryt        t        | t              ryt
        t        | t
              ryy)zCheck if cls is a pydantic BaseModel class (v1 or v2) without hard-depending
    on pydantic. Returns False if pydantic is not installed.FT)rY   rZ   
issubclassrI   _PydanticV1BaseModel_PydanticV2BaseModelr_   s    r   _is_pydantic_modelr     sG     c4 #v'Js<P,Q'Js<P,Qr   c                 v    t        | d      r| j                         S t        | d      r| j                         S | S )z,Convert a pydantic model instance to a dict.r   rn   )r   r   rn   )objs    r   _pydantic_instance_to_dictr     s4    sL!~~sFxxzJr   c                 P   i }t        | d      r| j                  j                         D ]  \  }}|j                  }|j	                         rd}n|j
                  }|j                  }t        |t              rt        |      rt        |      }|durt        |d      rt        |      }t        ||      }||_        |||<    |S t        | d      r| j                  j                         D ]  \  }}|j                  }t        |dd      r	t         |   }|j"                  rd}n|j
                  }|j                  |k7  r|j                  nd}t        |t              rt        |      rt        |      }|durt        |d      rt        |      }t        ||      }||_        |||<    |S )	zEExtract field definitions from a pydantic BaseModel class (v1 or v2).rO   .r   r-   
__fields__
allow_noneFN)r   rO   rW   r    r)   r   r   rY   rZ   r   ensure_schemar   r   r   outer_type_rV   r   required)pydantic_clsra   re   	pyd_fieldr    r   r   rh   s           r   _extract_pydantic_fieldsr     s   F|^,  ,88>>@ 	!OD)"--J$$&#++OOE*d+0B:0N*:6
c!gg|&D4W=gU;E)E F4L	!T M3 
|	,+66<<> 	!OD)"..J y,6%j1
!!#++'0$'>IOODE *d+0B:0N*:6
c!gg|&D4W=gU;E)E F4L+	!. Mr   c                 x   ddi}t        | d      rn| j                  }t        |dd      }t        |d      r|j                  }t	        |t
              r|n
t        |      |d<   t        |d      r|j                  |d<   |S t        | d      r/t	        | j                  t              rt        | j                        }|S )z@Extract model config from a pydantic BaseModel class (v1 or v2).rL   rJ   rw   r   rM   rN   )	r   rw   rV   r   rY   r   rM   rN   rn   )r   rs   cfgrL   s       r   _extract_pydantic_configr     s    wF|\*%%Wg.5'"KKE#-eS#9%s5zw312030K0KF,- M 
~	.:!!44 l//0Mr   c                 F   t        | t              rt        | t              r| S t	        |       s| S | t
        v r	t
        |    S t        |       }t        |       }| t        t        |       t        fi       }||_	        ||_
        t        fd       }||_        |t
        | <   |S )uf  Ensure *schema_cls* satisfies the Schema interface.

    If it already is a Schema subclass, return it unchanged.
    If it is a pydantic BaseModel (v1 or v2), build a thin Schema wrapper
    that exposes the same ``model_fields`` / ``model_config`` and delegates
    ``model_validate`` to the original pydantic class so that pydantic
    validators, strict types, constrained types etc. keep working.

    This allows downstream libraries (spaCy, thinc, …) to keep passing
    pydantic schemas to ``registry.resolve()`` / ``registry.fill()`` even
    though confection itself no longer depends on pydantic.
    c                    t               }	 t        d      rj                  |       n&t        d      rj                  |       n di | t        |      }| j                  j                         D ]D  \  }}|j                  |j                  n|}||vs%|j                         r6|j                  ||<   F t        |      S # |$ r}t	        |j                               d d }~ww xY w)Nrr   	parse_objr   )r   r   rr   r   r   r?   rn   rO   rW   r   r)   r   rC   )	r_   rG   pyd_validation_errr6   rp   re   rh   rq   pyd_clss	           r   _pydantic_model_validatez/ensure_schema.<locals>._pydantic_model_validate$  s     <=
	w 01&&t,+.!!$'$ 4j++113 	6KD%&+kk&=u{{4H{*53D3D3F(-H%	6  ,, " 	!
	s   AC C,C''C,)rY   rZ   r   rI   r   r   r   r   pydantic_cls_namerO   rN   r[   rr   )
schema_clsra   rs   wrapperr   r   s        @r   r   r     s     *d#
:v(Fj) _$z**%j1F%j1F G$Z06)R@G!G!G - -0 6G")OJNr   c                     t        | dd      S )Nr   PydanticSchema)rV   r   s    r   r   r   C  s    3
$455r   r*   r#   )-r   rz   r   rx   r   r   r   typecheckerr   r   r   version_infor   r   pydantic.v1r   r   ImportErrorModuleNotFoundErrorpydanticr   r   r   r   r   r   r.   r   rC   rI   r   ry   r   r   rm   r   rn   rQ   r   r   r   r   r   r   r   r   r   r   <module>r      sA    
 0 0  6
 w!%	*	
	
	&	 		 		 	# #3 3	i 	# #y yx)^*

4 9|  &1h.>B6O ,- *#%)"* 	() &!%&s#   C C CCC+*C+