
    g#                        d dl Z d dlmZ d dlZd dlmZ d dlmZ d dlZd dl	m
Z
mZmZmZmZ ddlmZmZmZ ddlmZmZmZ dd	l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#  ejH                  d      Z% e&       Z'dee   de
e(e(f   fdZ)dee   de*fdZ+dee   de*fdZ,dede-fdZ.dedee-   fdZ/dede-fdZ0dede-de
e-e-f   fdZ1dedefdZ2	 d<ddddddedee   de*de*de*de*defdZ3d ed!ed"e*fd#Z4d$edefd%Z5d edede*fd&Z6ded'e-de*de*d(ee-   ded ed"e*defd)Z7d* Z8ddddd+d,e-d-ee   dee   de*d.eee-      defd/Z9d0 Z:d1 Z;d=d2Z<dd3d4ee-   de*defd5Z=dede-fd6Z>d7 Z?d8e-d9e-de-fd:Z@d; ZAy)>    N)StringIO)path)deepcopy)TupleSetOptionalListAny   )
DictSchemaSchemaNamedSchemas)FlatDictRepositorySchemaRepositoryErrorAbstractSchemaRepository)
AVRO_TYPES)

PRIMITIVESUnknownTypeSchemaParseExceptionRESERVED_PROPERTIESOPTIONAL_FIELD_PROPERTIESRESERVED_FIELD_PROPERTIESJAVA_FINGERPRINT_MAPPINGFINGERPRINT_ALGORITHMSRABIN_64rabin_fingerprintz[A-Za-z_][A-Za-z0-9_]*schemareturnc                     d}d}| D ]@  }t        |      }|dk(  r|dz  }|dz  }|dk(  s|dk(  r|dz  }.|t        vs7|dz  }|dz  }B ||fS )Nr   recordr   enumfixed)extract_record_typer   )r   record_type_countnamed_type_countsextracted_types        H/var/www/openai/venv/lib/python3.12/site-packages/fastavro/_schema_py.py&_get_name_and_record_counts_from_unionr)   !   s    ,Q/X%"!v%7)B!:-! "  ...    c                 $    t        |       d   dk(  S )Nr   r)   r   s    r(   is_single_record_unionr.   5       1&9!<AAr*   c                 $    t        |       d   dk(  S )Nr   r   r,   r-   s    r(   is_single_name_unionr1   9   r/   r*   c                 R    t        | t              r| d   S t        | t              ry| S )Ntypeunion)
isinstancedictlistr-   s    r(   r#   r#   =   s(    &$f~&$Mr*   c                 h    t        | t              sy | }|d   }|j                  d      }|r| d| S y )Nr3   logicalType-)r5   r6   get)r   d_schemartlts       r(   extract_logical_typer?   G   sB    fd#H	&	B	m	$B	Qrd|r*   c                      t        | d      d   S )aQ  Returns the fullname of a schema

    Parameters
    ----------
    schema
        Input schema


    Example::

        from fastavro.schema import fullname

        schema = {
            'doc': 'A weather reading.',
            'name': 'Weather',
            'namespace': 'test',
            'type': 'record',
            'fields': [
                {'name': 'station', 'type': 'string'},
                {'name': 'time', 'type': 'long'},
                {'name': 'temp', 'type': 'int'},
            ],
        }

        fname = fullname(schema)
        assert fname == "test.Weather"
     r   )schema_namer-   s    r(   fullnamerC   S   s    8 vr"1%%r*   	parent_nsc                     	 | d   }| j                  d|      }d|v r|j                  dd      d   |fS |r	|| d| fS d|fS # t         $ r t        d|        w xY w)Nnamez4"name" is a required field missing from the schema: 	namespace.r   r   rA   )KeyErrorr   r;   rsplit)r   rD   rF   rG   s       r(   rB   rB   r   s    
f~ 

;	2I
d{{{3"1%t++	YKq///4x  
"B6(K
 	

s   A Ac                     t        | dd      S )a  Returns a schema where all named types are expanded to their real schema

    NOTE: The output of this function produces a schema that can include
    multiple definitions of the same named type (as per design) which are not
    valid per the avro specification. Therefore, the output of this should not
    be passed to the normal `writer`/`reader` functions as it will likely
    result in an error.

    Parameters
    ----------
    schema: dict
        Input schema


    Example::

        from fastavro.schema import expand_schema

        original_schema = {
            "name": "MasterSchema",
            "namespace": "com.namespace.master",
            "type": "record",
            "fields": [{
                "name": "field_1",
                "type": {
                    "name": "Dependency",
                    "namespace": "com.namespace.dependencies",
                    "type": "record",
                    "fields": [
                        {"name": "sub_field_1", "type": "string"}
                    ]
                }
            }, {
                "name": "field_2",
                "type": "com.namespace.dependencies.Dependency"
            }]
        }

        expanded_schema = expand_schema(original_schema)

        assert expanded_schema == {
            "name": "com.namespace.master.MasterSchema",
            "type": "record",
            "fields": [{
                "name": "field_1",
                "type": {
                    "name": "com.namespace.dependencies.Dependency",
                    "type": "record",
                    "fields": [
                        {"name": "sub_field_1", "type": "string"}
                    ]
                }
            }, {
                "name": "field_2",
                "type": {
                    "name": "com.namespace.dependencies.Dependency",
                    "type": "record",
                    "fields": [
                        {"name": "sub_field_1", "type": "string"}
                    ]
                }
            }]
        }
    TF)expand_write_hint)parse_schemar-   s    r(   expand_schemarO      s    B t??r*   FTrL   rM   _force_ignore_default_errornamed_schemasrL   rM   rQ   rR   c                   |i }t        | t              rGd| v rCd| v r!| d   j                         D ]
  \  }}|||<    nt        | d||t	               |t
        |      S |s|rt        | d||t	               |t
        |      S t        | t              rd| v r| S t        | t              r| D cg c]  }t        ||||||       c}S t        | d||t	               |t
        |      S c c}w )a|  Returns a parsed avro schema

    It is not necessary to call parse_schema but doing so and saving the parsed
    schema for use later will make future operations faster as the schema will
    not need to be reparsed.

    Parameters
    ----------
    schema
        Input schema
    named_schemas
        Dictionary of named schemas to their schema definition
    expand
        If true, named schemas will be fully expanded to their true schemas
        rather than being represented as just the name. This format should be
        considered an output only and not passed in to other reader/writer
        functions as it does not conform to the avro specification and will
        likely cause an exception
    _write_hint
        Internal API argument specifying whether or not the __fastavro_parsed
        marker should be added to the schema
    _force
        Internal API argument. If True, the schema will always be parsed even
        if it has been parsed and has the __fastavro_parsed marker
    _ignore_default_error
        Internal API argument. If True, when a union has the wrong default
        value, an error will not be raised.


    Example::

        from fastavro import parse_schema
        from fastavro import writer

        parsed_schema = parse_schema(original_schema)
        with open('weather.avro', 'wb') as out:
            writer(out, parsed_schema, records)


    Sometimes you might have two schemas where one schema references another.
    For the sake of example, let's assume you have a `Parent` schema that
    references a `Child` schema`. If you were to try to parse the parent schema
    on its own, you would get an exception because the child schema isn't
    defined. To accommodate this, we can use the `named_schemas` argument to pass
    a shared dictionary when parsing both of the schemas. The dictionary will
    get populated with the necessary schema references to make parsing possible.
    For example::

        from fastavro import parse_schema

        named_schemas = {}
        parsed_child = parse_schema(child_schema, named_schemas)
        parsed_parent = parse_schema(parent_schema, named_schemas)
    __fastavro_parsed__named_schemasrA   rP   )r5   r6   items_parse_schemaset
NO_DEFAULTr7   rN   )	r   rS   rL   rM   rQ   rR   keyvaluer&   s	            r(   rN   rN      s7   ~ &$$76$A&$%67==?
U%*c" @ !%	 	 E!	
 		
 
FD	!&9V&C	FD	! 

  '&; 

 
	
 E!	
 		


s   (C!defaultschema_typeignore_default_errorc                 `    |ry t        |t              rd| }nd| }t        d|  d|       )Nza schema in union with type: zschema type: zDefault value <z> must match )r5   r7   r   )r]   r^   r_   texts       r(   _raise_default_value_errorrb   D  sD     	K	&.{m<{m,
	tfM
NNr*   r\   c                 H    	 t        |       S # t        t        f$ r | cY S w xY wN)float	TypeError
ValueError)r\   s    r(   _maybe_floatrh   Q  s*    U|z" s   
 !!c                 ^   |dk(  r| |dk(  rt        | t              r|dk(  rt        | t              r{|dk(  rt        | t              rf|dk(  rt        t        |       t              rH|dk(  rt        t        |       t              r*|dk(  rt        | t
              r|dk(  rt        | t
              sy	y
)Nnullbooleanstringbytesdoublere   intlongFT)r5   boolstrrh   re   ro   )r]   r   s     r(   _default_matches_schemars   X  s     
6	g1i
7D(Ahz'3'?gj#&>hz,w2G'Ogjg1F&NeOJw$<fZ%=r*   rG   namesc                 r
   t        | t              rP| D cg c]  }t        |||d||t        |       }	}|t        ur#|	D ]  }t	        ||      s |	S  t        || |       |	S t        | t              sX| t        v r#|t        urt	        ||       st        || |       | S d| vr
|r|dz   | z   } | |vrt        |       |rd||    v r||    S | S | d   }
| j                         D ci c]  \  }}|t        vr|| }}}|
|d<   d| v r| d   |d<   |j                  d      }|dk(  r|j                  d      }|r#t        |t              r|d	k  rt        d
|       |j                  d      }|rt        |t              r|d	k  rt        dd| z         |
dk(  rY| d   }t        t        j                  t        j                   d      d|z  dz
  z              }||kD  rt        d| dd| z         |r|r||k  rt        dd| z         |
dk(  rCt        | d   ||d||t        |      |d<   |t        urt        |t              st        ||
|       |S |
dk(  rCt        | d   ||d||t        |      |d<   |t        urt        |t              st        ||
|       |S |
dk(  rvt#        | |      \  }}||v rt        d|       |j%                  |       t'        |        |t        urt        |t(              st        ||
|       |||<   ||d<   | d   |d<   |S |
dk(  rkt#        | |      \  }}||v rt        d|       |j%                  |       |t        urt        |t(              st        ||
|       |||<   ||d<   | d   |d<   |S |
dk(  s|
d k(  rt#        | |      \  }}||v rt        d|       |j%                  |       |t        urt        |t              st        ||
|       |||<   g }| j                  d!g       D ]!  }|j+                  t-        ||||||             # ||d<   ||d!<   |r1|j                         D ci c]  \  }}||
 c}}||<   d"|d#<   ||d$<   |S |
t        v r|
|d<   |t        ur|
d%k(  r||
d&k(  rt        |t.              r~|
d'k(  rt        |t(              ri|
d(k(  rt        |t(              rT|
d)k(  rt        |t0              r?|
d*k(  rt        |t0              r*|
d+k(  rt        |t              r|
d,k(  rt        |t              st        ||
|       |S t        |       c c}w c c}}w c c}}w )-NFrH   rF   r3   docr9   decimalscaler   z.decimal scale must be a positive integer, not 	precisionz.decimal precision must be a positive integer, znot r"   size      r   zdecimal precision of z doesn't fit zinto array of length z,decimal scale must be less than or equal to zthe precision of arrayrW   mapvaluesr!   zredefined named type: symbolsr    errorfieldsTrU   rV   rj   rk   rl   rm   rn   re   ro   rp   )r5   r7   rX   rZ   rs   rb   r6   r   r   rW   r   r;   ro   r   mathfloorlog10rB   add_validate_enum_symbolsrr   appendparse_fieldrq   re   )r   rG   rL   rM   rt   rS   r]   r_   r&   parsed_schemasr^   r[   r\   parsed_schemalogical_typerx   ry   rz   max_precision_rC   r   fieldkvs                            r(   rX   rX   h  sv    &$ 
  $	  	 
 *$#*7A6  $ +7F<PQ %Zj(.w?.w@TUMf_v-F&f%%ff 55 !(( Vn %lln
,
U-- J, 	 

 !,fF?#)%=M%  %((79$!%%g.Ej4	*DUGL  &))+6I!)S1Y!^.H ,-  ')!&>D$'

4::a=AHqL3Q(R$SM =023I;mL 5dV<= 
 y5'8*B))56 
 '!%2w$	&M'" j(GT1J*7KAUVP M E!&3x $	'M(# j(GT1J*7KAUVt q F"%fi8KAx5 *-CH:+NOOIIh"6*j(GS1I*7KAUV&3M(#$,M&!'-i'8M)$T Q G#%fi8KAx5 *-CH:+NOOIIhj(GS1I*7KAUV&3M(#$,M&!$*6NM&!x u H$w(>"-fi"@Ix5 *-CH:+NOOIIhj(GT1J*7KAUV&3M(#FHb1!%,	 2 %-M&!&,M(#  =J<O<O<Q*R<QDAq1a4<Q*Rh'59123@/0, ) J&$/M&!j( F*w/B#y0GT9R#x/
7C8P#w.z'37O#x/
7E8R#w.z'57Q#u,Z5M#v-j#6N..B  f%%Y
`
J +Ss   T(!T-?T3c           
      d   | j                         D ci c]  \  }}|t        vr|| }}}t        D ]  }	|	| v s| |	   ||	<    |j                  dg       }
t	        |
t
              st        d|
       | j                  dt              }| d   |d<   t        | d   ||d||||      |d<   |S c c}}w )Naliaseszaliases must be a list, not r]   rF   r3   F)	rW   r   r   r;   r5   r7   r   rZ   rX   )r   rG   rL   rt   rS   r_   r[   r\   parsed_fieldpropr   r]   s               r(   r   r   E  s      ++-'JC// 	U
'   *5=!&tL *
 y"-Ggt$"%A'#KLLii	:.G =L(f	L ;s   B,)reporS   rM   _injected_schemasschema_pathr   r   c                    | }|;t        j                  |       \  }}t        j                  |      \  }}t        |      }|i }|
t	               }t        |||||      S )a  Returns a schema loaded from repository.

    Will recursively load referenced schemas attempting to load them from
    same repository, using `schema_path` as schema name.

    If `repo` is not provided, `FlatDictRepository` is used.
    `FlatDictRepository` will try to load schemas from the same directory
    assuming files are named with the convention `<full_name>.avsc`.

    Parameters
    ----------
    schema_path
        Full schema name, or path to schema file if default repo is used.
    repo:
        Schema repository instance.
    named_schemas
        Dictionary of named schemas to their schema definition
    _write_hint
        Internal API argument specifying whether or not the __fastavro_parsed
        marker should be added to the schema
    _injected_schemas
        Internal API argument. Set of names that have been injected


    Consider the following example with default FlatDictRepository...


    namespace.Parent.avsc::

        {
            "type": "record",
            "name": "Parent",
            "namespace": "namespace",
            "fields": [
                {
                    "name": "child",
                    "type": "Child"
                }
            ]
        }


    namespace.Child.avsc::

        {
            "type": "record",
            "namespace": "namespace",
            "name": "Child",
            "fields": []
        }


    Code::

        from fastavro.schema import load_schema

        parsed_schema = load_schema("namespace.Parent.avsc")
    )r   splitsplitextr   rY   _load_schema)	r   r   rS   rM   r   rB   file_dir	file_name	_file_exts	            r(   load_schemar   f  sq    D K|"jj5)!%y!9Y!(+ ET=+7H r*   c                 j    	 |j                  |       }t        |||||      S # t        $ r}|d }~ww xY wrd   )load_parse_schema_with_repor   )rB   r   rS   
write_hintinjected_schemasr   r   s          r(   r   r     sH    
;'&
 	
 ! s   " 	2-2c                 r   	 t        |      }t        | ||      S # t        $ r}|j                  }	 t	        ||d|      }n# t
        $ r |w xY w|d   |vrEt        | |      }	t        | t              st        | t              r|	d   } |j                  |d          t        | ||||      cY d }~S d }~ww xY w)NrS   rM   F)rS   r   r   rF   r   )r   rN   r   rF   r   r   _inject_schemar5   rr   r7   r   r   )
r   r   rS   r   r   schema_copyr   missing_subject
sub_schemainjected_schemas
             r(   r   r     s    
}-'"
 	

  
**		%) !1J % 	K	 f%55,VZ@O&#&*VT*B(+  F!34&D+z3C
 	
%
s2    	B6B1AB1AAB1+B61B6c                 &   |}|du r| |fS t        | t              rJg }| D ]?  }|r|j                  |       t        ||||      \  }}|j                  |       |du s>|}A ||fS t        | t              s*| t
        v r| |fS d| vr
|r|dz   | z   } | |d   k(  r|dfS | |fS | d   }	|	dk(  rt        | d   |||      \  }}|| d<   | |fS |	dk(  rt        | d   |||      \  }}|| d<   | |fS |	d	k(  r| |fS |	d
k(  r| |fS |	dk(  s|	dk(  rxt        | |      \  }}
g }| j                  dg       D ]G  }|r|j                  |       t        |d   |||      \  }}||d<   |j                  |       |du sF|}I |r|| d<   | |fS |	t
        v r| |fS t        d      )NTrH   rF   r3   r}   rW   r~   r   r!   r"   r    r   r   zKInternal error; You should raise an issue in the fastavro github repository)	r5   r7   r   r   r6   r   rB   r;   	Exception)outer_schemainner_schemansis_injectedrG   r4   each_schemareturn_schemainjectedr^   r   r   r   s                r(   r   r     sX   I d[(( ,%'K[)*8y++'x ]+t#"*K ( k!! d+:%,,l"y$s?\9L<//%%  ,, #6*'!&4W%|Y'#M8 %2L!))E!&4X&i'#M8 &3L"))F",,G#,,H$w(>&|Y?LIqF%))(B7MM%(.<f|Y/+M8 %2E&MMM%(4'&. 8 )/X&,,J&,, P r*   )rM   ordered_schemasc                   g }i }t        |       D ]9  \  }}|dz   t        |       k(  r|nd}t        |||      }|j                  |       ; |ddd   }|j	                  d      }	|r |j	                  d      }
t        |	|
       |r |	S )a  Returns a schema loaded from a list of schemas.

    The list of schemas should be ordered such that any dependencies are listed
    before any other schemas that use those dependencies. For example, if schema
    `A` depends on schema `B` and schema B depends on schema `C`, then the list
    of schemas should be [C, B, A].

    Parameters
    ----------
    ordered_schemas
        List of paths to schemas
    _write_hint
        Internal API argument specifying whether or not the __fastavro_parsed
        marker should be added to the schema


    Consider the following example...


    Parent.avsc::

        {
            "type": "record",
            "name": "Parent",
            "namespace": "namespace",
            "fields": [
                {
                    "name": "child",
                    "type": "Child"
                }
            ]
        }


    namespace.Child.avsc::

        {
            "type": "record",
            "namespace": "namespace",
            "name": "Child",
            "fields": []
        }


    Code::

        from fastavro.schema import load_schema_ordered

        parsed_schema = load_schema_ordered(
            ["path/to/namespace.Child.avsc", "path/to/Parent.avsc"]
        )
    r   Fr   Nr   )	enumeratelenr   r   popr   )r   rM   loaded_schemasrS   idxr   _lastr   top_first_orderr   r   s              r(   load_schema_orderedr   G  s    n N"$M%o6["Qw#o*>>E}%
 	f% 7 %TrT*O"&&q)L
$((+
|Z0  r*   c                 `    t               }t        t        |       |       |j                         S )a'  Returns a string represening the parsing canonical form of the schema.

    For more details on the parsing canonical form, see here:
    https://avro.apache.org/docs/current/spec.html#Parsing+Canonical+Form+for+Schemas

    Parameters
    ----------
    schema
        Schema to transform

    )r   _to_parsing_canonical_formrN   getvalue)r   fos     r(   to_parsing_canonical_formr     s&     
B|F3R8;;=r*   c           	         t        | t              rX|j                  d       t        |       D ]'  \  }}|dk7  r|j                  d       t	        ||       ) |j                  d       y t        | t
              s|j                  d|  d       y | d   }|dk(  r6|j                  d| d	       t	        | d
   |       |j                  d       y |dk(  r6|j                  d| d       t	        | d   |       |j                  d       y |dk(  rp| d   }|j                  d| d| d       t        | d         D ]0  \  }}|dk7  r|j                  d       |j                  d| d       2 |j                  d       y |dk(  r&| d   }| d   }|j                  d| d| d| d       y |dk(  s|dk(  r| d   }|j                  d| d       t        | d         D ]U  \  }}|dk7  r|j                  d       |d   }|j                  d| d       t	        |d   |       |j                  d       W |j                  d       y |t        v r|j                  d| d       y y )N[r   ,]"r3   r}   z	{"type":"z
","items":rW   }r~   z","values":r   r!   rF   z	{"name":"z
","type":"z","symbols":[r   z]}r"   rz   z	","size":r    r   z","type":"record","fields":[r   z	","type":)r5   r7   writer   r   r6   r   )	r   r   r   r&   r^   rF   symbolrz   r   s	            r(   r   r     s[   &$
'FCax&q"- ( 	 %
1VHA Vn'!HHz+j9:&vg;HHSME!HHz+k:;&vh'7<HHSMF"&>DHHz$z+mLM(	):;V!8HHSM1VHA'  < HHTNG#&>D&>DHHz$z+ivRPQH$w(>&>DHHz$'CDE'x(89
U!8HHSMV}:dV956*5="= : HHTNJ&HHqQ'( 'r*   parsing_canonical_form	algorithmc                    |t         vrt        d| ddt          z         t        j                  ||      }|t        k(  rt        | j                               S t        j                  || j                               }|j                         S )at  Returns a string represening a fingerprint/hash of the parsing canonical
    form of a schema.

    For more details on the fingerprint, see here:
    https://avro.apache.org/docs/current/spec.html#schema_fingerprints

    Parameters
    ----------
    parsing_canonical_form
        The parsing canonical form of a schema
    algorithm
        The hashing algorithm

    z%Unknown schema fingerprint algorithm z. zValid values include: )
r   rg   r   r;   r   r   encodehashlibnew	hexdigest)r   r   hs      r(   fingerprintr     s     ..3I;bA&'=&>?@
 	
 ),,Y	BIH !7!>!>!@AAI5<<>?A;;=r*   c                     | d   }|D ]2  }t        |t              rt        j                  |      r)t	        d       t        |      t        t        |            k7  rt	        d      d| v r| d   |vrt	        d      y y )Nr   zEEvery symbol must match the regular expression [A-Za-z_][A-Za-z0-9_]*z%All symbols in an enum must be uniquer]   z.Default value for enum must be in symbols list)r5   rr   SYMBOL_REGEX	fullmatchr   r   rY   )r   r   r   s      r(   r   r     s    YG&#&l.D.DV.L&W  
 7|s3w<(("#JKKFvi0?"#STT  @r*   rd   )rA   F)Br   ior   r   osr   copyr   retypingr   r   r   r	   r
   typesr   r   r   
repositoryr   r   r   constr   _schema_commonr   r   r   r   r   r   r   r   r   r   compiler   objectrZ   ro   r)   rq   r.   r1   rr   r#   r?   rC   rB   rO   rN   rb   rh   rs   rX   r   r   r   r   r   r   r   r   r   r    r*   r(   <module>r      s2        	 2 2 3 3 
    rzz34X
/4< /E#s(O /(B4< BD BBf B$ B 3 	 	HSM 	&Z &C &>
 s uS#X "A@& A@V A@L -1z
 "'z
z
L)z
 	z

 z
 z
  z
 z
z
O
O"
O:>
O  S & T  ZZZ Z 	Z
 s8Z  Z Z Z ZzH 04,0,0PP +
,P L)	P
 P  C)P Pf"
JXx 8<H#YH04HHVf  "9)x   >Ur*   