U
    ꥡcN                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZda	dd Z
dd Zejdd Zd	d
 Zdd ZdddZG dd dejZG dd deZe ZG dd deZdd ZG dd deZdS )    NTc                   C   s   da d S NT
DEBUG_MODE r   r   9/tmp/pip-unpacked-wheel-y9_o96ar/altair/utils/schemapi.pyenable_debug_mode   s    r   c                   C   s   da d S r   r   r   r   r   r   disable_debug_mode   s    r   c                 c   s   t }| a z
d V  W 5 |a X d S Nr   )argoriginalr   r   r   
debug_mode   s
    
r   c                 c   sF   t  }| h}|rB||O }t jdd |D  }|| D ]
} | V  q4qdS )z=Breadth-first sequence of all classes which inherit from cls.c                 s   s   | ]}t | V  qd S r	   )set__subclasses__).0clsr   r   r   	<genexpr>0   s     z_subclasses.<locals>.<genexpr>N)r   union)r   seenZcurrent_setr   r   r   _subclasses*   s    r   c                    s   t | tr| j dS t | tttjfr> fdd| D S t | tr` fdd|  D S t	| drr|  S t | tj
rt| S t | tjtjfrt|  S | S dS )z+Convert an object to a dict representation.validatecontextc                    s   g | ]}t | qS r   )_todictr   vr   r   r   r   
<listcomp>:   s     z_todict.<locals>.<listcomp>c                    s&   i | ]\}}|t k	r|t| qS r   )	Undefinedr   r   kr   r   r   r   
<dictcomp><   s    z_todict.<locals>.<dictcomp>to_dictN)
isinstance
SchemaBaser!   listtuplenpZndarraydictitemshasattrnumberfloatpdZ	TimestampZ
datetime64	isoformat)objr   r   r   r   r   r   5   s    


r   c              	   C   s<   t j|p| }d| kr8|| d 
}|} W 5 Q R X q| S )zResolve schema references.z$ref)
jsonschemaRefResolverfrom_schemaZ	resolving)schemarootresolverZresolvedr   r   r   _resolve_referencesK   s
    r5   c                       s4   e Zd ZdZ fddZedd Zdd Z  ZS )SchemaValidationErrorzBA wrapper for jsonschema.ValidationError with friendlier tracebackc                    s"   t t| jf | | || _d S r	   )superr6   __init___get_contentsr.   )selfr.   err	__class__r   r   r8   W   s    zSchemaValidationError.__init__c                    st   z   }W nb tk
rn   zt j}W n  tk
rL   t j}Y nX  fdd|jdd D }Y nX |S )z7Get a dictionary with the contents of a ValidationErrorc                    s   i | ]}|t  |qS r   )getattr)r   keyr;   r   r   r    h   s      z7SchemaValidationError._get_contents.<locals>.<dictcomp>   N)Z	_contentsAttributeErrorinspectgetfullargspecr8   
getargspecargs)r;   contentsspecr   r@   r   r9   [   s    "z#SchemaValidationError._get_contentsc                 C   sT   | j j}d|j|jg}|| j ddd |d d D }d|| j| j	S )Nz{}.{}z->c                 s   s   | ]}|d krt |V  qdS ))
propertiesZadditionalPropertiesZpatternPropertiesN)strr   valr   r   r   r   o   s   z0SchemaValidationError.__str__.<locals>.<genexpr>zGInvalid specification

        {}, validating {!r}

        {}
        )
r.   r=   format
__module____name__extendschema_pathjoinZ	validatormessage)r:   r   rR   r   r   r   __str__k   s    

  zSchemaValidationError.__str__)	rP   rO   __qualname____doc__r8   staticmethodr9   rU   __classcell__r   r   r<   r   r6   T   s
   
r6   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )UndefinedTypez3A singleton object for marking undefined attributesNc                 O   s&   t | j| s tj| f||| _| jS r	   )r"   _UndefinedType__instanceobject__new__)r   rF   kwargsr   r   r   r]      s    zUndefinedType.__new__c                 C   s   dS )Nr   r   r:   r   r   r   __repr__   s    zUndefinedType.__repr__)rP   rO   rV   rW   r[   r]   r`   r   r   r   r   rZ   ~   s   rZ   c                       s   e Zd ZdZdZdZdZejZ	dd Z
d*ddZefd	d
Z fddZdd Zdd Zdd Zdd Zdd Zd+ddZdg i ddfddZedd Zed,ddZed-d d!Zed.d"d#Zed/d$d%Zed0d&d'Zd(d) Z  ZS )1r#   zBase class for schema wrappers.

    Each derived class should set the _schema class attribute (and optionally
    the _rootschema class attribute) which is used for validation.
    NTc                 O   sv   | j d krtd| j|r0t|dks@tnt|dks@tt| d| t| d| trr| j	rr| j
dd d S )NzMCannot instantiate object of type {}: _schema class attribute is not defined.r   )r   rA   _args_kwdsTr   )_schema
ValueErrorrN   r=   lenAssertionErrorr\   __setattr__r    _class_is_valid_at_instantiationr!   )r:   rF   kwdsr   r   r   r8      s    

zSchemaBase.__init__r   c              	      s   dd }d	 fdd	 zt |}W n tk
r:   d}Y nX d}|rT|sT | |dS td | j| j| j}W 5 Q R X |r|D ]}|||||< q|S )
a  Return a copy of the object

        Parameters
        ----------
        deep : boolean or list, optional
            If True (default) then return a deep copy of all dict, list, and
            SchemaBase objects within the object structure.
            If False, then only copy the top object.
            If a list or iterable, then only copy the listed attributes.
        ignore : list, optional
            A list of keys for which the contents should not be copied, but
            only stored by reference.
        c                 S   sF   t | tr| jddS t | tr,| d d  S t | tr>|  S | S d S )NF)deep)r"   r#   copyr$   r'   )r.   r   r   r   _shallow_copy   s    


z&SchemaBase.copy.<locals>._shallow_copyr   c              
      s   t | trftfdd| jD } fdd| j D }td | j||W  5 Q R  S Q R X nDt | tr fdd| D S t | t	r fdd|  D S | S d S )	Nc                 3   s   | ]} |V  qd S r	   r   )r   r
   
_deep_copyr   r   r      s     z6SchemaBase.copy.<locals>._deep_copy.<locals>.<genexpr>c                    s*   i | ]"\}}||kr" |d n|qS ignorer   r   ro   rr   r   r   r       s    z7SchemaBase.copy.<locals>._deep_copy.<locals>.<dictcomp>Fc                    s   g | ]} |d qS rp   r   r   rs   r   r   r      s     z7SchemaBase.copy.<locals>._deep_copy.<locals>.<listcomp>c                    s*   i | ]"\}}||kr" |d n|qS rp   r   r   rs   r   r   r       s    )
r"   r#   r%   ra   rb   r(   r   r=   r$   r'   )r.   rr   rF   rj   rn   rq   r   ro      s    

 

z#SchemaBase.copy.<locals>._deep_copyFTrq   )r   )r$   	TypeErrorr   r=   ra   rb   _get)r:   rk   rr   rm   Zdeep_is_listrl   attrr   rn   r   rl      s    


zSchemaBase.copyc                 C   s   | j |t}|tkr|}|S )z3Get an attribute, returning default if not present.)rb   getr   )r:   rv   defaultr   r   r   ru      s    zSchemaBase._getc                    s`   |dkrt  || jkr"| j| S ztt| j}W n  t k
rR   tt| j}Y nX ||S d S )Nrb   )rB   rb   r7   r#   __getattr____getattribute__)r:   rv   Z_getattrr<   r   r   ry      s    

zSchemaBase.__getattr__c                 C   s   || j |< d S r	   rb   r:   itemrL   r   r   r   rh     s    zSchemaBase.__setattr__c                 C   s
   | j | S r	   r{   )r:   r}   r   r   r   __getitem__  s    zSchemaBase.__getitem__c                 C   s   || j |< d S r	   r{   r|   r   r   r   __setitem__
  s    zSchemaBase.__setitem__c                 C   s^   | j rDdd t| j  D }dd| }d| jj|ddS d| jj| jd S d S )	Nc                 s   s&   | ]\}}|t k	rd ||V  qdS )z{}: {!r}N)r   rN   r   r?   rL   r   r   r   r     s   z&SchemaBase.__repr__.<locals>.<genexpr>
z,
z{0}({{{1}
}})z
  z{}({!r})r   )	rb   sortedr(   rS   rN   r=   rP   replacera   )r:   rF   r   r   r   r`     s     
zSchemaBase.__repr__c                 C   s(   t | t |ko&| j|jko&| j|jkS r	   )typera   rb   )r:   otherr   r   r   __eq__  s
    

zSchemaBase.__eq__c              
      s   |dkri } dkrg  |dkr$dnd}| j rJ| jsJt| j d ||d}n:| j stt fdd| j D ||d}ntd| j|rz| | W n. tj	k
r } zt
| |W 5 d}~X Y nX |S )	a  Return a dictionary representation of the object

        Parameters
        ----------
        validate : boolean or string
            If True (default), then validate the output dictionary
            against the schema. If "deep" then recursively validate
            all objects in the spec. This takes much more time, but
            it results in friendlier tracebacks for large objects.
        ignore : list
            A list of keys to ignore. This will *not* passed to child to_dict
            function calls.
        context : dict (optional)
            A context dictionary that will be passed to all child to_dict
            function calls

        Returns
        -------
        dct : dictionary
            The dictionary representation of this object

        Raises
        ------
        jsonschema.ValidationError :
            if validate=True and the dict does not conform to the schema
        Nrk   Fr   r   c                    s   i | ]\}}| kr||qS r   r   r   rq   r   r   r    G  s       z&SchemaBase.to_dict.<locals>.<dictcomp>zF{} instance has both a value and properties : cannot serialize to dict)ra   rb   r   r(   re   rN   r=   r   r/   ValidationErrorr6   )r:   r   rr   r   Zsub_validateresultr;   r   rq   r   r!   "  s0    zSchemaBase.to_dict   c                 K   s(   | j |||d}tj|f||d|S )a  Emit the JSON representation for this object as a string.

        Parameters
        ----------
        validate : boolean or string
            If True (default), then validate the output dictionary
            against the schema. If "deep" then recursively validate
            all objects in the spec. This takes much more time, but
            it results in friendlier tracebacks for large objects.
        ignore : list
            A list of keys to ignore. This will *not* passed to child to_dict
            function calls.
        context : dict (optional)
            A context dictionary that will be passed to all child to_dict
            function calls
        indent : integer, default 2
            the number of spaces of indentation to use
        sort_keys : boolean, default True
            if True, sort keys in the output
        **kwargs
            Additional keyword arguments are passed to ``json.dumps()``

        Returns
        -------
        spec : string
            The JSON specification of the chart object.
        )r   rr   r   )indent	sort_keys)r!   jsondumps)r:   r   rr   r   r   r   r^   dctr   r   r   to_jsonW  s    zSchemaBase.to_jsonc                 C   s   t tS )z5Return the set of classes used within cls.from_dict())r   r#   r   r   r   r   _default_wrapper_classesx  s    z#SchemaBase._default_wrapper_classesc                 C   s2   |r|  | |dkr|  }t|}||| S )a  Construct class from a dictionary representation

        Parameters
        ----------
        dct : dictionary
            The dict from which to construct the class
        validate : boolean
            If True (default), then validate the input against the schema.
        _wrapper_classes : list (optional)
            The set of SchemaBase classes to use when constructing wrappers
            of the dict inputs. If not specified, the result of
            cls._default_wrapper_classes will be used.

        Returns
        -------
        obj : Schema object
            The wrapped schema

        Raises
        ------
        jsonschema.ValidationError :
            if validate=True and dct does not conform to the schema
        N)r   r   	_FromDict	from_dict)r   r   r   Z_wrapper_classes	converterr   r   r   r   }  s    
zSchemaBase.from_dictc                 K   s   t j|f|}| j||dS )a  Instantiate the object from a valid JSON string

        Parameters
        ----------
        json_string : string
            The string containing a valid JSON chart specification.
        validate : boolean
            If True (default), then validate the input against the schema.
        **kwargs :
            Additional keyword arguments are passed to json.loads

        Returns
        -------
        chart : Chart object
            The altair Chart object built from the specification.
        rc   )r   loadsr   )r   Zjson_stringr   r^   r   r   r   r   	from_json  s    zSchemaBase.from_jsonc                 C   s6   |dkr| j }tj| jp| j }tj||| j|dS )zj
        Validate the instance against the class schema in the context of the
        rootschema.
        N)r   r4   )rd   r/   r0   r1   _rootschemar   
_validator)r   instancer2   r4   r   r   r   r     s       zSchemaBase.validatec                 C   s   t |p
| j| jp| jp|dS )zIResolve references in the context of this object's schema or root schema.)r2   r3   )r5   rd   r   )r   r2   r   r   r   resolve_references  s    zSchemaBase.resolve_referencesc                 C   sR   t |di d}| |p| jdi }tj| jp6| j}tj|||i |dS )zf
        Validate a property against property schema in the context of the
        rootschema
        Fr   rI   r4   )	r   r   rd   rw   r/   r0   r1   r   r   )r   namevaluer2   propsr4   r   r   r   validate_property  s    zSchemaBase.validate_propertyc                 C   s   t | j S r	   )r$   rb   keysr_   r   r   r   __dir__  s    zSchemaBase.__dir__)Tr   )TNN)TN)T)N)N)N)rP   rO   rV   rW   rd   r   ri   r/   ZDraft7Validatorr   r8   rl   r   ru   ry   rh   r~   r   r`   r   r!   r   classmethodr   r   r   r   r   r   r   rY   r   r   r<   r   r#      sD   
=
6    
!

r#   c                  O   s   | r| d S |S )Nr   r   )rF   rj   r   r   r   _passthrough  s    r   c                   @   s<   e Zd ZdZdZdd ZedddZdddefd	d
Z	dS )r   a!  Class used to construct SchemaBase class hierarchies from a dict

    The primary purpose of using this class is to be able to build a hash table
    that maps schemas to their wrapper classes. The candidate classes are
    specified in the ``class_list`` argument to the constructor.
    )Zdefinitionstitledescriptionz$schemaidc                 C   s<   t t| _|D ]&}|jd k	r| j| |j | qd S r	   )collectionsdefaultdictr$   
class_dictrd   hash_schemaappend)r:   Z
class_listr   r   r   r   r8     s    
z_FromDict.__init__Tc                    s\   j r&t|tr&fdd| D }|r@tj|dd}t|S  fdd t |S dS )a  
        Compute a python hash for a nested dictionary which
        properly handles dicts, lists, sets, and tuples.

        At the top level, the function excludes from the hashed schema all keys
        listed in `exclude_keys`.

        This implements two methods: one based on conversion to JSON, and one based
        on recursive conversions of unhashable to hashable types; the former seems
        to be slightly faster in several benchmarks.
        c                    s    i | ]\}}| j kr||qS r   )_hash_exclude_keysr   r   r   r   r      s   
 z)_FromDict.hash_schema.<locals>.<dictcomp>T)r   c                    sf   t | tr$t fdd|  D S t | tr<tt | S t | tsPt | tr^tt | S | S d S )Nc                 3   s   | ]\}}| |fV  qd S r	   r   r   _freezer   r   r     s     z9_FromDict.hash_schema.<locals>._freeze.<locals>.<genexpr>)r"   r'   	frozensetr(   r   mapr$   r%   )rL   r   r   r   r     s    

z&_FromDict.hash_schema.<locals>._freezeN)r   r"   r'   r(   r   r   hash)r   r2   Zuse_jsonsr   )r   r   r   r     s    

z_FromDict.hash_schemaNc              	      s  |dk|dkkrt d|dkr4|p(|j}p2|jp:|t|trJ|S |dkrtj| }|rp|d }n|}t|}d|ksd|kr|dg |dg  }|D ]V}t	j
}	zt	j|||	d W n t	jk
r   Y qY qX j|||d  S qt|trd|di }
i }| D ]0\}}||
krNj||
| d	}|||< q(|f |S t|tr|d
i   fdd|D }||S ||S dS )z.Construct an object from a dict representationNz0Must provide either cls or schema, but not both.r   ZanyOfoneOfr   )r2   
rootschemadefault_classrI   r2   r   r(   c                    s   g | ]}j | d qS )r   )r   rK   Zitem_schemar   r:   r   r   r   E  s   z'_FromDict.from_dict.<locals>.<listcomp>)re   rd   r   r"   r#   r   r   r5   rw   r/   r0   r1   r   r   r   r'   r(   r$   )r:   r   r   r2   r   r   matchesZschemasZpossible_schemar4   r   rj   r?   rL   r   r   r   r     sV    







z_FromDict.from_dict)T)
rP   rO   rV   rW   r   r8   r   r   r   r   r   r   r   r   r     s   $   r   )N)r   
contextlibrC   r   r/   Znumpyr&   Zpandasr,   r   r   r   contextmanagerr   r   r   r5   r   r6   r\   rZ   r   r#   r   r   r   r   r   r   <module>   s,   


	*  I