
    od}s                         d dl Z d dlZddlmZ ddlmZmZ ddddd	d
ddZ ej        d          Z	 G d de          Z
dS )    N   )JsonSchemaDefinitionException)CodeGeneratorenforce_listNoneTypeboolz
int, floatintstrzlist, tupledict)nullbooleannumberintegerstringarrayobjectz	(?<!\\)\$c                        e Zd ZdddddddZdi d	f fd
	Ze fd            Zd Zd Zd Z	d Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd  Zd! Zd" Zd# Zd$ Z xZ S )%CodeGeneratorDraft04zk^\d{4}-[01]\d-[0-3]\d(t|T)[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:[+-][0-2]\d:[0-5]\d|[+-][0-2]\d[0-5]\d|z|Z)\Zz^[^@]+@[^@]+\.[^@]+\Zzv^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9])\ZzV^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\Za  ^(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)\Zz^\w+:(\/?\/?)[^\s]+\Z)z	date-timeemailhostnameipv4ipv6uriNTc                 *   t                                          ||           || _        || _        | j                            d| j        fd| j        fd| j        fd| j	        fd| j
        fd| j        fd| j        fd| j        fd	| j        fd
| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        fd| j        ff           d| _        d S )NtypeenumallOfanyOfoneOfnot	minLength	maxLengthpatternformatminimummaximum
multipleOfminItemsmaxItemsuniqueItemsitemsminPropertiesmaxPropertiesrequireddependencies
propertiespatternPropertiesadditionalPropertiesr   )super__init___custom_formats_use_default_json_keywords_to_functionupdategenerate_typegenerate_enumgenerate_all_ofgenerate_any_ofgenerate_one_ofgenerate_notgenerate_min_lengthgenerate_max_lengthgenerate_patterngenerate_formatgenerate_minimumgenerate_maximumgenerate_multiple_ofgenerate_min_itemsgenerate_max_itemsgenerate_unique_itemsgenerate_itemsgenerate_min_propertiesgenerate_max_propertiesgenerate_requiredgenerate_dependenciesgenerate_propertiesgenerate_pattern_propertiesgenerate_additional_properties_any_or_one_of_count)self
definitionresolverformatsuse_default	__class__s        6lib/python3.11/site-packages/fastjsonschema/draft04.pyr4   zCodeGeneratorDraft04.__init__%   se   X...&''..T'(T'(d*+d*+d*+D%&$23$23-.t+,-.-.4450101D67d)*d:;d:;/0T78434 $"BC#T%HI30
 	 	 	6 %&!!!    c                 B    t                      j        }| j        |d<   |S )Ncustom_formats)r3   global_stater5   )rR   resrW   s     rX   r\   z!CodeGeneratorDraft04.global_stateF   s"    gg" $ 4
rY   c                    t          | j        d                   }	 d                    d |D                       }n4# t          $ r'}t	          d                    |                    d}~ww xY wd}d|v sd|v rd	|vrd
                    | j                  }|                     d||          5  |                     dd                    |          d           ddd           dS # 1 swxY w Y   dS )z
        Validation of type. Can be one type or list of types.

        .. code-block:: python

            {'type': 'string'}
            {'type': ['string', 'number']}
        r   z, c              3   0   K   | ]}t           |         V  d S )N)JSON_TYPE_TO_PYTHON_TYPE).0ts     rX   	<genexpr>z5CodeGeneratorDraft04.generate_type.<locals>.<genexpr>W   s(      $P$PQ%=a%@$P$P$P$P$P$PrY   zUnknown type: {}N r   r   r   z  or isinstance({variable}, bool))variablez&if not isinstance({variable}, ({})){}:{name} must be {}z or rule)	r   _definitionjoinKeyErrorr   r$   	_variablelexc)rR   typespython_typesrn   extras        rX   r9   z"CodeGeneratorDraft04.generate_typeL   s|    T-f566	P99$P$P%$P$P$PPPLL 	P 	P 	P/0B0I0I#0N0NOOO	P  	We!3 	W%9O 	W6==t~=VVEVV<lERR 	K 	KHH(&++e*<*<6HJJJ	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	Ks'   < 
A-"A((A-0,C))C-0C-c                 (   | j         d         }t          |t          t          f          st	          d          |                     d          5  |                     d|                     |          d           ddd           dS # 1 swxY w Y   dS )z
        Means that only value specified in the enum is valid.

        .. code-block:: python

            {
                'enum': ['a', 'b'],
            }
        r   zenum must be an arrayzif {variable} not in {enum}:z{name} must be one of {}rg   N)ri   
isinstancelisttupler   rm   rn   e)rR   r   s     rX   r:   z"CodeGeneratorDraft04.generate_enumb   s     '$u.. 	I/0GHHHVV233 	L 	LHH/FHKKK	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	Ls   ,BBBc                 l    | j         d         D ]%}|                     || j        | j        d           &dS )a  
        Means that value have to be valid by all of those definitions. It's like put it in
        one big definition.

        .. code-block:: python

            {
                'allOf': [
                    {'type': 'number'},
                    {'minimum': 5},
                ],
            }

        Valid values for this definition are 5, 6, 7, ... but not 4 or 'abc' for example.
        r   Tclear_variablesN)ri   generate_func_code_blockrl   _variable_name)rR   definition_items     rX   r;   z$CodeGeneratorDraft04.generate_all_ofr   sO       $/8 	v 	vO))/4>4K^pt)uuuu	v 	vrY   c           	      n   | xj         dz  c_         | j         }|                     d|           | j        d         D ]}|                     d|d          5  |                     dd	          5  |                     || j        | j        d
           |                     d|           ddd           n# 1 swxY w Y   |                     d           ddd           n# 1 swxY w Y   |                     d|d          5  |                     dd           ddd           dS # 1 swxY w Y   dS )a  
        Means that value have to be valid by any of those definitions. It can also be valid
        by all of them.

        .. code-block:: python

            {
                'anyOf': [
                    {'type': 'number', 'minimum': 10},
                    {'type': 'number', 'maximum': 5},
                ],
            }

        Valid values for this definition are 3, 4, 5, 10, 11, ... but not 8 for example.
        r   z"{variable}_any_of_count{count} = 0countr   z&if not {variable}_any_of_count{count}:Fr   optimizetry:r   Trx   z#{variable}_any_of_count{count} += 1N%except JsonSchemaValueException: passz,{name} cannot be validated by any definitionrg   rQ   rm   ri   rz   rl   r{   rn   )rR   r   r|   s      rX   r<   z$CodeGeneratorDraft04.generate_any_of   sH     	!!Q&!!)35AAA#/8 	@ 	@O@X]^^ @ @VVFUV33 O O11/4>SWSfx|1}}}FF@FNNNO O O O O O O O O O O O O O O >???	@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ VV<ETYVZZ 	S 	SHHC'HRRR	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	SsH   C!.;B5)C!5B99C!<B9=C!!C%	(C%	D**D.1D.c           	      t   | xj         dz  c_         | j         }|                     d|           | j        d         D ]}|                     d|d          5  |                     dd	          5  |                     || j        | j        d
           |                     d|           ddd           n# 1 swxY w Y   |                     d           ddd           n# 1 swxY w Y   |                     d|          5  d}|                     d||d           ddd           dS # 1 swxY w Y   dS )a  
        Means that value have to be valid by only one of those definitions. It can't be valid
        by two or more of them.

        .. code-block:: python

            {
                'oneOf': [
                    {'type': 'number', 'multipleOf': 3},
                    {'type': 'number', 'multipleOf': 5},
                ],
            }

        Valid values for this definition are 3, 5, 6, ... but not 15 for example.
        r   z"{variable}_one_of_count{count} = 0r~   r   z&if {variable}_one_of_count{count} < 2:Fr   r   r   Trx   z#{variable}_one_of_count{count} += 1Nr   z'if {variable}_one_of_count{count} != 1:z9" (" + str({variable}_one_of_count{}) + " matches found)"z.{name} must be valid exactly by one definition)append_to_msgrh   r   )rR   r   r|   dynamics       rX   r=   z$CodeGeneratorDraft04.generate_one_of   sP     	!!Q&!!)35AAA#/8 	@ 	@O@X]^^ @ @VVFUV33 O O11/4>SWSfx|1}}}FF@FNNNO O O O O O O O O O O O O O O >???	@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ VV=UVKK 	s 	sQGHHEu\cjqHrrr	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	s 	ssH   C!.;B5)C!5B99C!<B9=C!!C%	(C%	D--D14D1c                 X   | j         d         }|du r|                     dd           dS |du rdS |sM|                     d| j                  5  |                     dd           ddd           dS # 1 swxY w Y   dS |                     d	d
          5  |                     || j        | j                   ddd           n# 1 swxY w Y   |                     d           |                     d          5  |                     dd           ddd           dS # 1 swxY w Y   dS )aT  
        Means that value have not to be valid by this definition.

        .. code-block:: python

            {'not': {'type': 'null'}}

        Valid values for this definition are 'hello', 42, {} ... but not None.

        Since draft 06 definition can be boolean. False means nothing, True
        means everything is invalid.
        r    T{name} must not be thererg   FNzif {}:z-{name} must NOT match a disallowed definitionr   r   r   zelse:)ri   rn   rm   rl   rz   r{   )rR   not_definitions     rX   r>   z!CodeGeneratorDraft04.generate_not   sJ    )%0T! 	VHH/eH<<<<<u$ 
	VF 	V$.11 V VHuUUUV V V V V V V V V V V V V V V V V V // c c--ndndNabbbc c c c c c c c c c c c c c cFF:;;; V VHuUUUV V V V V V V V V V V V V V V V V Vs6   A33A7:A7"CC	C	:DD#&D#c                 p   |                      d          5  |                                  t          | j        d         t                    st          d          |                      d          5  |                     dd           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nif isinstance({variable}, str):r!   zminLength must be a numberz if {variable}_len < {minLength}:z={name} must be longer than or equal to {minLength} charactersrg   rm   create_variable_with_lengthrs   ri   r	   r   rn   rR   s    rX   r?   z(CodeGeneratorDraft04.generate_min_length   sZ   VV566 	l 	l,,...d.{;SAA R34PQQQ:;; l lX_jkkkl l l l l l l l l l l l l l l		l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l 	l6   AB+/BB+B	B+B	B++B/2B/c                 p   |                      d          5  |                                  t          | j        d         t                    st          d          |                      d          5  |                     dd           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r"   zmaxLength must be a numberz if {variable}_len > {maxLength}:z>{name} must be shorter than or equal to {maxLength} charactersrg   r   r   s    rX   r@   z(CodeGeneratorDraft04.generate_max_length   sZ   VV566 	m 	m,,...d.{;SAA R34PQQQ:;; m mY`klllm m m m m m m m m m m m m m m		m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	m 	mr   c                    |                      d          5  | j        d         }|                    dd                              dd          }t                              d|          }t          j        |          | j        |<   |                      dt          |                    5  | 	                    d	|d
           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r#   \z\\"z\"z\\Zz-if not REGEX_PATTERNS[{}].search({variable}):z{name} must match pattern {}rg   )
rm   ri   replaceDOLLAR_FINDERsubrecompile_compile_regexpsreprrn   )rR   r#   safe_patternend_of_string_fixed_patterns       rX   rA   z%CodeGeneratorDraft04.generate_pattern   s   VV566 	W 	W&y1G"??488@@eLLL*7*;*;FG*L*L'-/Z8S-T-TD!'*GgWW W W7IVVVW W W W W W W W W W W W W W W	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	Ws6   BC%(CC%C	C%C	C%%C),C)c                 \   |                      d          5  | j        d         }|| j        v r| j        |         }t          |t                    r|                     ||dz   |           n)|                      d|          5  |                     d|d           ddd           n# 1 swxY w Y   n|| j        v r(| j        |         }|                     ||dz   |           n|dk    r|                      d	d
          5  |                      d           ddd           n# 1 swxY w Y   |                      d          5  |                     dd           ddd           n# 1 swxY w Y   n"t          d	                    |                    ddd           dS # 1 swxY w Y   dS )z
        Means that value have to be in specified format. For example date, email or other.

        .. code-block:: python

            {'format': 'email'}

        Valid value for this definition is user@example.com but not @username
        r   r$   _re_patternz(if not custom_formats["{}"]({variable}):rf   rg   Nregexr   Fr   zre.compile({variable})zexcept Exception:z{name} must be a valid regexzUnknown format: {})
rm   ri   r5   rs   r
   _generate_formatrn   FORMAT_REGEXSr   r$   )rR   format_custom_formatformat_regexs       rX   rB   z$CodeGeneratorDraft04.generate_format   s    VV566 	Z 	Z&x0G$.. Z $ 4W =mS11 N))'7]3JMZZZZ JGTT N N!4gHMMMN N N N N N N N N N N N N N ND.. 
Z#1':%%gw/FUUUUG# ZVVFUV33 5 5FF34445 5 5 5 5 5 5 5 5 5 5 5 5 5 5VV/00 L LHH;(HKKKL L L L L L L L L L L L L L L 44H4O4OPW4X4XYYY)	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Zs   A+F!B&F!&B*	*F!-B*	.AF! D"F!"D&	&F!)D&	*F!E&F!&E*	*F!-E*	.&F!!F%(F%c                    | j         d         |k    rn|| j        vrt          j        |          | j        |<   |                     d|          5  |                     d|d           d d d            d S # 1 swxY w Y   d S d S )Nr$   z.if not REGEX_PATTERNS["{}"].match({variable}):rf   rg   )ri   r   r   r   rm   rn   )rR   format_nameregexp_nameregexps       rX   r   z%CodeGeneratorDraft04._generate_format  s    H%4 	J$"77 H57Z5G5G%k2H+VV J J,kIIIJ J J J J J J J J J J J J J J J J J	J 	Js   A33A7:A7c                    |                      d          5  t          | j        d         t          t          f          st          d          | j                            dd          rE|                      d          5  |                     dd           d d d            n# 1 swxY w Y   nD|                      d	          5  |                     d
d           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )N(if isinstance({variable}, (int, float)):r%   zminimum must be a numberexclusiveMinimumFzif {variable} <= {minimum}:z${name} must be bigger than {minimum}rg   zif {variable} < {minimum}:z0{name} must be bigger than or equal to {minimum}rm   rs   ri   r	   floatr   getrn   r   s    rX   rC   z%CodeGeneratorDraft04.generate_minimum  s   VV>?? 	a 	ad.y9C<HH P34NOOO##$6>> aVV9:: U UHHC)HTTTU U U U U U U U U U U U U U U VV899 a aHHOV_H```a a a a a a a a a a a a a a a	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	a 	aZ   A'C>=B!C>!B%	%C>(B%	)C>C&C>&C*	*C>-C*	.C>>DDc                    |                      d          5  t          | j        d         t          t          f          st          d          | j                            dd          rE|                      d          5  |                     dd           d d d            n# 1 swxY w Y   nD|                      d	          5  |                     d
d           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r&   zmaximum must be a numberexclusiveMaximumFzif {variable} >= {maximum}:z%{name} must be smaller than {maximum}rg   zif {variable} > {maximum}:z1{name} must be smaller than or equal to {maximum}r   r   s    rX   rD   z%CodeGeneratorDraft04.generate_maximum*  s   VV>?? 	b 	bd.y9C<HH P34NOOO##$6>> bVV9:: V VHHD9HUUUV V V V V V V V V V V V V V V VV899 b bHHPW`Haaab b b b b b b b b b b b b b b	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	br   c                 H   |                      d          5  t          | j        d         t          t          f          st          d          t          | j        d         t                    rD| j                            d           t          j	        | j
        d<   |                      d           n|                      d           |                      d          5  |                     d	d
           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r'   zmultipleOf must be a numberzfrom decimal import DecimalDecimalzBquotient = Decimal(repr({variable})) / Decimal(repr({multipleOf}))z$quotient = {variable} / {multipleOf}zif int(quotient) != quotient:z'{name} must be multiple of {multipleOf}rg   )rm   rs   ri   r	   r   r   _extra_imports_linesappenddecimalr   _extra_imports_objectsrn   r   s    rX   rE   z)CodeGeneratorDraft04.generate_multiple_of5  s   VV>?? 	W 	Wd.|<sElKK S34QRRR $*<8%@@ ?)001NOOO9@+I6[\\\\=>>>788 W WBVVVW W W W W W W W W W W W W W W	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	Ws6   CDC?3D?D	DD	DDDc                    |                                   |                     d          5  t          | j        d         t                    st          d          |                                  |                     d          5  |                     dd           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nif {variable}_is_list:r(   zminItems must be a numberzif {variable}_len < {minItems}:z-{name} must contain at least {minItems} itemsrg   create_variable_is_listrm   rs   ri   r	   r   r   rn   r   s    rX   rF   z'CodeGeneratorDraft04.generate_min_itemsD  sk   $$&&&VV,-- 	[ 	[d.z:C@@ Q34OPPP,,...9:: [ [HzZZZ[ [ [ [ [ [ [ [ [ [ [ [ [ [ [		[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[6   AB?B'B?'B+	+B?.B+	/B??CCc                    |                                   |                     d          5  t          | j        d         t                    st          d          |                                  |                     d          5  |                     dd           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r)   zmaxItems must be a numberzif {variable}_len > {maxItems}:z:{name} must contain less than or equal to {maxItems} itemsrg   r   r   s    rX   rG   z'CodeGeneratorDraft04.generate_max_itemsM  sl   $$&&&VV,-- 	h 	hd.z:C@@ Q34OPPP,,...9:: h hU\fgggh h h h h h h h h h h h h h h		h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	h 	hr   c                    | j         d         }|sdS |                                  |                     d          5  |                     d           |                                  |                     d          5  |                     dd           ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )a  
        With Python 3.4 module ``timeit`` recommended this solutions:

        .. code-block:: python

            >>> timeit.timeit("len(x) > len(set(x))", "x=range(100)+range(100)", number=100000)
            0.5839540958404541
            >>> timeit.timeit("len({}.fromkeys(x)) == len(x)", "x=range(100)+range(100)", number=100000)
            0.7094449996948242
            >>> timeit.timeit("seen = set(); any(i in seen or seen.add(i) for i in x)", "x=range(100)+range(100)", number=100000)
            2.0819358825683594
            >>> timeit.timeit("np.unique(x).size == len(x)", "x=range(100)+range(100); import numpy as np", number=100000)
            2.1439831256866455
        r*   Nr   zdef fn(var): return frozenset(dict((k, fn(v)) for k, v in var.items()).items()) if hasattr(var, "items") else tuple(fn(v) for v in var) if isinstance(var, (dict, list)) else str(var) if isinstance(var, bool) else varzNif {variable}_len > len(set(fn({variable}_x) for {variable}_x in {variable})):z {name} must contain unique itemsrg   )ri   r   rm   r   rn   )rR   unique_definitions     rX   rH   z*CodeGeneratorDraft04.generate_unique_itemsV  s{    !,];  	F$$&&&VV,-- 	Q 	QFF45 5 5 ,,...hii Q Q;-PPPQ Q Q Q Q Q Q Q Q Q Q Q Q Q Q	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Qs5   ?B6:BB6B"	"B6%B"	&B66B:=B:c                    | j         d         }|du rdS |                                  |                     d          5  |                                  |du rF|                     d          5  |                     dd           ddd           n# 1 swxY w Y   nt          |t                    rt          |          D ]\  }}|                     d	|          5  |                     d
|           |                     |d	                    | j
        |          d	                    | j        |                     ddd           n# 1 swxY w Y   | j        rBt          |t                    r-d|v r)|                     dt          |d                              d| j         v r| j         d         du rT|                     d	t          |                    5  |                     dd           ddd           n# 1 swxY w Y   nF|                     dt          |                    5  |                     | j         d         d	                    | j
                  d	                    | j        | j
                            }|dk    r|                     d           ddd           n# 1 swxY w Y   n|r|                     d          5  |                     |d	                    | j
                  d	                    | j        | j
                            }|dk    r|                     d           ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )a  
        Means array is valid only when all items are valid by this definition.

        .. code-block:: python

            {
                'items': [
                    {'type': 'integer'},
                    {'type': 'string'},
                ],
            }

        Valid arrays are those with integers or strings, nothing else.

        Since draft 06 definition can be also boolean. True means nothing, False
        means everything is invalid.
        r+   TNr   Fzif {variable}:r   rg   zif {variable}_len > {}:z!{variable}__{0} = {variable}[{0}]{}__{}z{}[{}]defaultzelse: {variable}.append({})additionalItemsz({name} must contain only specified itemszFfor {variable}_x, {variable}_item in enumerate({variable}[{0}:], {0}):z{}_itemz{}[{{{}_x}}]r   passz;for {variable}_x, {variable}_item in enumerate({variable}):)ri   r   rm   r   rn   rs   rt   	enumeraterz   r$   rl   r{   r6   r   r   len)rR   items_definitionidxitem_definitionr   s        rX   rI   z#CodeGeneratorDraft04.generate_itemsw  s+   $  +G4t# 	F$$&&&VV,-- '	+ '	+,,...5( %+VV,-- G GHH7gHFFFG G G G G G G G G G G G G G G,d33 "+,56F,G,G 	` 	`(C 93??  BCHHH55+$OODNC@@$OOD,?EE                 ( `Z-N-N `S\`oSo `<d?S\C]>^>^___$(88 /'(9:eC /!VV$=sCS?T?TUU _ _ HH%OV]H^^^_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ "VV$lnq  sC  oD  oD  E  E / /$($A$A $ 01B C ) 0 0 @ @ . 5 5d6I4> Z Z% %E
  %z / $v/ / / / / / / / / / / / / / / $ + ]^^ + + $ = =,%,,T^<<*11$2Et~VV! !
 !A: + FF6NNN+ + + + + + + + + + + + + + +A'	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+ '	+s   .M+BMB	MB	AMA E<MEMEB	MG=1M=H	MH	(M-A4J-!M-J1	1M4J1	5MA)M9MM			MM		MM!$M!c                    |                                   |                     d          5  t          | j        d         t                    st          d          |                                  |                     d          5  |                     dd           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nif {variable}_is_dict:r,   zminProperties must be a numberz$if {variable}_len < {minProperties}:z7{name} must contain at least {minProperties} propertiesrg   create_variable_is_dictrm   rs   ri   r	   r   r   rn   r   s    rX   rJ   z,CodeGeneratorDraft04.generate_min_properties  sl   $$&&&VV,-- 	j 	jd.?EE V34TUUU,,...>?? j jRYhiiij j j j j j j j j j j j j j j		j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	j 	jr   c                    |                                   |                     d          5  t          | j        d         t                    st          d          |                                  |                     d          5  |                     dd           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r-   zmaxProperties must be a numberz$if {variable}_len > {maxProperties}:zD{name} must contain less than or equal to {maxProperties} propertiesrg   r   r   s    rX   rK   z,CodeGeneratorDraft04.generate_max_properties  sl   $$&&&VV,-- 	w 	wd.?EE V34TUUU,,...>?? w w_fuvvvw w w w w w w w w w w w w w w		w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	w 	wr   c           	         |                                   |                     d          5  t          | j        d         t          t
          f          st          d          |                                  |                     d          5  |                     d| 	                    | j        d                   d           d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr   r.   zrequired must be an arrayz6if not all(prop in {variable} for prop in {required}):z!{name} must contain {} propertiesrg   )
r   rm   rs   ri   rt   ru   r   r   rn   rv   r   s    rX   rL   z&CodeGeneratorDraft04.generate_required  s   $$&&&VV,-- 	u 	ud.z:T5MJJ Q34OPPP,,...PQQ u u<dffTEUV`Ea>b>bistttu u u u u u u u u u u u u u u		u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	u 	us6   A C%
7CC%C	C%C	C%%C),C)c                 T   |                                   |                     d          5  |                                  | j        d                                         D ]\  }}t          j        dd|          }t          |t          t          f          s(t          d                    | j        |                    |                     d|                     |                    5  |                     d|                     |                     |                     d||                     |                     |                     |d	                    | j        |          d
                    | j        |                     |                    d           ddd           n# 1 swxY w Y   | j        rVt          |t                    rAd|v r=|                     d|                     |          t#          |d                              	 ddd           dS # 1 swxY w Y   dS )a  
        Means object with defined keys.

        .. code-block:: python

            {
                'properties': {
                    'key': {'type': 'number'},
                },
            }

        Valid object is containing key called 'key' and value any number.
        r   r0   z($[^a-zA-Z]|[^a-zA-Z0-9])rd   z{}[{}] must be objectzif "{}" in {variable}_keys:z{variable}_keys.remove("{}")z#{variable}__{0} = {variable}["{1}"]r   z{}.{}Trx   Nr   zelse: {variable}["{}"] = {})r   rm   create_variable_keysri   r+   r   r   rs   r   r   r   r$   rl   rv   rz   r{   r6   r   )rR   keyprop_definitionkey_names       rX   rN   z(CodeGeneratorDraft04.generate_properties  s    	$$&&&VV,-- 	i 	i%%'''(,(8(F(L(L(N(N i i$_6">CHH!/D$<@@ r78O8V8VW[Wego8p8pqqqVV9466#;;GG  FF9466#;;GGGFF@(DFFSVKKXXX11' AAt':DFF3KKHH(,	 2                  $ iOT)J)J iy\kOk iFF8$&&++tO\eLfGgGghhhi	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	i 	is8   B=H'B2F%H%F))H,F)-A"HH!$H!c                 r   |                                   |                     d          5  |                                  | j        d                                         D ]!\  }}t          j        |          | j        |<   "|                     d          5  | j        d                                         D ]\  }}|                     dt          |                    5  |                     d          5  |                     d           ddd           n# 1 swxY w Y   | 	                    |d
                    | j                  d	
                    | j        | j                  d
           ddd           n# 1 swxY w Y   	 ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )a4  
        Means object with defined keys as patterns.

        .. code-block:: python

            {
                'patternProperties': {
                    '^x': {'type': 'number'},
                },
            }

        Valid object is containing key starting with a 'x' and value any number.
        r   r1   z9for {variable}_key, {variable}_val in {variable}.items():z-if REGEX_PATTERNS[{}].search({variable}_key):z%if {variable}_key in {variable}_keys:z&{variable}_keys.remove({variable}_key)Nz{}_val{}.{{{}_key}}Trx   )r   rm   r   ri   r+   r   r   r   r   rz   r$   rl   r{   )rR   r#   rS   s      rX   rO   z0CodeGeneratorDraft04.generate_pattern_properties  s    	$$&&&VV,-- 	 	%%''''+'78K'L'R'R'T'T E E#13G1D1D%g..STT 
 
+/+;<O+P+V+V+X+X 	 	'GZ OQUV]Q^Q^__  !VV$KLL M M FF#KLLLM M M M M M M M M M M M M M M55&$OODN;;+2243FWW,0	 6                 	
 
 
 
 
 
 
 
 
 
 
 
 
 
 
		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   A+F,AFE;	3D	E;	DE;	DAE;	/F;E??FE?FF,F	F,F	F,,F03F0c                 x   |                                   |                     d          5  |                                  | j        d         }|du s|i k    r	 ddd           dS |rt	          | j                            di                                                     }|                     d          5  |                     d|          5  |                     d           |                     |d	                    | j	                  d
                    | j
        | j	                             ddd           n# 1 swxY w Y   ddd           n# 1 swxY w Y   nD|                     d          5  |                     dd           ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS )a  
        Means object with keys with values defined by definition.

        .. code-block:: python

            {
                'properties': {
                    'key': {'type': 'number'},
                }
                'additionalProperties': {'type': 'string'},
            }

        Valid object is containing key called 'key' and it's value any number and
        any other key with any string.
        r   r2   TNr0   z&for {variable}_key in {variable}_keys:zif {variable}_key not in {}:z1{variable}_value = {variable}.get({variable}_key)z{}_valuer   zif {variable}_keys:z;{name} must not contain "+str({variable}_keys)+" propertiesrg   )r   rm   r   ri   rt   r   keysrz   r$   rl   r{   rn   )rR   add_prop_definitionproperties_keyss      rX   rP   z3CodeGeneratorDraft04.generate_additional_properties  s     	$$&&&VV,-- 	y 	y%%'''"&"23I"J"d* .AR.G 		y 	y 	y 	y 	y 	y 	y 	y
 # y"&t'7';';L"'M'M'R'R'T'T"U"UVVDEE   >PP  RSSS55/&--dn==+2243FWW                               VV122 y yHHZawHxxxy y y y y y y y y y y y y y y!	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	y 	ys   -F/$AF/5EA#D;/E;D??ED?EF/E	F/E	F/3FF/F	F/F	F//F36F3c                 \   |                                   |                     d          5  d}| j        d                                         D ]/\  }}|g k    s|du rd}|                     d|                     |                    5  |du r|                     d|d           nt          |t                    r|D ]}|                     d|                     |                    5  |                     d	|                     |          |                     |          d           d
d
d
           n# 1 swxY w Y   n#|                     || j	        | j
        d           d
d
d
           n# 1 swxY w Y   1|r|                     d           d
d
d
           d
S # 1 swxY w Y   d
S )a  
        Means when object has property, it needs to have also other property.

        .. code-block:: python

            {
                'dependencies': {
                    'bar': ['foo'],
                },
            }

        Valid object is containing only foo, both bar and foo or none of them, but not
        object with only bar.

        Since draft 06 definition can be boolean or empty array. True and empty array
        means nothing, False means that key cannot be there at all.
        r   Tr/   Fzif "{}" in {variable}:z{} in {name} must not be thererg   zif "{}" not in {variable}:z#{name} missing dependency {} for {}Nrx   r   )r   rm   ri   r+   rv   rn   rs   rt   rz   rl   r{   )rR   is_emptyr   valuesvalues        rX   rM   z*CodeGeneratorDraft04.generate_dependencies6  s   $ 	$$&&&VV,-- 	 	H#/?EEGG y yVR< 6T>  VV4dffSkkBB y y y!A3^\\\\#FD11 y%+ A AE!%(DdffUmm!T!T A A $)NPTPVPVW\P]P]_c_e_efi_j_jq  !A  !A  !AA A A A A A A A A A A A A A AA 55fdndNasw5xxxy y y y y y y y y y y y y y y  v!	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s\   AF!A E0(A D4(E04D88E0;D8<(E0$F!0E44F!7E48F!!F%(F%)!__name__
__module____qualname__r   r4   propertyr\   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   r   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rN   rO   rP   rM   __classcell__)rW   s   @rX   r   r      sQ        D) Ni y' M -1"$ & & & & & &B     X
K K K,L L L v v v&S S S<s s s>V V V8l l lm m mW W WZ Z ZBJ J J	a 	a 	a	b 	b 	bW W W[ [ [h h hQ Q QB>+ >+ >+@j j jw w wu u ui i iB  >"y "y "yH# # # # # # #rY   r   )r   r   
exceptionsr   	generatorr   r   r`   r   r   r    rY   rX   <module>r      s     				 5 5 5 5 5 5 2 2 2 2 2 2 2 2    
<((C	 C	 C	 C	 C	= C	 C	 C	 C	 C	rY   