
    MhXx                         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, Decimal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	d	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])\ZzS^((25[0-5]|2[0-4][0-9]|1?[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_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use_formatsdetailed_exceptions	__class__s          V/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/fastjsonschema/draft04.pyr4   zCodeGeneratorDraft04.__init__%   sp   X/BCCC&'''..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   )rS   resrZ   s     r[   r_   z!CodeGeneratorDraft04.global_stateG   s"    gg" $ 4
r\   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     r[   	<genexpr>z5CodeGeneratorDraft04.generate_type.<locals>.<genexpr>X   s(      $P$PQ%=a%@$P$P$P$P$P$Pr\   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)rS   typespython_typesrr   extras        r[   r:   z"CodeGeneratorDraft04.generate_typeM   ss    T-f566	P99$P$P%$P$P$PPPLL 	P 	P 	P/0B0I0I#0N0NOOO	P e!3!3%9O9O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 {}rk   N)rm   
isinstancelisttupler   rq   rr   e)rS   r   s     r[   r;   z"CodeGeneratorDraft04.generate_enumc   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)rm   generate_func_code_blockrp   _variable_name)rS   definition_items     r[   r<   z$CodeGeneratorDraft04.generate_all_ofs   sO       $/8 	v 	vO))/4>4K^pt)uuuu	v 	vr\   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   Tr|   z#{variable}_any_of_count{count} += 1N%except JsonSchemaValueException: passz,{name} cannot be validated by any definitionrk   rR   rq   rm   r~   rp   r   rr   )rS   r   r   s      r[   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   Tr|   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_msgrl   r   )rS   r   r   dynamics       r[   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                    | j         d         }|du r|                     dd           dS |du rdS |s|                     dd           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 thererk   FNz-{name} must NOT match a disallowed definitionr   r   r   zelse:)rm   rr   rq   r~   rp   r   )rS   not_definitions     r[   r?   z!CodeGeneratorDraft04.generate_not   s    )%0T!!HH/eH<<<<<u$$F 	VHHD5HQQQQQ// 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s$   #"BBBC++C/2C/c                 ~   |                      d          5  |                                  t          | j        d         t          t
          f          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} charactersrk   rq   create_variable_with_lengthrw   rm   r	   floatr   rr   rS   s    r[   r@   z(CodeGeneratorDraft04.generate_min_length   s^   VV566 	l 	l,,...d.{;c5\JJ 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 B26BB2B	B2!B	"B22B69B6c                 ~   |                      d          5  |                                  t          | j        d         t          t
          f          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} charactersrk   r   r   s    r[   rA   z(CodeGeneratorDraft04.generate_max_length   s^   VV566 	m 	m,,...d.{;c5\JJ 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 {}rk   )
rq   rm   replaceDOLLAR_FINDERsubrecompile_compile_regexpsreprrr   )rS   r#   safe_patternend_of_string_fixed_patterns       r[   rB   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                 ~   | j         sdS |                     d          5  | j        d         }|| j        v r| j        |         }t	          |t
                    r|                     ||dz   |           n1|                     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    rd	g| _	        |                     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
        Nr   r$   _re_patternz(if not custom_formats["{}"]({variable}):rj   rk   regexz	import rer   Fr   zre.compile({variable})zexcept Exception:z{name} must be a valid regexzUnknown format: {})r6   rq   rm   r5   rw   r
   _generate_formatrr   FORMAT_REGEXS_extra_imports_linesr   r$   )rS   format_custom_formatformat_regexs       r[   rC   z$CodeGeneratorDraft04.generate_format   s      	FVV566 	Z 	Z&x0G$... $ 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...#1':%%gw/FUUUUG##-8M)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+F2
B/#F2/B3	3F26B3	7AF2D3'F23D7	7F2:D7	;F2E7+F27E;	;F2>E;	?&F22F69F6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}):rj   rk   )rm   r   r   r   rq   rr   )rS   format_nameregexp_nameregexps       r[   r   z%CodeGeneratorDraft04._generate_format  s    H%44$"77757Z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 54s   A33A7:A7c                 ,   |                      d          5  t          | j        d         t          t          t
          j        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 )N1if isinstance({variable}, (int, float, Decimal)):r%   zminimum must be a numberexclusiveMinimumFzif {variable} <= {minimum}:z${name} must be bigger than {minimum}rk   zif {variable} < {minimum}:z0{name} must be bigger than or equal to {minimum}
rq   rw   rm   r	   r   decimalDecimalr   getrr   r   s    r[   rD   z%CodeGeneratorDraft04.generate_minimum"  s   VVGHH 	a 	ad.y9C;XYY 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   A2D	B, D	,B0	0D	3B0	4D	C1%D	1C5	5D	8C5	9D		DDc                 ,   |                      d          5  t          | j        d         t          t          t
          j        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}rk   zif {variable} > {maximum}:z1{name} must be smaller than or equal to {maximum}r   r   s    r[   rE   z%CodeGeneratorDraft04.generate_maximum-  s   VVGHH 	b 	bd.y9C;XYY 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                    |                      d          5  t          | j        d         t          t          t
          j        f          st          d          t          | j        d         t                    r|                      d           n|                      d           |                      d          5  |                     d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   d d d            d S # 1 swxY w Y   d S )Nr   r'   zmultipleOf must be a numberzBquotient = Decimal(repr({variable})) / Decimal(repr({multipleOf}))z$quotient = {variable} / {multipleOf}zif int(quotient) != quotient:z'{name} must be multiple of {multipleOf}rk   z-if {variable} / {multipleOf} == float("inf"):zinifinity reached)	rq   rw   rm   r	   r   r   r   r   rr   r   s    r[   rF   z)CodeGeneratorDraft04.generate_multiple_of8  s'   VVGHH 	A 	Ad.|<sE7?>[\\ S34QRRR $*<8%@@ ?[\\\\=>>>788 W WBVVVW W W W W W W W W W W W W W W GH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 	A 	AsZ   B"D88CD8C 	 D8#C 	$D8<D D8 D$	$D8'D$	(D88D<?D<c                    |                                   |                     d          5  t          | j        d         t          t
          f          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} itemsrk   	create_variable_is_listrq   rw   rm   r	   r   r   r   rr   r   s    r[   rG   z'CodeGeneratorDraft04.generate_min_itemsH  so   $$&&&VV,-- 	[ 	[d.z:S%LII Q34OPPP,,...9:: [ [HzZZZ[ [ [ [ [ [ [ [ [ [ [ [ [ [ [		[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[ 	[6   A C
B."C.B2	2C5B2	6CC
C
c                    |                                   |                     d          5  t          | j        d         t          t
          f          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} itemsrk   r   r   s    r[   rH   z'CodeGeneratorDraft04.generate_max_itemsQ  sp   $$&&&VV,-- 	h 	hd.z:S%LII 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 itemsrk   )rm   r   rq   r   rr   )rS   unique_definitions     r[   rI   z*CodeGeneratorDraft04.generate_unique_itemsZ  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   rk   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}):)rm   r   rq   r   rr   rw   rx   	enumerater~   r$   rp   r   r7   r   r   len)rS   items_definitionidxitem_definitionr   s        r[   rJ   z#CodeGeneratorDraft04.generate_items{  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\`oSoSo<d?S\C]>^>^___$(888'(9:eC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
  %zz $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          t
          f          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} propertiesrk   	create_variable_is_dictrq   rw   rm   r	   r   r   r   rr   r   s    r[   rK   z,CodeGeneratorDraft04.generate_min_properties  sp   $$&&&VV,-- 	j 	jd.?#uNN 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          t
          f          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} propertiesrk   r   r   s    r[   rL   z,CodeGeneratorDraft04.generate_max_properties  sp   $$&&&VV,-- 	w 	wd.?#uNN 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           	      N                                                            d          5  t           j        d         t          t
          f          st          d          t           j        d                   t          t           j        d                             k    rt          d           j        	                    dd          sC fd j        d         D             }|r(t          d
                     j        |                                         d	                                d
          5  d}                     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 arrayz%required must contain unique elementsr2   Tc           	          g | ]Uj                             d i           vt          fdj                             di           D                       SVS )r0   c              3   B   K   | ]}t          j        |          V  d S rc   )r   search)re   r   props     r[   rg   zDCodeGeneratorDraft04.generate_required.<locals>.<listcomp>.<genexpr>  s/      #v#vuBIeT$:$:#v#v#v#v#v#vr\   r1   )rm   r   any)re   r   rS   s    @r[   
<listcomp>z:CodeGeneratorDraft04.generate_required.<locals>.<listcomp>  s          D$4$8$8r$J$JJJ ##v#v#v#vHXH\H\]prtHuHu#v#v#v v v K  KJJr\   z){}: items {} are required but not allowedz>{variable}__missing_keys = set({required}) - {variable}.keys()zif {variable}__missing_keys:z5str(sorted({variable}__missing_keys)) + " properties"z{name} must contain )rl   r   )r   rq   rw   rm   rx   ry   r   r   setr   r$   rp   rr   rz   )rS   not_possibler   s   `  r[   rM   z&CodeGeneratorDraft04.generate_required  sa   $$&&&VV,-- 	 	d.z:T5MJJ Q34OPPP4#J/00CD<LZ<X8Y8Y4Z4ZZZ34[\\\#''(>EE 	J        $ 0 <        J78c8j8jkoky  |H  9I  9I  J  J  JFFSTTT677  Q/8H8T1U1U\fv}~~~              !	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s6   DF<:F6FF	F	F	
FF!F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])rh   z{}[{}] must be objectzif "{}" in {variable}_keys:z{variable}_keys.remove("{}")z#{variable}__{0} = {variable}["{1}"]r   z{}.{}Tr|   Nr   zelse: {variable}["{}"] = {})r   rq   create_variable_keysrm   r+   r   r   rw   r   r   r   r$   rp   rz   r~   r   r7   r   )rS   keyprop_definitionkey_names       r[   rO   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\kOkOk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}}Tr|   )r   rq   r   rm   r+   r   r   r   r   r~   r$   rp   r   )rS   r#   rT   s      r[   rP   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)+" propertiesrk   )r   rq   r   rm   rx   r   keysr~   r$   rp   r   rr   )rS   add_prop_definitionproperties_keyss      r[   rQ   z3CodeGeneratorDraft04.generate_additional_properties#  s     	$$&&&VV,-- 	y 	y%%'''"&"23I"J"d**.AR.G.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 thererk   zif "{}" not in {variable}:z#{name} missing dependency {} for {}Nr|   r   )r   rq   rm   r+   rz   rr   rw   rx   r~   rp   r   )rS   is_emptyr   valuesvalues        r[   rN   z*CodeGeneratorDraft04.generate_dependenciesG  s   $ 	$$&&&VV,-- 	 	H#/?EEGG y yVR<<6T>> VV4dffSkkBB 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_   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   r   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rO   rP   rQ   rN   __classcell__)rZ   s   @r[   r   r      sW        DB Nf y' M -1"$\`vz  &  &  &  &  &  &D     X
K K K,L L L v v v&S S S<s s s>V V V6l l lm m mW W W!Z !Z !ZHJ J J	a 	a 	a	b 	b 	bA A A [ [ [h h hQ Q QB>+ >+ >+@j j jw w w  ,i i iB  >"y "y "yH# # # # # # #r\   r   )r   r   
exceptionsr   	generatorr   r   rd   r   r   r    r\   r[   <module>r      s     				 5 5 5 5 5 5 2 2 2 2 2 2 2 2 #   
<((T	 T	 T	 T	 T	= T	 T	 T	 T	 T	r\   